Blob Blame Raw
From 964a153b420b26140e0bbddfbebb4a51aaa0e4ea Mon Sep 17 00:00:00 2001
From: James Chapman <jachapma@redhat.com>
Date: Thu, 3 Jun 2021 15:16:22 +0000
Subject: [PATCH 1/7] Issue 4791 - Missing dependency for RetroCL RFE

Description: The RetroCL exclude attribute RFE is dependent on functionality of the
	     EntryUUID bug fix, that didn't make into the latest build. This breaks the
             RetroCL exclude attr feature so we need to provide a workaround.

Fixes: https://github.com/389ds/389-ds-base/issues/4791

Relates: https://github.com/389ds/389-ds-base/pull/4723

Relates: https://github.com/389ds/389-ds-base/issues/4224

Reviewed by: tbordaz, droideck (Thank you)
---
 .../tests/suites/retrocl/basic_test.py        |  6 ++--
 .../lib389/cli_conf/plugins/retrochangelog.py | 35 +++++++++++++++++--
 2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/dirsrvtests/tests/suites/retrocl/basic_test.py b/dirsrvtests/tests/suites/retrocl/basic_test.py
index 112c73cb9..f3bc50f29 100644
--- a/dirsrvtests/tests/suites/retrocl/basic_test.py
+++ b/dirsrvtests/tests/suites/retrocl/basic_test.py
@@ -17,7 +17,7 @@ from lib389.utils import *
 from lib389.tasks import *
 from lib389.cli_base import FakeArgs, connect_instance, disconnect_instance
 from lib389.cli_base.dsrc import dsrc_arg_concat
-from lib389.cli_conf.plugins.retrochangelog import retrochangelog_add
+from lib389.cli_conf.plugins.retrochangelog import retrochangelog_add_attr
 from lib389.idm.user import UserAccount, UserAccounts, nsUserAccounts
 
 pytestmark = pytest.mark.tier1
@@ -122,7 +122,7 @@ def test_retrocl_exclude_attr_add(topology_st):
     args.bindpw = None
     args.prompt = False
     args.exclude_attrs = ATTR_HOMEPHONE
-    args.func = retrochangelog_add
+    args.func = retrochangelog_add_attr
     dsrc_inst = dsrc_arg_concat(args, None)
     inst = connect_instance(dsrc_inst, False, args)
     result = args.func(inst, None, log, args)
@@ -255,7 +255,7 @@ def test_retrocl_exclude_attr_mod(topology_st):
     args.bindpw = None
     args.prompt = False
     args.exclude_attrs = ATTR_CARLICENSE
-    args.func = retrochangelog_add
+    args.func = retrochangelog_add_attr
     dsrc_inst = dsrc_arg_concat(args, None)
     inst = connect_instance(dsrc_inst, False, args)
     result = args.func(inst, None, log, args)
diff --git a/src/lib389/lib389/cli_conf/plugins/retrochangelog.py b/src/lib389/lib389/cli_conf/plugins/retrochangelog.py
index 9940c6532..160fbb82d 100644
--- a/src/lib389/lib389/cli_conf/plugins/retrochangelog.py
+++ b/src/lib389/lib389/cli_conf/plugins/retrochangelog.py
@@ -6,8 +6,13 @@
 # See LICENSE for details.
 # --- END COPYRIGHT BLOCK ---
 
+# JC Work around for missing dependency on https://github.com/389ds/389-ds-base/pull/4344
+import ldap
+
 from lib389.plugins import RetroChangelogPlugin
-from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit
+# JC Work around for missing dependency https://github.com/389ds/389-ds-base/pull/4344
+# from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add_attr
+from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, _args_to_attrs
 
 arg_to_attr = {
     'is_replicated': 'isReplicated',
@@ -18,12 +23,38 @@ arg_to_attr = {
     'exclude_attrs': 'nsslapd-exclude-attrs'
 }
 
-
 def retrochangelog_edit(inst, basedn, log, args):
     log = log.getChild('retrochangelog_edit')
     plugin = RetroChangelogPlugin(inst)
     generic_object_edit(plugin, log, args, arg_to_attr)
 
+# JC Work around for missing dependency https://github.com/389ds/389-ds-base/pull/4344
+def retrochangelog_add_attr(inst, basedn, log, args):
+    log = log.getChild('retrochangelog_add_attr')
+    plugin = RetroChangelogPlugin(inst)
+    generic_object_add_attr(plugin, log, args, arg_to_attr)
+
+# JC Work around for missing dependency https://github.com/389ds/389-ds-base/pull/4344
+def generic_object_add_attr(dsldap_object, log, args, arg_to_attr):
+    """Add an attribute to the entry. This differs to 'edit' as edit uses replace,
+    and this allows multivalues to be added.
+
+    dsldap_object should be a single instance of DSLdapObject with a set dn
+    """
+    log = log.getChild('generic_object_add_attr')
+    # Gather the attributes
+    attrs = _args_to_attrs(args, arg_to_attr)
+
+    modlist = []
+    for attr, value in attrs.items():
+        if not isinstance(value, list):
+            value = [value]
+        modlist.append((ldap.MOD_ADD, attr, value))
+    if len(modlist) > 0:
+        dsldap_object.apply_mods(modlist)
+        log.info("Successfully changed the %s", dsldap_object.dn)
+    else:
+        raise ValueError("There is nothing to set in the %s plugin entry" % dsldap_object.dn)
 
 def _add_parser_args(parser):
     parser.add_argument('--is-replicated', choices=['TRUE', 'FALSE'], type=str.upper,
-- 
2.31.1