86baa9
From 750a60a989d7c1fe0872af292191889e7e23382d 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
---
86baa9
 ipaserver/servroles.py                     |  9 ++-
86baa9
 ipatests/test_integration/test_commands.py | 72 ++++++++++++----------
86baa9
 2 files changed, 45 insertions(+), 36 deletions(-)
deb461
deb461
diff --git a/ipaserver/servroles.py b/ipaserver/servroles.py
86baa9
index 0988cbdd7eac599ef26c89a015523b2d92e9502f..984d4bc269fffb4c667e9b8a432b1caf8d3b4f18 100644
deb461
--- a/ipaserver/servroles.py
deb461
+++ b/ipaserver/servroles.py
86baa9
@@ -346,11 +346,14 @@ class ServerAttribute(LDAPBasedProperty):
deb461
     def _get_assoc_role_providers(self, api_instance):
86baa9
         """get list of all servers on which the associated role is enabled
86baa9
 
86baa9
-        Consider a hidden server as a valid provider for a role.
86baa9
+        Consider a hidden and 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(
86baa9
-                api_instance) if r[u'status'] in {ENABLED, HIDDEN}]
deb461
+            r[u'server_server']
deb461
+            for r in self.associated_role.status(api_instance)
86baa9
+            if r[u'status'] in {ENABLED, HIDDEN, 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
86baa9
index b172a6dd036b5cba4d117f9160ee1ada8712c949..c20213d4b6f0b9d004a8b44afa161a60c538916f 100644
deb461
--- a/ipatests/test_integration/test_commands.py
deb461
+++ b/ipatests/test_integration/test_commands.py
86baa9
@@ -24,10 +24,15 @@ from ipalib.constants import IPAAPI_USER
86baa9
 
86baa9
 from ipaplatform.paths import paths
deb461
 
deb461
+from ipapython.dn import DN
deb461
+
deb461
+from ipaserver.masters import (
deb461
+    CONFIGURED_SERVICE, ENABLED_SERVICE, HIDDEN_SERVICE
deb461
+)
86baa9
+
86baa9
 from ipatests.test_integration.base import IntegrationTest
86baa9
 from ipatests.pytest_ipa.integration import tasks
86baa9
 from ipatests.pytest_ipa.integration.create_external_ca import ExternalCA
86baa9
-from ipatests.test_ipalib.test_x509 import good_pkcs7, badcert
deb461
 
86baa9
 logger = logging.getLogger(__name__)
deb461
 
86baa9
@@ -499,36 +504,37 @@ class TestIPACommand(IntegrationTest):
86baa9
         assert result.returncode != 0
86baa9
         assert 'HBAC rule not found' in result.stderr_text
86baa9
 
86baa9
-    def test_ipa_cacert_manage_install(self):
86baa9
-        # Re-install the IPA CA
86baa9
-        self.master.run_command([
86baa9
-            paths.IPA_CACERT_MANAGE,
86baa9
-            'install',
86baa9
-            paths.IPA_CA_CRT])
86baa9
-
86baa9
-        # Test a non-existent file
86baa9
-        result = self.master.run_command([
86baa9
-            paths.IPA_CACERT_MANAGE,
86baa9
-            'install',
86baa9
-            '/var/run/cert_not_found'], raiseonerr=False)
86baa9
-        assert result.returncode == 1
deb461
+    def test_config_show_configured_services(self):
deb461
+        # https://pagure.io/freeipa/issue/7929
86baa9
+        states = {CONFIGURED_SERVICE, ENABLED_SERVICE, HIDDEN_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
+        )
86baa9
 
86baa9
-        cmd = self.master.run_command(['mktemp'])
86baa9
-        filename = cmd.stdout_text.strip()
86baa9
-
86baa9
-        for contents in (good_pkcs7,):
86baa9
-            self.master.put_file_contents(filename, contents)
86baa9
-            result = self.master.run_command([
86baa9
-                paths.IPA_CACERT_MANAGE,
86baa9
-                'install',
86baa9
-                filename])
86baa9
-
86baa9
-        for contents in (badcert,):
86baa9
-            self.master.put_file_contents(filename, contents)
86baa9
-            result = self.master.run_command([
86baa9
-                paths.IPA_CACERT_MANAGE,
86baa9
-                'install',
86baa9
-                filename], raiseonerr=False)
86baa9
-            assert result.returncode == 1
86baa9
-
86baa9
-        self.master.run_command(['rm', '-f', filename])
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:
86baa9
+            # test with hidden
86baa9
+            cfg = [HIDDEN_SERVICE]
86baa9
+            cfg.extend(other_cfg)
86baa9
+            entry['ipaConfigString'] = cfg
86baa9
+            conn.update_entry(entry)  # pylint: disable=no-member
86baa9
+            self.master.run_command(['ipa', 'config-show'])
86baa9
+
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