freeipa/ipaserver/plugins/serverroles.py
Martin Babinsky f4d77533f5 *config-show: Do not show empty roles/attributes
If the role or attribute is empty (i.e. no server provides the role or
the caller has no read access to  the required information) do not
return empty attributes. This is consistent with other behavior
displayed by optional multivalued Params.

https://pagure.io/freeipa/issue/7029

Reviewed-By: Martin Basti <mbasti@redhat.com>
2017-07-04 14:42:43 +02:00

156 lines
5.0 KiB
Python

#
# 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):
result = {}
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]
if enabled_masters:
result.update({role.attr_name: enabled_masters})
return result
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
for name, attr in assoc_attributes.items():
attr_value = attr.get(self.api)
if attr_value:
result.update({name: attr_value})
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)))