pgreco / rpms / ipa

Forked from forks/areguera/rpms/ipa 4 years ago
Clone

Blame SOURCES/0066-Delay-enabling-services-until-end-of-installer.patch

979ee0
From f0d829754e2e35225f0dfba980c9f4bae011407e Mon Sep 17 00:00:00 2001
979ee0
From: Christian Heimes <cheimes@redhat.com>
979ee0
Date: Fri, 6 Jul 2018 00:04:39 +0200
979ee0
Subject: [PATCH] Delay enabling services until end of installer
979ee0
979ee0
Service entries in cn=FQDN,cn=masters,cn=ipa,cn=etc are no longer
979ee0
created as enabled. Instead they are flagged as configuredService. At
979ee0
the very end of the installer, the service entries are switched from
979ee0
configured to enabled service.
979ee0
979ee0
- SRV records are created at the very end of the installer.
979ee0
- Dogtag installer only picks fully installed servers
979ee0
- Certmonger ignores all configured but not yet enabled servers.
979ee0
979ee0
Fixes: https://pagure.io/freeipa/issue/7566
979ee0
Signed-off-by: Christian Heimes <cheimes@redhat.com>
979ee0
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
979ee0
Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
979ee0
---
979ee0
 install/tools/ipa-adtrust-install          |  6 +-
979ee0
 install/tools/ipa-ca-install               | 12 ++-
979ee0
 install/tools/ipa-dns-install              |  4 +
979ee0
 ipaserver/dns_data_management.py           | 18 +++--
979ee0
 ipaserver/install/adtrustinstance.py       |  6 +-
979ee0
 ipaserver/install/bindinstance.py          |  6 +-
979ee0
 ipaserver/install/cainstance.py            |  2 +-
979ee0
 ipaserver/install/dnskeysyncinstance.py    |  4 +-
979ee0
 ipaserver/install/httpinstance.py          |  4 +-
979ee0
 ipaserver/install/ipa_kra_install.py       |  7 ++
979ee0
 ipaserver/install/krainstance.py           |  2 +-
979ee0
 ipaserver/install/krbinstance.py           |  4 +-
979ee0
 ipaserver/install/odsexporterinstance.py   |  4 +-
979ee0
 ipaserver/install/opendnssecinstance.py    |  6 +-
979ee0
 ipaserver/install/server/install.py        | 18 +++--
979ee0
 ipaserver/install/server/replicainstall.py |  9 ++-
979ee0
 ipaserver/install/service.py               | 90 ++++++++++++++++++++--
979ee0
 ipaserver/plugins/serverrole.py            |  7 +-
979ee0
 18 files changed, 161 insertions(+), 48 deletions(-)
979ee0
979ee0
diff --git a/install/tools/ipa-adtrust-install b/install/tools/ipa-adtrust-install
979ee0
index 1484598adba5b1237f00cc55e95167d45a6b40d7..4258f489873b4095a6672e20f2ac5f2858b71982 100755
979ee0
--- a/install/tools/ipa-adtrust-install
979ee0
+++ b/install/tools/ipa-adtrust-install
979ee0
@@ -31,7 +31,7 @@ import six
979ee0
 from optparse import SUPPRESS_HELP  # pylint: disable=deprecated-module
979ee0
 
979ee0
 from ipalib.install import sysrestore
