summaryrefslogtreecommitdiffstats
path: root/ipaserver
diff options
context:
space:
mode:
authorMartin Babinsky <mbabinsk@redhat.com>2016-05-19 11:24:18 +0200
committerMartin Basti <mbasti@redhat.com>2016-06-13 17:50:54 +0200
commitd07b7e0f6fe62eb10edcc7d3a4e884e5c8fd1d29 (patch)
tree734491d5197da7584ace58a6c917debee66e7c9b /ipaserver
parent7e2bef0b9f36a90902784be9363cbcb5ba4221b4 (diff)
downloadfreeipa-d07b7e0f6fe62eb10edcc7d3a4e884e5c8fd1d29.tar.gz
freeipa-d07b7e0f6fe62eb10edcc7d3a4e884e5c8fd1d29.tar.xz
freeipa-d07b7e0f6fe62eb10edcc7d3a4e884e5c8fd1d29.zip
Server Roles: Backend plugin to query roles and attributes
`serverroles` backend consumes the role/attribute instances defined in `ipaserver/servroles.py` module to provide low-level API for querying role/attribute status in the topology. This plugin shall be used to implement higher-level API commands. https://www.freeipa.org/page/V4/Server_Roles https://fedorahosted.org/freeipa/ticket/5181 Reviewed-By: Jan Cholasta <jcholast@redhat.com> Reviewed-By: Martin Basti <mbasti@redhat.com> Reviewed-By: Pavel Vomacka <pvomacka@redhat.com>
Diffstat (limited to 'ipaserver')
-rw-r--r--ipaserver/plugins/serverroles.py149
1 files changed, 149 insertions, 0 deletions
diff --git a/ipaserver/plugins/serverroles.py b/ipaserver/plugins/serverroles.py
new file mode 100644
index 000000000..4a44fca5a
--- /dev/null
+++ b/ipaserver/plugins/serverroles.py
@@ -0,0 +1,149 @@
+#
+# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
+#
+
+
+"""
+serverroles backend
+=======================================
+
+The `serverroles` backend has access to all roles and attributes stored in
+module-level lists exposed in `ipaserver/servroles.py` module. It uses these
+lists to populate populate its internal stores with instances of the
+roles/attributes. The information contained in them can be accessed by
+the following methods:
+
+ *api.Backend.serverroles.server_role_search(
+ server_server=None, role_servrole=None status=None)
+ search for roles matching the given substrings and return the status of
+ the matched roles. Optionally filter the result by role status. If
+ `server_erver` is not None, the search is limited to a single master.
+ Otherwise, the status is computed for all masters in the topology. If
+ `role_servrole` is None, the all configured roled are queried
+
+ *api.Backend.serverroles.server_role_retrieve(server_server, role_servrole)
+ retrieve the status of a single role on a given master
+
+ *api.Backend.serverroles.config_retrieve(role_servrole)
+ return a configuration object given role name. This object is a
+ dictionary containing a list of enabled masters and all attributes
+ associated with the role along with master(s) on which they are set.
+
+ *api.Backend.serverroles.config_update(**attrs_values)
+ update configuration object. Since server roles are currently
+ immutable, only attributes can be set
+
+Note that attribute/role names are searched/matched case-insensitively. Also
+note that the `serverroles` backend does not create/destroy any LDAP connection
+by itself, so make sure `ldap2` backend connections are taken care of
+in the calling code
+"""
+
+
+import six
+
+from ipalib import errors, _
+from ipalib.backend import Backend
+from ipalib.plugable import Registry
+from ipaserver.servroles import (attribute_instances, ENABLED, role_instances)
+
+
+if six.PY3:
+ unicode = str
+
+
+register = Registry()
+
+
+@register()
+class serverroles(Backend):
+ """
+ This Backend can be used to query various information about server roles
+ and attributes configured in the topology.
+ """
+
+ def __init__(self, api_instance):
+ super(serverroles, self).__init__(api_instance)
+
+ self.role_names = {
+ obj.name.lower(): obj for obj in role_instances}
+
+ self.attributes = {
+ attr.attr_name: attr for attr in attribute_instances}
+
+ def _get_role(self, role_name):
+ key = role_name.lower()
+
+ try:
+ return self.role_names[key]
+ except KeyError:
+ raise errors.NotFound(
+ reason=_("{role}: role not found".format(role=role_name)))
+
+ def _get_enabled_masters(self, role_name):
+ role = self._get_role(role_name)
+
+ enabled_masters = [
+ r[u'server_server'] for r in role.status(self.api, server=None) if
+ r[u'status'] == ENABLED]
+
+ return {role.attr_name: enabled_masters}
+
+ def _get_assoc_attributes(self, role_name):
+ role = self._get_role(role_name)
+ assoc_attributes = {
+ name: attr for name, attr in self.attributes.items() if
+ attr.associated_role is role}
+
+ if not assoc_attributes:
+ raise NotImplementedError(
+ "Role {} has no associated attribute to set".format(role.name))
+
+ return assoc_attributes
+
+ def server_role_search(self, server_server=None, role_servrole=None,
+ status=None):
+ if role_servrole is None:
+ found_roles = self.role_names.values()
+ else:
+ try:
+ found_roles = [self._get_role(role_servrole)]
+ except errors.NotFound:
+ found_roles = []
+
+ result = []
+ for found_role in found_roles:
+ role_status = found_role.status(self.api, server=server_server)
+
+ result.extend(role_status)
+
+ if status is not None:
+ return [r for r in result if r[u'status'] == status]
+
+ return result
+
+ def server_role_retrieve(self, server_server, role_servrole):
+ return self._get_role(role_servrole).status(
+ self.api, server=server_server)
+
+ def config_retrieve(self, servrole):
+ result = self._get_enabled_masters(servrole)
+
+ try:
+ assoc_attributes = self._get_assoc_attributes(servrole)
+ except NotImplementedError:
+ return result
+
+ result.update(
+ {name: attr.get(self.api) for name, attr in
+ assoc_attributes.items()})
+
+ return result
+
+ def config_update(self, **attrs_values):
+ for attr, value in attrs_values.items():
+ try:
+ self.attributes[attr].set(self.api, value)
+ except KeyError:
+ raise errors.NotFound(
+ reason=_('{attr}: no such attribute'.format(attr=attr)))