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