Migrate CA profiles after enabling LDAPProfileSubsystem

After enabling LDAPProfileSubsystem in Dogtag, migrate the
file-based profiles into the LDAP database.

Reviewed-By: Martin Basti <mbasti@redhat.com>
This commit is contained in:
Fraser Tweedale 2015-06-16 07:38:06 -04:00 committed by Tomas Babej
parent 6e641e8d18
commit 3827137b32
2 changed files with 113 additions and 30 deletions

View File

@ -1639,6 +1639,29 @@ def update_people_entry(dercert):
return True return True
def ensure_ldap_profiles_container():
server_id = installutils.realm_to_serverid(api.env.realm)
dogtag_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % server_id
conn = ldap2.ldap2(shared_instance=False, ldap_uri=dogtag_uri)
if not conn.isconnected():
conn.connect(autobind=True)
dn = DN(('ou', 'certificateProfiles'), ('ou', 'ca'), ('o', 'ipaca'))
try:
conn.get_entry(dn)
except errors.NotFound:
# entry doesn't exist; add it
entry = conn.make_entry(
dn,
objectclass=['top', 'organizationalUnit'],
ou=['certificateProfiles'],
)
conn.add_entry(entry)
conn.disconnect()
def configure_profiles_acl(): def configure_profiles_acl():
server_id = installutils.realm_to_serverid(api.env.realm) server_id = installutils.realm_to_serverid(api.env.realm)
dogtag_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % server_id dogtag_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % server_id
@ -1677,6 +1700,9 @@ def import_included_profiles():
if not conn.isconnected(): if not conn.isconnected():
conn.connect(autobind=True) conn.connect(autobind=True)
api.Backend.ra_certprofile._read_password()
api.Backend.ra_certprofile.override_port = 8443
for (profile_id, desc, store_issued) in dogtag.INCLUDED_PROFILES: for (profile_id, desc, store_issued) in dogtag.INCLUDED_PROFILES:
dn = DN(('cn', profile_id), dn = DN(('cn', profile_id),
api.env.container_certprofile, api.env.basedn) api.env.container_certprofile, api.env.basedn)
@ -1685,9 +1711,6 @@ def import_included_profiles():
continue # the profile is present continue # the profile is present
except errors.NotFound: except errors.NotFound:
# profile not found; add it # profile not found; add it
profile_data = ipautil.template_file(
'/usr/share/ipa/profiles/{}.cfg'.format(profile_id), sub_dict)
entry = conn.make_entry( entry = conn.make_entry(
dn, dn,
objectclass=['ipacertprofile'], objectclass=['ipacertprofile'],
@ -1696,34 +1719,93 @@ def import_included_profiles():
ipacertprofilestoreissued=['TRUE' if store_issued else 'FALSE'], ipacertprofilestoreissued=['TRUE' if store_issued else 'FALSE'],
) )
conn.add_entry(entry) conn.add_entry(entry)
api.Backend.ra_certprofile._read_password() profile_data = ipautil.template_file(
api.Backend.ra_certprofile.override_port = 8443 '/usr/share/ipa/profiles/{}.cfg'.format(profile_id), sub_dict)
with api.Backend.ra_certprofile as profile_api: _create_dogtag_profile(profile_id, profile_data)
# import the profile
try:
profile_api.create_profile(profile_data)
except errors.RemoteRetrieveError:
# conflicting profile; replace it if we are
# installing IPA, but keep it for upgrades
if api.env.context == 'installer':
try:
profile_api.disable_profile(profile_id)
except errors.RemoteRetrieveError:
pass
profile_api.delete_profile(profile_id)
profile_api.create_profile(profile_data)
# enable the profile
try:
profile_api.enable_profile(profile_id)
except errors.RemoteRetrieveError:
pass
api.Backend.ra_certprofile.override_port = None
root_logger.info("Imported profile '%s'", profile_id) root_logger.info("Imported profile '%s'", profile_id)
api.Backend.ra_certprofile.override_port = None
conn.disconnect() conn.disconnect()
def migrate_profiles_to_ldap():
"""Migrate profiles from filesystem to LDAP.
This must be run *after* switching to the LDAPProfileSubsystem
and restarting the CA.
The profile might already exist, e.g. if a replica was already
upgraded, so this case is ignored.
"""
ensure_ldap_profiles_container()
api.Backend.ra_certprofile._read_password()
api.Backend.ra_certprofile.override_port = 8443
with open(dogtag.configured_constants().CS_CFG_PATH) as f:
cs_cfg = f.read()
match = re.search(r'^profile\.list=(\S*)', cs_cfg, re.MULTILINE)
profile_ids = match.group(1).split(',')
for profile_id in profile_ids:
match = re.search(
r'^profile\.{}\.config=(\S*)'.format(profile_id),
cs_cfg, re.MULTILINE
)
if match is None:
root_logger.info("No file for profile '%s'; skipping", profile_id)
continue
filename = match.group(1)
match = re.search(
r'^profile\.{}\.class_id=(\S*)'.format(profile_id),
cs_cfg, re.MULTILINE
)
if match is None:
root_logger.info("No class_id for profile '%s'; skipping", profile_id)
continue
class_id = match.group(1)
root_logger.info("Migrating profile '%s' to LDAP", profile_id)
with open(filename) as f:
profile_data = f.read()
if profile_data[-1] != '\n':
profile_data += '\n'
profile_data += 'profileId={}\n'.format(profile_id)
profile_data += 'classId={}\n'.format(class_id)
_create_dogtag_profile(profile_id, profile_data)
api.Backend.ra_certprofile.override_port = None
def _create_dogtag_profile(profile_id, profile_data):
with api.Backend.ra_certprofile as profile_api:
# import the profile
try:
profile_api.create_profile(profile_data)
except errors.RemoteRetrieveError:
# conflicting profile; replace it if we are
# installing IPA, but keep it for upgrades
if api.env.context == 'installer':
try:
profile_api.disable_profile(profile_id)
except errors.RemoteRetrieveError:
root_logger.debug(
"Failed to disable profile '%s' "
"(it is probably already disabled)")
profile_api.delete_profile(profile_id)
profile_api.create_profile(profile_data)
# enable the profile
try:
profile_api.enable_profile(profile_id)
except errors.RemoteRetrieveError:
root_logger.debug(
"Failed to enable profile '%s' "
"(it is probably already enabled)")
if __name__ == "__main__": if __name__ == "__main__":
standard_logging_setup("install.log") standard_logging_setup("install.log")
ds = dsinstance.DsInstance() ds = dsinstance.DsInstance()

