ac7d03
From fd6873ad33493b5f395a92f03d54cd184b90d2a2 Mon Sep 17 00:00:00 2001
ac7d03
From: Martin Babinsky <mbabinsk@redhat.com>
ac7d03
Date: Tue, 25 Apr 2017 18:55:59 +0200
ac7d03
Subject: [PATCH] separate function to set ipaConfigString values on service
ac7d03
 entry
ac7d03
ac7d03
There is some code duplication regarding setting ipaConfigString values
ac7d03
when:
ac7d03
   * LDAP-enabling a service entry
ac7d03
   * advertising enabled KDCProxy in LDAP
ac7d03
ac7d03
We can delegate the common work to a single re-usable function and thus
ac7d03
expose it to future use-cases (like PKINIT advertising).
ac7d03
ac7d03
https://pagure.io/freeipa/issue/6830
ac7d03
ac7d03
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
ac7d03
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
ac7d03
Reviewed-By: Martin Basti <mbasti@redhat.com>
ac7d03
Reviewed-By: Simo Sorce <ssorce@redhat.com>
ac7d03
---
ac7d03
 ipaserver/install/httpinstance.py |  43 +-----------
ac7d03
 ipaserver/install/service.py      | 135 ++++++++++++++++++++++++++------------
ac7d03
 2 files changed, 94 insertions(+), 84 deletions(-)
ac7d03
ac7d03
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
ac7d03
index aeb5c5e450813469e1b6cd374b30cd4aab338537..f0a477e0bf16b03ed8b937279dad88e6e2b3aab6 100644
ac7d03
--- a/ipaserver/install/httpinstance.py
ac7d03
+++ b/ipaserver/install/httpinstance.py
ac7d03
@@ -42,7 +42,6 @@ from ipapython.ipa_log_manager import root_logger
ac7d03
 import ipapython.errors
ac7d03
 from ipaserver.install import sysupgrade
ac7d03
 from ipalib import api
ac7d03
-from ipalib import errors
ac7d03
 from ipalib.constants import ANON_USER
ac7d03
 from ipaplatform.constants import constants
ac7d03
 from ipaplatform.tasks import tasks
ac7d03
@@ -451,46 +450,8 @@ class HTTPInstance(service.Service):
ac7d03
 
ac7d03
     def enable_kdcproxy(self):
ac7d03
         """Add ipaConfigString=kdcProxyEnabled to cn=KDC"""
ac7d03
-        entry_name = DN(('cn', 'KDC'), ('cn', self.fqdn), ('cn', 'masters'),
ac7d03
-                        ('cn', 'ipa'), ('cn', 'etc'), self.suffix)
ac7d03
-        attr_name = 'kdcProxyEnabled'
ac7d03
-
ac7d03
-        try:
ac7d03
-            entry = api.Backend.ldap2.get_entry(
ac7d03
-                entry_name, ['ipaConfigString'])
ac7d03
-        except errors.NotFound:
ac7d03
-            pass
ac7d03
-        else:
ac7d03
-            if any(attr_name.lower() == val.lower()
ac7d03
-                   for val in entry.get('ipaConfigString', [])):
ac7d03
-                root_logger.debug("service KDCPROXY already enabled")
ac7d03
-                return
ac7d03
-
ac7d03
-            entry.setdefault('ipaConfigString', []).append(attr_name)
ac7d03
-            try:
ac7d03
-                api.Backend.ldap2.update_entry(entry)
ac7d03
-            except errors.EmptyModlist:
ac7d03
-                root_logger.debug("service KDCPROXY already enabled")
ac7d03
-                return
ac7d03
-            except:
ac7d03
-                root_logger.debug("failed to enable service KDCPROXY")
ac7d03
-                raise
ac7d03
-
ac7d03
-            root_logger.debug("service KDCPROXY enabled")
ac7d03
-            return
ac7d03
-
ac7d03
-        entry = api.Backend.ldap2.make_entry(
ac7d03
-            entry_name,
ac7d03
-            objectclass=["nsContainer", "ipaConfigObject"],
ac7d03
-            cn=['KDC'],
ac7d03
-            ipaconfigstring=[attr_name]
ac7d03
-        )
ac7d03
-
ac7d03
-        try:
ac7d03
-            api.Backend.ldap2.add_entry(entry)
ac7d03
-        except errors.DuplicateEntry:
ac7d03
-            root_logger.debug("failed to add service KDCPROXY entry")
ac7d03
-            raise
ac7d03
+        service.set_service_entry_config(
ac7d03
+            'KDC', self.fqdn, [u'kdcProxyEnabled'], self.suffix)
ac7d03
 
