pgreco / rpms / ipa

Forked from forks/areguera/rpms/ipa 4 years ago
Clone
Blob Blame History Raw
From f0d829754e2e35225f0dfba980c9f4bae011407e Mon Sep 17 00:00:00 2001
From: Christian Heimes <cheimes@redhat.com>
Date: Fri, 6 Jul 2018 00:04:39 +0200
Subject: [PATCH] Delay enabling services until end of installer

Service entries in cn=FQDN,cn=masters,cn=ipa,cn=etc are no longer
created as enabled. Instead they are flagged as configuredService. At
the very end of the installer, the service entries are switched from
configured to enabled service.

- SRV records are created at the very end of the installer.
- Dogtag installer only picks fully installed servers
- Certmonger ignores all configured but not yet enabled servers.

Fixes: https://pagure.io/freeipa/issue/7566
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Fraser Tweedale <ftweedal@redhat.com>
---
 install/tools/ipa-adtrust-install          |  6 +-
 install/tools/ipa-ca-install               | 12 ++-
 install/tools/ipa-dns-install              |  4 +
 ipaserver/dns_data_management.py           | 18 +++--
 ipaserver/install/adtrustinstance.py       |  6 +-
 ipaserver/install/bindinstance.py          |  6 +-
 ipaserver/install/cainstance.py            |  2 +-
 ipaserver/install/dnskeysyncinstance.py    |  4 +-
 ipaserver/install/httpinstance.py          |  4 +-
 ipaserver/install/ipa_kra_install.py       |  7 ++
 ipaserver/install/krainstance.py           |  2 +-
 ipaserver/install/krbinstance.py           |  4 +-
 ipaserver/install/odsexporterinstance.py   |  4 +-
 ipaserver/install/opendnssecinstance.py    |  6 +-
 ipaserver/install/server/install.py        | 18 +++--
 ipaserver/install/server/replicainstall.py |  9 ++-
 ipaserver/install/service.py               | 90 ++++++++++++++++++++--
 ipaserver/plugins/serverrole.py            |  7 +-
 18 files changed, 161 insertions(+), 48 deletions(-)

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