From de1a075b775fedc9f5e54f3e56634159de1e9ed8 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Mar 29 2019 08:55:13 +0000 Subject: Improve config-show to show hidden servers 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 Reviewed-By: Thomas Woerner Reviewed-By: Francois Cami --- diff --git a/ipaserver/plugins/config.py b/ipaserver/plugins/config.py index 4a24733..d67a929 100644 --- a/ipaserver/plugins/config.py +++ b/ipaserver/plugins/config.py @@ -250,21 +250,45 @@ class config(LDAPObject): flags={'virtual_attribute', 'no_create', 'no_update'} ), Str( + 'ipa_master_hidden_server*', + label=_('Hidden IPA masters'), + doc=_('List of all hidden IPA masters'), + flags={'virtual_attribute', 'no_create', 'no_update'} + ), + Str( + 'pkinit_server_server*', + label=_('IPA master capable of PKINIT'), + doc=_('IPA master which can process PKINIT requests'), + flags={'virtual_attribute', 'no_create', 'no_update'} + ), + Str( 'ca_server_server*', label=_('IPA CA servers'), doc=_('IPA servers configured as certificate authority'), flags={'virtual_attribute', 'no_create', 'no_update'} ), Str( + 'ca_server_hidden_server*', + label=_('Hidden IPA CA servers'), + doc=_('Hidden IPA servers configured as certificate authority'), + flags={'virtual_attribute', 'no_create', 'no_update'} + ), + Str( 'ca_renewal_master_server?', label=_('IPA CA renewal master'), doc=_('Renewal master for IPA certificate authority'), flags={'virtual_attribute', 'no_create'} ), Str( - 'pkinit_server_server*', - label=_('IPA master capable of PKINIT'), - doc=_('IPA master which can process PKINIT requests'), + 'kra_server_server*', + label=_('IPA KRA servers'), + doc=_('IPA servers configured as key recovery agent'), + flags={'virtual_attribute', 'no_create', 'no_update'} + ), + Str( + 'kra_server_hidden_server*', + label=_('Hidden IPA KRA servers'), + doc=_('Hidden IPA servers configured as key recovery agent'), flags={'virtual_attribute', 'no_create', 'no_update'} ), Str( @@ -273,7 +297,25 @@ class config(LDAPObject): label=_('Domain resolution order'), doc=_('colon-separated list of domains used for short name' ' qualification') - ) + ), + Str( + 'dns_server_server*', + label=_('IPA DNS servers'), + doc=_('IPA servers configured as domain name server'), + flags={'virtual_attribute', 'no_create', 'no_update'} + ), + Str( + 'dns_server_hidden_server*', + label=_('Hidden IPA DNS servers'), + doc=_('Hidden IPA servers configured as domain name server'), + flags={'virtual_attribute', 'no_create', 'no_update'} + ), + Str( + 'dnssec_key_master_server?', + label=_('IPA DNSSec key master'), + doc=_('DNSec key master'), + flags={'virtual_attribute', 'no_create', 'no_update'} + ), ) def get_dn(self, *keys, **kwargs): @@ -554,7 +596,8 @@ class config_mod(LDAPUpdate): def post_callback(self, ldap, dn, entry_attrs, *keys, **options): self.obj.show_servroles_attributes( - entry_attrs, "CA server", "IPA master", **options) + entry_attrs, "CA server", "KRA server", "IPA master", + "DNS server", **options) return dn @@ -564,5 +607,6 @@ class config_show(LDAPRetrieve): def post_callback(self, ldap, dn, entry_attrs, *keys, **options): self.obj.show_servroles_attributes( - entry_attrs, "CA server", "IPA master", **options) + entry_attrs, "CA server", "KRA server", "IPA master", + "DNS server", **options) return dn diff --git a/ipaserver/plugins/serverroles.py b/ipaserver/plugins/serverroles.py index a1ac2cf..6897f41 100644 --- a/ipaserver/plugins/serverroles.py +++ b/ipaserver/plugins/serverroles.py @@ -45,7 +45,9 @@ 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) +from ipaserver.servroles import ( + attribute_instances, ENABLED, HIDDEN, role_instances +) from ipaserver.servroles import SingleValuedServerAttribute @@ -81,17 +83,26 @@ class serverroles(Backend): raise errors.NotFound( reason=_("{role}: role not found").format(role=role_name)) - def _get_enabled_masters(self, 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.status(self.api, server=None) if - r[u'status'] == ENABLED] - + 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): @@ -131,8 +142,8 @@ class serverroles(Backend): return self._get_role(role_servrole).status( self.api, server=server_server) - def config_retrieve(self, servrole): - result = self._get_enabled_masters(servrole) + 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) diff --git a/ipaserver/servroles.py b/ipaserver/servroles.py index e1f7c11..d3f13ed 100644 --- a/ipaserver/servroles.py +++ b/ipaserver/servroles.py @@ -104,6 +104,12 @@ class LDAPBasedProperty(object): def __init__(self, attr_name, name): self.attr_name = attr_name self.name = name + # for hidden services, insert hidden before '_server' suffix + if attr_name.endswith(u'_server'): + parts = attr_name.rsplit(u'_', 1) + self.attr_name_hidden = u'{}_hidden_server'.format(parts[0]) + else: + self.attr_name_hidden = None @six.add_metaclass(abc.ABCMeta) diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py index e00fd5c..6304a00 100644 --- a/ipatests/test_integration/test_replica_promotion.py +++ b/ipatests/test_integration/test_replica_promotion.py @@ -754,11 +754,32 @@ class TestHiddenReplicaPromotion(IntegrationTest): expected = 'Role status: {}'.format(status) assert expected in result.stdout_text + def _check_config(self, enabled=(), hidden=()): + enabled = {host.hostname for host in enabled} + hidden = {host.hostname for host in hidden} + services = [ + 'IPA masters', 'IPA CA servers', 'IPA KRA servers', + 'IPA DNS servers' + ] + + result = self.master.run_command(['ipa', 'config-show']) + values = {} + for line in result.stdout_text.split('\n'): + if ':' not in line: + continue + k, v = line.split(':', 1) + values[k.strip()] = {item.strip() for item in v.split(',')} + + for service in services: + assert values[service] == enabled + assert values['Hidden {}'.format(service)] == hidden + def test_hidden_replica_install(self): # TODO: check that all services are running on hidden replica self._check_server_role(self.master, 'enabled') self._check_server_role(self.replicas[0], 'hidden') self._check_dnsrecords([self.master], [self.replicas[0]]) + self._check_config([self.master], [self.replicas[0]]) def test_hidden_replica_promote(self): self.replicas[0].run_command([ @@ -767,6 +788,8 @@ class TestHiddenReplicaPromotion(IntegrationTest): ]) self._check_server_role(self.replicas[0], 'enabled') self._check_dnsrecords([self.master, self.replicas[0]]) + self._check_config([self.master, self.replicas[0]]) + result = self.replicas[0].run_command([ 'ipa', 'server-state', self.replicas[0].hostname, '--state=enabled'