ac7d03
     def create_kdcproxy_conf(self):
ac7d03
         """Create ipa-kdc-proxy.conf in /etc/ipa/kdcproxy"""
ac7d03
diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
ac7d03
index 9533a887ca41b8d9f9480ec30b908b213807ca7e..6b5e69ccd08444c591f15eb680b4cbdf5b6f4de1 100644
ac7d03
--- a/ipaserver/install/service.py
ac7d03
+++ b/ipaserver/install/service.py
ac7d03
@@ -136,6 +136,87 @@ def find_providing_server(svcname, conn, host_name=None, api=api):
ac7d03
     return None
ac7d03
 
ac7d03
 
ac7d03
+def case_insensitive_attr_has_value(attr, value):
ac7d03
+    """
ac7d03
+    Helper function to find value in an attribute having case-insensitive
ac7d03
+    matching rules
ac7d03
+
ac7d03
+    :param attr: attribute values
ac7d03
+    :param value: value to find
ac7d03
+
ac7d03
+    :returns: True if the case-insensitive match succeeds, false otherwise
ac7d03
+
ac7d03
+    """
ac7d03
+    if any(value.lower() == val.lower()
ac7d03
+           for val in attr):
ac7d03
+        return True
ac7d03
+
ac7d03
+    return False
ac7d03
+
ac7d03
+
ac7d03
+def set_service_entry_config(name, fqdn, config_values,
ac7d03
+                             ldap_suffix='',
ac7d03
+                             post_add_config=()):
ac7d03
+    """
ac7d03
+    Sets the 'ipaConfigString' values on the entry. If the entry is not present
ac7d03
+    already, create a new one with desired 'ipaConfigString'
ac7d03
+
ac7d03
+    :param name: service entry name
ac7d03
+    :param config_values: configuration values to store
ac7d03
+    :param fqdn: master fqdn
ac7d03
+    :param ldap_suffix: LDAP backend suffix
ac7d03
+    :param post_add_config: additional configuration to add when adding a
ac7d03
+        non-existent entry
ac7d03
+    """
ac7d03
+    assert isinstance(ldap_suffix, DN)
ac7d03
+
ac7d03
+    entry_name = DN(
ac7d03
+        ('cn', name), ('cn', fqdn), ('cn', 'masters'),
ac7d03
+        ('cn', 'ipa'), ('cn', 'etc'), ldap_suffix)
ac7d03
+
ac7d03
+    # enable disabled service
ac7d03
+    try:
ac7d03
+        entry = api.Backend.ldap2.get_entry(
ac7d03
+            entry_name, ['ipaConfigString'])
ac7d03
+    except errors.NotFound:
ac7d03
+        pass
ac7d03
+    else:
ac7d03
+        existing_values = entry.get('ipaConnfigString', [])
ac7d03
+        for value in config_values:
ac7d03
+            if case_insensitive_attr_has_value(existing_values, value):
ac7d03
+                root_logger.debug(
ac7d03
+                    "service %s: config string %s already set", name, value)
ac7d03
+
ac7d03
+            entry.setdefault('ipaConfigString', []).append(value)
ac7d03
+
ac7d03
+        try:
ac7d03
+            api.Backend.ldap2.update_entry(entry)
ac7d03
+        except errors.EmptyModlist:
ac7d03
+            root_logger.debug(
ac7d03
+                "service %s has already enabled config values %s", name,
ac7d03
+                config_values)
ac7d03
+            return
ac7d03
+        except:
ac7d03
+            root_logger.debug("failed to set service %s config values", name)
ac7d03
+            raise
ac7d03
+
ac7d03
+        root_logger.debug("service %s has all config values set", name)
ac7d03
+        return
ac7d03
+
ac7d03
+    entry = api.Backend.ldap2.make_entry(
ac7d03
+        entry_name,
ac7d03
+        objectclass=["nsContainer", "ipaConfigObject"],
ac7d03
+        cn=[name],
ac7d03
+        ipaconfigstring=config_values + list(post_add_config),
ac7d03
+    )
ac7d03
+
ac7d03
+    try:
ac7d03
+        api.Backend.ldap2.add_entry(entry)
ac7d03
+    except (errors.DuplicateEntry) as e:
ac7d03
+        root_logger.debug("failed to add service entry %s", name)
ac7d03
+        raise e
ac7d03
+
ac7d03
+
ac7d03
 class Service(object):