979ee0
-from ipaserver.install import adtrust
979ee0
+from ipaserver.install import adtrust, service
979ee0
 from ipaserver.install.installutils import (
979ee0
     read_password,
979ee0
     check_server_configuration,
979ee0
@@ -210,6 +210,10 @@ def main():
979ee0
     adtrust.install_check(True, options, api)
979ee0
     adtrust.install(True, options, fstore, api)
979ee0
 
979ee0
+    # Enable configured services and update DNS SRV records
979ee0
+    service.enable_services(api.env.host)
979ee0
+    api.Command.dns_update_system_records()
979ee0
+
979ee0
     print("""
979ee0
 =============================================================================
979ee0
 Setup complete
979ee0
diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
979ee0
index a3694007e5815d1c44f642057c749879d336dfc5..215a60ae744577de73a7260bbf3dea5a09a4d118 100755
979ee0
--- a/install/tools/ipa-ca-install
979ee0
+++ b/install/tools/ipa-ca-install
979ee0
@@ -303,18 +303,26 @@ def main():
979ee0
     )
979ee0
     api.finalize()
979ee0
     api.Backend.ldap2.connect()
979ee0
-
979ee0
     domain_level = dsinstance.get_domain_level(api)
979ee0
+
979ee0
     if domain_level > DOMAIN_LEVEL_0:
979ee0
         promote(safe_options, options, filename)
979ee0
     else:
979ee0
         install(safe_options, options, filename)
979ee0
 
979ee0
+    # pki-spawn restarts 389-DS, reconnect
979ee0
+    api.Backend.ldap2.close()
979ee0
+    api.Backend.ldap2.connect()
979ee0
+
979ee0
+    # Enable configured services and update DNS SRV records
979ee0
+    service.enable_services(api.env.host)
979ee0
+    api.Command.dns_update_system_records()
979ee0
+    api.Backend.ldap2.disconnect()
979ee0
+
979ee0
     # execute ipactl to refresh services status
979ee0
     ipautil.run(['ipactl', 'start', '--ignore-service-failures'],
979ee0
                 raiseonerr=False)
979ee0
 
979ee0
-    api.Backend.ldap2.disconnect()
979ee0
 
979ee0
 fail_message = '''
979ee0
 Your system may be partly configured.
979ee0
diff --git a/install/tools/ipa-dns-install b/install/tools/ipa-dns-install
979ee0
index cb6c5d887f101135ca593ea6d4ed0caf51478a4c..04d1b140d2c79a0fa72d7df47d556643751bddb7 100755
979ee0
--- a/install/tools/ipa-dns-install
979ee0
+++ b/install/tools/ipa-dns-install
979ee0
@@ -36,6 +36,7 @@ from ipapython.config import IPAOptionParser
979ee0
 from ipapython.ipa_log_manager import standard_logging_setup, root_logger
979ee0
 
979ee0
 from ipaserver.install import dns as dns_installer
979ee0
+from ipaserver.install import service
979ee0
 
979ee0
 log_file_name = paths.IPASERVER_INSTALL_LOG
979ee0
 
979ee0
@@ -145,6 +146,9 @@ def main():
979ee0
 
979ee0
     dns_installer.install_check(True, api, False, options, hostname=api.env.host)
979ee0
     dns_installer.install(True, False, options)
979ee0
+    # Enable configured services and update DNS SRV records
979ee0
+    service.enable_services(api.env.host)
979ee0
+    api.Command.dns_update_system_records()
979ee0
 
979ee0
     # execute ipactl to refresh services status
979ee0
     ipautil.run(['ipactl', 'start', '--ignore-service-failures'],
979ee0
diff --git a/ipaserver/dns_data_management.py b/ipaserver/dns_data_management.py
979ee0
index 6016d8a0044d487c3118f43f199b2a433facfa9a..e5987b4bd7b43d3920e9da917258153e448206b7 100644
979ee0
--- a/ipaserver/dns_data_management.py
979ee0
+++ b/ipaserver/dns_data_management.py
979ee0
@@ -65,11 +65,11 @@ class IPASystemRecords(object):
979ee0
     PRIORITY_HIGH = 0
979ee0
     PRIORITY_LOW = 50
979ee0
 
979ee0
-    def __init__(self, api_instance):
979ee0
+    def __init__(self, api_instance, all_servers=False):
979ee0
         self.api_instance = api_instance
979ee0
         self.domain_abs = DNSName(self.api_instance.env.domain).make_absolute()
979ee0
         self.servers_data = {}
979ee0
-        self.__init_data()
979ee0
+        self.__init_data(all_servers=all_servers)
979ee0
 
979ee0
     def reload_data(self):
979ee0
         """
979ee0
@@ -89,14 +89,16 @@ class IPASystemRecords(object):
979ee0
     def __get_location_suffix(self, location):
979ee0
         return location + DNSName('_locations') + self.domain_abs
979ee0
 
979ee0
-    def __init_data(self):
979ee0
+    def __init_data(self, all_servers=False):
979ee0
         self.servers_data = {}
979ee0
 
979ee0
-        servers_result = self.api_instance.Command.server_find(
979ee0
-            no_members=False,
979ee0
-            servrole=u"IPA master",  # only active, fully installed masters
979ee0
-        )['result']
979ee0
-        for s in servers_result:
979ee0
+        kwargs = dict(no_members=False)
979ee0
+        if not all_servers:
979ee0
+            # only active, fully installed masters]
979ee0
+            kwargs["servrole"] = u"IPA master"
979ee0
+        servers = self.api_instance.Command.server_find(**kwargs)
979ee0
+
979ee0
+        for s in servers['result']:
979ee0
             weight, location, roles = self.__get_server_attrs(s)
979ee0
             self.servers_data[s['cn'][0]] = {
979ee0
                 'weight': weight,
979ee0
diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py
979ee0
index b4db055045823ce8ae7e3b264e1442a085f81b2d..a7261b92ac227228b5b6af41db621ed2e5e96668 100644
979ee0
--- a/ipaserver/install/adtrustinstance.py
979ee0
+++ b/ipaserver/install/adtrustinstance.py
979ee0
@@ -581,7 +581,7 @@ class ADTRUSTInstance(service.Service):
979ee0
             self.print_msg(err_msg)
979ee0
             self.print_msg("Add the following service records to your DNS " \
979ee0
                            "server for DNS zone %s: " % zone)
979ee0
-            system_records = IPASystemRecords(api)
979ee0
+            system_records = IPASystemRecords(api, all_servers=True)
979ee0
             adtrust_records = system_records.get_base_records(
979ee0
                 [self.fqdn], ["AD trust controller"],
979ee0
                 include_master_role=False, include_kerberos_realm=False)
979ee0
@@ -734,12 +734,12 @@ class ADTRUSTInstance(service.Service):
979ee0
         # Note that self.dm_password is None for ADTrustInstance because
979ee0
         # we ensure to be called as root and using ldapi to use autobind
979ee0
         try:
979ee0
-            self.ldap_enable('ADTRUST', self.fqdn, None, self.suffix)
979ee0
+            self.ldap_configure('ADTRUST', self.fqdn, None, self.suffix)
979ee0
         except (ldap.ALREADY_EXISTS, errors.DuplicateEntry):
979ee0
             root_logger.info("ADTRUST Service startup entry already exists.")
979ee0
 
979ee0
         try:
979ee0
-            self.ldap_enable('EXTID', self.fqdn, None, self.suffix)
979ee0
+            self.ldap_configure('EXTID', self.fqdn, None, self.suffix)
979ee0
         except (ldap.ALREADY_EXISTS, errors.DuplicateEntry):
979ee0
             root_logger.info("EXTID Service startup entry already exists.")
979ee0
 
979ee0
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
979ee0
index 03dce56aa0610b3dc530e6b2a185515be7956e8b..771c6b0483d07b20fbc8470397eed306651f4a8f 100644
979ee0
--- a/ipaserver/install/bindinstance.py
979ee0
+++ b/ipaserver/install/bindinstance.py
979ee0
@@ -664,7 +664,7 @@ class BindInstance(service.Service):
979ee0
         return normalize_zone(self.host_domain) == normalize_zone(self.domain)
979ee0
 
979ee0
     def create_file_with_system_records(self):
979ee0
-        system_records = IPASystemRecords(self.api)
979ee0
+        system_records = IPASystemRecords(self.api, all_servers=True)
979ee0
         text = u'\n'.join(
979ee0
             IPASystemRecords.records_list_from_zone(
979ee0
                 system_records.get_base_records()
979ee0
@@ -741,7 +741,7 @@ class BindInstance(service.Service):
979ee0
         # Instead we reply on the IPA init script to start only enabled
979ee0
         # components as found in our LDAP configuration tree
979ee0
         try:
979ee0
-            self.ldap_enable('DNS', self.fqdn, None, self.suffix)
979ee0
+            self.ldap_configure('DNS', self.fqdn, None, self.suffix)
979ee0
         except errors.DuplicateEntry:
979ee0
             # service already exists (forced DNS reinstall)
979ee0
             # don't crash, just report error
979ee0
@@ -1175,7 +1175,7 @@ class BindInstance(service.Service):
979ee0
             except ValueError as error:
979ee0
                 root_logger.debug(error)
979ee0
 
979ee0
-        # disabled by default, by ldap_enable()
979ee0
+        # disabled by default, by ldap_configure()
979ee0
         if enabled:
979ee0
             self.enable()
979ee0
 
979ee0
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
979ee0
index 0c4d9bf9ad8ae11ac88523857845e16eb62651b9..62e9ad7de6f00eabb48f726a3931eb8acf0ba22b 100644
979ee0
--- a/ipaserver/install/cainstance.py
979ee0
+++ b/ipaserver/install/cainstance.py
979ee0
@@ -1218,7 +1218,7 @@ class CAInstance(DogtagInstance):
979ee0
             config = ['caRenewalMaster']
979ee0
         else:
979ee0
             config = []
979ee0
-        self.ldap_enable('CA', self.fqdn, None, basedn, config)
979ee0
+        self.ldap_configure('CA', self.fqdn, None, basedn, config)
979ee0
 
979ee0
     def setup_lightweight_ca_key_retrieval(self):
979ee0
         if sysupgrade.get_upgrade_state('dogtag', 'setup_lwca_key_retrieval'):
979ee0
diff --git a/ipaserver/install/dnskeysyncinstance.py b/ipaserver/install/dnskeysyncinstance.py
979ee0
index 3849626e5a253667271913337d1a5aa4a72755bb..28468826d7194e7103e61c0ef3957b849e1be896 100644
979ee0
--- a/ipaserver/install/dnskeysyncinstance.py
979ee0
+++ b/ipaserver/install/dnskeysyncinstance.py
979ee0
@@ -384,8 +384,8 @@ class DNSKeySyncInstance(service.Service):
979ee0
 
979ee0
     def __enable(self):
979ee0
         try:
979ee0
-            self.ldap_enable('DNSKeySync', self.fqdn, None,
979ee0
-                             self.suffix, self.extra_config)
979ee0
+            self.ldap_configure('DNSKeySync', self.fqdn, None,
979ee0
+                                self.suffix, self.extra_config)
979ee0
         except errors.DuplicateEntry:
979ee0
             self.logger.error("DNSKeySync service already exists")
979ee0
 
979ee0
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
979ee0
index 7081c7418e76afbd1b4ae28deafefb6b264c62f0..2df51eaa77d3ee3246027a6bcbc4023dbad61160 100644
979ee0
--- a/ipaserver/install/httpinstance.py
979ee0
+++ b/ipaserver/install/httpinstance.py
979ee0
@@ -200,7 +200,7 @@ class HTTPInstance(service.Service):
979ee0
         # We do not let the system start IPA components on its own,
979ee0
         # Instead we reply on the IPA init script to start only enabled
979ee0
         # components as found in our LDAP configuration tree
979ee0
-        self.ldap_enable('HTTP', self.fqdn, None, self.suffix)
979ee0
+        self.ldap_configure('HTTP', self.fqdn, None, self.suffix)
979ee0
 
979ee0
     def configure_selinux_for_httpd(self):
979ee0
         try:
979ee0
@@ -583,7 +583,7 @@ class HTTPInstance(service.Service):
979ee0
         if running:
979ee0
             self.restart()
979ee0
 
979ee0
-        # disabled by default, by ldap_enable()
979ee0
+        # disabled by default, by ldap_configure()
979ee0
         if enabled:
979ee0
             self.enable()
979ee0
 
979ee0
diff --git a/ipaserver/install/ipa_kra_install.py b/ipaserver/install/ipa_kra_install.py
979ee0
index 9ebabe057513141ee76d238a3f20e76a27dd932e..3a639ac20f101293edd7449f8846a451469e2297 100644
979ee0
--- a/ipaserver/install/ipa_kra_install.py
979ee0
+++ b/ipaserver/install/ipa_kra_install.py
979ee0
@@ -224,4 +224,11 @@ class KRAInstaller(KRAInstall):
979ee0
             self.log.error(dedent(self.FAIL_MESSAGE))
979ee0
             raise
979ee0
 
979ee0
+        # pki-spawn restarts 389-DS, reconnect
979ee0
+        api.Backend.ldap2.close()
979ee0
+        api.Backend.ldap2.connect()
979ee0
+
979ee0
+        # Enable configured services and update DNS SRV records
979ee0
+        service.enable_services(api.env.host)
979ee0
+        api.Command.dns_update_system_records()
979ee0
         api.Backend.ldap2.disconnect()
979ee0
diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
979ee0
index 915d3c3c6e038eeb6a8f94f1ed7f7008c0ef4ead..a23de3960f0789761b4b86227508236c80e97c2f 100644
979ee0
--- a/ipaserver/install/krainstance.py
979ee0
+++ b/ipaserver/install/krainstance.py
979ee0
@@ -376,4 +376,4 @@ class KRAInstance(DogtagInstance):
979ee0
                 directives[nickname], cert, paths.KRA_CS_CFG_PATH)
979ee0
 
979ee0
     def __enable_instance(self):
979ee0
-        self.ldap_enable('KRA', self.fqdn, None, self.suffix)
979ee0
+        self.ldap_configure('KRA', self.fqdn, None, self.suffix)
979ee0
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
979ee0
index 5971a30fc566f6e96ce0b08632772d33da5602d2..4041d1b5fb3c3cf3db78b6cb282ce5f17793a0e3 100644
979ee0
--- a/ipaserver/install/krbinstance.py
979ee0
+++ b/ipaserver/install/krbinstance.py
979ee0
@@ -240,7 +240,7 @@ class KrbInstance(service.Service):
979ee0
         # We do not let the system start IPA components on its own,
979ee0
         # Instead we reply on the IPA init script to start only enabled
979ee0
         # components as found in our LDAP configuration tree
979ee0
-        self.ldap_enable('KDC', self.fqdn, None, self.suffix)
979ee0
+        self.ldap_configure('KDC', self.fqdn, None, self.suffix)
979ee0
 
979ee0
     def __start_instance(self):
979ee0
         try:
979ee0
@@ -598,7 +598,7 @@ class KrbInstance(service.Service):
979ee0
             except ValueError as error:
979ee0
                 root_logger.debug(error)
979ee0
 
979ee0
-        # disabled by default, by ldap_enable()
979ee0
+        # disabled by default, by ldap_configure()
979ee0
         if enabled:
979ee0
             self.enable()
979ee0
 
979ee0
diff --git a/ipaserver/install/odsexporterinstance.py b/ipaserver/install/odsexporterinstance.py
979ee0
index 59f27f578dab5663b1a7b734dff3699a6996084d..1694704f967b0b2a5debe76252ae859ae8a47f2b 100644
979ee0
--- a/ipaserver/install/odsexporterinstance.py
979ee0
+++ b/ipaserver/install/odsexporterinstance.py
979ee0
@@ -69,8 +69,8 @@ class ODSExporterInstance(service.Service):
979ee0
     def __enable(self):
979ee0
 
979ee0
         try:
979ee0
-            self.ldap_enable('DNSKeyExporter', self.fqdn, None,
979ee0
-                             self.suffix)
979ee0
+            self.ldap_configure('DNSKeyExporter', self.fqdn, None,
979ee0
+                                self.suffix)
979ee0
         except errors.DuplicateEntry:
979ee0
             root_logger.error("DNSKeyExporter service already exists")
979ee0
 
979ee0
diff --git a/ipaserver/install/opendnssecinstance.py b/ipaserver/install/opendnssecinstance.py
979ee0
index bc2974a2cf56e4ade1b778303c14f9ce05a8bf0f..92a46a9f6e318454084398ed625cf27a8250c2af 100644
979ee0
--- a/ipaserver/install/opendnssecinstance.py
979ee0
+++ b/ipaserver/install/opendnssecinstance.py
979ee0
@@ -136,8 +136,8 @@ class OpenDNSSECInstance(service.Service):
979ee0
 
979ee0
     def __enable(self):
979ee0
         try:
979ee0
-            self.ldap_enable('DNSSEC', self.fqdn, None,
979ee0
-                             self.suffix, self.extra_config)
979ee0
+            self.ldap_configure('DNSSEC', self.fqdn, None,
979ee0
+                                self.suffix, self.extra_config)
979ee0
         except errors.DuplicateEntry:
979ee0
             root_logger.error("DNSSEC service already exists")
979ee0
 
979ee0
@@ -368,7 +368,7 @@ class OpenDNSSECInstance(service.Service):
979ee0
 
979ee0
         self.restore_state("kasp_db_configured")  # just eat state
979ee0
 
979ee0
-        # disabled by default, by ldap_enable()
979ee0
+        # disabled by default, by ldap_configure()
979ee0
         if enabled:
979ee0
             self.enable()
979ee0
 
979ee0
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
979ee0
index 3651cde827ecf299e5570feed4936311f91749fb..dcdd9aabb746c4973b3f73934d94225503728f0b 100644
979ee0
--- a/ipaserver/install/server/install.py
979ee0
+++ b/ipaserver/install/server/install.py
979ee0
@@ -869,14 +869,6 @@ def install(installer):
979ee0
 
979ee0
     if options.setup_dns:
979ee0
         dns.install(False, False, options)
979ee0
-    else:
979ee0
-        # Create a BIND instance
979ee0
-        bind = bindinstance.BindInstance(fstore)
979ee0
-        bind.setup(host_name, ip_addresses, realm_name,
979ee0
-                   domain_name, (), 'first', (),
979ee0
-                   zonemgr=options.zonemgr,
979ee0
-                   no_dnssec_validation=options.no_dnssec_validation)
979ee0
-        bind.create_file_with_system_records()
979ee0
 
979ee0
     if options.setup_adtrust:
979ee0
         adtrust.install(False, options, fstore, api)
979ee0
@@ -908,6 +900,16 @@ def install(installer):
979ee0
     # Make sure the files we crated in /var/run are recreated at startup
979ee0
     tasks.configure_tmpfiles()
979ee0
 
979ee0
+    # Enable configured services and update DNS SRV records
979ee0
+    service.enable_services(host_name)
979ee0
+    api.Command.dns_update_system_records()
979ee0
+
979ee0
+    if not options.setup_dns:
979ee0
+        # After DNS and AD trust are configured and services are
979ee0
+        # enabled, create a dummy instance to dump DNS configuration.
979ee0
+        bind = bindinstance.BindInstance(fstore)
979ee0
+        bind.create_file_with_system_records()
979ee0
+
979ee0
     # Everything installed properly, activate ipa service.
979ee0
     services.knownservices.ipa.enable()
979ee0
 
979ee0
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
979ee0
index b10f761e3f643f9fa868451192fa4550b24b6b16..59fec452c674b9941ce731748dd63985a08fefc0 100644
979ee0
--- a/ipaserver/install/server/replicainstall.py
979ee0
+++ b/ipaserver/install/server/replicainstall.py
979ee0
@@ -1518,14 +1518,10 @@ def install(installer):
979ee0
 
979ee0
     if options.setup_dns:
979ee0
         dns.install(False, True, options, api)
979ee0
-    else:
979ee0
-        api.Command.dns_update_system_records()
979ee0
 
979ee0
     if options.setup_adtrust:
979ee0
         adtrust.install(False, options, fstore, api)
979ee0
 
979ee0
-    api.Backend.ldap2.disconnect()
979ee0
-
979ee0
     if not promote:
979ee0
         # Call client install script
979ee0
         service.print_msg("Configuring client side components")
979ee0
@@ -1556,6 +1552,11 @@ def install(installer):
979ee0
     # Make sure the files we crated in /var/run are recreated at startup
979ee0
     tasks.configure_tmpfiles()
979ee0
 
979ee0
+    # Enable configured services and update DNS SRV records
979ee0
+    service.enable_services(config.host_name)
979ee0
+    api.Command.dns_update_system_records()
979ee0
+    api.Backend.ldap2.disconnect()
979ee0
+
979ee0
     # Everything installed properly, activate ipa service.
979ee0
     services.knownservices.ipa.enable()
979ee0
 
979ee0
diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
979ee0
index 0523e914aa7debf6aaa82ddcce9b7b26c1833cd3..4271ebe06be03199165894f7a884e17f311896cb 100644
979ee0
--- a/ipaserver/install/service.py
979ee0
+++ b/ipaserver/install/service.py
979ee0
@@ -24,6 +24,7 @@ import socket
979ee0
 import datetime
979ee0
 import traceback
979ee0
 import tempfile
979ee0
+import warnings
979ee0
 
979ee0
 import six
979ee0
 
979ee0
@@ -59,6 +60,10 @@ SERVICE_LIST = {
979ee0
     'DNSKeySync': ('ipa-dnskeysyncd', 110),
979ee0
 }
979ee0
 
979ee0
+CONFIGURED_SERVICE = u'configuredService'
979ee0
+ENABLED_SERVICE = 'enabledService'
979ee0
+
979ee0
+
979ee0
 def print_msg(message, output_fd=sys.stdout):
979ee0
     root_logger.debug(message)
979ee0
     output_fd.write(message)
979ee0
@@ -120,7 +125,7 @@ def find_providing_server(svcname, conn, host_name=None, api=api):
979ee0
     """
979ee0
     dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
979ee0
     query_filter = conn.make_filter({'objectClass': 'ipaConfigObject',
979ee0
-                                     'ipaConfigString': 'enabledService',
979ee0
+                                     'ipaConfigString': ENABLED_SERVICE,
979ee0
                                      'cn': svcname}, rules='&')
979ee0
     try:
979ee0
         entries, _trunc = conn.find_entries(filter=query_filter, base_dn=dn)
979ee0
@@ -217,6 +222,53 @@ def set_service_entry_config(name, fqdn, config_values,
979ee0
         raise e
979ee0
 
979ee0
 
979ee0
+def enable_services(fqdn):
979ee0
+    """Change all configured services to enabled
979ee0
+
979ee0
+    Server.ldap_configure() only marks a service as configured. Services
979ee0
+    are enabled at the very end of installation.
979ee0
+
979ee0
+    Note: DNS records must be updated with dns_update_system_records, too.
979ee0
+
979ee0
+    :param fqdn: hostname of server
979ee0
+    """
979ee0
+    ldap2 = api.Backend.ldap2
979ee0
+    search_base = DN(('cn', fqdn), api.env.container_masters, api.env.basedn)
979ee0
+    search_filter = ldap2.make_filter(
979ee0
+        {
979ee0
+            'objectClass': 'ipaConfigObject',
979ee0
+            'ipaConfigString': CONFIGURED_SERVICE
979ee0
+        },
979ee0
+        rules='&'
979ee0
+    )
979ee0
+    entries = ldap2.get_entries(
979ee0
+        search_base,
979ee0
+        filter=search_filter,
979ee0
+        scope=api.Backend.ldap2.SCOPE_ONELEVEL,
979ee0
+        attrs_list=['cn', 'ipaConfigString']
979ee0
+    )
979ee0
+    for entry in entries:
979ee0
+        name = entry['cn']
979ee0
+        cfgstrings = entry.setdefault('ipaConfigString', [])
979ee0
+        for value in list(cfgstrings):
979ee0
+            if value.lower() == CONFIGURED_SERVICE.lower():
979ee0
+                cfgstrings.remove(value)
979ee0
+        if not case_insensitive_attr_has_value(cfgstrings, ENABLED_SERVICE):
979ee0
+            cfgstrings.append(ENABLED_SERVICE)
979ee0
+
979ee0
+        try:
979ee0
+            ldap2.update_entry(entry)
979ee0
+        except errors.EmptyModlist:
979ee0
+            root_logger.debug("Nothing to do for service %s", name)
979ee0
+        except Exception:
979ee0
+            root_logger.exception(
979ee0
+                "failed to set service %s config values", name
979ee0
+            )
979ee0
+            raise
979ee0
+        else:
979ee0
+            root_logger.debug("Enabled service %s for %s", name, fqdn)
979ee0
+
979ee0
+
979ee0
 class Service(object):
979ee0
     def __init__(self, service_name, service_desc=None, sstore=None,
979ee0
                  fstore=None, api=api, realm_name=None,
979ee0
@@ -522,7 +574,35 @@ class Service(object):
979ee0
         self.steps = []
979ee0
 
979ee0
     def ldap_enable(self, name, fqdn, dm_password=None, ldap_suffix='',
979ee0
-                    config=[]):
979ee0
+                    config=()):
979ee0
+        """Legacy function, all services should use ldap_configure()
979ee0
+        """
979ee0
+        warnings.warn(
979ee0
+            "ldap_enable is deprecated, use ldap_configure instead.",
979ee0
+            DeprecationWarning,
979ee0
+            stacklevel=2
979ee0
+        )
979ee0
+        self._ldap_enable(ENABLED_SERVICE, name, fqdn, ldap_suffix, config)
979ee0
+
979ee0
+    def ldap_configure(self, name, fqdn, dm_password=None, ldap_suffix='',
979ee0
+                       config=()):
979ee0
+        """Create or modify service entry in cn=masters,cn=ipa,cn=etc
979ee0
+
979ee0
+        Contrary to ldap_enable(), the method only sets
979ee0
+        ipaConfigString=configuredService. ipaConfigString=enabledService
979ee0
+        is set at the very end of the installation process, to ensure that
979ee0
+        other machines see this master/replica after it is fully installed.
979ee0
+
979ee0
+        To switch all configured services to enabled, use::
979ee0
+
979ee0
+            ipaserver.install.service.enable_services(api.env.host)
979ee0
+            api.Command.dns_update_system_records()
979ee0
+        """
979ee0
+        self._ldap_enable(
979ee0
+            CONFIGURED_SERVICE, name, fqdn, ldap_suffix, config
979ee0
+        )
979ee0
+
979ee0
+    def _ldap_enable(self, value, name, fqdn, ldap_suffix, config):
979ee0
         extra_config_opts = [
979ee0
             ' '.join([u'startOrder', unicode(SERVICE_LIST[name][1])])
979ee0
         ]
979ee0
@@ -533,7 +613,7 @@ class Service(object):
979ee0
         set_service_entry_config(
979ee0
             name,
979ee0
             fqdn,
979ee0
-            [u'enabledService'],
979ee0
+            [value],
979ee0
             ldap_suffix=ldap_suffix,
979ee0
             post_add_config=extra_config_opts)
979ee0
 
979ee0
@@ -559,7 +639,7 @@ class Service(object):
979ee0
 
979ee0
         # case insensitive
979ee0
         for value in entry.get('ipaConfigString', []):
979ee0
-            if value.lower() == u'enabledservice':
979ee0
+            if value.lower() == ENABLED_SERVICE:
979ee0
                 entry['ipaConfigString'].remove(value)
979ee0
                 break
979ee0
 
979ee0
@@ -672,7 +752,7 @@ class SimpleServiceInstance(Service):
979ee0
         if self.gensvc_name == None:
979ee0
             self.enable()
979ee0
         else:
979ee0
-            self.ldap_enable(self.gensvc_name, self.fqdn, None, self.suffix)
979ee0
+            self.ldap_configure(self.gensvc_name, self.fqdn, None, self.suffix)
979ee0
 
979ee0
     def is_installed(self):
979ee0
         return self.service.is_installed()
979ee0
diff --git a/ipaserver/plugins/serverrole.py b/ipaserver/plugins/serverrole.py
979ee0
index db88b3885c538c2800f6e4a1d649083859d43641..35b199387b4d3512d39f197d125c20571e23ad7a 100644
979ee0
--- a/ipaserver/plugins/serverrole.py
979ee0
+++ b/ipaserver/plugins/serverrole.py
979ee0
@@ -15,16 +15,21 @@ IPA server roles
979ee0
 """) + _("""
979ee0
 Get status of roles (DNS server, CA, etc.) provided by IPA masters.
979ee0
 """) + _("""
979ee0
+The status of a role is either enabled, configured, or absent.
979ee0
+""") + _("""
979ee0
 EXAMPLES:
979ee0
 """) + _("""
979ee0
   Show status of 'DNS server' role on a server:
979ee0
     ipa server-role-show ipa.example.com "DNS server"
979ee0
 """) + _("""
979ee0
   Show status of all roles containing 'AD' on a server:
979ee0
-    ipa server-role-find --server ipa.example.com --role='AD'
979ee0
+    ipa server-role-find --server ipa.example.com --role="AD trust controller"
979ee0
 """) + _("""
979ee0
   Show status of all configured roles on a server:
979ee0
     ipa server-role-find ipa.example.com
979ee0
+""") + _("""
979ee0
+  Show implicit IPA master role:
979ee0
+    ipa server-role-find --include-master
979ee0
 """)
979ee0
 
979ee0
 
979ee0
-- 
979ee0
2.17.1
979ee0