View File

@ -333,8 +333,8 @@ def ca_enable_ldap_profile_subsystem(ca):
quotes=False, quotes=False,
separator='=') separator='=')
# TODO import file-based profiles into Dogtag ca.restart(dogtag.configured_constants().PKI_INSTANCE_NAME)
# More code needed on Dogtag side for this. cainstance.migrate_profiles_to_ldap()
return needs_update return needs_update
@ -1479,7 +1479,6 @@ def upgrade_configuration():
certificate_renewal_update(ca), certificate_renewal_update(ca),
ca_enable_pkix(ca), ca_enable_pkix(ca),
ca_configure_profiles_acl(ca), ca_configure_profiles_acl(ca),
ca_enable_ldap_profile_subsystem(ca),
]) ])
if ca_restart: if ca_restart:
@ -1489,6 +1488,8 @@ def upgrade_configuration():
except ipautil.CalledProcessError as e: except ipautil.CalledProcessError as e:
root_logger.error("Failed to restart %s: %s", ca.service_name, e) root_logger.error("Failed to restart %s: %s", ca.service_name, e)
ca_enable_ldap_profile_subsystem(ca)
# This step MUST be done after ca_enable_ldap_profile_subsystem and # This step MUST be done after ca_enable_ldap_profile_subsystem and
# ca_configure_profiles_acl, and the consequent restart, but does not # ca_configure_profiles_acl, and the consequent restart, but does not
# itself require a restart. # itself require a restart.