ac7d03
     def __init__(self, service_name, service_desc=None, sstore=None,
ac7d03
                  fstore=None, api=api, realm_name=None,
ac7d03
@@ -442,51 +523,19 @@ class Service(object):
ac7d03
 
ac7d03
     def ldap_enable(self, name, fqdn, dm_password=None, ldap_suffix='',
ac7d03
                     config=[]):
ac7d03
-        assert isinstance(ldap_suffix, DN)
ac7d03
-        self.disable()
ac7d03
+        extra_config_opts = [
ac7d03
+            ' '.join([u'startOrder', unicode(SERVICE_LIST[name][1])])
ac7d03
+        ]
ac7d03
+        extra_config_opts.extend(config)
ac7d03
 
ac7d03
-        entry_name = DN(('cn', name), ('cn', fqdn), ('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), ldap_suffix)
ac7d03
-
ac7d03
-        # enable disabled service
ac7d03
-        try:
ac7d03
-            entry = api.Backend.ldap2.get_entry(
ac7d03
-                entry_name, ['ipaConfigString'])
ac7d03
-        except errors.NotFound:
ac7d03
-            pass
ac7d03
-        else:
ac7d03
-            if any(u'enabledservice' == val.lower()
ac7d03
-                   for val in entry.get('ipaConfigString', [])):
ac7d03
-                root_logger.debug("service %s startup entry already enabled", name)
ac7d03
-                return
ac7d03
-
ac7d03
-            entry.setdefault('ipaConfigString', []).append(u'enabledService')
ac7d03
-
ac7d03
-            try:
ac7d03
-                api.Backend.ldap2.update_entry(entry)
ac7d03
-            except errors.EmptyModlist:
ac7d03
-                root_logger.debug("service %s startup entry already enabled", name)
ac7d03
-                return
ac7d03
-            except:
ac7d03
-                root_logger.debug("failed to enable service %s startup entry", name)
ac7d03
-                raise
ac7d03
-
ac7d03
-            root_logger.debug("service %s startup entry enabled", name)
ac7d03
-            return
ac7d03
-
ac7d03
-        order = SERVICE_LIST[name][1]
ac7d03
-        entry = api.Backend.ldap2.make_entry(
ac7d03
-            entry_name,
ac7d03
-            objectclass=["nsContainer", "ipaConfigObject"],
ac7d03
-            cn=[name],
ac7d03
-            ipaconfigstring=[
ac7d03
-                "enabledService", "startOrder " + str(order)] + config,
ac7d03
-        )
ac7d03
+        self.disable()
ac7d03
 
ac7d03
-        try:
ac7d03
-            api.Backend.ldap2.add_entry(entry)
ac7d03
-        except (errors.DuplicateEntry) as e:
ac7d03
-            root_logger.debug("failed to add service %s startup entry", name)
ac7d03
-            raise e
ac7d03
+        set_service_entry_config(
ac7d03
+            name,
ac7d03
+            fqdn,
ac7d03
+            [u'enabledService'],
ac7d03
+            ldap_suffix=ldap_suffix,
ac7d03
+            post_add_config=extra_config_opts)
ac7d03
 
ac7d03
     def ldap_disable(self, name, fqdn, ldap_suffix):
ac7d03
         assert isinstance(ldap_suffix, DN)
ac7d03
-- 
ac7d03
2.12.2
ac7d03