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()
def get_entry(dn, attrs):
return inst.getEntry(dn, attrlist=attrs)
return inst.getEntry(str(dn), attrlist=attrs)
self.sub_dict['REPLICATION_PLUGIN'] = (
replication.get_replication_plugin_name(get_entry))
installutils.get_replication_plugin_name(get_entry)
)
try:
ipadomain = IpaDomain(inst, dn=self.suffix.ldap_text())

View File

@ -1552,3 +1552,31 @@ def validate_mask():
if mask & 0b111101101 > 0:
mask_str = "{:04o}".format(mask)
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.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(
REALM=api.env.realm,
DOMAIN=api.env.domain,
@ -329,19 +344,11 @@ class LDAPUpdate:
# uid / gid for autobind
NAMED_UID=platformconstants.NAMED_USER.uid,
NAMED_GID=platformconstants.NAMED_GROUP.gid,
REPLICATION_PLUGIN=replication_plugin,
)
for k, v in default_sub.items():
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):
try:
return ipautil.template_str(s, self.sub_dict)
@ -961,8 +968,6 @@ class LDAPUpdate:
"""
self.modified = False
try:
self.create_connection()
upgrade_files = files
if ordered:
upgrade_files = sorted(files)

View File

@ -232,23 +232,6 @@ def get_ds_version(conn):
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:
"""Manage replication agreements
@ -757,7 +740,9 @@ class ReplicationManager:
def get_entry(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(
DN(('cn', replication_plugin_name), ('cn', 'plugins'),

View File

@ -98,7 +98,6 @@ class IPAUpgrade(service.Service):
self.modified = False
self.serverid = serverid
self.schema_files = schema_files
self.sub_dict = dict()
def __start(self):
srv = services.service(self.service_name, api)
@ -172,20 +171,6 @@ class IPAUpgrade(service.Service):
else:
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:
parser = GetEntryFromLDIF(in_file, entries_dn=[COMPAT_DN])
parser.parse()
@ -300,7 +285,7 @@ class IPAUpgrade(service.Service):
def __upgrade(self):
try:
ld = ldapupdate.LDAPUpdate(api=self.api, sub_dict=self.sub_dict)
ld = ldapupdate.LDAPUpdate(api=self.api)
if len(self.files) == 0:
self.files = ld.get_all_files(ldapupdate.UPDATES_DIR)
self.modified = (ld.update(self.files) or self.modified)