From ad3022b24462cc7bc33f810c2d20b4b00006a14c Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Mon, 29 Apr 2019 11:12:30 +0200 Subject: [PATCH] Consider configured servers as valid Under some conditions, ipa config-show and several other commands were failing with error message: ERROR: invalid 'PKINIT enabled server': all masters must have IPA master role enabled Amongst others the issue can be caused by a broken installation, when some services are left in state 'configuredServices'. The problem even block uninstallation or removal of replicas. Now configured servers are also consider valid providers for associated roles. A new test verifies that config-show works with hidden and configured HTTP service. Remark: The original intent of the sanity check is no longer clear to me. I think it was used to very that all services can be started by ipactl. Since ipactl starts hidden, configured, and enabled services, the new logic reflect the fact, too. Fixes: https://pagure.io/freeipa/issue/7929 Signed-off-by: Christian Heimes Reviewed-By: Alexander Bokovoy --- ipaserver/servroles.py | 12 +++++--- ipatests/test_integration/test_commands.py | 33 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/ipaserver/servroles.py b/ipaserver/servroles.py index bf33923ded4ca6559fba504e1b447086e87d2083..756ce91a8164144978363f04f6abd8de18b93524 100644 --- a/ipaserver/servroles.py +++ b/ipaserver/servroles.py @@ -338,12 +338,16 @@ class ServerAttribute(LDAPBasedProperty): ldap.update_entry(service_entry) def _get_assoc_role_providers(self, api_instance): - """ - get list of all servers on which the associated role is enabled + """get list of all servers on which the associated role is enabled + + Consider a configured server as a valid provider for a + role, as all services are started. """ return [ - r[u'server_server'] for r in self.associated_role.status( - api_instance) if r[u'status'] == ENABLED] + r[u'server_server'] + for r in self.associated_role.status(api_instance) + if r[u'status'] in {ENABLED,CONFIGURED} + ] def _remove(self, api_instance, masters): """ diff --git a/ipatests/test_integration/test_commands.py b/ipatests/test_integration/test_commands.py index b2c0d5c710c9810cfd74216983f793808f4cf3c4..4237de4eea2981c52ecb664d132e6607cb2ac25d 100644 --- a/ipatests/test_integration/test_commands.py +++ b/ipatests/test_integration/test_commands.py @@ -6,6 +6,11 @@ from __future__ import absolute_import from ipatests.test_integration.base import IntegrationTest +from ipapython.dn import DN + +from ipaserver.masters import ( + CONFIGURED_SERVICE, ENABLED_SERVICE, HIDDEN_SERVICE +) class TestIPACommand(IntegrationTest): @@ -46,3 +51,31 @@ class TestIPACommand(IntegrationTest): assert result.returncode == 0 assert "SELinux user map order: {}".format( maporder) in result.stdout_text + + def test_config_show_configured_services(self): + # https://pagure.io/freeipa/issue/7929 + states = {CONFIGURED_SERVICE, ENABLED_SERVICE} + dn = DN( + ('cn', 'HTTP'), ('cn', self.master.hostname), ('cn', 'masters'), + ('cn', 'ipa'), ('cn', 'etc'), + self.master.domain.basedn # pylint: disable=no-member + ) + + conn = self.master.ldap_connect() + entry = conn.get_entry(dn) # pylint: disable=no-member + + # original setting and all settings without state + orig_cfg = list(entry['ipaConfigString']) + other_cfg = [item for item in orig_cfg if item not in states] + + try: + # test with configured + cfg = [CONFIGURED_SERVICE] + cfg.extend(other_cfg) + entry['ipaConfigString'] = cfg + conn.update_entry(entry) # pylint: disable=no-member + self.master.run_command(['ipa', 'config-show']) + finally: + # reset + entry['ipaConfigString'] = orig_cfg + conn.update_entry(entry) # pylint: disable=no-member -- 2.20.1