Use get_replication_plugin_name in LDAP updater

This allows for a consistent way to retrieve the value from
LDAP. The method is used to find an existing entry. It is not usable
to add or remove entries.

Moving it in the code allows the value to always be set in the
substitution dictionary and not rely on a specific caller.

It was moved to installutils.py to avoid circular import.

https://pagure.io/freeipa/issue/8885

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
This commit is contained in:
Rob Crittenden 2021-06-18 10:11:57 -04:00 committed by Florence Blanc-Renaud
parent 16057898af
commit 922357b748
5 changed files with 51 additions and 47 deletions

View File

@ -572,10 +572,11 @@ class DsInstance(service.Service):
inst.open() inst.open()
def get_entry(dn, attrs): def get_entry(dn, attrs):
return inst.getEntry(dn, attrlist=attrs) return inst.getEntry(str(dn), attrlist=attrs)
self.sub_dict['REPLICATION_PLUGIN'] = ( self.sub_dict['REPLICATION_PLUGIN'] = (
replication.get_replication_plugin_name(get_entry)) installutils.get_replication_plugin_name(get_entry)
)
try: try:
ipadomain = IpaDomain(inst, dn=self.suffix.ldap_text()) ipadomain = IpaDomain(inst, dn=self.suffix.ldap_text())

View File

@ -1552,3 +1552,31 @@ def validate_mask():
if mask & 0b111101101 > 0: if mask & 0b111101101 > 0:
mask_str = "{:04o}".format(mask) mask_str = "{:04o}".format(mask)
return mask_str return mask_str
def get_replication_plugin_name(dirsrv_get_entry):
# Support renaming of a replication plugin in 389-ds
# IPA topology plugin depends on the replication plugin but
# 389-ds cannot handle older alias querying in the plugin
# configuration with 'nsslapd-plugin-depends-on-named: ..' attribute
#
# dirsrv_get_entry: function (dn, attrs) can return different types
# depending on the function. The 389-ds connection returns bytes
# and ipaldap will return a list of string values.
try:
entry = dirsrv_get_entry(
DN('cn=Multisupplier Replication Plugin,cn=plugins,cn=config'),
['cn'])
except (errors.NotFound, ldap.NO_SUCH_OBJECT):
return 'Multimaster Replication Plugin'
else:
cn = entry['cn']
if isinstance(cn, list):
return cn[0]
elif isinstance(cn, bytes):
return cn.decode('utf-8')
else:
raise RuntimeError(
'LDAP query returned unknown type for cn %s: %s' %
(cn, type(cn))
)

View File

@ -306,6 +306,21 @@ class LDAPUpdate:
self.modified = False self.modified = False
self.ldapuri = ipaldap.realm_to_ldapi_uri(api.env.realm) self.ldapuri = ipaldap.realm_to_ldapi_uri(api.env.realm)
self.api = create_api(mode=None)
self.api.bootstrap(
in_server=True,
context='updates',
confdir=paths.ETC_IPA,
ldap_uri=self.ldapuri
)
self.api.finalize()
self.create_connection()
replication_plugin = (
installutils.get_replication_plugin_name(self.conn.get_entry)
)
default_sub = dict( default_sub = dict(
REALM=api.env.realm, REALM=api.env.realm,
DOMAIN=api.env.domain, DOMAIN=api.env.domain,
@ -329,19 +344,11 @@ class LDAPUpdate:
# uid / gid for autobind # uid / gid for autobind
NAMED_UID=platformconstants.NAMED_USER.uid, NAMED_UID=platformconstants.NAMED_USER.uid,
NAMED_GID=platformconstants.NAMED_GROUP.gid, NAMED_GID=platformconstants.NAMED_GROUP.gid,
REPLICATION_PLUGIN=replication_plugin,
) )
for k, v in default_sub.items(): for k, v in default_sub.items():
self.sub_dict.setdefault(k, v) self.sub_dict.setdefault(k, v)
self.api = create_api(mode=None)
self.api.bootstrap(
in_server=True,
context='updates',
confdir=paths.ETC_IPA,
ldap_uri=self.ldapuri
)
self.api.finalize()
def _template_str(self, s): def _template_str(self, s):
try: try:
return ipautil.template_str(s, self.sub_dict) return ipautil.template_str(s, self.sub_dict)
@ -961,8 +968,6 @@ class LDAPUpdate:
""" """
self.modified = False self.modified = False
try: try:
self.create_connection()
upgrade_files = files upgrade_files = files
if ordered: if ordered:
upgrade_files = sorted(files) upgrade_files = sorted(files)

