Blame SOURCES/0016-Issue-4775-Add-entryuuid-CLI-and-Fixup-4776.patch

b2bc38
From 93588ea455aff691bdfbf59cdef4df8fcedb69f2 Mon Sep 17 00:00:00 2001
b03d2c
From: Firstyear <william@blackhats.net.au>
b03d2c
Date: Thu, 19 Aug 2021 10:46:00 +1000
b2bc38
Subject: [PATCH 1/2] Issue 4775 - Add entryuuid CLI and Fixup (#4776)
b03d2c
b03d2c
Bug Description: EntryUUID when added was missing it's CLI
b03d2c
and helpers for fixups.
b03d2c
b03d2c
Fix Description: Add the CLI elements.
b03d2c
b03d2c
fixes: https://github.com/389ds/389-ds-base/issues/4775
b03d2c
b03d2c
Author: William Brown <william@blackhats.net.au>
b03d2c
b03d2c
Review by: @mreynolds389 (thanks!)
b03d2c
---
b2bc38
 src/lib389/lib389/cli_conf/plugin.py          |  6 ++-
b2bc38
 .../lib389/cli_conf/plugins/entryuuid.py      | 39 ++++++++++++++
b2bc38
 src/plugins/entryuuid/src/lib.rs              | 54 ++++++++-----------
b2bc38
 3 files changed, 65 insertions(+), 34 deletions(-)
b03d2c
 create mode 100644 src/lib389/lib389/cli_conf/plugins/entryuuid.py
b03d2c
b03d2c
diff --git a/src/lib389/lib389/cli_conf/plugin.py b/src/lib389/lib389/cli_conf/plugin.py
b2bc38
index 560c57f9b..7c0cf2c80 100644
b03d2c
--- a/src/lib389/lib389/cli_conf/plugin.py
b03d2c
+++ b/src/lib389/lib389/cli_conf/plugin.py
b2bc38
@@ -1,5 +1,5 @@
b2bc38
 # --- BEGIN COPYRIGHT BLOCK ---
b2bc38
-# Copyright (C) 2018 Red Hat, Inc.
b2bc38
+# Copyright (C) 2022 Red Hat, Inc.
b2bc38
 # All rights reserved.
b2bc38
 #
b2bc38
 # License: GPL (version 3 or any later version).
b2bc38
@@ -27,6 +27,8 @@ from lib389.cli_conf.plugins import passthroughauth as cli_passthroughauth
b03d2c
 from lib389.cli_conf.plugins import retrochangelog as cli_retrochangelog
b03d2c
 from lib389.cli_conf.plugins import automember as cli_automember
b03d2c
 from lib389.cli_conf.plugins import posix_winsync as cli_posix_winsync
b2bc38
+from lib389.cli_conf.plugins import contentsync as cli_contentsync
b03d2c
+from lib389.cli_conf.plugins import entryuuid as cli_entryuuid
b03d2c
 
b03d2c
 SINGULAR = Plugin
b03d2c
 MANY = Plugins
b2bc38
@@ -113,6 +115,8 @@ def create_parser(subparsers):
b03d2c
     cli_passthroughauth.create_parser(subcommands)
b03d2c
     cli_retrochangelog.create_parser(subcommands)
b03d2c
     cli_posix_winsync.create_parser(subcommands)
b2bc38
+    cli_contentsync.create_parser(subcommands)
b03d2c
+    cli_entryuuid.create_parser(subcommands)
b03d2c
 
b03d2c
     list_parser = subcommands.add_parser('list', help="List current configured (enabled and disabled) plugins")
b03d2c
     list_parser.set_defaults(func=plugin_list)
b03d2c
diff --git a/src/lib389/lib389/cli_conf/plugins/entryuuid.py b/src/lib389/lib389/cli_conf/plugins/entryuuid.py
b03d2c
new file mode 100644
b03d2c
index 000000000..6c86bff4b
b03d2c
--- /dev/null
b03d2c
+++ b/src/lib389/lib389/cli_conf/plugins/entryuuid.py
b03d2c
@@ -0,0 +1,39 @@
b03d2c
+# --- BEGIN COPYRIGHT BLOCK ---
b03d2c
+# Copyright (C) 2021 William Brown <william@blackhats.net.au>
b03d2c
+# All rights reserved.
b03d2c
+#
b03d2c
+# License: GPL (version 3 or any later version).
b03d2c
+# See LICENSE for details.
b03d2c
+# --- END COPYRIGHT BLOCK ---
b03d2c
+
b03d2c
+import ldap
b03d2c
+from lib389.plugins import EntryUUIDPlugin
b03d2c
+from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add
b03d2c
+
b03d2c
+def do_fixup(inst, basedn, log, args):
b03d2c
+    plugin = EntryUUIDPlugin(inst)
b03d2c
+    log.info('Attempting to add task entry...')
b03d2c
+    if not plugin.status():
b03d2c
+        log.error("'%s' is disabled. Fix up task can't be executed" % plugin.rdn)
b03d2c
+        return
b03d2c
+    fixup_task = plugin.fixup(args.DN, args.filter)
b03d2c
+    fixup_task.wait()
b03d2c
+    exitcode = fixup_task.get_exit_code()
b03d2c
+    if exitcode != 0:
b03d2c
+        log.error('EntryUUID fixup task has failed. Please, check the error log for more - %s' % exitcode)
b03d2c
+    else:
b03d2c
+        log.info('Successfully added task entry')
b03d2c
+
b03d2c
+def create_parser(subparsers):
b03d2c
+    referint = subparsers.add_parser('entryuuid', help='Manage and configure EntryUUID plugin')
b03d2c
+    subcommands = referint.add_subparsers(help='action')
b03d2c
+
b03d2c
+    add_generic_plugin_parsers(subcommands, EntryUUIDPlugin)
b03d2c
+
b03d2c
+    fixup = subcommands.add_parser('fixup', help='Run the fix-up task for EntryUUID plugin')
b03d2c
+    fixup.set_defaults(func=do_fixup)
b03d2c
+    fixup.add_argument('DN', help="Base DN that contains entries to fix up")
b03d2c
+    fixup.add_argument('-f', '--filter',
b03d2c
+                       help='Filter for entries to fix up.\n If omitted, all entries under base DN'
b03d2c
+                            'will have their EntryUUID attribute regenerated if not present.')
b03d2c
+
b03d2c
diff --git a/src/plugins/entryuuid/src/lib.rs b/src/plugins/entryuuid/src/lib.rs
b2bc38
index da9f0c239..29a9f1258 100644
b03d2c
--- a/src/plugins/entryuuid/src/lib.rs
b03d2c
+++ b/src/plugins/entryuuid/src/lib.rs
b03d2c
@@ -33,7 +33,7 @@ fn assign_uuid(e: &mut EntryRef) {
b03d2c
     // 🚧 safety barrier 🚧
b03d2c
     if e.contains_attr("entryUUID") {
b03d2c
         log_error!(
b03d2c
-            ErrorLevel::Trace,
b03d2c
+            ErrorLevel::Plugin,
b03d2c
             "assign_uuid -> entryUUID exists, skipping dn {}",
b03d2c
             sdn.to_dn_string()
b03d2c
         );
b03d2c
@@ -47,7 +47,7 @@ fn assign_uuid(e: &mut EntryRef) {
b03d2c
     if sdn.is_below_suffix(&*config_sdn) || sdn.is_below_suffix(&*schema_sdn) {
b03d2c
         // We don't need to assign to these suffixes.
b03d2c
         log_error!(
b03d2c
-            ErrorLevel::Trace,
b03d2c
+            ErrorLevel::Plugin,
b03d2c
             "assign_uuid -> not assigning to {:?} as part of system suffix",
b03d2c
             sdn.to_dn_string()
b03d2c
         );
b03d2c
@@ -57,7 +57,7 @@ fn assign_uuid(e: &mut EntryRef) {
b03d2c
     // Generate a new Uuid.
b03d2c
     let u: Uuid = Uuid::new_v4();
b03d2c
     log_error!(
b03d2c
-        ErrorLevel::Trace,
b03d2c
+        ErrorLevel::Plugin,
b03d2c
         "assign_uuid -> assigning {:?} to dn {}",
b03d2c
         u,
b03d2c
         sdn.to_dn_string()
b03d2c
@@ -78,13 +78,13 @@ impl SlapiPlugin3 for EntryUuid {
b03d2c
     fn betxn_pre_add(pb: &mut PblockRef) -> Result<(), PluginError> {
b03d2c
         if pb.get_is_replicated_operation() {
b03d2c
             log_error!(
b03d2c
-                ErrorLevel::Trace,
b03d2c
+                ErrorLevel::Plugin,
b03d2c
                 "betxn_pre_add -> replicated operation, will not change"
b03d2c
             );
b03d2c
             return Ok(());
b03d2c
         }
b03d2c
 
b03d2c
-        log_error!(ErrorLevel::Trace, "betxn_pre_add -> start");
b03d2c
+        log_error!(ErrorLevel::Plugin, "betxn_pre_add -> start");
b03d2c
 
b03d2c
         let mut e = pb.get_op_add_entryref().map_err(|_| PluginError::Pblock)?;
b03d2c
         assign_uuid(&mut e);
b03d2c
@@ -105,7 +105,7 @@ impl SlapiPlugin3 for EntryUuid {
b03d2c
                 .first()
b03d2c
                 .ok_or_else(|| {
b03d2c
                     log_error!(
b03d2c
-                        ErrorLevel::Trace,
b03d2c
+                        ErrorLevel::Plugin,
b03d2c
                         "task_validate basedn error -> empty value array?"
b03d2c
                     );
b03d2c
                     LDAPError::Operation
b03d2c
@@ -113,7 +113,7 @@ impl SlapiPlugin3 for EntryUuid {
b03d2c
                 .as_ref()
b03d2c
                 .try_into()
b03d2c
                 .map_err(|e| {
b03d2c
-                    log_error!(ErrorLevel::Trace, "task_validate basedn error -> {:?}", e);
b03d2c
+                    log_error!(ErrorLevel::Plugin, "task_validate basedn error -> {:?}", e);
b03d2c
                     LDAPError::Operation
b03d2c
                 })?,
b03d2c
             None => return Err(LDAPError::ObjectClassViolation),
b03d2c
@@ -124,7 +124,7 @@ impl SlapiPlugin3 for EntryUuid {
b03d2c
                 .first()
b03d2c
                 .ok_or_else(|| {
b03d2c
                     log_error!(
b03d2c
-                        ErrorLevel::Trace,
b03d2c
+                        ErrorLevel::Plugin,
b03d2c
                         "task_validate filter error -> empty value array?"
b03d2c
                     );
b03d2c
                     LDAPError::Operation
b03d2c
@@ -132,7 +132,7 @@ impl SlapiPlugin3 for EntryUuid {
b03d2c
                 .as_ref()
b03d2c
                 .try_into()
b03d2c
                 .map_err(|e| {
b03d2c
-                    log_error!(ErrorLevel::Trace, "task_validate filter error -> {:?}", e);
b03d2c
+                    log_error!(ErrorLevel::Plugin, "task_validate filter error -> {:?}", e);
b03d2c
                     LDAPError::Operation
b03d2c
                 })?,
b03d2c
             None => {
b2bc38
@@ -144,17 +144,11 @@ impl SlapiPlugin3 for EntryUuid {
b03d2c
         // Error if the first filter is empty?
b03d2c
 
b03d2c
         // Now, to make things faster, we wrap the filter in a exclude term.
b2bc38
-
b2bc38
-        // 2021 - #4877 because we allow entryuuid to be strings, on import these may
b2bc38
-        // be invalid. As a result, we DO need to allow the fixup to check the entryuuid
b2bc38
-        // value is correct, so we can not exclude these during the search.
b2bc38
-        /*
b2bc38
         let raw_filter = if !raw_filter.starts_with('(') && !raw_filter.ends_with('(') {
b2bc38
             format!("(&({})(!(entryuuid=*)))", raw_filter)
b2bc38
         } else {
b2bc38
             format!("(&{}(!(entryuuid=*)))", raw_filter)
b2bc38
         };
b2bc38
-        */
b03d2c
 
b03d2c
         Ok(FixupData { basedn, raw_filter })
b03d2c
     }
b2bc38
@@ -165,7 +159,7 @@ impl SlapiPlugin3 for EntryUuid {
b03d2c
 
b03d2c
     fn task_handler(_task: &Task, data: Self::TaskData) -> Result<Self::TaskData, PluginError> {
b03d2c
         log_error!(
b03d2c
-            ErrorLevel::Trace,
b03d2c
+            ErrorLevel::Plugin,
b03d2c
             "task_handler -> start thread with -> {:?}",
b03d2c
             data
b03d2c
         );
b2bc38
@@ -205,12 +199,12 @@ impl SlapiPlugin3 for EntryUuid {
b03d2c
     }
b03d2c
 
b03d2c
     fn start(_pb: &mut PblockRef) -> Result<(), PluginError> {
b03d2c
-        log_error!(ErrorLevel::Trace, "plugin start");
b03d2c
+        log_error!(ErrorLevel::Plugin, "plugin start");
b03d2c
         Ok(())
b03d2c
     }
b03d2c
 
b03d2c
     fn close(_pb: &mut PblockRef) -> Result<(), PluginError> {
b03d2c
-        log_error!(ErrorLevel::Trace, "plugin close");
b03d2c
+        log_error!(ErrorLevel::Plugin, "plugin close");
b03d2c
         Ok(())
b03d2c
     }
b03d2c
 }
b2bc38
@@ -219,20 +213,14 @@ pub fn entryuuid_fixup_mapfn(e: &EntryRef, _data: &()) -> Result<(), PluginError
b2bc38
     /* Supply a modification to the entry. */
b2bc38
     let sdn = e.get_sdnref();
b2bc38
 
b2bc38
-    /* Check that entryuuid doesn't already exist, and is valid */
b2bc38
-    if let Some(valueset) = e.get_attr("entryUUID") {
b2bc38
-        if valueset.iter().all(|v| {
b2bc38
-            let u: Result<Uuid, _> = (&v).try_into();
b2bc38
-            u.is_ok()
b2bc38
-        }) {
b2bc38
-            // All values were valid uuid, move on!
b2bc38
-            log_error!(
b2bc38
-                ErrorLevel::Plugin,
b2bc38
-                "skipping fixup for -> {}",
b2bc38
-                sdn.to_dn_string()
b2bc38
-            );
b2bc38
-            return Ok(());
b2bc38
-        }
b2bc38
+    /* Sanity check that entryuuid doesn't already exist */
b2bc38
+    if e.contains_attr("entryUUID") {
b2bc38
+        log_error!(
b03d2c
+            ErrorLevel::Plugin,
b2bc38
+            "skipping fixup for -> {}",
b2bc38
+            sdn.to_dn_string()
b2bc38
+        );
b2bc38
+        return Ok(());
b2bc38
     }
b2bc38
 
b2bc38
     // Setup the modifications
b2bc38
@@ -248,7 +236,7 @@ pub fn entryuuid_fixup_mapfn(e: &EntryRef, _data: &()) -> Result<(), PluginError
b03d2c
 
b03d2c
     match lmod.execute() {
b03d2c
         Ok(_) => {
b03d2c
-            log_error!(ErrorLevel::Trace, "fixed-up -> {}", sdn.to_dn_string());
b03d2c
+            log_error!(ErrorLevel::Plugin, "fixed-up -> {}", sdn.to_dn_string());
b03d2c
             Ok(())
b03d2c
         }
b03d2c
         Err(e) => {
b03d2c
-- 
b2bc38
2.34.1
b03d2c