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