View File

@ -232,23 +232,6 @@ def get_ds_version(conn):
return vendor_version return vendor_version
def get_replication_plugin_name(dirsrv_get_entry):
# Support renaming of a replication plugin in 389-ds
# IPA topology plugin depends on the replication plugin but
# 389-ds cannot handle older alias querying in the plugin
# configuration with 'nsslapd-plugin-depends-on-named: ..' attribute
#
# dirsrv_get_entry: function (dn, attrs) -> str
# returns entry dictionary
try:
entry = dirsrv_get_entry(
'cn=Multisupplier Replication Plugin,cn=plugins,cn=config',
['cn'])
return str(entry['cn'], encoding='utf-8')
except Exception:
return 'Multimaster Replication Plugin'
class ReplicationManager: class ReplicationManager:
"""Manage replication agreements """Manage replication agreements
@ -757,7 +740,9 @@ class ReplicationManager:
def get_entry(dn, attrs): def get_entry(dn, attrs):
return self.conn.get_entry(DN(dn), attrs) return self.conn.get_entry(DN(dn), attrs)
replication_plugin_name = get_replication_plugin_name(get_entry) replication_plugin_name = (
installutils.get_replication_plugin_name(get_entry)
)
plgent = self.conn.get_entry( plgent = self.conn.get_entry(
DN(('cn', replication_plugin_name), ('cn', 'plugins'), DN(('cn', replication_plugin_name), ('cn', 'plugins'),

View File

@ -98,7 +98,6 @@ class IPAUpgrade(service.Service):
self.modified = False self.modified = False
self.serverid = serverid self.serverid = serverid
self.schema_files = schema_files self.schema_files = schema_files
self.sub_dict = dict()
def __start(self): def __start(self):
srv = services.service(self.service_name, api) srv = services.service(self.service_name, api)
@ -172,20 +171,6 @@ class IPAUpgrade(service.Service):
else: else:
self.backup_state('nsslapd-global-backend-lock', global_lock) self.backup_state('nsslapd-global-backend-lock', global_lock)
# update self.sub_dict with the replication plugin name
# It may be different depending on 389-ds version
with open(self.filename, "r") as in_file:
parser = GetEntryFromLDIF(in_file, entries_dn=[])
parser.parse()
results = parser.get_results()
dn = REPL_PLUGIN_DN_TEMPLATE % "supplier"
if dn not in results:
dn = REPL_PLUGIN_DN_TEMPLATE % "master"
self.sub_dict['REPLICATION_PLUGIN'] = results[dn].get('cn')
with open(self.filename, "r") as in_file: with open(self.filename, "r") as in_file:
parser = GetEntryFromLDIF(in_file, entries_dn=[COMPAT_DN]) parser = GetEntryFromLDIF(in_file, entries_dn=[COMPAT_DN])
parser.parse() parser.parse()
@ -300,7 +285,7 @@ class IPAUpgrade(service.Service):
def __upgrade(self): def __upgrade(self):
try: try:
ld = ldapupdate.LDAPUpdate(api=self.api, sub_dict=self.sub_dict) ld = ldapupdate.LDAPUpdate(api=self.api)
if len(self.files) == 0: if len(self.files) == 0:
self.files = ld.get_all_files(ldapupdate.UPDATES_DIR) self.files = ld.get_all_files(ldapupdate.UPDATES_DIR)
self.modified = (ld.update(self.files) or self.modified) self.modified = (ld.update(self.files) or self.modified)