URL: https://github.com/freeipa/freeipa/pull/5182 Author: tiran Title: #5182: Speed up cainstance.migrate_profiles_to_ldap Action: opened
PR body: """ The ra_certprofile API is slow. It takes ~200ms to migrate and enable a profile even when the profile already available. The migration step slows down the installer and upgrader by about 12 to 15 seconds. Skip all profiles that have been imported by Dogtag already. Related: https://pagure.io/freeipa/issue/8522 Related: https://pagure.io/freeipa/issue/8521 Signed-off-by: Christian Heimes <chei...@redhat.com> """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/5182/head:pr5182 git checkout pr5182
From bf64e0a7c01dd02ce3096e9dab43a2b80c0cc69d Mon Sep 17 00:00:00 2001 From: Christian Heimes <chei...@redhat.com> Date: Thu, 8 Oct 2020 14:25:21 +0200 Subject: [PATCH] Speed up cainstance.migrate_profiles_to_ldap The ra_certprofile API is slow. It takes ~200ms to migrate and enable a profile even when the profile already available. The migration step slows down the installer and upgrader by about 12 to 15 seconds. Skip all profiles that have been imported by Dogtag already. Related: https://pagure.io/freeipa/issue/8522 Related: https://pagure.io/freeipa/issue/8521 Signed-off-by: Christian Heimes <chei...@redhat.com> --- ipaserver/install/cainstance.py | 45 +++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index 79d2a14769..a8edd14099 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -23,6 +23,7 @@ import base64 import binascii +import enum import logging import dbus @@ -73,6 +74,8 @@ ACME_AGENT_GROUP = 'ACME Agents' +PROFILES_DN = DN(('ou', 'certificateProfiles'), ('ou', 'ca'), ('o', 'ipaca')) + def check_ports(): """Check that dogtag ports (8080, 8443) are available. @@ -1713,7 +1716,7 @@ def update_ca_renewal_entry(conn, nickname, cert): def ensure_ldap_profiles_container(): ensure_entry( - DN(('ou', 'certificateProfiles'), ('ou', 'ca'), ('o', 'ipaca')), + PROFILES_DN, objectclass=['top', 'organizationalUnit'], ou=['certificateProfiles'], ) @@ -1898,7 +1901,6 @@ def import_included_profiles(): api.env.container_certprofile, api.env.basedn) try: conn.get_entry(dn) - continue # the profile is present except errors.NotFound: # profile not found; add it entry = conn.make_entry( @@ -1914,6 +1916,10 @@ def import_included_profiles(): profile_data = __get_profile_config(profile_id) _create_dogtag_profile(profile_id, profile_data, overwrite=True) logger.debug("Imported profile '%s'", profile_id) + else: + logger.info( + "Profile '%s' is already in LDAP; skipping", profile_id + ) api.Backend.ra_certprofile.override_port = None conn.disconnect() @@ -1982,6 +1988,16 @@ def migrate_profiles_to_ldap(): profile_ids = match.group(1).split(',') for profile_id in profile_ids: + state = _check_ldap_profile_state(profile_id) + if state in (ProfileState.ENABLED, ProfileState.DISABLED): + logger.info( + "Profile '%s' is already in LDAP and %s; skipping", + profile_id, state.value + ) + continue + else: + logger.info("Migrating profile '%s'", profile_id) + match = re.search( r'^profile\.{}\.config=(\S*)'.format(profile_id), cs_cfg, re.MULTILINE @@ -2016,6 +2032,31 @@ def migrate_profiles_to_ldap(): api.Backend.ra_certprofile.override_port = None +class ProfileState(enum.Enum): + MISSING = "missing" + ENABLED = "enabled" + DISABLED = "disabled" + + +def _check_ldap_profile_state(profile_id): + """Check if LDAP profile is loaded and enabled + + The function directly access LDAP for performance reasons. It's much + faster than Dogtag's REST API and it's easier to check profiles for all + subsystems. + """ + profile_dn = DN(("cn", profile_id), PROFILES_DN) + try: + entry = api.Backend.ldap2.get_entry(profile_dn) + except errors.NotFound: + return ProfileState.MISSING + cfg = entry.single_value["certProfileConfig"] + for line in cfg.split("\n"): + if line.lower() == "enable=true": + return ProfileState.ENABLED + return ProfileState.DISABLED + + def _create_dogtag_profile(profile_id, profile_data, overwrite): with api.Backend.ra_certprofile as profile_api: # import the profile
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org