mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-01-12 09:11:55 -06:00
f4d77533f5
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>
156 lines
5.0 KiB
Python
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)))
|