|
|
86baa9 |
From ae9ab0545ff06b60df4b66c0ebccb7baa79b8898 Mon Sep 17 00:00:00 2001
|
|
|
86baa9 |
From: Christian Heimes <cheimes@redhat.com>
|
|
|
86baa9 |
Date: Mon, 25 Mar 2019 15:59:51 +0100
|
|
|
86baa9 |
Subject: [PATCH] Improve config-show to show hidden servers
|
|
|
86baa9 |
|
|
|
86baa9 |
config-show only used to show enabled servers. Now also show hidden
|
|
|
86baa9 |
servers on separate lines. Additionally include information about
|
|
|
86baa9 |
KRA and DNS servers.
|
|
|
86baa9 |
|
|
|
86baa9 |
The augmented config-show output makes it easier to diagnose a cluster
|
|
|
86baa9 |
and simplifies sanity checks.
|
|
|
86baa9 |
|
|
|
86baa9 |
Fixes: https://pagure.io/freeipa/issue/7892
|
|
|
86baa9 |
Signed-off-by: Christian Heimes <cheimes@redhat.com>
|
|
|
86baa9 |
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
|
|
|
86baa9 |
Reviewed-By: Francois Cami <fcami@redhat.com>
|
|
|
86baa9 |
---
|
|
|
86baa9 |
ipaserver/plugins/config.py | 56 +++++++++++++++++--
|
|
|
86baa9 |
ipaserver/plugins/serverroles.py | 25 ++++++---
|
|
|
86baa9 |
ipaserver/servroles.py | 6 ++
|
|
|
86baa9 |
.../test_replica_promotion.py | 23 ++++++++
|
|
|
86baa9 |
4 files changed, 97 insertions(+), 13 deletions(-)
|
|
|
86baa9 |
|
|
|
86baa9 |
diff --git a/ipaserver/plugins/config.py b/ipaserver/plugins/config.py
|
|
|
86baa9 |
index fff58ac656f4fad3491dfa9f95c22b7d54a6da56..58b48935c2c7471ff2ce0bb3f5ce92a9fb47a503 100644
|
|
|
86baa9 |
--- a/ipaserver/plugins/config.py
|
|
|
86baa9 |
+++ b/ipaserver/plugins/config.py
|
|
|
86baa9 |
@@ -249,6 +249,18 @@ class config(LDAPObject):
|
|
|
86baa9 |
doc=_('List of all IPA masters'),
|
|
|
86baa9 |
flags={'virtual_attribute', 'no_create', 'no_update'}
|
|
|
86baa9 |
),
|
|
|
86baa9 |
+ Str(
|
|
|
86baa9 |
+ 'ipa_master_hidden_server*',
|
|
|
86baa9 |
+ label=_('Hidden IPA masters'),
|
|
|
86baa9 |
+ doc=_('List of all hidden IPA masters'),
|
|
|
86baa9 |
+ flags={'virtual_attribute', 'no_create', 'no_update'}
|
|
|
86baa9 |
+ ),
|
|
|
86baa9 |
+ Str(
|
|
|
86baa9 |
+ 'pkinit_server_server*',
|
|
|
86baa9 |
+ label=_('IPA master capable of PKINIT'),
|
|
|
86baa9 |
+ doc=_('IPA master which can process PKINIT requests'),
|
|
|
86baa9 |
+ flags={'virtual_attribute', 'no_create', 'no_update'}
|
|
|
86baa9 |
+ ),
|
|
|
86baa9 |
Str(
|
|
|
86baa9 |
'ca_server_server*',
|
|
|
86baa9 |
label=_('IPA CA servers'),
|
|
|
86baa9 |
@@ -261,6 +273,12 @@ class config(LDAPObject):
|
|
|
86baa9 |
doc=_('IPA servers with enabled NTP'),
|
|
|
86baa9 |
flags={'virtual_attribute', 'no_create', 'no_update'}
|
|
|
86baa9 |
),
|
|
|
86baa9 |
+ Str(
|
|
|
86baa9 |
+ 'ca_server_hidden_server*',
|
|
|
86baa9 |
+ label=_('Hidden IPA CA servers'),
|
|
|
86baa9 |
+ doc=_('Hidden IPA servers configured as certificate authority'),
|
|
|
86baa9 |
+ flags={'virtual_attribute', 'no_create', 'no_update'}
|
|
|
86baa9 |
+ ),
|
|
|
86baa9 |
Str(
|
|
|
86baa9 |
'ca_renewal_master_server?',
|
|
|
86baa9 |
label=_('IPA CA renewal master'),
|
|
|
86baa9 |
@@ -268,9 +286,15 @@ class config(LDAPObject):
|
|
|
86baa9 |
flags={'virtual_attribute', 'no_create'}
|
|
|
86baa9 |
),
|
|
|
86baa9 |
Str(
|
|
|
86baa9 |
- 'pkinit_server_server*',
|
|
|
86baa9 |
- label=_('IPA master capable of PKINIT'),
|
|
|
86baa9 |
- doc=_('IPA master which can process PKINIT requests'),
|
|
|
86baa9 |
+ 'kra_server_server*',
|
|
|
86baa9 |
+ label=_('IPA KRA servers'),
|
|
|
86baa9 |
+ doc=_('IPA servers configured as key recovery agent'),
|
|
|
86baa9 |
+ flags={'virtual_attribute', 'no_create', 'no_update'}
|
|
|
86baa9 |
+ ),
|
|
|
86baa9 |
+ Str(
|
|
|
86baa9 |
+ 'kra_server_hidden_server*',
|
|
|
86baa9 |
+ label=_('Hidden IPA KRA servers'),
|
|
|
86baa9 |
+ doc=_('Hidden IPA servers configured as key recovery agent'),
|
|
|
86baa9 |
flags={'virtual_attribute', 'no_create', 'no_update'}
|
|
|
86baa9 |
),
|
|
|
86baa9 |
Str(
|
|
|
86baa9 |
@@ -279,7 +303,25 @@ class config(LDAPObject):
|
|
|
86baa9 |
label=_('Domain resolution order'),
|
|
|
86baa9 |
doc=_('colon-separated list of domains used for short name'
|
|
|
86baa9 |
' qualification')
|
|
|
86baa9 |
- )
|
|
|
86baa9 |
+ ),
|
|
|
86baa9 |
+ Str(
|
|
|
86baa9 |
+ 'dns_server_server*',
|
|
|
86baa9 |
+ label=_('IPA DNS servers'),
|
|
|
86baa9 |
+ doc=_('IPA servers configured as domain name server'),
|
|
|
86baa9 |
+ flags={'virtual_attribute', 'no_create', 'no_update'}
|
|
|
86baa9 |
+ ),
|
|
|
86baa9 |
+ Str(
|
|
|
86baa9 |
+ 'dns_server_hidden_server*',
|
|
|
86baa9 |
+ label=_('Hidden IPA DNS servers'),
|
|
|
86baa9 |
+ doc=_('Hidden IPA servers configured as domain name server'),
|
|
|
86baa9 |
+ flags={'virtual_attribute', 'no_create', 'no_update'}
|
|
|
86baa9 |
+ ),
|
|
|
86baa9 |
+ Str(
|
|
|
86baa9 |
+ 'dnssec_key_master_server?',
|
|
|
86baa9 |
+ label=_('IPA DNSSec key master'),
|
|
|
86baa9 |
+ doc=_('DNSec key master'),
|
|
|
86baa9 |
+ flags={'virtual_attribute', 'no_create', 'no_update'}
|
|
|
86baa9 |
+ ),
|
|
|
86baa9 |
)
|
|
|
86baa9 |
|
|
|
86baa9 |
def get_dn(self, *keys, **kwargs):
|
|
|
86baa9 |
@@ -560,7 +602,8 @@ class config_mod(LDAPUpdate):
|
|
|
86baa9 |
|
|
|
86baa9 |
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
|
|
86baa9 |
self.obj.show_servroles_attributes(
|
|
|
86baa9 |
- entry_attrs, "CA server", "IPA master", "NTP server", **options)
|
|
|
86baa9 |
+ entry_attrs, "CA server", "KRA server", "IPA master",
|
|
|
86baa9 |
+ "NTP server", "DNS server", **options)
|
|
|
86baa9 |
return dn
|
|
|
86baa9 |
|
|
|
86baa9 |
|
|
|
86baa9 |
@@ -570,5 +613,6 @@ class config_show(LDAPRetrieve):
|
|
|
86baa9 |
|
|
|
86baa9 |
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
|
|
86baa9 |
self.obj.show_servroles_attributes(
|
|
|
86baa9 |
- entry_attrs, "CA server", "IPA master", "NTP server", **options)
|
|
|
86baa9 |
+ entry_attrs, "CA server", "KRA server", "IPA master",
|
|
|
86baa9 |
+ "NTP server", "DNS server", **options)
|
|
|
86baa9 |
return dn
|
|
|
86baa9 |
diff --git a/ipaserver/plugins/serverroles.py b/ipaserver/plugins/serverroles.py
|
|
|
86baa9 |
index 0abf48ae5295be5f622bf8c90d32e7adff5e6cf7..5bba84972a5828b6c7230d0d0d858e6683e5986b 100644
|
|
|
86baa9 |
--- a/ipaserver/plugins/serverroles.py
|
|
|
86baa9 |
+++ b/ipaserver/plugins/serverroles.py
|
|
|
86baa9 |
@@ -45,7 +45,9 @@ import six
|
|
|
86baa9 |
from ipalib import errors, _
|
|
|
86baa9 |
from ipalib.backend import Backend
|
|
|
86baa9 |
from ipalib.plugable import Registry
|
|
|
86baa9 |
-from ipaserver.servroles import (attribute_instances, ENABLED, role_instances)
|
|
|
86baa9 |
+from ipaserver.servroles import (
|
|
|
86baa9 |
+ attribute_instances, ENABLED, HIDDEN, role_instances
|
|
|
86baa9 |
+)
|
|
|
86baa9 |
from ipaserver.servroles import SingleValuedServerAttribute
|
|
|
86baa9 |
|
|
|
86baa9 |
|
|
|
86baa9 |
@@ -81,17 +83,26 @@ class serverroles(Backend):
|
|
|
86baa9 |
raise errors.NotFound(
|
|
|
86baa9 |
reason=_("{role}: role not found".format(role=role_name)))
|
|
|
86baa9 |
|
|
|
86baa9 |
- def _get_enabled_masters(self, role_name):
|
|
|
86baa9 |
+ def _get_masters(self, role_name, include_hidden):
|
|
|
86baa9 |
result = {}
|
|
|
86baa9 |
role = self._get_role(role_name)
|
|
|
86baa9 |
+ role_states = role.status(self.api, server=None)
|
|
|
86baa9 |
|
|
|
86baa9 |
enabled_masters = [
|
|
|
86baa9 |
- r[u'server_server'] for r in role.status(self.api, server=None) if
|
|
|
86baa9 |
- r[u'status'] == ENABLED]
|
|
|
86baa9 |
-
|
|
|
86baa9 |
+ r[u'server_server'] for r in role_states if
|
|
|
86baa9 |
+ r[u'status'] == ENABLED
|
|
|
86baa9 |
+ ]
|
|
|
86baa9 |
if enabled_masters:
|
|
|
86baa9 |
result.update({role.attr_name: enabled_masters})
|
|
|
86baa9 |
|
|
|
86baa9 |
+ if include_hidden and role.attr_name_hidden is not None:
|
|
|
86baa9 |
+ hidden_masters = [
|
|
|
86baa9 |
+ r[u'server_server'] for r in role_states if
|
|
|
86baa9 |
+ r[u'status'] == HIDDEN
|
|
|
86baa9 |
+ ]
|
|
|
86baa9 |
+ if hidden_masters:
|
|
|
86baa9 |
+ result.update({role.attr_name_hidden: hidden_masters})
|
|
|
86baa9 |
+
|
|
|
86baa9 |
return result
|
|
|
86baa9 |
|
|
|
86baa9 |
def _get_assoc_attributes(self, role_name):
|
|
|
86baa9 |
@@ -131,8 +142,8 @@ class serverroles(Backend):
|
|
|
86baa9 |
return self._get_role(role_servrole).status(
|
|
|
86baa9 |
self.api, server=server_server)
|
|
|
86baa9 |
|
|
|
86baa9 |
- def config_retrieve(self, servrole):
|
|
|
86baa9 |
- result = self._get_enabled_masters(servrole)
|
|
|
86baa9 |
+ def config_retrieve(self, servrole, include_hidden=True):
|
|
|
86baa9 |
+ result = self._get_masters(servrole, include_hidden=include_hidden)
|
|
|
86baa9 |
|
|
|
86baa9 |
try:
|
|
|
86baa9 |
assoc_attributes = self._get_assoc_attributes(servrole)
|
|
|
86baa9 |
diff --git a/ipaserver/servroles.py b/ipaserver/servroles.py
|
|
|
86baa9 |
index 9c963be53527bb955ebf2b8cec7960f0d90717a4..0988cbdd7eac599ef26c89a015523b2d92e9502f 100644
|
|
|
86baa9 |
--- a/ipaserver/servroles.py
|
|
|
86baa9 |
+++ b/ipaserver/servroles.py
|
|
|
86baa9 |
@@ -104,6 +104,12 @@ class LDAPBasedProperty(object):
|
|
|
86baa9 |
def __init__(self, attr_name, name):
|
|
|
86baa9 |
self.attr_name = attr_name
|
|
|
86baa9 |
self.name = name
|
|
|
86baa9 |
+ # for hidden services, insert hidden before '_server' suffix
|
|
|
86baa9 |
+ if attr_name.endswith(u'_server'):
|
|
|
86baa9 |
+ parts = attr_name.rsplit(u'_', 1)
|
|
|
86baa9 |
+ self.attr_name_hidden = u'{}_hidden_server'.format(parts[0])
|
|
|
86baa9 |
+ else:
|
|
|
86baa9 |
+ self.attr_name_hidden = None
|
|
|
86baa9 |
|
|
|
86baa9 |
|
|
|
86baa9 |
@six.add_metaclass(abc.ABCMeta)
|
|
|
86baa9 |
diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py
|
|
|
86baa9 |
index a4f3e402ce5d6f74af4bd6fed9376f0f039f297a..3be2ea95fa2325edfc74cbb902ce0a5966aa82d7 100644
|
|
|
86baa9 |
--- a/ipatests/test_integration/test_replica_promotion.py
|
|
|
86baa9 |
+++ b/ipatests/test_integration/test_replica_promotion.py
|
|
|
86baa9 |
@@ -851,11 +851,32 @@ class TestHiddenReplicaPromotion(IntegrationTest):
|
|
|
86baa9 |
expected = 'Role status: {}'.format(status)
|
|
|
86baa9 |
assert expected in result.stdout_text
|
|
|
86baa9 |
|
|
|
86baa9 |
+ def _check_config(self, enabled=(), hidden=()):
|
|
|
86baa9 |
+ enabled = {host.hostname for host in enabled}
|
|
|
86baa9 |
+ hidden = {host.hostname for host in hidden}
|
|
|
86baa9 |
+ services = [
|
|
|
86baa9 |
+ 'IPA masters', 'IPA CA servers', 'IPA KRA servers',
|
|
|
86baa9 |
+ 'IPA DNS servers'
|
|
|
86baa9 |
+ ]
|
|
|
86baa9 |
+
|
|
|
86baa9 |
+ result = self.master.run_command(['ipa', 'config-show'])
|
|
|
86baa9 |
+ values = {}
|
|
|
86baa9 |
+ for line in result.stdout_text.split('\n'):
|
|
|
86baa9 |
+ if ':' not in line:
|
|
|
86baa9 |
+ continue
|
|
|
86baa9 |
+ k, v = line.split(':', 1)
|
|
|
86baa9 |
+ values[k.strip()] = {item.strip() for item in v.split(',')}
|
|
|
86baa9 |
+
|
|
|
86baa9 |
+ for service in services:
|
|
|
86baa9 |
+ assert values[service] == enabled
|
|
|
86baa9 |
+ assert values['Hidden {}'.format(service)] == hidden
|
|
|
86baa9 |
+
|
|
|
86baa9 |
def test_hidden_replica_install(self):
|
|
|
86baa9 |
# TODO: check that all services are running on hidden replica
|
|
|
86baa9 |
self._check_server_role(self.master, 'enabled')
|
|
|
86baa9 |
self._check_server_role(self.replicas[0], 'hidden')
|
|
|
86baa9 |
self._check_dnsrecords([self.master], [self.replicas[0]])
|
|
|
86baa9 |
+ self._check_config([self.master], [self.replicas[0]])
|
|
|
86baa9 |
|
|
|
86baa9 |
def test_hidden_replica_promote(self):
|
|
|
86baa9 |
self.replicas[0].run_command([
|
|
|
86baa9 |
@@ -864,6 +885,8 @@ class TestHiddenReplicaPromotion(IntegrationTest):
|
|
|
86baa9 |
])
|
|
|
86baa9 |
self._check_server_role(self.replicas[0], 'enabled')
|
|
|
86baa9 |
self._check_dnsrecords([self.master, self.replicas[0]])
|
|
|
86baa9 |
+ self._check_config([self.master, self.replicas[0]])
|
|
|
86baa9 |
+
|
|
|
86baa9 |
result = self.replicas[0].run_command([
|
|
|
86baa9 |
'ipa', 'server-state',
|
|
|
86baa9 |
self.replicas[0].hostname, '--state=enabled'
|
|
|
86baa9 |
--
|
|
|
86baa9 |
2.20.1
|
|
|
86baa9 |
|