mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-25 16:31:08 -06:00
56d97f942b
config-show only used to show enabled servers. Now also show hidden servers on separate lines. Additionally include information about KRA and DNS servers. The augmented config-show output makes it easier to diagnose a cluster and simplifies sanity checks. Fixes: https://pagure.io/freeipa/issue/7892 Signed-off-by: Christian Heimes <cheimes@redhat.com> Reviewed-By: Francois Cami <fcami@redhat.com> Reviewed-By: Thomas Woerner <twoerner@redhat.com>
179 lines
6.1 KiB
Python
179 lines
6.1 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, HIDDEN, role_instances
|
|
)
|
|
from ipaserver.servroles import SingleValuedServerAttribute
|
|
|
|
|
|
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_masters(self, role_name, include_hidden):
|
|
result = {}
|
|
role = self._get_role(role_name)
|
|
role_states = role.status(self.api, server=None)
|
|
|
|
enabled_masters = [
|
|
r[u'server_server'] for r in role_states if
|
|
r[u'status'] == ENABLED
|
|
]
|
|
if enabled_masters:
|
|
result.update({role.attr_name: enabled_masters})
|
|
|
|
if include_hidden and role.attr_name_hidden is not None:
|
|
hidden_masters = [
|
|
r[u'server_server'] for r in role_states if
|
|
r[u'status'] == HIDDEN
|
|
]
|
|
if hidden_masters:
|
|
result.update({role.attr_name_hidden: hidden_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, include_hidden=True):
|
|
result = self._get_masters(servrole, include_hidden=include_hidden)
|
|
|
|
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:
|
|
# attr can be a SingleValuedServerAttribute
|
|
# in this case, the API expects a value, not a list of values
|
|
if isinstance(attr, SingleValuedServerAttribute):
|
|
attr_value = attr_value[0]
|
|
result.update({name: attr_value})
|
|
|
|
return result
|
|
|
|
def config_update(self, **attrs_values):
|
|
for attr, value in attrs_values.items():
|
|
try:
|
|
# when the attribute is single valued, it will be stored
|
|
# in a SingleValuedServerAttribute. The set method expects
|
|
# a list containing a single value.
|
|
# We need to convert value to a list containing value
|
|
if isinstance(self.attributes[attr],
|
|
SingleValuedServerAttribute):
|
|
value = [value]
|
|
self.attributes[attr].set(self.api, value)
|
|
except KeyError:
|
|
raise errors.NotFound(
|
|
reason=_('{attr}: no such attribute').format(attr=attr))
|