diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml new file mode 100644 index 0000000000..f51413d05e --- /dev/null +++ b/.github/workflows/coverity.yml @@ -0,0 +1,24 @@ +name: Coverity Scan + +on: + schedule: + - cron: '30 9 * * 1' + +jobs: + coverity: + runs-on: ubuntu-22.04 + + container: + image: quay.io/389ds/ci-images:fedora + + steps: + - uses: actions/checkout@v4 + - name: Checkout and configure + run: autoreconf -fvi && ./configure + + - uses: vapier/coverity-scan-action@v1 + with: + project: '389ds/389-ds-base' + command: make + email: ${{ secrets.COVERITY_SCAN_EMAIL }} + token: ${{ secrets.COVERITY_SCAN_TOKEN }} diff --git a/dirsrvtests/tests/suites/ds_logs/audit_log_test.py b/dirsrvtests/tests/suites/ds_logs/audit_log_test.py index d09ce8b00b..baf2571c04 100644 --- a/dirsrvtests/tests/suites/ds_logs/audit_log_test.py +++ b/dirsrvtests/tests/suites/ds_logs/audit_log_test.py @@ -95,6 +95,35 @@ def test_auditlog_display_attrs(topo): time.sleep(1) assert inst.ds_audit_log.match("#sn: modrdn_delete") +def test_auditlog_bof(topo): + """Test that value containing 256 chars doesn't crash the server + + :id: 767c0604-146d-4d07-8bf4-1093f51ce97b + :setup: Standalone Instance + :steps: + 1. Change 'cn' attribute to contain exactly 256 chars + 2. Test that server didn't crash + :expectedresults: + 1. Success + 2. Success + """ + + inst = topo.standalone + inst.config.replace('nsslapd-auditlog-logging-enabled', 'on') + + inst.config.replace('nsslapd-auditlog-display-attrs', 'cn') + users = UserAccounts(inst, DEFAULT_SUFFIX) + user = users.ensure_state(properties={ + 'uid': 'test_auditlog_bof', + 'cn': 'A'*256, + 'sn': 'user', + 'uidNumber': '1001', + 'gidNumber': '1001', + 'homeDirectory': '/home/auditlog_bof', + }) + time.sleep(1) + assert inst.status() == True + if __name__ == '__main__': # Run isolated diff --git a/dirsrvtests/tests/suites/password/pwp_history_test.py b/dirsrvtests/tests/suites/password/pwp_history_test.py index ba5449d79a..8a15a1986d 100644 --- a/dirsrvtests/tests/suites/password/pwp_history_test.py +++ b/dirsrvtests/tests/suites/password/pwp_history_test.py @@ -9,12 +9,14 @@ import pytest import time import logging +import ldap from lib389.tasks import * from lib389.utils import ds_is_newer from lib389.topologies import topology_st from lib389.idm.user import UserAccounts, TEST_USER_PROPERTIES from lib389.idm.directorymanager import DirectoryManager from lib389.idm.organizationalunit import OrganizationalUnits +from lib389.passwd import password_hash from lib389._constants import DEFAULT_SUFFIX pytestmark = pytest.mark.tier1 @@ -325,6 +327,87 @@ def test_basic(topology_st, user): # Done log.info('Test suite PASSED.') +def test_prehashed_pwd(topology_st): + """Test password history is updated with a pre-hashed password change + + :id: 24d08663-f36a-44ab-8f02-b8a3f502925b + :setup: Standalone instance + :steps: + 1. Configure password history policy as bellow: + passwordHistory: on + passwordChange: on + nsslapd-allow-hashed-passwords: on + 2. Create ACI to allow users change their password + 3. Add a test user + 4. Attempt to change password using non hased value + 5. Bind with non hashed value + 6. Create a hash value for update + 7. Update user password with hash value + 8. Bind with hashed password cleartext + 9. Check users passwordHistory + + :expectedresults: + 1. Password history policy should be configured successfully + 2. ACI applied correctly + 3. User successfully added + 4. Password change accepted + 5. Successful bind + 6. Hash value created + 7. Password change accepted + 8. Successful bind + 9. Users passwordHistory should contain 2 enteries + """ + + # Configure password history policy and add a test user + try: + topology_st.standalone.config.replace_many(('passwordHistory', 'on'), + ('passwordChange', 'on'), + ('nsslapd-allow-hashed-passwords', 'on')) + log.info('Configured password policy.') + except ldap.LDAPError as e: + log.fatal('Failed to configure password policy: ' + str(e)) + assert False + time.sleep(1) + + # Add aci so users can change their own password + USER_ACI = '(targetattr="userpassword || passwordHistory")(version 3.0; acl "pwp test"; allow (all) userdn="ldap:///self";)' + ous = OrganizationalUnits(topology_st.standalone, DEFAULT_SUFFIX) + ou = ous.get('people') + ou.add('aci', USER_ACI) + + # Create user + users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX) + user = users.create(properties=TEST_USER_PROPERTIES) + user.set('userpassword', 'password') + user.rebind('password') + + # Change user pwd to generate a history of 1 entry + user.replace('userpassword', 'password1') + user.rebind('password1') + + #Create pwd hash + pwd_hash = password_hash('password2', scheme='PBKDF2_SHA256', bin_dir=topology_st.standalone.ds_paths.bin_dir) + #log.info(pwd_hash) + + # Update user pwd hash + user.replace('userpassword', pwd_hash) + time.sleep(2) + + # Bind with hashed password + user.rebind('password2') + + # Check password history + pwds = user.get_attr_vals('passwordHistory') + if len(pwds) != 2: + log.fatal('Incorrect number of passwords stored in history: %d' % + len(pwds)) + log.error('password history: ' + str(pwds)) + assert False + else: + log.info('Correct number of passwords found in history.') + + # Done + log.info('Test suite PASSED.') if __name__ == '__main__': # Run isolated diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl index 0604f0bd3a..4fb11890ed 100755 --- a/ldap/admin/src/logconv.pl +++ b/ldap/admin/src/logconv.pl @@ -267,7 +267,7 @@ my %cipher = (); my @removefiles = (); -my @conncodes = qw(A1 B1 B4 T1 T2 B2 B3 R1 P1 P2 U1); +my @conncodes = qw(A1 B1 B4 T1 T2 T3 B2 B3 R1 P1 P2 U1); my %conn = (); map {$conn{$_} = $_} @conncodes; @@ -355,6 +355,7 @@ $connmsg{"B4"} = "Server failed to flush data (response) back to Client"; $connmsg{"T1"} = "Idle Timeout Exceeded"; $connmsg{"T2"} = "IO Block Timeout Exceeded or NTSSL Timeout"; +$connmsg{"T3"} = "Paged Search Time Limit Exceeded"; $connmsg{"B2"} = "Ber Too Big"; $connmsg{"B3"} = "Ber Peek"; $connmsg{"R1"} = "Revents"; @@ -1723,6 +1724,10 @@ sub dummy { print "\n $recCount. You have some coonections that are being closed by the ioblocktimeout setting. You may want to increase the ioblocktimeout.\n"; $recCount++; } + if (defined($conncount->{"T3"}) and $conncount->{"T3"} > 0){ + print "\n $recCount. You have some connections that are being closed because a paged result search limit has been exceeded. You may want to increase the search time limit.\n"; + $recCount++; + } # compare binds to unbinds, if the difference is more than 30% of the binds, then report a issue if (($bindCount - $unbindCount) > ($bindCount*.3)){ print "\n $recCount. You have a significant difference between binds and unbinds. You may want to investigate this difference.\n"; @@ -2366,6 +2371,7 @@ sub parseLineNormal $brokenPipeCount++; if (m/- T1/){ $hashes->{rc}->{"T1"}++; } elsif (m/- T2/){ $hashes->{rc}->{"T2"}++; } + elsif (m/- T3/){ $hashes->{rc}->{"T3"}++; } elsif (m/- A1/){ $hashes->{rc}->{"A1"}++; } elsif (m/- B1/){ $hashes->{rc}->{"B1"}++; } elsif (m/- B4/){ $hashes->{rc}->{"B4"}++; } @@ -2381,6 +2387,7 @@ sub parseLineNormal $connResetByPeerCount++; if (m/- T1/){ $hashes->{src}->{"T1"}++; } elsif (m/- T2/){ $hashes->{src}->{"T2"}++; } + elsif (m/- T3/){ $hashes->{src}->{"T3"}++; } elsif (m/- A1/){ $hashes->{src}->{"A1"}++; } elsif (m/- B1/){ $hashes->{src}->{"B1"}++; } elsif (m/- B4/){ $hashes->{src}->{"B4"}++; } @@ -2396,6 +2403,7 @@ sub parseLineNormal $resourceUnavailCount++; if (m/- T1/){ $hashes->{rsrc}->{"T1"}++; } elsif (m/- T2/){ $hashes->{rsrc}->{"T2"}++; } + elsif (m/- T3/){ $hashes->{rsrc}->{"T3"}++; } elsif (m/- A1/){ $hashes->{rsrc}->{"A1"}++; } elsif (m/- B1/){ $hashes->{rsrc}->{"B1"}++; } elsif (m/- B4/){ $hashes->{rsrc}->{"B4"}++; } @@ -2494,6 +2502,20 @@ sub parseLineNormal } } } + if (m/- T3/){ + if ($_ =~ /conn= *([0-9A-Z]+)/i) { + $exc = "no"; + $ip = getIPfromConn($1, $serverRestartCount); + for (my $xxx = 0; $xxx < $#excludeIP; $xxx++){ + if ($ip eq $excludeIP[$xxx]){$exc = "yes";} + } + if ($exc ne "yes"){ + $hashes->{T3}->{$ip}++; + $hashes->{conncount}->{"T3"}++; + $connCodeCount++; + } + } + } if (m/- B2/){ if ($_ =~ /conn= *([0-9A-Z]+)/i) { $exc = "no"; @@ -2852,12 +2874,13 @@ sub parseLineNormal $stats->{'unbind'}, $stats->{'notesA'}, $stats->{'notesU'}, + $stats->{'notesF'}, $stats->{'etime'}), "\n" ); } else { $stats->{'fh'}->print( "Time,time_t,Results,Search,Add,Mod,Modrdn,Moddn,Compare,Delete,Abandon,". - "Connections,SSL Conns,Bind,Anon Bind,Unbind,Unindexed search,Unindexed component,ElapsedTime\n" + "Connections,SSL Conns,Bind,Anon Bind,Unbind,Unindexed search,Unindexed component,Invalid filter,ElapsedTime\n" ); } } diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c index 77e1e0e4e6..d6ed6cf7a7 100644 --- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c +++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c @@ -7,12 +7,12 @@ * END COPYRIGHT BLOCK **/ -#include -#include #ifdef HAVE_CONFIG_H #include #endif #include "bdb_layer.h" +#include +#include #include #include #include @@ -7198,7 +7198,7 @@ bdb_dblayer_cursor_iterate(dbi_cursor_t *cursor, dbi_iterate_cb_t *action_cb, dbi_val_t key = {0}; dbi_val_t data = {0}; int rc = 0; - + if (bdb_cur == NULL) { return DBI_RC_INVALID; } diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c index 0a33e7d874..9e2f32c437 100644 --- a/ldap/servers/slapd/daemon.c +++ b/ldap/servers/slapd/daemon.c @@ -1567,9 +1567,9 @@ setup_pr_read_pds(Connection_Table *ct, int listnum) int add_fd = 1; /* check timeout for PAGED RESULTS */ if (pagedresults_is_timedout_nolock(c)) { - /* Exceeded the timelimit; disconnect the client */ + /* Exceeded the paged search timelimit; disconnect the client */ disconnect_server_nomutex(c, c->c_connid, -1, - SLAPD_DISCONNECT_IO_TIMEOUT, + SLAPD_DISCONNECT_PAGED_SEARCH_LIMIT, 0); connection_table_move_connection_out_of_active_list(ct, c); diff --git a/ldap/servers/slapd/disconnect_error_strings.h b/ldap/servers/slapd/disconnect_error_strings.h index b824c8f602..62e7f74177 100644 --- a/ldap/servers/slapd/disconnect_error_strings.h +++ b/ldap/servers/slapd/disconnect_error_strings.h @@ -27,6 +27,7 @@ ER2(SLAPD_DISCONNECT_BER_FLUSH, "Server failed to flush response back to Client ER2(SLAPD_DISCONNECT_IDLE_TIMEOUT, "Idle Timeout (nsslapd-idletimeout) - T1") ER2(SLAPD_DISCONNECT_REVENTS, "Poll revents - R1") ER2(SLAPD_DISCONNECT_IO_TIMEOUT, "IO Block Timeout (nsslapd-ioblocktimeout) - T2") +ER2(SLAPD_DISCONNECT_PAGED_SEARCH_LIMIT, "Paged Search Time Limit Exceeded - T3") ER2(SLAPD_DISCONNECT_PLUGIN, "Plugin - P1") ER2(SLAPD_DISCONNECT_UNBIND, "Cleanly Closed Connection - U1") ER2(SLAPD_DISCONNECT_POLL, "Poll - P2") diff --git a/ldap/servers/slapd/disconnect_errors.h b/ldap/servers/slapd/disconnect_errors.h index a0484f1c23..e118f674c7 100644 --- a/ldap/servers/slapd/disconnect_errors.h +++ b/ldap/servers/slapd/disconnect_errors.h @@ -35,6 +35,6 @@ #define SLAPD_DISCONNECT_SASL_FAIL SLAPD_DISCONNECT_ERROR_BASE + 12 #define SLAPD_DISCONNECT_PROXY_INVALID_HEADER SLAPD_DISCONNECT_ERROR_BASE + 13 #define SLAPD_DISCONNECT_PROXY_UNKNOWN SLAPD_DISCONNECT_ERROR_BASE + 14 - +#define SLAPD_DISCONNECT_PAGED_SEARCH_LIMIT SLAPD_DISCONNECT_ERROR_BASE + 15 #endif /* __DISCONNECT_ERRORS_H_ */ diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c index 24c2dc3893..33e73efde0 100644 --- a/ldap/servers/slapd/pw.c +++ b/ldap/servers/slapd/pw.c @@ -1065,6 +1065,7 @@ int check_pw_syntax_ext(Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, char **old_pw, Slapi_Entry *e, int mod_op, Slapi_Mods *smods) { Slapi_Attr *attr; + Slapi_Value **va = NULL; int i, pwresponse_req = 0; int is_replication = 0; int internal_op = 0; @@ -1124,7 +1125,24 @@ check_pw_syntax_ext(Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, c report_pw_violation(pb, dn, pwresponse_req, "invalid password syntax - passwords with storage scheme are not allowed"); return (1); } else { - /* We want to skip syntax checking since this is a pre-hashed password */ + /* We want to skip syntax checking since this is a pre-hashed password. But if the user + * has thrown caution to wind and allowed hashed passwords, we capture the history + */ + if (config_get_allow_hashed_pw() && pwpolicy->pw_history) { + e = get_entry(pb, dn); + if (e == NULL) { + return -1; + } + attr = attrlist_find(e->e_attrs, SLAPI_USERPWD_ATTR); + if (attr && !valueset_isempty(&attr->a_present_values)) { + if (old_pw && (va = valueset_get_valuearray(&attr->a_present_values))) { + *old_pw = slapi_ch_strdup(slapi_value_get_string(va[0])); + } else { + *old_pw = NULL; + } + } + slapi_entry_free(e); + } return (0); } } @@ -1335,7 +1353,6 @@ check_pw_syntax_ext(Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, c /* check for password history */ if (pwpolicy->pw_history == 1) { - Slapi_Value **va = NULL; attr = attrlist_find(e->e_attrs, "passwordHistory"); if (pwpolicy->pw_inhistory && attr && !valueset_isempty(&attr->a_present_values)) { /* Resetting password history array if necessary. */ @@ -1908,6 +1925,7 @@ pw_is_pwp_admin(Slapi_PBlock *pb, passwdPolicy *pwp, int rootdn_flag) /* first check if it's root */ if (is_requestor_root && rootdn_flag == PWP_ADMIN_OR_ROOTDN) { return 1; + } /* now check if it's a Password Policy Administrator */ slapi_pblock_get(pb, SLAPI_REQUESTOR_SDN, &bind_sdn); diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index aea052983c..a2a9af271c 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -74,6 +74,7 @@ static char ptokPBE[34] = "Internal (Software) Token "; #include #include #include +#include #include #include diff --git a/src/lib389/cli/dsconf b/src/lib389/cli/dsconf index 23068efdd4..b8a9808775 100755 --- a/src/lib389/cli/dsconf +++ b/src/lib389/cli/dsconf @@ -33,16 +33,13 @@ from lib389.cli_base import disconnect_instance, connect_instance from lib389.cli_base.dsrc import dsrc_to_ldap, dsrc_arg_concat from lib389.cli_base import setup_script_logger from lib389.cli_base import format_error_to_dict +from lib389.cli_base import parent_argparser from lib389.utils import instance_choices -parser = argparse.ArgumentParser(allow_abbrev=True) +parser = argparse.ArgumentParser(allow_abbrev=True, parents=[parent_argparser]) parser.add_argument('instance', help="The name of the instance or its LDAP URL, such as ldap://server.example.com:389", ).completer = instance_choices -parser.add_argument('-v', '--verbose', - help="Display verbose operation tracing during command execution", - action='store_true', default=False - ) parser.add_argument('-D', '--binddn', help="The account to bind as for executing operations", default=None @@ -67,10 +64,6 @@ parser.add_argument('-Z', '--starttls', help="Connect with StartTLS", default=False, action='store_true' ) -parser.add_argument('-j', '--json', - help="Return result in JSON object", - default=False, action='store_true' - ) subparsers = parser.add_subparsers(help="resources to act upon") diff --git a/src/lib389/cli/dsctl b/src/lib389/cli/dsctl index 7583a12717..ac12340fbb 100755 --- a/src/lib389/cli/dsctl +++ b/src/lib389/cli/dsctl @@ -30,21 +30,15 @@ from lib389.cli_ctl.instance import instance_remove_all from lib389.cli_base import ( disconnect_instance, setup_script_logger, - format_error_to_dict) + format_error_to_dict, + parent_argparser + ) from lib389._constants import DSRC_CONTAINER -parser = argparse.ArgumentParser(allow_abbrev=False) -parser.add_argument('-v', '--verbose', - help="Display verbose operation tracing during command execution", - action='store_true', default=False - ) +parser = argparse.ArgumentParser(allow_abbrev=False, parents=[parent_argparser]) parser.add_argument('instance', nargs='?', default=False, help="The name of the instance to act upon", ).completer = instance_choices -parser.add_argument('-j', '--json', - help="Return result in JSON object", - default=False, action='store_true' - ) parser.add_argument('-l', '--list', help="List available Directory Server instances", default=False, action='store_true' diff --git a/src/lib389/cli/dsidm b/src/lib389/cli/dsidm index 1b6762646a..970973f4f5 100755 --- a/src/lib389/cli/dsidm +++ b/src/lib389/cli/dsidm @@ -2,7 +2,7 @@ # --- BEGIN COPYRIGHT BLOCK --- # Copyright (C) 2016, William Brown -# Copyright (C) 2023 Red Hat, Inc. +# Copyright (C) 2024 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -19,6 +19,7 @@ import argparse import argcomplete from lib389.utils import get_instance_list, instance_choices from lib389._constants import DSRC_HOME +from lib389.cli_idm import _get_basedn_arg from lib389.cli_idm import account as cli_account from lib389.cli_idm import initialise as cli_init from lib389.cli_idm import organizationalunit as cli_ou @@ -32,8 +33,9 @@ from lib389.cli_idm import service as cli_service from lib389.cli_base import connect_instance, disconnect_instance, setup_script_logger from lib389.cli_base.dsrc import dsrc_to_ldap, dsrc_arg_concat from lib389.cli_base import format_error_to_dict +from lib389.cli_base import parent_argparser -parser = argparse.ArgumentParser(allow_abbrev=True) +parser = argparse.ArgumentParser(allow_abbrev=True, parents=[parent_argparser]) # First, add the LDAP options parser.add_argument('instance', help="The name of the instance or its LDAP URL, such as ldap://server.example.com:389", @@ -42,10 +44,6 @@ parser.add_argument('-b', '--basedn', help="Base DN (root naming context) of the instance to manage", default=None ) -parser.add_argument('-v', '--verbose', - help="Display verbose operation tracing during command execution", - action='store_true', default=False - ) parser.add_argument('-D', '--binddn', help="The account to bind as for executing operations", default=None @@ -66,10 +64,6 @@ parser.add_argument('-Z', '--starttls', help="Connect with StartTLS", default=False, action='store_true' ) -parser.add_argument('-j', '--json', - help="Return result in JSON object", - default=False, action='store_true' - ) subparsers = parser.add_subparsers(help="resources to act upon") # Call all the other cli modules to register their bits cli_account.create_parser(subparsers) @@ -124,14 +118,6 @@ if __name__ == '__main__': parser.print_help() sys.exit(1) - if dsrc_inst['basedn'] is None: - errmsg = "Must provide a basedn!" - if args.json: - sys.stderr.write('{"desc": "%s"}\n' % errmsg) - else: - log.error(errmsg) - sys.exit(1) - if not args.verbose: signal.signal(signal.SIGINT, signal_handler) @@ -142,7 +128,15 @@ if __name__ == '__main__': result = False try: inst = connect_instance(dsrc_inst=dsrc_inst, verbose=args.verbose, args=args) - result = args.func(inst, dsrc_inst['basedn'], log, args) + basedn = _get_basedn_arg(inst, args, log, msg="Enter basedn") + if basedn is None: + errmsg = "Must provide a basedn!" + if args.json: + sys.stderr.write('{"desc": "%s"}\n' % errmsg) + else: + log.error(errmsg) + sys.exit(1) + result = args.func(inst, basedn, log, args) if args.verbose: log.info("Command successful.") except Exception as e: diff --git a/src/lib389/lib389/__init__.py b/src/lib389/lib389/__init__.py index 4edea63b72..b4cee81e84 100644 --- a/src/lib389/lib389/__init__.py +++ b/src/lib389/lib389/__init__.py @@ -1105,7 +1105,7 @@ def start(self, timeout=120, post_open=True): if self.status() is True: return - if self.with_systemd(): + if self.with_systemd_running(): self.log.debug("systemd status -> True") # Do systemd things here ... try: @@ -1186,7 +1186,7 @@ def stop(self, timeout=120): if self.status() is False: return - if self.with_systemd(): + if self.with_systemd_running(): self.log.debug("systemd status -> True") # Do systemd things here ... subprocess.check_output(["systemctl", "stop", "dirsrv@%s" % self.serverid], stderr=subprocess.STDOUT) @@ -1213,7 +1213,7 @@ def status(self): Will update the self.state parameter. """ - if self.with_systemd(): + if self.with_systemd_running(): self.log.debug("systemd status -> True") # Do systemd things here ... rc = subprocess.call(["systemctl", @@ -1730,6 +1730,17 @@ def with_systemd(self): return self.systemd_override return self.ds_paths.with_systemd + def with_systemd_running(self): + if not self.with_systemd(): + return False + cp = subprocess.run(["systemctl", "is-system-running"], + universal_newlines=True, capture_output=True) + # is-system-running can detect the 7 modes (initializing, starting, + # running, degraded, maintenance, stopping, offline) or "unknown". + # To keep things simple, we assume that anything other than "offline" + # means that systemd is usable. + return cp.stdout.strip() != 'offline' + def pid_file(self): if self._containerised: return "/data/run/slapd-localhost.pid" diff --git a/src/lib389/lib389/cli_base/__init__.py b/src/lib389/lib389/cli_base/__init__.py index 60dd6cd708..c431f066df 100644 --- a/src/lib389/lib389/cli_base/__init__.py +++ b/src/lib389/lib389/cli_base/__init__.py @@ -7,6 +7,7 @@ # See LICENSE for details. # --- END COPYRIGHT BLOCK --- +import argparse import ast import logging import sys @@ -365,6 +366,42 @@ def _generic_modify_dn(inst, basedn, log, manager_class, dn, args=None): _generic_modify_inner(log, o, args.changes) +# We need parent parser to be able to add -v and -j to all subparsers +# because we use parent_arguments in CustomHelpFormatter +parent_arguments = [] +parent_argparser = argparse.ArgumentParser(add_help=False) +parent_arguments.append(parent_argparser.add_argument('-v', '--verbose', + help="Display verbose operation tracing during command execution", + action='store_true', default=False + )) +parent_arguments.append(parent_argparser.add_argument('-j', '--json', + help="Return result in JSON object", + default=False, action='store_true' + )) + + +class CustomHelpFormatter(argparse.HelpFormatter): + """Custom help formatter to add [-v] [-j] to the usage line and add these options' + description to the full help output + """ + def add_arguments(self, actions): + if len(actions) > 0 and actions[0].option_strings: + actions = parent_arguments + actions + super(CustomHelpFormatter, self).add_arguments(actions) + + def _format_usage(self, usage, actions, groups, prefix): + usage = super(CustomHelpFormatter, self)._format_usage(usage, actions, groups, prefix) + formatted_options = self._format_actions_usage(parent_arguments, []) + # If formatted_options already in usage - remove them + if formatted_options in usage: + usage = usage.replace(f' {formatted_options}', '') + usage = usage.split(' ') + usage.insert(2, formatted_options) + usage = ' '.join(usage) + + return usage + + class LogCapture(logging.Handler): """ This useful class is for intercepting logs, and then making assertions about diff --git a/src/lib389/lib389/cli_conf/__init__.py b/src/lib389/lib389/cli_conf/__init__.py index ef9db91660..44f39ed2fa 100644 --- a/src/lib389/lib389/cli_conf/__init__.py +++ b/src/lib389/lib389/cli_conf/__init__.py @@ -7,6 +7,7 @@ # --- END COPYRIGHT BLOCK --- import ldap from lib389 import ensure_list_str +from lib389.cli_base import CustomHelpFormatter def _args_to_attrs(args, arg_to_attr): @@ -155,16 +156,16 @@ def generic_status(inst, basedn, log, args): def add_generic_plugin_parsers(subparser, plugin_cls): - show_parser = subparser.add_parser('show', help='Displays the plugin configuration') + show_parser = subparser.add_parser('show', help='Displays the plugin configuration', formatter_class=CustomHelpFormatter) show_parser.set_defaults(func=generic_show, plugin_cls=plugin_cls) - enable_parser = subparser.add_parser('enable', help='Enables the plugin') + enable_parser = subparser.add_parser('enable', help='Enables the plugin', formatter_class=CustomHelpFormatter) enable_parser.set_defaults(func=generic_enable, plugin_cls=plugin_cls) - disable_parser = subparser.add_parser('disable', help='Disables the plugin') + disable_parser = subparser.add_parser('disable', help='Disables the plugin', formatter_class=CustomHelpFormatter) disable_parser.set_defaults(func=generic_disable, plugin_cls=plugin_cls) - status_parser = subparser.add_parser('status', help='Displays the plugin status') + status_parser = subparser.add_parser('status', help='Displays the plugin status', formatter_class=CustomHelpFormatter) status_parser.set_defaults(func=generic_status, plugin_cls=plugin_cls) diff --git a/src/lib389/lib389/cli_conf/backend.py b/src/lib389/lib389/cli_conf/backend.py index 87a5646cd3..ec319045f1 100644 --- a/src/lib389/lib389/cli_conf/backend.py +++ b/src/lib389/lib389/cli_conf/backend.py @@ -28,6 +28,7 @@ _generic_get_dn, _get_arg, _warn, + CustomHelpFormatter ) import json import ldap @@ -839,39 +840,39 @@ def backend_compact(inst, basedn, log, args): def create_parser(subparsers): - backend_parser = subparsers.add_parser('backend', help="Manage database suffixes and backends") + backend_parser = subparsers.add_parser('backend', help="Manage database suffixes and backends", formatter_class=CustomHelpFormatter) subcommands = backend_parser.add_subparsers(help="action") ##################################################### # Suffix parser ##################################################### - suffix_parser = subcommands.add_parser('suffix', help="Manage backend suffixes") + suffix_parser = subcommands.add_parser('suffix', help="Manage backend suffixes", formatter_class=CustomHelpFormatter) suffix_subcommands = suffix_parser.add_subparsers(help="action") # List backends/suffixes - list_parser = suffix_subcommands.add_parser('list', help="List active backends and suffixes") + list_parser = suffix_subcommands.add_parser('list', help="List active backends and suffixes", formatter_class=CustomHelpFormatter) list_parser.set_defaults(func=backend_list) list_parser.add_argument('--suffix', action='store_true', help='Displays the suffixes without backend name') list_parser.add_argument('--skip-subsuffixes', action='store_true', help='Displays the list of suffixes without sub-suffixes') # Get backend - get_parser = suffix_subcommands.add_parser('get', help='Display the suffix entry') + get_parser = suffix_subcommands.add_parser('get', help='Display the suffix entry', formatter_class=CustomHelpFormatter) get_parser.set_defaults(func=backend_get) get_parser.add_argument('selector', nargs='?', help='The backend database name to search for') # Get the DN of a backend - get_dn_parser = suffix_subcommands.add_parser('get-dn', help='Display the DN of a backend') + get_dn_parser = suffix_subcommands.add_parser('get-dn', help='Display the DN of a backend', formatter_class=CustomHelpFormatter) get_dn_parser.set_defaults(func=backend_get_dn) get_dn_parser.add_argument('dn', nargs='?', help='The DN to the database entry in cn=ldbm database,cn=plugins,cn=config') # Get subsuffixes - get_subsuffix_parser = suffix_subcommands.add_parser('get-sub-suffixes', help='Display sub-suffixes') + get_subsuffix_parser = suffix_subcommands.add_parser('get-sub-suffixes', help='Display sub-suffixes', formatter_class=CustomHelpFormatter) get_subsuffix_parser.set_defaults(func=backend_get_subsuffixes) get_subsuffix_parser.add_argument('--suffix', action='store_true', help='Displays the list of suffixes without backend name') get_subsuffix_parser.add_argument('be_name', help='The backend name or suffix') # Set the backend/suffix configuration - set_backend_parser = suffix_subcommands.add_parser('set', help='Set configuration settings for a specific backend') + set_backend_parser = suffix_subcommands.add_parser('set', help='Set configuration settings for a specific backend', formatter_class=CustomHelpFormatter) set_backend_parser.set_defaults(func=backend_set) set_backend_parser.add_argument('--enable-readonly', action='store_true', help='Enables read-only mode for the backend database') set_backend_parser.add_argument('--disable-readonly', action='store_true', help='Disables read-only mode for the backend database') @@ -892,11 +893,11 @@ def create_parser(subparsers): ######################################### # Index parser ######################################### - index_parser = subcommands.add_parser('index', help="Manage backend indexes") + index_parser = subcommands.add_parser('index', help="Manage backend indexes", formatter_class=CustomHelpFormatter) index_subcommands = index_parser.add_subparsers(help="action") # Create index - add_index_parser = index_subcommands.add_parser('add', help='Add an index') + add_index_parser = index_subcommands.add_parser('add', help='Add an index', formatter_class=CustomHelpFormatter) add_index_parser.set_defaults(func=backend_add_index) add_index_parser.add_argument('--index-type', required=True, action='append', help='Sets the indexing type (eq, sub, pres, or approx)') add_index_parser.add_argument('--matching-rule', action='append', help='Sets the matching rule for the index') @@ -905,7 +906,7 @@ def create_parser(subparsers): add_index_parser.add_argument('be_name', help='The backend name or suffix') # Edit index - edit_index_parser = index_subcommands.add_parser('set', help='Update an index') + edit_index_parser = index_subcommands.add_parser('set', help='Update an index', formatter_class=CustomHelpFormatter) edit_index_parser.set_defaults(func=backend_set_index) edit_index_parser.add_argument('--attr', required=True, help='Sets the indexed attribute to update') edit_index_parser.add_argument('--add-type', action='append', help='Adds an index type to the index (eq, sub, pres, or approx)') @@ -916,25 +917,25 @@ def create_parser(subparsers): edit_index_parser.add_argument('be_name', help='The backend name or suffix') # Get index - get_index_parser = index_subcommands.add_parser('get', help='Display an index entry') + get_index_parser = index_subcommands.add_parser('get', help='Display an index entry', formatter_class=CustomHelpFormatter) get_index_parser.set_defaults(func=backend_get_index) get_index_parser.add_argument('--attr', required=True, action='append', help='Sets the index name to display') get_index_parser.add_argument('be_name', help='The backend name or suffix') # list indexes - list_index_parser = index_subcommands.add_parser('list', help='Display the index') + list_index_parser = index_subcommands.add_parser('list', help='Display the index', formatter_class=CustomHelpFormatter) list_index_parser.set_defaults(func=backend_list_index) list_index_parser.add_argument('--just-names', action='store_true', help='Displays only the names of indexed attributes') list_index_parser.add_argument('be_name', help='The backend name or suffix') # Delete index - del_index_parser = index_subcommands.add_parser('delete', help='Delete an index') + del_index_parser = index_subcommands.add_parser('delete', help='Delete an index', formatter_class=CustomHelpFormatter) del_index_parser.set_defaults(func=backend_del_index) del_index_parser.add_argument('--attr', action='append', help='Sets the name of the attribute to delete from the index') del_index_parser.add_argument('be_name', help='The backend name or suffix') # reindex index - reindex_parser = index_subcommands.add_parser('reindex', help='Re-index the database for a single index or all indexes') + reindex_parser = index_subcommands.add_parser('reindex', help='Re-index the database for a single index or all indexes', formatter_class=CustomHelpFormatter) reindex_parser.set_defaults(func=backend_reindex) reindex_parser.add_argument('--attr', action='append', help='Sets the name of the attribute to re-index. Omit this argument to re-index all attributes') reindex_parser.add_argument('--wait', action='store_true', help='Waits for the index task to complete and reports the status') @@ -943,17 +944,17 @@ def create_parser(subparsers): ############################################# # VLV parser ############################################# - vlv_parser = subcommands.add_parser('vlv-index', help="Manage VLV searches and indexes") + vlv_parser = subcommands.add_parser('vlv-index', help="Manage VLV searches and indexes", formatter_class=CustomHelpFormatter) vlv_subcommands = vlv_parser.add_subparsers(help="action") # List VLV Searches - list_vlv_search_parser = vlv_subcommands.add_parser('list', help='List VLV search and index entries') + list_vlv_search_parser = vlv_subcommands.add_parser('list', help='List VLV search and index entries', formatter_class=CustomHelpFormatter) list_vlv_search_parser.set_defaults(func=backend_list_vlv) list_vlv_search_parser.add_argument('--just-names', action='store_true', help='Displays only the names of VLV search entries') list_vlv_search_parser.add_argument('be_name', help='The backend name of the VLV index') # Get VLV search entry and indexes - get_vlv_search_parser = vlv_subcommands.add_parser('get', help='Display a VLV search and indexes') + get_vlv_search_parser = vlv_subcommands.add_parser('get', help='Display a VLV search and indexes', formatter_class=CustomHelpFormatter) get_vlv_search_parser.set_defaults(func=backend_get_vlv) get_vlv_search_parser.add_argument('--name', help='Displays the VLV search entry and its index entries') get_vlv_search_parser.add_argument('be_name', help='The backend name of the VLV index') @@ -970,7 +971,7 @@ def create_parser(subparsers): add_vlv_search_parser.add_argument('be_name', help='The backend name of the VLV index') # Edit vlv search - edit_vlv_search_parser = vlv_subcommands.add_parser('edit-search', help='Update a VLV search and index') + edit_vlv_search_parser = vlv_subcommands.add_parser('edit-search', help='Update a VLV search and index', formatter_class=CustomHelpFormatter) edit_vlv_search_parser.set_defaults(func=backend_edit_vlv) edit_vlv_search_parser.add_argument('--name', required=True, help='Sets the name of the VLV index') edit_vlv_search_parser.add_argument('--search-base', help='Sets the VLV search base') @@ -980,13 +981,13 @@ def create_parser(subparsers): edit_vlv_search_parser.add_argument('be_name', help='The backend name of the VLV index to update') # Delete vlv search(and index) - del_vlv_search_parser = vlv_subcommands.add_parser('del-search', help='Delete VLV search & index') + del_vlv_search_parser = vlv_subcommands.add_parser('del-search', help='Delete VLV search & index', formatter_class=CustomHelpFormatter) del_vlv_search_parser.set_defaults(func=backend_del_vlv) del_vlv_search_parser.add_argument('--name', required=True, help='Sets the name of the VLV search index') del_vlv_search_parser.add_argument('be_name', help='The backend name of the VLV index') # Create VLV Index - add_vlv_index_parser = vlv_subcommands.add_parser('add-index', help='Create a VLV index under a VLV search entry (parent entry). ' + add_vlv_index_parser = vlv_subcommands.add_parser('add-index', help='Create a VLV index under a VLV search entry (parent entry, formatter_class=CustomHelpFormatter). ' 'The VLV index specifies the attributes to sort') add_vlv_index_parser.set_defaults(func=backend_create_vlv_index) add_vlv_index_parser.add_argument('--parent-name', required=True, help='Sets the name or "cn" attribute of the parent VLV search entry') @@ -996,7 +997,7 @@ def create_parser(subparsers): add_vlv_index_parser.add_argument('be_name', help='The backend name of the VLV index') # Delete VLV Index - del_vlv_index_parser = vlv_subcommands.add_parser('del-index', help='Delete a VLV index under a VLV search entry (parent entry)') + del_vlv_index_parser = vlv_subcommands.add_parser('del-index', help='Delete a VLV index under a VLV search entry (parent entry)', formatter_class=CustomHelpFormatter) del_vlv_index_parser.set_defaults(func=backend_delete_vlv_index) del_vlv_index_parser.add_argument('--parent-name', required=True, help='Sets the name or "cn" attribute value of the parent VLV search entry') del_vlv_index_parser.add_argument('--index-name', help='Sets the name of the VLV index to delete') @@ -1004,7 +1005,7 @@ def create_parser(subparsers): del_vlv_index_parser.add_argument('be_name', help='The backend name of the VLV index') # Reindex VLV - reindex_vlv_parser = vlv_subcommands.add_parser('reindex', help='Index/re-index the VLV database index') + reindex_vlv_parser = vlv_subcommands.add_parser('reindex', help='Index/re-index the VLV database index', formatter_class=CustomHelpFormatter) reindex_vlv_parser.set_defaults(func=backend_reindex_vlv) reindex_vlv_parser.add_argument('--index-name', help='Sets the name of the VLV index entry to re-index. If not set, all indexes are re-indexed') reindex_vlv_parser.add_argument('--parent-name', required=True, help='Sets the name or "cn" attribute value of the parent VLV search entry') @@ -1013,7 +1014,7 @@ def create_parser(subparsers): ############################################ # Encrypted Attributes ############################################ - attr_encrypt_parser = subcommands.add_parser('attr-encrypt', help='Manage encrypted attribute settings') + attr_encrypt_parser = subcommands.add_parser('attr-encrypt', help='Manage encrypted attribute settings', formatter_class=CustomHelpFormatter) attr_encrypt_parser.set_defaults(func=backend_attr_encrypt) attr_encrypt_parser.add_argument('--list', action='store_true', help='Lists all encrypted attributes in the backend') attr_encrypt_parser.add_argument('--just-names', action='store_true', help='List only the names of the encrypted attributes when used with --list') @@ -1024,15 +1025,15 @@ def create_parser(subparsers): ############################################ # Global DB Config ############################################ - db_parser = subcommands.add_parser('config', help="Manage the global database configuration settings") + db_parser = subcommands.add_parser('config', help="Manage the global database configuration settings", formatter_class=CustomHelpFormatter) db_subcommands = db_parser.add_subparsers(help="action") # Get the global database configuration - get_db_config_parser = db_subcommands.add_parser('get', help='Display the global database configuration') + get_db_config_parser = db_subcommands.add_parser('get', help='Display the global database configuration', formatter_class=CustomHelpFormatter) get_db_config_parser.set_defaults(func=db_config_get) # Update the global database configuration - set_db_config_parser = db_subcommands.add_parser('set', help='Set the global database configuration') + set_db_config_parser = db_subcommands.add_parser('set', help='Set the global database configuration', formatter_class=CustomHelpFormatter) set_db_config_parser.set_defaults(func=db_config_set) set_db_config_parser.add_argument('--lookthroughlimit', help='Specifies the maximum number of entries that the server ' 'will check when examining candidate entries in response to a search request') @@ -1092,14 +1093,14 @@ def create_parser(subparsers): ####################################################### # Database & Suffix Monitor ####################################################### - get_monitor_parser = subcommands.add_parser('monitor', help="Displays global database or suffix monitoring information") + get_monitor_parser = subcommands.add_parser('monitor', help="Displays global database or suffix monitoring information", formatter_class=CustomHelpFormatter) get_monitor_parser.set_defaults(func=get_monitor) get_monitor_parser.add_argument('--suffix', help='Displays monitoring information only for the specified suffix') ####################################################### # Import LDIF ####################################################### - import_parser = subcommands.add_parser('import', help="Online import of a suffix") + import_parser = subcommands.add_parser('import', help="Online import of a suffix", formatter_class=CustomHelpFormatter) import_parser.set_defaults(func=backend_import) import_parser.add_argument('be_name', nargs='?', help='The backend name or the root suffix') @@ -1130,7 +1131,7 @@ def create_parser(subparsers): ####################################################### # Export LDIF ####################################################### - export_parser = subcommands.add_parser('export', help='Online export of a suffix') + export_parser = subcommands.add_parser('export', help='Online export of a suffix', formatter_class=CustomHelpFormatter) export_parser.set_defaults(func=backend_export) export_parser.add_argument('be_names', nargs='+', help="The backend names or the root suffixes") @@ -1161,7 +1162,7 @@ def create_parser(subparsers): ####################################################### # Create a new backend database ####################################################### - create_parser = subcommands.add_parser('create', help='Create a backend database') + create_parser = subcommands.add_parser('create', help='Create a backend database', formatter_class=CustomHelpFormatter) create_parser.set_defaults(func=backend_create) create_parser.add_argument('--parent-suffix', default=False, help="Sets the parent suffix only if this backend is a sub-suffix") @@ -1174,7 +1175,7 @@ def create_parser(subparsers): ####################################################### # Delete backend ####################################################### - delete_parser = subcommands.add_parser('delete', help='Delete a backend database') + delete_parser = subcommands.add_parser('delete', help='Delete a backend database', formatter_class=CustomHelpFormatter) delete_parser.set_defaults(func=backend_delete) delete_parser.add_argument('be_name', help='The backend name or suffix') delete_parser.add_argument('--do-it', dest="ack", @@ -1184,13 +1185,13 @@ def create_parser(subparsers): ####################################################### # Get Suffix Tree (for use in web console) ####################################################### - get_tree_parser = subcommands.add_parser('get-tree', help='Display the suffix tree') + get_tree_parser = subcommands.add_parser('get-tree', help='Display the suffix tree', formatter_class=CustomHelpFormatter) get_tree_parser.set_defaults(func=backend_get_tree) ####################################################### # Run the db compaction task ####################################################### - compact_parser = subcommands.add_parser('compact-db', help='Compact the database and the replication changelog') + compact_parser = subcommands.add_parser('compact-db', help='Compact the database and the replication changelog', formatter_class=CustomHelpFormatter) compact_parser.set_defaults(func=backend_compact) compact_parser.add_argument('--only-changelog', action='store_true', help='Compacts only the replication change log') compact_parser.add_argument('--timeout', default=0, type=int, diff --git a/src/lib389/lib389/cli_conf/backup.py b/src/lib389/lib389/cli_conf/backup.py index 32f5db2f1e..2996c0bd28 100644 --- a/src/lib389/lib389/cli_conf/backup.py +++ b/src/lib389/lib389/cli_conf/backup.py @@ -6,6 +6,7 @@ # See LICENSE for details. # --- END COPYRIGHT BLOCK --- +from lib389.cli_base import CustomHelpFormatter def backup_create(inst, basedn, log, args): log = log.getChild('backup_create') @@ -41,11 +42,11 @@ def backup_restore(inst, basedn, log, args): def create_parser(subparsers): - backup_parser = subparsers.add_parser('backup', help="Manage online backups") + backup_parser = subparsers.add_parser('backup', help="Manage online backups", formatter_class=CustomHelpFormatter) subcommands = backup_parser.add_subparsers(help="action") - create_backup_parser = subcommands.add_parser('create', help="Creates a backup of the database") + create_backup_parser = subcommands.add_parser('create', help="Creates a backup of the database", formatter_class=CustomHelpFormatter) create_backup_parser.set_defaults(func=backup_create) create_backup_parser.add_argument('archive', nargs='?', default=None, help="Sets the directory where to store the backup files. " @@ -56,7 +57,7 @@ def create_parser(subparsers): create_backup_parser.add_argument('--timeout', type=int, default=120, help="Sets the task timeout. Default is 120 seconds,") - restore_parser = subcommands.add_parser('restore', help="Restores a database from a backup") + restore_parser = subcommands.add_parser('restore', help="Restores a database from a backup", formatter_class=CustomHelpFormatter) restore_parser.set_defaults(func=backup_restore) restore_parser.add_argument('archive', help="Set the directory that contains the backup files") restore_parser.add_argument('-t', '--db-type', default="ldbm database", diff --git a/src/lib389/lib389/cli_conf/chaining.py b/src/lib389/lib389/cli_conf/chaining.py index f76e7f991d..d0f691a502 100644 --- a/src/lib389/lib389/cli_conf/chaining.py +++ b/src/lib389/lib389/cli_conf/chaining.py @@ -13,6 +13,7 @@ _generic_list, _generic_get, _get_arg, + CustomHelpFormatter ) from lib389.cli_conf.monitor import _format_status from lib389.utils import get_passwd_from_file @@ -220,25 +221,25 @@ def list_links(inst, basedn, log, args): def create_parser(subparsers): - chaining_parser = subparsers.add_parser('chaining', help="Manage database chaining and database links") + chaining_parser = subparsers.add_parser('chaining', help="Manage database chaining and database links", formatter_class=CustomHelpFormatter) subcommands = chaining_parser.add_subparsers(help="action") - config_get_parser = subcommands.add_parser('config-get', help='Display the chaining controls and server component lists') + config_get_parser = subcommands.add_parser('config-get', help='Display the chaining controls and server component lists', formatter_class=CustomHelpFormatter) config_get_parser.set_defaults(func=config_get) config_get_parser.add_argument('--avail-controls', action='store_true', help="Lists available chaining controls") config_get_parser.add_argument('--avail-comps', action='store_true', help="Lists available chaining plugin components") - config_set_parser = subcommands.add_parser('config-set', help='Set the chaining controls and server component lists') + config_set_parser = subcommands.add_parser('config-set', help='Set the chaining controls and server component lists', formatter_class=CustomHelpFormatter) config_set_parser.set_defaults(func=config_set) config_set_parser.add_argument('--add-control', action='append', help="Adds a transmitted control OID") config_set_parser.add_argument('--del-control', action='append', help="Deletes a transmitted control OID") config_set_parser.add_argument('--add-comp', action='append', help="Adds a chaining component") config_set_parser.add_argument('--del-comp', action='append', help="Deletes a chaining component") - def_config_get_parser = subcommands.add_parser('config-get-def', help='Display the default creation parameters for new database links') + def_config_get_parser = subcommands.add_parser('config-get-def', help='Display the default creation parameters for new database links', formatter_class=CustomHelpFormatter) def_config_get_parser.set_defaults(func=def_config_get) - def_config_set_parser = subcommands.add_parser('config-set-def', help='Set the default creation parameters for new database links') + def_config_set_parser = subcommands.add_parser('config-set-def', help='Set the default creation parameters for new database links', formatter_class=CustomHelpFormatter) def_config_set_parser.set_defaults(func=def_config_set) def_config_set_parser.add_argument('--conn-bind-limit', help="Sets the maximum number of BIND connections the database link establishes " @@ -293,7 +294,7 @@ def create_parser(subparsers): create_link_parser.add_argument('--bind-pw-file', help="File containing the password") create_link_parser.add_argument('--bind-pw-prompt', action='store_true', help="Prompt for password") - get_link_parser = subcommands.add_parser('link-get', help='Displays chaining database links') + get_link_parser = subcommands.add_parser('link-get', help='Displays chaining database links', formatter_class=CustomHelpFormatter) get_link_parser.set_defaults(func=get_link) get_link_parser.add_argument('CHAIN_NAME', nargs=1, help='The chaining link name or suffix to retrieve') @@ -312,13 +313,13 @@ def create_parser(subparsers): edit_link_parser.add_argument('--bind-pw-file', help="File containing the password") edit_link_parser.add_argument('--bind-pw-prompt', action='store_true', help="Prompt for password") - delete_link_parser = subcommands.add_parser('link-delete', help='Delete a database link') + delete_link_parser = subcommands.add_parser('link-delete', help='Delete a database link', formatter_class=CustomHelpFormatter) delete_link_parser.set_defaults(func=delete_link) delete_link_parser.add_argument('CHAIN_NAME', nargs=1, help='The name of the database link') - monitor_link_parser = subcommands.add_parser('monitor', help='Display monitor information for a database chaining link') + monitor_link_parser = subcommands.add_parser('monitor', help='Display monitor information for a database chaining link', formatter_class=CustomHelpFormatter) monitor_link_parser.set_defaults(func=monitor_link) monitor_link_parser.add_argument('CHAIN_NAME', nargs=1, help='The name of the database link') - list_link_parser = subcommands.add_parser('link-list', help='List database links') + list_link_parser = subcommands.add_parser('link-list', help='List database links', formatter_class=CustomHelpFormatter) list_link_parser.set_defaults(func=list_links) diff --git a/src/lib389/lib389/cli_conf/config.py b/src/lib389/lib389/cli_conf/config.py index 97e22cdbc7..fb4c68f8bf 100644 --- a/src/lib389/lib389/cli_conf/config.py +++ b/src/lib389/lib389/cli_conf/config.py @@ -13,6 +13,7 @@ _generic_get_entry, _generic_get_attr, _generic_replace_attr, + CustomHelpFormatter ) OpType = Enum("OpType", "add delete") @@ -122,22 +123,22 @@ def config_del_attr(inst, basedn, log, args): def create_parser(subparsers): - config_parser = subparsers.add_parser('config', help="Manage the server configuration") + config_parser = subparsers.add_parser('config', help="Manage the server configuration", formatter_class=CustomHelpFormatter) subcommands = config_parser.add_subparsers(help="action") - get_parser = subcommands.add_parser('get', help='get') + get_parser = subcommands.add_parser('get', help='get', formatter_class=CustomHelpFormatter) get_parser.set_defaults(func=config_get) get_parser.add_argument('attrs', nargs='*', help='Configuration attribute(s) to get') - add_attr_parser = subcommands.add_parser('add', help='Add attribute value to configuration') + add_attr_parser = subcommands.add_parser('add', help='Add attribute value to configuration', formatter_class=CustomHelpFormatter) add_attr_parser.set_defaults(func=config_add_attr) add_attr_parser.add_argument('attr', nargs='*', help='Configuration attribute to add') - replace_attr_parser = subcommands.add_parser('replace', help='Replace attribute value in configuration') + replace_attr_parser = subcommands.add_parser('replace', help='Replace attribute value in configuration', formatter_class=CustomHelpFormatter) replace_attr_parser.set_defaults(func=config_replace_attr) replace_attr_parser.add_argument('attr', nargs='*', help='Configuration attribute to replace') - del_attr_parser = subcommands.add_parser('delete', help='Delete attribute value in configuration') + del_attr_parser = subcommands.add_parser('delete', help='Delete attribute value in configuration', formatter_class=CustomHelpFormatter) del_attr_parser.set_defaults(func=config_del_attr) del_attr_parser.add_argument('attr', nargs='*', help='Configuration attribute to delete') diff --git a/src/lib389/lib389/cli_conf/conflicts.py b/src/lib389/lib389/cli_conf/conflicts.py index c6758fb70e..5d2ef72270 100644 --- a/src/lib389/lib389/cli_conf/conflicts.py +++ b/src/lib389/lib389/cli_conf/conflicts.py @@ -8,6 +8,7 @@ import json from lib389.conflicts import (ConflictEntries, ConflictEntry, GlueEntries, GlueEntry) +from lib389.cli_base import CustomHelpFormatter conflict_attrs = ['nsds5replconflict', '*'] @@ -84,23 +85,23 @@ def convert_glue(inst, basedn, log, args): def create_parser(subparsers): - conflict_parser = subparsers.add_parser('repl-conflict', help="Manage replication conflicts") + conflict_parser = subparsers.add_parser('repl-conflict', help="Manage replication conflicts", formatter_class=CustomHelpFormatter) subcommands = conflict_parser.add_subparsers(help='action') # coinflict entry arguments - list_parser = subcommands.add_parser('list', help="List conflict entries") + list_parser = subcommands.add_parser('list', help="List conflict entries", formatter_class=CustomHelpFormatter) list_parser.add_argument('suffix', help='Sets the backend name, or suffix, to look for conflict entries') list_parser.set_defaults(func=list_conflicts) - cmp_parser = subcommands.add_parser('compare', help="Compare the conflict entry with its valid counterpart") + cmp_parser = subcommands.add_parser('compare', help="Compare the conflict entry with its valid counterpart", formatter_class=CustomHelpFormatter) cmp_parser.add_argument('DN', help='The DN of the conflict entry') cmp_parser.set_defaults(func=cmp_conflict) - del_parser = subcommands.add_parser('delete', help="Delete a conflict entry") + del_parser = subcommands.add_parser('delete', help="Delete a conflict entry", formatter_class=CustomHelpFormatter) del_parser.add_argument('DN', help='The DN of the conflict entry') del_parser.set_defaults(func=del_conflict) - replace_parser = subcommands.add_parser('swap', help="Replace the valid entry with the conflict entry") + replace_parser = subcommands.add_parser('swap', help="Replace the valid entry with the conflict entry", formatter_class=CustomHelpFormatter) replace_parser.add_argument('DN', help='The DN of the conflict entry') replace_parser.set_defaults(func=swap_conflict) @@ -114,14 +115,14 @@ def create_parser(subparsers): replace_parser.set_defaults(func=convert_conflict) # Glue entry arguments - list_glue_parser = subcommands.add_parser('list-glue', help="List replication glue entries") + list_glue_parser = subcommands.add_parser('list-glue', help="List replication glue entries", formatter_class=CustomHelpFormatter) list_glue_parser.add_argument('suffix', help='The backend name, or suffix, to look for glue entries') list_glue_parser.set_defaults(func=list_glue) - del_glue_parser = subcommands.add_parser('delete-glue', help="Delete the glue entry and its child entries") + del_glue_parser = subcommands.add_parser('delete-glue', help="Delete the glue entry and its child entries", formatter_class=CustomHelpFormatter) del_glue_parser.add_argument('DN', help='The DN of the glue entry') del_glue_parser.set_defaults(func=del_glue) - convert_glue_parser = subcommands.add_parser('convert-glue', help="Convert the glue entry into a regular entry") + convert_glue_parser = subcommands.add_parser('convert-glue', help="Convert the glue entry into a regular entry", formatter_class=CustomHelpFormatter) convert_glue_parser.add_argument('DN', help='The DN of the glue entry') convert_glue_parser.set_defaults(func=convert_glue) diff --git a/src/lib389/lib389/cli_conf/directory_manager.py b/src/lib389/lib389/cli_conf/directory_manager.py index 0886d506da..b7d4ada037 100644 --- a/src/lib389/lib389/cli_conf/directory_manager.py +++ b/src/lib389/lib389/cli_conf/directory_manager.py @@ -7,7 +7,7 @@ # --- END COPYRIGHT BLOCK --- from lib389.idm.directorymanager import DirectoryManager -from lib389.cli_base import _get_arg +from lib389.cli_base import _get_arg, CustomHelpFormatter def password_change(inst, basedn, log, args): @@ -19,11 +19,11 @@ def password_change(inst, basedn, log, args): def create_parsers(subparsers): - directory_manager_parser = subparsers.add_parser('directory_manager', help="Manage the Directory Manager account") + directory_manager_parser = subparsers.add_parser('directory_manager', help="Manage the Directory Manager account", formatter_class=CustomHelpFormatter) subcommands = directory_manager_parser.add_subparsers(help='action') - password_change_parser = subcommands.add_parser('password_change', help="Changes the password of the Directory Manager account") + password_change_parser = subcommands.add_parser('password_change', help="Changes the password of the Directory Manager account", formatter_class=CustomHelpFormatter) password_change_parser.set_defaults(func=password_change) # This is to put in a dummy attr that args can work with. We do this # because the actual test case will over-ride it, but it prevents diff --git a/src/lib389/lib389/cli_conf/monitor.py b/src/lib389/lib389/cli_conf/monitor.py index a56ad2fee9..d69e2f06b0 100644 --- a/src/lib389/lib389/cli_conf/monitor.py +++ b/src/lib389/lib389/cli_conf/monitor.py @@ -14,7 +14,7 @@ from lib389.chaining import (ChainingLinks) from lib389.backend import Backends from lib389.utils import convert_bytes -from lib389.cli_base import _format_status +from lib389.cli_base import _format_status, CustomHelpFormatter def monitor(inst, basedn, log, args): @@ -297,30 +297,30 @@ def db_monitor(inst, basedn, log, args): def create_parser(subparsers): - monitor_parser = subparsers.add_parser('monitor', help="Monitor the state of the instance") + monitor_parser = subparsers.add_parser('monitor', help="Monitor the state of the instance", formatter_class=CustomHelpFormatter) subcommands = monitor_parser.add_subparsers(help='action') - server_parser = subcommands.add_parser('server', help="Displays the server statistics, connections, and operations") + server_parser = subcommands.add_parser('server', help="Displays the server statistics, connections, and operations", formatter_class=CustomHelpFormatter) server_parser.set_defaults(func=monitor) - dbmon_parser = subcommands.add_parser('dbmon', help="Monitor all database statistics in a single report") + dbmon_parser = subcommands.add_parser('dbmon', help="Monitor all database statistics in a single report", formatter_class=CustomHelpFormatter) dbmon_parser.set_defaults(func=db_monitor) dbmon_parser.add_argument('-b', '--backends', help="Specifies a list of space-separated backends to monitor. Default is all backends.") dbmon_parser.add_argument('-x', '--indexes', action='store_true', default=False, help="Shows index stats for each backend") - ldbm_parser = subcommands.add_parser('ldbm', help="Monitor the LDBM statistics, such as dbcache") + ldbm_parser = subcommands.add_parser('ldbm', help="Monitor the LDBM statistics, such as dbcache", formatter_class=CustomHelpFormatter) ldbm_parser.set_defaults(func=ldbm_monitor) - backend_parser = subcommands.add_parser('backend', help="Monitor the behavior of a backend database") + backend_parser = subcommands.add_parser('backend', help="Monitor the behavior of a backend database", formatter_class=CustomHelpFormatter) backend_parser.add_argument('backend', nargs='?', help="The optional name of the backend to monitor") backend_parser.set_defaults(func=backend_monitor) - snmp_parser = subcommands.add_parser('snmp', help="Displays the SNMP statistics") + snmp_parser = subcommands.add_parser('snmp', help="Displays the SNMP statistics", formatter_class=CustomHelpFormatter) snmp_parser.set_defaults(func=snmp_monitor) - chaining_parser = subcommands.add_parser('chaining', help="Monitor database chaining statistics") + chaining_parser = subcommands.add_parser('chaining', help="Monitor database chaining statistics", formatter_class=CustomHelpFormatter) chaining_parser.add_argument('backend', nargs='?', help="The optional name of the chaining backend to monitor") chaining_parser.set_defaults(func=chaining_monitor) - disk_parser = subcommands.add_parser('disk', help="Displays the disk space statistics. All values are in bytes.") + disk_parser = subcommands.add_parser('disk', help="Displays the disk space statistics. All values are in bytes.", formatter_class=CustomHelpFormatter) disk_parser.set_defaults(func=disk_monitor) diff --git a/src/lib389/lib389/cli_conf/plugin.py b/src/lib389/lib389/cli_conf/plugin.py index a0bdb21e81..5a35a7740d 100644 --- a/src/lib389/lib389/cli_conf/plugin.py +++ b/src/lib389/lib389/cli_conf/plugin.py @@ -12,6 +12,7 @@ from lib389.cli_base import ( _generic_get, _get_arg, + CustomHelpFormatter ) from lib389.cli_conf import generic_object_edit from lib389.cli_conf.plugins import memberof as cli_memberof @@ -99,7 +100,7 @@ def plugin_edit(inst, basedn, log, args): def create_parser(subparsers): - plugin_parser = subparsers.add_parser('plugin', help="Manage plug-ins available on the server") + plugin_parser = subparsers.add_parser('plugin', help="Manage plug-ins available on the server", formatter_class=CustomHelpFormatter) subcommands = plugin_parser.add_subparsers(help="Plugins") @@ -120,14 +121,14 @@ def create_parser(subparsers): cli_contentsync.create_parser(subcommands) cli_entryuuid.create_parser(subcommands) - list_parser = subcommands.add_parser('list', help="List current configured (enabled and disabled) plugins") + list_parser = subcommands.add_parser('list', help="List current configured (enabled and disabled) plugins", formatter_class=CustomHelpFormatter) list_parser.set_defaults(func=plugin_list) - get_parser = subcommands.add_parser('show', help='Show the plugin data') + get_parser = subcommands.add_parser('show', help='Show the plugin data', formatter_class=CustomHelpFormatter) get_parser.set_defaults(func=plugin_get) get_parser.add_argument('selector', nargs='?', help='The plugin to search for') - edit_parser = subcommands.add_parser('set', help='Edit the plugin settings') + edit_parser = subcommands.add_parser('set', help='Edit the plugin settings', formatter_class=CustomHelpFormatter) edit_parser.set_defaults(func=plugin_edit) edit_parser.add_argument('selector', nargs='?', help='The plugin to edit') edit_parser.add_argument('--type', help='The type of plugin.') diff --git a/src/lib389/lib389/cli_conf/plugins/accountpolicy.py b/src/lib389/lib389/cli_conf/plugins/accountpolicy.py index d3551e41a6..3cf95d3372 100644 --- a/src/lib389/lib389/cli_conf/plugins/accountpolicy.py +++ b/src/lib389/lib389/cli_conf/plugins/accountpolicy.py @@ -9,6 +9,7 @@ import ldap from lib389.plugins import AccountPolicyPlugin, AccountPolicyConfig from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add +from lib389.cli_base import CustomHelpFormatter arg_to_attr = { 'config_entry': 'nsslapd_pluginconfigarea' @@ -105,31 +106,31 @@ def _add_parser_args(parser): def create_parser(subparsers): - accountpolicy = subparsers.add_parser('account-policy', help='Manage and configure Account Policy plugin') + accountpolicy = subparsers.add_parser('account-policy', help='Manage and configure Account Policy plugin', formatter_class=CustomHelpFormatter) subcommands = accountpolicy.add_subparsers(help='action') add_generic_plugin_parsers(subcommands, AccountPolicyPlugin) - edit = subcommands.add_parser('set', help='Edit the plugin settings') + edit = subcommands.add_parser('set', help='Edit the plugin settings', formatter_class=CustomHelpFormatter) edit.set_defaults(func=accountpolicy_edit) edit.add_argument('--config-entry', help='Sets the nsslapd-pluginConfigArea attribute') - config = subcommands.add_parser('config-entry', help='Manage the config entry') + config = subcommands.add_parser('config-entry', help='Manage the config entry', formatter_class=CustomHelpFormatter) config_subcommands = config.add_subparsers(help='action') - add_config = config_subcommands.add_parser('add', help='Add the config entry') + add_config = config_subcommands.add_parser('add', help='Add the config entry', formatter_class=CustomHelpFormatter) add_config.set_defaults(func=accountpolicy_add_config) add_config.add_argument('DN', help='The full DN of the config entry') _add_parser_args(add_config) - edit_config = config_subcommands.add_parser('set', help='Edit the config entry') + edit_config = config_subcommands.add_parser('set', help='Edit the config entry', formatter_class=CustomHelpFormatter) edit_config.set_defaults(func=accountpolicy_edit_config) edit_config.add_argument('DN', help='The full DN of the config entry') _add_parser_args(edit_config) - show_config_parser = config_subcommands.add_parser('show', help='Display the config entry') + show_config_parser = config_subcommands.add_parser('show', help='Display the config entry', formatter_class=CustomHelpFormatter) show_config_parser.set_defaults(func=accountpolicy_show_config) show_config_parser.add_argument('DN', help='The full DN of the config entry') - del_config_parser = config_subcommands.add_parser('delete', help='Delete the config entry') + del_config_parser = config_subcommands.add_parser('delete', help='Delete the config entry', formatter_class=CustomHelpFormatter) del_config_parser.set_defaults(func=accountpolicy_del_config) del_config_parser.add_argument('DN', help='The full DN of the config entry') diff --git a/src/lib389/lib389/cli_conf/plugins/attruniq.py b/src/lib389/lib389/cli_conf/plugins/attruniq.py index f9bacab784..0c398b9449 100644 --- a/src/lib389/lib389/cli_conf/plugins/attruniq.py +++ b/src/lib389/lib389/cli_conf/plugins/attruniq.py @@ -10,6 +10,7 @@ import ldap from lib389.plugins import AttributeUniquenessPlugin, AttributeUniquenessPlugins from lib389.cli_conf import (generic_object_edit, generic_object_add) +from lib389.cli_base import CustomHelpFormatter arg_to_attr = { 'enabled': 'nsslapd-pluginenabled', @@ -136,37 +137,37 @@ def _add_parser_args(parser): def create_parser(subparsers): - attruniq = subparsers.add_parser('attr-uniq', help='Manage and configure Attribute Uniqueness plugin') + attruniq = subparsers.add_parser('attr-uniq', help='Manage and configure Attribute Uniqueness plugin', formatter_class=CustomHelpFormatter) subcommands = attruniq.add_subparsers(help='action') # We can't use the add_generic_plugin_parsers as we need named sub instances. - list = subcommands.add_parser('list', help='Lists available plugin configs') + list = subcommands.add_parser('list', help='Lists available plugin configs', formatter_class=CustomHelpFormatter) list.set_defaults(func=attruniq_list) - add = subcommands.add_parser('add', help='Add the config entry') + add = subcommands.add_parser('add', help='Add the config entry', formatter_class=CustomHelpFormatter) add.set_defaults(func=attruniq_add) _add_parser_args(add) - edit = subcommands.add_parser('set', help='Edit the config entry') + edit = subcommands.add_parser('set', help='Edit the config entry', formatter_class=CustomHelpFormatter) edit.set_defaults(func=attruniq_edit) _add_parser_args(edit) - show = subcommands.add_parser('show', help='Display the config entry') + show = subcommands.add_parser('show', help='Display the config entry', formatter_class=CustomHelpFormatter) show.add_argument('NAME', help='The name of the plug-in configuration record') show.set_defaults(func=attruniq_show) - delete = subcommands.add_parser('delete', help='Delete the config entry') + delete = subcommands.add_parser('delete', help='Delete the config entry', formatter_class=CustomHelpFormatter) delete.add_argument('NAME', help='The name of the plug-in configuration record') delete.set_defaults(func=attruniq_del) - enable = subcommands.add_parser('enable', help='enable plugin') + enable = subcommands.add_parser('enable', help='enable plugin', formatter_class=CustomHelpFormatter) enable.add_argument('NAME', help='The name of the plug-in configuration record') enable.set_defaults(func=attruniq_enable) - disable = subcommands.add_parser('disable', help='disable plugin') + disable = subcommands.add_parser('disable', help='disable plugin', formatter_class=CustomHelpFormatter) disable.add_argument('NAME', help='The name of the plug-in configuration record') disable.set_defaults(func=attruniq_disable) - status = subcommands.add_parser('status', help='display plugin status') + status = subcommands.add_parser('status', help='display plugin status', formatter_class=CustomHelpFormatter) status.add_argument('NAME', help='The name of the plug-in configuration record') status.set_defaults(func=attruniq_status) diff --git a/src/lib389/lib389/cli_conf/plugins/automember.py b/src/lib389/lib389/cli_conf/plugins/automember.py index 8851aab32f..62b907630d 100644 --- a/src/lib389/lib389/cli_conf/plugins/automember.py +++ b/src/lib389/lib389/cli_conf/plugins/automember.py @@ -11,6 +11,7 @@ from lib389.plugins import (AutoMembershipPlugin, AutoMembershipDefinition, AutoMembershipDefinitions, AutoMembershipRegexRule, AutoMembershipRegexRules, AutoMembershipFixupTasks) from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add +from lib389.cli_base import CustomHelpFormatter from lib389.utils import get_task_status arg_to_attr_definition = { @@ -221,49 +222,49 @@ def _add_parser_args_regex(parser): def create_parser(subparsers): - automember = subparsers.add_parser('automember', help="Manage and configure Automembership plugin") + automember = subparsers.add_parser('automember', help="Manage and configure Automembership plugin", formatter_class=CustomHelpFormatter) subcommands = automember.add_subparsers(help='action') add_generic_plugin_parsers(subcommands, AutoMembershipPlugin) - automember_list = subcommands.add_parser('list', help='List Automembership definitions or regex rules.') + automember_list = subcommands.add_parser('list', help='List Automembership definitions or regex rules.', formatter_class=CustomHelpFormatter) subcommands_list = automember_list.add_subparsers(help='action') - list_definitions = subcommands_list.add_parser('definitions', help='Lists Automembership definitions.') + list_definitions = subcommands_list.add_parser('definitions', help='Lists Automembership definitions.', formatter_class=CustomHelpFormatter) list_definitions.set_defaults(func=definition_list) - list_regexes = subcommands_list.add_parser('regexes', help='List Automembership regex rules.') + list_regexes = subcommands_list.add_parser('regexes', help='List Automembership regex rules.', formatter_class=CustomHelpFormatter) list_regexes.add_argument('DEFNAME', help='The definition entry CN') list_regexes.set_defaults(func=regex_list) - definition = subcommands.add_parser('definition', help='Manage Automembership definition.') + definition = subcommands.add_parser('definition', help='Manage Automembership definition.', formatter_class=CustomHelpFormatter) definition.add_argument('DEFNAME', help='The definition entry CN.') subcommands_definition = definition.add_subparsers(help='action') - add_def = subcommands_definition.add_parser('add', help='Creates Automembership definition.') + add_def = subcommands_definition.add_parser('add', help='Creates Automembership definition.', formatter_class=CustomHelpFormatter) add_def.set_defaults(func=definition_add) _add_parser_args_definition(add_def) - edit_def = subcommands_definition.add_parser('set', help='Edits Automembership definition.') + edit_def = subcommands_definition.add_parser('set', help='Edits Automembership definition.', formatter_class=CustomHelpFormatter) edit_def.set_defaults(func=definition_edit) _add_parser_args_definition(edit_def) - delete_def = subcommands_definition.add_parser('delete', help='Removes Automembership definition.') + delete_def = subcommands_definition.add_parser('delete', help='Removes Automembership definition.', formatter_class=CustomHelpFormatter) delete_def.set_defaults(func=definition_del) - show_def = subcommands_definition.add_parser('show', help='Displays Automembership definition.') + show_def = subcommands_definition.add_parser('show', help='Displays Automembership definition.', formatter_class=CustomHelpFormatter) show_def.set_defaults(func=definition_show) - regex = subcommands_definition.add_parser('regex', help='Manage Automembership regex rules.') + regex = subcommands_definition.add_parser('regex', help='Manage Automembership regex rules.', formatter_class=CustomHelpFormatter) regex.add_argument('REGEXNAME', help='The regex entry CN') subcommands_regex = regex.add_subparsers(help='action') - add_regex = subcommands_regex.add_parser('add', help='Creates Automembership regex.') + add_regex = subcommands_regex.add_parser('add', help='Creates Automembership regex.', formatter_class=CustomHelpFormatter) add_regex.set_defaults(func=regex_add) _add_parser_args_regex(add_regex) - edit_regex = subcommands_regex.add_parser('set', help='Edits Automembership regex.') + edit_regex = subcommands_regex.add_parser('set', help='Edits Automembership regex.', formatter_class=CustomHelpFormatter) edit_regex.set_defaults(func=regex_edit) _add_parser_args_regex(edit_regex) - delete_regex = subcommands_regex.add_parser('delete', help='Removes Automembership regex.') + delete_regex = subcommands_regex.add_parser('delete', help='Removes Automembership regex.', formatter_class=CustomHelpFormatter) delete_regex.set_defaults(func=regex_del) - show_regex = subcommands_regex.add_parser('show', help='Displays Automembership regex.') + show_regex = subcommands_regex.add_parser('show', help='Displays Automembership regex.', formatter_class=CustomHelpFormatter) show_regex.set_defaults(func=regex_show) - fixup_task = subcommands.add_parser('fixup', help='Run a rebuild membership task.') + fixup_task = subcommands.add_parser('fixup', help='Run a rebuild membership task.', formatter_class=CustomHelpFormatter) fixup_task.set_defaults(func=fixup) fixup_task.add_argument('DN', help="Base DN that contains entries to fix up") fixup_task.add_argument('-f', '--filter', required=True, help='Sets the LDAP filter for entries to fix up') @@ -276,14 +277,14 @@ def create_parser(subparsers): fixup_task.add_argument('--timeout', default=0, type=int, help="Set a timeout to wait for the fixup task. Default is 0 (no timeout)") - fixup_status = subcommands.add_parser('fixup-status', help='Check the status of a fix-up task') + fixup_status = subcommands.add_parser('fixup-status', help='Check the status of a fix-up task', formatter_class=CustomHelpFormatter) fixup_status.set_defaults(func=do_fixup_status) fixup_status.add_argument('--dn', help="The task entry's DN") fixup_status.add_argument('--show-log', action='store_true', help="Display the task log") fixup_status.add_argument('--watch', action='store_true', help="Watch the task's status and wait for it to finish") - abort_fixup = subcommands.add_parser('abort-fixup', help='Abort the rebuild membership task.') + abort_fixup = subcommands.add_parser('abort-fixup', help='Abort the rebuild membership task.', formatter_class=CustomHelpFormatter) abort_fixup.set_defaults(func=abort) abort_fixup.add_argument('--timeout', default=0, type=int, help="Set a timeout to wait for the abort task. Default is 0 (no timeout)") \ No newline at end of file diff --git a/src/lib389/lib389/cli_conf/plugins/contentsync.py b/src/lib389/lib389/cli_conf/plugins/contentsync.py index dc84e86a7c..10153a35b4 100644 --- a/src/lib389/lib389/cli_conf/plugins/contentsync.py +++ b/src/lib389/lib389/cli_conf/plugins/contentsync.py @@ -8,6 +8,7 @@ from lib389.plugins import ContentSyncPlugin from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add_attr +from lib389.cli_base import CustomHelpFormatter arg_to_attr = { 'allow_openldap': 'syncrepl-allow-openldap', @@ -30,14 +31,14 @@ def _add_parser_args(parser): help='Allows openldap servers to act as read only consumers of this server via syncrepl') def create_parser(subparsers): - contentsync_parser = subparsers.add_parser('contentsync', help='Manage and configure Content Sync Plugin (aka syncrepl)') + contentsync_parser = subparsers.add_parser('contentsync', help='Manage and configure Content Sync Plugin (aka syncrepl)', formatter_class=CustomHelpFormatter) subcommands = contentsync_parser.add_subparsers(help='action') add_generic_plugin_parsers(subcommands, ContentSyncPlugin) - edit = subcommands.add_parser('set', help='Edit the plugin settings') + edit = subcommands.add_parser('set', help='Edit the plugin settings', formatter_class=CustomHelpFormatter) edit.set_defaults(func=contentsync_edit) _add_parser_args(edit) - addp = subcommands.add_parser('add', help='Add attributes to the plugin') + addp = subcommands.add_parser('add', help='Add attributes to the plugin', formatter_class=CustomHelpFormatter) addp.set_defaults(func=contentsync_add) _add_parser_args(addp) diff --git a/src/lib389/lib389/cli_conf/plugins/dna.py b/src/lib389/lib389/cli_conf/plugins/dna.py index 20d5aa584e..bc766ecac4 100644 --- a/src/lib389/lib389/cli_conf/plugins/dna.py +++ b/src/lib389/lib389/cli_conf/plugins/dna.py @@ -10,6 +10,7 @@ import ldap from lib389.plugins import DNAPlugin, DNAPluginConfig, DNAPluginConfigs, DNAPluginSharedConfig, DNAPluginSharedConfigs from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add, _args_to_attrs +from lib389.cli_base import CustomHelpFormatter arg_to_attr = { 'type': 'dnaType', @@ -201,43 +202,43 @@ def _add_parser_args(parser): 'can request a range from a new server (dnaRangeRequestTimeout)') def create_parser(subparsers): - dna = subparsers.add_parser('dna', help='Manage and configure DNA plugin') + dna = subparsers.add_parser('dna', help='Manage and configure DNA plugin', formatter_class=CustomHelpFormatter) subcommands = dna.add_subparsers(help='action') add_generic_plugin_parsers(subcommands, DNAPlugin) - list = subcommands.add_parser('list', help='List available plugin configs') + list = subcommands.add_parser('list', help='List available plugin configs', formatter_class=CustomHelpFormatter) subcommands_list = list.add_subparsers(help='action') - list_configs = subcommands_list.add_parser('configs', help='List main DNA plugin config entries') + list_configs = subcommands_list.add_parser('configs', help='List main DNA plugin config entries', formatter_class=CustomHelpFormatter) list_configs.set_defaults(func=dna_list) - list_shared_configs = subcommands_list.add_parser('shared-configs', help='List DNA plugin shared config entries') + list_shared_configs = subcommands_list.add_parser('shared-configs', help='List DNA plugin shared config entries', formatter_class=CustomHelpFormatter) list_shared_configs.add_argument('BASEDN', help='The search DN') list_shared_configs.set_defaults(func=dna_config_list) - config = subcommands.add_parser('config', help='Manage plugin configs') + config = subcommands.add_parser('config', help='Manage plugin configs', formatter_class=CustomHelpFormatter) config.add_argument('NAME', help='The DNA configuration name') config_subcommands = config.add_subparsers(help='action') - add = config_subcommands.add_parser('add', help='Add the config entry') + add = config_subcommands.add_parser('add', help='Add the config entry', formatter_class=CustomHelpFormatter) add.set_defaults(func=dna_add) _add_parser_args(add) - edit = config_subcommands.add_parser('set', help='Edit the config entry') + edit = config_subcommands.add_parser('set', help='Edit the config entry', formatter_class=CustomHelpFormatter) edit.set_defaults(func=dna_edit) _add_parser_args(edit) - show = config_subcommands.add_parser('show', help='Display the config entry') + show = config_subcommands.add_parser('show', help='Display the config entry', formatter_class=CustomHelpFormatter) show.set_defaults(func=dna_show) - delete = config_subcommands.add_parser('delete', help='Delete the config entry') + delete = config_subcommands.add_parser('delete', help='Delete the config entry', formatter_class=CustomHelpFormatter) delete.set_defaults(func=dna_del) - shared_config = config_subcommands.add_parser('shared-config-entry', help='Manage the shared config entry') + shared_config = config_subcommands.add_parser('shared-config-entry', help='Manage the shared config entry', formatter_class=CustomHelpFormatter) shared_config.add_argument('SHARED_CFG', help='Use HOSTNAME:PORT for this argument to identify the host name and port of a server in a shared range, as part of the DNA range ' 'configuration for that specific host in multi-supplier replication. (dnaHostname+dnaPortNum)') shared_config_subcommands = shared_config.add_subparsers(help='action') - edit_config = shared_config_subcommands.add_parser('set', help='Edit the shared config entry') + edit_config = shared_config_subcommands.add_parser('set', help='Edit the shared config entry', formatter_class=CustomHelpFormatter) edit_config.set_defaults(func=dna_config_edit) edit_config.add_argument('--remote-bind-method', help='Specifies the remote bind method "SIMPLE", "SSL" (for SSL client auth), "SASL/GSSAPI", or "SASL/DIGEST-MD5" (dnaRemoteBindMethod)') edit_config.add_argument('--remote-conn-protocol', help='Specifies the remote connection protocol "LDAP", or "TLS" (dnaRemoteConnProtocol)') - show_config_parser = shared_config_subcommands.add_parser('show', help='Display the shared config entry') + show_config_parser = shared_config_subcommands.add_parser('show', help='Display the shared config entry', formatter_class=CustomHelpFormatter) show_config_parser.set_defaults(func=dna_config_show) - del_config_parser = shared_config_subcommands.add_parser('delete', help='Delete the shared config entry') + del_config_parser = shared_config_subcommands.add_parser('delete', help='Delete the shared config entry', formatter_class=CustomHelpFormatter) del_config_parser.set_defaults(func=dna_config_del) diff --git a/src/lib389/lib389/cli_conf/plugins/entryuuid.py b/src/lib389/lib389/cli_conf/plugins/entryuuid.py index af5ffd4e3d..98506b6fcb 100644 --- a/src/lib389/lib389/cli_conf/plugins/entryuuid.py +++ b/src/lib389/lib389/cli_conf/plugins/entryuuid.py @@ -11,6 +11,7 @@ from lib389.plugins import EntryUUIDPlugin, EntryUUIDFixupTasks from lib389.cli_conf import add_generic_plugin_parsers from lib389.utils import get_task_status +from lib389.cli_base import CustomHelpFormatter def do_fixup(inst, basedn, log, args): @@ -41,12 +42,12 @@ def do_fixup_status(inst, basedn, log, args): def create_parser(subparsers): - referint = subparsers.add_parser('entryuuid', help='Manage and configure EntryUUID plugin') + referint = subparsers.add_parser('entryuuid', help='Manage and configure EntryUUID plugin', formatter_class=CustomHelpFormatter) 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 = subcommands.add_parser('fixup', help='Run the fix-up task for EntryUUID plugin', formatter_class=CustomHelpFormatter) fixup.set_defaults(func=do_fixup) fixup.add_argument('DN', help="Base DN that contains entries to fix up") fixup.add_argument('-f', '--filter', @@ -57,7 +58,7 @@ def create_parser(subparsers): fixup.add_argument('--timeout', type=int, default=0, help="Sets the task timeout. Default is 0 (no timeout)") - fixup_status = subcommands.add_parser('fixup-status', help='Check the status of a fix-up task') + fixup_status = subcommands.add_parser('fixup-status', help='Check the status of a fix-up task', formatter_class=CustomHelpFormatter) fixup_status.set_defaults(func=do_fixup_status) fixup_status.add_argument('--dn', help="The task entry's DN") fixup_status.add_argument('--show-log', action='store_true', help="Display the task log") diff --git a/src/lib389/lib389/cli_conf/plugins/ldappassthrough.py b/src/lib389/lib389/cli_conf/plugins/ldappassthrough.py index f787d84361..1c88dd149f 100644 --- a/src/lib389/lib389/cli_conf/plugins/ldappassthrough.py +++ b/src/lib389/lib389/cli_conf/plugins/ldappassthrough.py @@ -10,7 +10,7 @@ import json import ldap from lib389.plugins import (PassThroughAuthenticationPlugin) - +from lib389.cli_base import CustomHelpFormatter from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add, generic_show, generic_enable, generic_disable, generic_status @@ -130,20 +130,20 @@ def create_parser(subparsers): add_generic_plugin_parsers(subcommands, PassThroughAuthenticationPlugin) - list_urls = subcommands.add_parser('list', help='Lists LDAP URLs') + list_urls = subcommands.add_parser('list', help='Lists LDAP URLs', formatter_class=CustomHelpFormatter) list_urls.set_defaults(func=pta_list) - # url = subcommands.add_parser('url', help='Manage PTA LDAP URL configurations') + # url = subcommands.add_parser('url', help='Manage PTA LDAP URL configurations', formatter_class=CustomHelpFormatter) # subcommands_url = url.add_subparsers(help='action') - add_url = subcommands.add_parser('add', help='Add an LDAP url to the config entry') + add_url = subcommands.add_parser('add', help='Add an LDAP url to the config entry', formatter_class=CustomHelpFormatter) add_url.add_argument('URL', help='The full LDAP URL in format ' '"ldap|ldaps://authDS/subtree maxconns,maxops,timeout,ldver,connlifetime,startTLS". ' 'If one optional parameter is specified the rest should be specified too') add_url.set_defaults(func=pta_add) - edit_url = subcommands.add_parser('modify', help='Edit the LDAP pass through config entry') + edit_url = subcommands.add_parser('modify', help='Edit the LDAP pass through config entry', formatter_class=CustomHelpFormatter) edit_url.add_argument('OLD_URL', help='The full LDAP URL you get from the "list" command') edit_url.add_argument('NEW_URL', help='Sets the full LDAP URL in format ' @@ -151,7 +151,7 @@ def create_parser(subparsers): 'If one optional parameter is specified the rest should be specified too.') edit_url.set_defaults(func=pta_edit) - delete_url = subcommands.add_parser('delete', help='Delete a URL from the config entry') + delete_url = subcommands.add_parser('delete', help='Delete a URL from the config entry', formatter_class=CustomHelpFormatter) delete_url.add_argument('URL', help='The full LDAP URL you get from the "list" command') delete_url.set_defaults(func=pta_del) diff --git a/src/lib389/lib389/cli_conf/plugins/linkedattr.py b/src/lib389/lib389/cli_conf/plugins/linkedattr.py index 3af8c3a644..3c400a5824 100644 --- a/src/lib389/lib389/cli_conf/plugins/linkedattr.py +++ b/src/lib389/lib389/cli_conf/plugins/linkedattr.py @@ -11,6 +11,7 @@ import ldap from lib389.plugins import LinkedAttributesPlugin, LinkedAttributesConfig, LinkedAttributesConfigs, LinkedAttributesFixupTasks from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add +from lib389.cli_base import CustomHelpFormatter from lib389.utils import get_task_status arg_to_attr = { @@ -110,36 +111,36 @@ def _add_parser_args(parser): def create_parser(subparsers): - linkedattr_parser = subparsers.add_parser('linked-attr', help='Manage and configure Linked Attributes plugin') + linkedattr_parser = subparsers.add_parser('linked-attr', help='Manage and configure Linked Attributes plugin', formatter_class=CustomHelpFormatter) subcommands = linkedattr_parser.add_subparsers(help='action') add_generic_plugin_parsers(subcommands, LinkedAttributesPlugin) - fixup_parser = subcommands.add_parser('fixup', help='Run the fix-up task for linked attributes plugin') + fixup_parser = subcommands.add_parser('fixup', help='Run the fix-up task for linked attributes plugin', formatter_class=CustomHelpFormatter) fixup_parser.add_argument('-l', '--linkdn', help="Sets the base DN that contains entries to fix up") fixup_parser.add_argument('--wait', action='store_true', help="Wait for the task to finish, this could take a long time") fixup_parser.set_defaults(func=fixup) - fixup_status = subcommands.add_parser('fixup-status', help='Check the status of a fix-up task') + fixup_status = subcommands.add_parser('fixup-status', help='Check the status of a fix-up task', formatter_class=CustomHelpFormatter) fixup_status.set_defaults(func=do_fixup_status) fixup_status.add_argument('--dn', help="The task entry's DN") fixup_status.add_argument('--show-log', action='store_true', help="Display the task log") fixup_status.add_argument('--watch', action='store_true', help="Watch the task's status and wait for it to finish") - list = subcommands.add_parser('list', help='List available plugin configs') + list = subcommands.add_parser('list', help='List available plugin configs', formatter_class=CustomHelpFormatter) list.set_defaults(func=linkedattr_list) - config = subcommands.add_parser('config', help='Manage plugin configs') + config = subcommands.add_parser('config', help='Manage plugin configs', formatter_class=CustomHelpFormatter) config.add_argument('NAME', help='The Linked Attributes configuration name') config_subcommands = config.add_subparsers(help='action') - add = config_subcommands.add_parser('add', help='Add the config entry') + add = config_subcommands.add_parser('add', help='Add the config entry', formatter_class=CustomHelpFormatter) add.set_defaults(func=linkedattr_add) _add_parser_args(add) - edit = config_subcommands.add_parser('set', help='Edit the config entry') + edit = config_subcommands.add_parser('set', help='Edit the config entry', formatter_class=CustomHelpFormatter) edit.set_defaults(func=linkedattr_edit) _add_parser_args(edit) - show = config_subcommands.add_parser('show', help='Display the config entry') + show = config_subcommands.add_parser('show', help='Display the config entry', formatter_class=CustomHelpFormatter) show.set_defaults(func=linkedattr_show) - delete = config_subcommands.add_parser('delete', help='Delete the config entry') + delete = config_subcommands.add_parser('delete', help='Delete the config entry', formatter_class=CustomHelpFormatter) delete.set_defaults(func=linkedattr_del) diff --git a/src/lib389/lib389/cli_conf/plugins/managedentries.py b/src/lib389/lib389/cli_conf/plugins/managedentries.py index 4dd9cce536..f8d133c137 100644 --- a/src/lib389/lib389/cli_conf/plugins/managedentries.py +++ b/src/lib389/lib389/cli_conf/plugins/managedentries.py @@ -11,6 +11,7 @@ from lib389.backend import Backends from lib389.plugins import ManagedEntriesPlugin, MEPConfig, MEPConfigs, MEPTemplate, MEPTemplates from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add +from lib389.cli_base import CustomHelpFormatter arg_to_attr = { 'config_area': 'nsslapd-pluginconfigarea' @@ -201,15 +202,15 @@ def _add_parser_args_template(parser): def create_parser(subparsers): - mep = subparsers.add_parser('managed-entries', help='Manage and configure Managed Entries Plugin') + mep = subparsers.add_parser('managed-entries', help='Manage and configure Managed Entries Plugin', formatter_class=CustomHelpFormatter) subcommands = mep.add_subparsers(help='action') add_generic_plugin_parsers(subcommands, ManagedEntriesPlugin) - edit = subcommands.add_parser('set', help='Edit the plugin settings') + edit = subcommands.add_parser('set', help='Edit the plugin settings', formatter_class=CustomHelpFormatter) edit.set_defaults(func=mep_edit) edit.add_argument('--config-area', help='Sets the value of the nsslapd-pluginConfigArea attribute') - list = subcommands.add_parser('list', help='List Managed Entries Plugin configs and templates') + list = subcommands.add_parser('list', help='List Managed Entries Plugin configs and templates', formatter_class=CustomHelpFormatter) subcommands_list = list.add_subparsers(help='action') list_configs = subcommands_list.add_parser('configs', help='List Managed Entries Plugin configs (list config-area ' 'if specified in the main plugin entry)') @@ -219,30 +220,30 @@ def create_parser(subparsers): list_templates.add_argument('BASEDN', nargs='?', help='The base DN where to search the templates') list_templates.set_defaults(func=mep_template_list) - config = subcommands.add_parser('config', help='Handle Managed Entries Plugin configs') + config = subcommands.add_parser('config', help='Handle Managed Entries Plugin configs', formatter_class=CustomHelpFormatter) config.add_argument('NAME', help='The config entry CN') config_subcommands = config.add_subparsers(help='action') - add = config_subcommands.add_parser('add', help='Add the config entry') + add = config_subcommands.add_parser('add', help='Add the config entry', formatter_class=CustomHelpFormatter) add.set_defaults(func=mep_config_add) _add_parser_args_config(add) - edit = config_subcommands.add_parser('set', help='Edit the config entry') + edit = config_subcommands.add_parser('set', help='Edit the config entry', formatter_class=CustomHelpFormatter) edit.set_defaults(func=mep_config_edit) _add_parser_args_config(edit) - show = config_subcommands.add_parser('show', help='Display the config entry') + show = config_subcommands.add_parser('show', help='Display the config entry', formatter_class=CustomHelpFormatter) show.set_defaults(func=mep_config_show) - delete = config_subcommands.add_parser('delete', help='Delete the config entry') + delete = config_subcommands.add_parser('delete', help='Delete the config entry', formatter_class=CustomHelpFormatter) delete.set_defaults(func=mep_config_del) - template = subcommands.add_parser('template', help='Handle Managed Entries Plugin templates') + template = subcommands.add_parser('template', help='Handle Managed Entries Plugin templates', formatter_class=CustomHelpFormatter) template.add_argument('DN', help='The template entry DN.') template_subcommands = template.add_subparsers(help='action') - add = template_subcommands.add_parser('add', help='Add the template entry') + add = template_subcommands.add_parser('add', help='Add the template entry', formatter_class=CustomHelpFormatter) add.set_defaults(func=mep_template_add) _add_parser_args_template(add) - edit = template_subcommands.add_parser('set', help='Edit the template entry') + edit = template_subcommands.add_parser('set', help='Edit the template entry', formatter_class=CustomHelpFormatter) edit.set_defaults(func=mep_template_edit) _add_parser_args_template(edit) - show = template_subcommands.add_parser('show', help='Display the template entry') + show = template_subcommands.add_parser('show', help='Display the template entry', formatter_class=CustomHelpFormatter) show.set_defaults(func=mep_template_show) - delete = template_subcommands.add_parser('delete', help='Delete the template entry') + delete = template_subcommands.add_parser('delete', help='Delete the template entry', formatter_class=CustomHelpFormatter) delete.set_defaults(func=mep_template_del) diff --git a/src/lib389/lib389/cli_conf/plugins/memberof.py b/src/lib389/lib389/cli_conf/plugins/memberof.py index 2d0f80c577..90c1af2c35 100644 --- a/src/lib389/lib389/cli_conf/plugins/memberof.py +++ b/src/lib389/lib389/cli_conf/plugins/memberof.py @@ -12,6 +12,7 @@ from lib389.plugins import MemberOfPlugin, MemberOfSharedConfig, MemberOfFixupTasks from lib389.utils import get_task_status from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add +from lib389.cli_base import CustomHelpFormatter arg_to_attr = { 'initfunc': 'nsslapd-pluginInitfunc', @@ -121,35 +122,35 @@ def _add_parser_args(parser): def create_parser(subparsers): - memberof = subparsers.add_parser('memberof', help='Manage and configure MemberOf plugin') + memberof = subparsers.add_parser('memberof', help='Manage and configure MemberOf plugin', formatter_class=CustomHelpFormatter) subcommands = memberof.add_subparsers(help='action') add_generic_plugin_parsers(subcommands, MemberOfPlugin) - edit = subcommands.add_parser('set', help='Edit the plugin settings') + edit = subcommands.add_parser('set', help='Edit the plugin settings', formatter_class=CustomHelpFormatter) edit.set_defaults(func=memberof_edit) _add_parser_args(edit) edit.add_argument('--config-entry', help='The value to set as nsslapd-pluginConfigArea') - config = subcommands.add_parser('config-entry', help='Manage the config entry') + config = subcommands.add_parser('config-entry', help='Manage the config entry', formatter_class=CustomHelpFormatter) config_subcommands = config.add_subparsers(help='action') - add_config = config_subcommands.add_parser('add', help='Add the config entry') + add_config = config_subcommands.add_parser('add', help='Add the config entry', formatter_class=CustomHelpFormatter) add_config.set_defaults(func=memberof_add_config) add_config.add_argument('DN', help='The config entry full DN') _add_parser_args(add_config) - edit_config = config_subcommands.add_parser('set', help='Edit the config entry') + edit_config = config_subcommands.add_parser('set', help='Edit the config entry', formatter_class=CustomHelpFormatter) edit_config.set_defaults(func=memberof_edit_config) edit_config.add_argument('DN', help='The config entry full DN') _add_parser_args(edit_config) - show_config = config_subcommands.add_parser('show', help='Display the config entry') + show_config = config_subcommands.add_parser('show', help='Display the config entry', formatter_class=CustomHelpFormatter) show_config.set_defaults(func=memberof_show_config) show_config.add_argument('DN', help='The config entry full DN') - del_config_ = config_subcommands.add_parser('delete', help='Delete the config entry') + del_config_ = config_subcommands.add_parser('delete', help='Delete the config entry', formatter_class=CustomHelpFormatter) del_config_.set_defaults(func=memberof_del_config) del_config_.add_argument('DN', help='The config entry full DN') - fixup = subcommands.add_parser('fixup', help='Run the fix-up task for memberOf plugin') + fixup = subcommands.add_parser('fixup', help='Run the fix-up task for memberOf plugin', formatter_class=CustomHelpFormatter) fixup.set_defaults(func=do_fixup) fixup.add_argument('DN', help="Base DN that contains entries to fix up") fixup.add_argument('-f', '--filter', @@ -161,7 +162,7 @@ def create_parser(subparsers): fixup.add_argument('--timeout', type=int, default=0, help="Sets the task timeout. ,Default is 0 (no timeout)") - fixup_status = subcommands.add_parser('fixup-status', help='Check the status of a fix-up task') + fixup_status = subcommands.add_parser('fixup-status', help='Check the status of a fix-up task', formatter_class=CustomHelpFormatter) fixup_status.set_defaults(func=do_fixup_status) fixup_status.add_argument('--dn', help="The task entry's DN") fixup_status.add_argument('--show-log', action='store_true', help="Display the task log") diff --git a/src/lib389/lib389/cli_conf/plugins/pampassthrough.py b/src/lib389/lib389/cli_conf/plugins/pampassthrough.py index 810f24422d..5dbfacec5c 100644 --- a/src/lib389/lib389/cli_conf/plugins/pampassthrough.py +++ b/src/lib389/lib389/cli_conf/plugins/pampassthrough.py @@ -10,7 +10,7 @@ import ldap from lib389.plugins import (PAMPassThroughAuthPlugin, PAMPassThroughAuthConfigs, PAMPassThroughAuthConfig) - +from lib389.cli_base import CustomHelpFormatter from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add @@ -114,20 +114,20 @@ def create_parser(subparsers): add_generic_plugin_parsers(subcommands, PAMPassThroughAuthPlugin) - list_pam = subcommands.add_parser('list', help='Lists PAM configurations') + list_pam = subcommands.add_parser('list', help='Lists PAM configurations', formatter_class=CustomHelpFormatter) list_pam.set_defaults(func=pam_pta_list) - pam = subcommands.add_parser('config', help='Manage PAM PTA configurations.') + pam = subcommands.add_parser('config', help='Manage PAM PTA configurations.', formatter_class=CustomHelpFormatter) pam.add_argument('NAME', help='The PAM PTA configuration name') subcommands_pam = pam.add_subparsers(help='action') - add = subcommands_pam.add_parser('add', help='Add the config entry') + add = subcommands_pam.add_parser('add', help='Add the config entry', formatter_class=CustomHelpFormatter) add.set_defaults(func=pam_pta_add) _add_parser_args_pam(add) - edit = subcommands_pam.add_parser('set', help='Edit the config entry') + edit = subcommands_pam.add_parser('set', help='Edit the config entry', formatter_class=CustomHelpFormatter) edit.set_defaults(func=pam_pta_edit) _add_parser_args_pam(edit) - show = subcommands_pam.add_parser('show', help='Display the config entry') + show = subcommands_pam.add_parser('show', help='Display the config entry', formatter_class=CustomHelpFormatter) show.set_defaults(func=pam_pta_show) - delete = subcommands_pam.add_parser('delete', help='Delete the config entry') + delete = subcommands_pam.add_parser('delete', help='Delete the config entry', formatter_class=CustomHelpFormatter) delete.set_defaults(func=pam_pta_del) diff --git a/src/lib389/lib389/cli_conf/plugins/posix_winsync.py b/src/lib389/lib389/cli_conf/plugins/posix_winsync.py index 8a97ef4226..4c73773305 100644 --- a/src/lib389/lib389/cli_conf/plugins/posix_winsync.py +++ b/src/lib389/lib389/cli_conf/plugins/posix_winsync.py @@ -8,6 +8,7 @@ from lib389.plugins import POSIXWinsyncPlugin from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit +from lib389.cli_base import CustomHelpFormatter arg_to_attr = { 'create_memberof_task': 'posixWinsyncCreateMemberOfTask', @@ -61,15 +62,15 @@ def _add_parser_args(parser): def create_parser(subparsers): - winsync = subparsers.add_parser('posix-winsync', help='Manage and configure the Posix Winsync API plugin') + winsync = subparsers.add_parser('posix-winsync', help='Manage and configure the Posix Winsync API plugin', formatter_class=CustomHelpFormatter) subcommands = winsync.add_subparsers(help='action') add_generic_plugin_parsers(subcommands, POSIXWinsyncPlugin) - edit = subcommands.add_parser('set', help='Edit the plugin settings') + edit = subcommands.add_parser('set', help='Edit the plugin settings', formatter_class=CustomHelpFormatter) edit.set_defaults(func=winsync_edit) _add_parser_args(edit) - fixup = subcommands.add_parser('fixup', help='Run the memberOf fix-up task to correct mismatched member and uniquemember values for synced users') + fixup = subcommands.add_parser('fixup', help='Run the memberOf fix-up task to correct mismatched member and uniquemember values for synced users', formatter_class=CustomHelpFormatter) fixup.set_defaults(func=do_fixup) fixup.add_argument('DN', help="Set the base DN that contains entries to fix up") fixup.add_argument('-f', '--filter', diff --git a/src/lib389/lib389/cli_conf/plugins/referint.py b/src/lib389/lib389/cli_conf/plugins/referint.py index c46da6d75d..b3982f3a20 100644 --- a/src/lib389/lib389/cli_conf/plugins/referint.py +++ b/src/lib389/lib389/cli_conf/plugins/referint.py @@ -9,6 +9,7 @@ import ldap from lib389.plugins import ReferentialIntegrityPlugin, ReferentialIntegrityConfig from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add +from lib389.cli_base import CustomHelpFormatter arg_to_attr = { 'update_delay': 'referint-update-delay', @@ -95,24 +96,24 @@ def create_parser(subparsers): add_generic_plugin_parsers(subcommands, ReferentialIntegrityPlugin) - edit = subcommands.add_parser('set', help='Edit the plugin settings') + edit = subcommands.add_parser('set', help='Edit the plugin settings', formatter_class=CustomHelpFormatter) edit.set_defaults(func=referint_edit) _add_parser_args(edit) edit.add_argument('--config-entry', help='The value to set as nsslapd-pluginConfigArea') - config = subcommands.add_parser('config-entry', help='Manage the config entry') + config = subcommands.add_parser('config-entry', help='Manage the config entry', formatter_class=CustomHelpFormatter) config_subcommands = config.add_subparsers(help='action') - add_config = config_subcommands.add_parser('add', help='Add the config entry') + add_config = config_subcommands.add_parser('add', help='Add the config entry', formatter_class=CustomHelpFormatter) add_config.set_defaults(func=referint_add_config) add_config.add_argument('DN', help='The config entry full DN') _add_parser_args(add_config) - edit_config = config_subcommands.add_parser('set', help='Edit the config entry') + edit_config = config_subcommands.add_parser('set', help='Edit the config entry', formatter_class=CustomHelpFormatter) edit_config.set_defaults(func=referint_edit_config) edit_config.add_argument('DN', help='The config entry full DN') _add_parser_args(edit_config) - show_config = config_subcommands.add_parser('show', help='Display the config entry') + show_config = config_subcommands.add_parser('show', help='Display the config entry', formatter_class=CustomHelpFormatter) show_config.set_defaults(func=referint_show_config) show_config.add_argument('DN', help='The config entry full DN') - del_config_ = config_subcommands.add_parser('delete', help='Delete the config entry') + del_config_ = config_subcommands.add_parser('delete', help='Delete the config entry', formatter_class=CustomHelpFormatter) del_config_.set_defaults(func=referint_del_config) del_config_.add_argument('DN', help='The config entry full DN') diff --git a/src/lib389/lib389/cli_conf/plugins/retrochangelog.py b/src/lib389/lib389/cli_conf/plugins/retrochangelog.py index a33c77c396..336f7e83fd 100644 --- a/src/lib389/lib389/cli_conf/plugins/retrochangelog.py +++ b/src/lib389/lib389/cli_conf/plugins/retrochangelog.py @@ -7,6 +7,7 @@ # --- END COPYRIGHT BLOCK --- from lib389.plugins import RetroChangelogPlugin from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add_attr, generic_object_del_attr +from lib389.cli_base import CustomHelpFormatter arg_to_attr = { 'is_replicated': 'isReplicated', @@ -58,18 +59,18 @@ def _add_parser_args(parser): def create_parser(subparsers): - retrochangelog = subparsers.add_parser('retro-changelog', help='Manage and configure Retro Changelog plugin') + retrochangelog = subparsers.add_parser('retro-changelog', help='Manage and configure Retro Changelog plugin', formatter_class=CustomHelpFormatter) subcommands = retrochangelog.add_subparsers(help='action') add_generic_plugin_parsers(subcommands, RetroChangelogPlugin) - edit = subcommands.add_parser('set', help='Edit the plugin') + edit = subcommands.add_parser('set', help='Edit the plugin', formatter_class=CustomHelpFormatter) edit.set_defaults(func=retrochangelog_edit) _add_parser_args(edit) - addp = subcommands.add_parser('add', help='Add attributes to the plugin') + addp = subcommands.add_parser('add', help='Add attributes to the plugin', formatter_class=CustomHelpFormatter) addp.set_defaults(func=retrochangelog_add) _add_parser_args(addp) - delp = subcommands.add_parser('del', help='Delete an attribute from plugin scope') + delp = subcommands.add_parser('del', help='Delete an attribute from plugin scope', formatter_class=CustomHelpFormatter) delp.set_defaults(func=retrochangelog_del) _add_parser_args(delp) diff --git a/src/lib389/lib389/cli_conf/plugins/rootdn_ac.py b/src/lib389/lib389/cli_conf/plugins/rootdn_ac.py index 8c36f3186c..65486fff81 100644 --- a/src/lib389/lib389/cli_conf/plugins/rootdn_ac.py +++ b/src/lib389/lib389/cli_conf/plugins/rootdn_ac.py @@ -10,6 +10,7 @@ from lib389.plugins import RootDNAccessControlPlugin from lib389.utils import is_valid_hostname from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit +from lib389.cli_base import CustomHelpFormatter arg_to_attr = { 'allow_host': 'rootdn-allow-host', @@ -124,11 +125,11 @@ def _add_parser_args(parser): def create_parser(subparsers): - rootdnac_parser = subparsers.add_parser('root-dn', help='Manage and configure RootDN Access Control plugin') + rootdnac_parser = subparsers.add_parser('root-dn', help='Manage and configure RootDN Access Control plugin', formatter_class=CustomHelpFormatter) subcommands = rootdnac_parser.add_subparsers(help='action') add_generic_plugin_parsers(subcommands, RootDNAccessControlPlugin) - edit = subcommands.add_parser('set', help='Edit the plugin settings') + edit = subcommands.add_parser('set', help='Edit the plugin settings', formatter_class=CustomHelpFormatter) edit.set_defaults(func=rootdn_edit) _add_parser_args(edit) diff --git a/src/lib389/lib389/cli_conf/plugins/usn.py b/src/lib389/lib389/cli_conf/plugins/usn.py index bbc55da75c..ed62856fe8 100644 --- a/src/lib389/lib389/cli_conf/plugins/usn.py +++ b/src/lib389/lib389/cli_conf/plugins/usn.py @@ -8,6 +8,7 @@ from lib389.plugins import USNPlugin from lib389.cli_conf import add_generic_plugin_parsers +from lib389.cli_base import CustomHelpFormatter def display_usn_mode(inst, basedn, log, args): @@ -48,19 +49,19 @@ def tombstone_cleanup(inst, basedn, log, args): def create_parser(subparsers): - usn_parser = subparsers.add_parser('usn', help='Manage and configure USN plugin') + usn_parser = subparsers.add_parser('usn', help='Manage and configure USN plugin', formatter_class=CustomHelpFormatter) subcommands = usn_parser.add_subparsers(help='action') add_generic_plugin_parsers(subcommands, USNPlugin) - global_mode_parser = subcommands.add_parser('global', help='Get or manage global USN mode (nsslapd-entryusn-global)') + global_mode_parser = subcommands.add_parser('global', help='Get or manage global USN mode (nsslapd-entryusn-global)', formatter_class=CustomHelpFormatter) global_mode_parser.set_defaults(func=display_usn_mode) global_mode_subcommands = global_mode_parser.add_subparsers(help='action') - on_global_mode_parser = global_mode_subcommands.add_parser('on', help='Enables USN global mode') + on_global_mode_parser = global_mode_subcommands.add_parser('on', help='Enables USN global mode', formatter_class=CustomHelpFormatter) on_global_mode_parser.set_defaults(func=enable_global_mode) - off_global_mode_parser = global_mode_subcommands.add_parser('off', help='Disables USN global mode') + off_global_mode_parser = global_mode_subcommands.add_parser('off', help='Disables USN global mode', formatter_class=CustomHelpFormatter) off_global_mode_parser.set_defaults(func=disable_global_mode) - cleanup_parser = subcommands.add_parser('cleanup', help='Runs the USN tombstone cleanup task') + cleanup_parser = subcommands.add_parser('cleanup', help='Runs the USN tombstone cleanup task', formatter_class=CustomHelpFormatter) cleanup_parser.set_defaults(func=tombstone_cleanup) cleanup_group = cleanup_parser.add_mutually_exclusive_group(required=True) cleanup_group.add_argument('-s', '--suffix', diff --git a/src/lib389/lib389/cli_conf/pwpolicy.py b/src/lib389/lib389/cli_conf/pwpolicy.py index bce40604a9..2d4ba9b218 100644 --- a/src/lib389/lib389/cli_conf/pwpolicy.py +++ b/src/lib389/lib389/cli_conf/pwpolicy.py @@ -13,6 +13,7 @@ from lib389.pwpolicy import PwPolicyEntries, PwPolicyManager from lib389.password_plugins import PasswordPlugins from lib389.idm.account import Account +from lib389.cli_base import CustomHelpFormatter def _args_to_attrs(args, arg_to_attr): @@ -212,23 +213,23 @@ def list_schemes(inst, basedn, log, args): def create_parser(subparsers): # Create our two parsers for local and global policies - globalpwp_parser = subparsers.add_parser('pwpolicy', help='Manage the global password policy settings') - localpwp_parser = subparsers.add_parser('localpwp', help='Manage the local user and subtree password policies') + globalpwp_parser = subparsers.add_parser('pwpolicy', help='Manage the global password policy settings', formatter_class=CustomHelpFormatter) + localpwp_parser = subparsers.add_parser('localpwp', help='Manage the local user and subtree password policies', formatter_class=CustomHelpFormatter) ############################################ # Local password policies ############################################ local_subcommands = localpwp_parser.add_subparsers(help='Local password policy') # List all the local policies - list_parser = local_subcommands.add_parser('list', help='List all the local password policies') + list_parser = local_subcommands.add_parser('list', help='List all the local password policies', formatter_class=CustomHelpFormatter) list_parser.set_defaults(func=list_policies) list_parser.add_argument('DN', nargs='?', help='Suffix to search for local password policies') # Get a local policy - get_parser = local_subcommands.add_parser('get', help='Get local password policy entry') + get_parser = local_subcommands.add_parser('get', help='Get local password policy entry', formatter_class=CustomHelpFormatter) get_parser.set_defaults(func=get_local_policy) get_parser.add_argument('DN', nargs=1, help='Get the local policy for this entry DN') # The "set" arguments... - set_parser = local_subcommands.add_parser('set', help='Set an attribute in a local password policy') + set_parser = local_subcommands.add_parser('set', help='Set an attribute in a local password policy', formatter_class=CustomHelpFormatter) set_parser.set_defaults(func=set_local_policy) # General settings set_parser.add_argument('--pwdscheme', help="The password storage scheme") @@ -278,18 +279,18 @@ def create_parser(subparsers): set_parser.add_argument('--pwptprdelayexpireat', help="Number of seconds after which a reset password expires") set_parser.add_argument('--pwptprdelayvalidfrom', help="Number of seconds to wait before using a reset password to authenticated") # delete local password policy - del_parser = local_subcommands.add_parser('remove', help='Remove a local password policy') + del_parser = local_subcommands.add_parser('remove', help='Remove a local password policy', formatter_class=CustomHelpFormatter) del_parser.set_defaults(func=del_local_policy) del_parser.add_argument('DN', nargs=1, help='Remove local policy for this entry DN') # # create USER local password policy # - add_user_parser = local_subcommands.add_parser('adduser', add_help=False, parents=[set_parser], help='Add new user password policy') + add_user_parser = local_subcommands.add_parser('adduser', add_help=False, parents=[set_parser], help='Add new user password policy', formatter_class=CustomHelpFormatter) add_user_parser.set_defaults(func=create_user_policy) # # create SUBTREE local password policy # - add_subtree_parser = local_subcommands.add_parser('addsubtree', add_help=False, parents=[set_parser], help='Add new subtree password policy') + add_subtree_parser = local_subcommands.add_parser('addsubtree', add_help=False, parents=[set_parser], help='Add new subtree password policy', formatter_class=CustomHelpFormatter) add_subtree_parser.set_defaults(func=create_subtree_policy) ########################################### @@ -297,7 +298,7 @@ def create_parser(subparsers): ########################################### global_subcommands = globalpwp_parser.add_subparsers(help='Global password policy') # Get policy - get_global_parser = global_subcommands.add_parser('get', help='Get the global password policy entry') + get_global_parser = global_subcommands.add_parser('get', help='Get the global password policy entry', formatter_class=CustomHelpFormatter) get_global_parser.set_defaults(func=get_global_policy) # Set policy set_global_parser = global_subcommands.add_parser('set', add_help=False, parents=[set_parser], @@ -308,7 +309,7 @@ def create_parser(subparsers): set_global_parser.add_argument('--pwdallowhash', help="Set to \"on\" to allow adding prehashed passwords") set_global_parser.add_argument('--pwpinheritglobal', help="Set to \"on\" to allow local policies to inherit the global policy") # list password storage schemes - list_scehmes_parser = global_subcommands.add_parser('list-schemes', help='Get a list of the current password storage schemes') + list_scehmes_parser = global_subcommands.add_parser('list-schemes', help='Get a list of the current password storage schemes', formatter_class=CustomHelpFormatter) list_scehmes_parser.set_defaults(func=list_schemes) ############################################# diff --git a/src/lib389/lib389/cli_conf/replication.py b/src/lib389/lib389/cli_conf/replication.py index 35233c5f50..e4f48a8985 100644 --- a/src/lib389/lib389/cli_conf/replication.py +++ b/src/lib389/lib389/cli_conf/replication.py @@ -15,7 +15,7 @@ from getpass import getpass from lib389._constants import ReplicaRole, DSRC_HOME from lib389.cli_base.dsrc import dsrc_to_repl_monitor -from lib389.cli_base import _get_arg +from lib389.cli_base import _get_arg, CustomHelpFormatter from lib389.utils import is_a_dn, copy_with_permissions, ds_supports_new_changelog, get_passwd_from_file from lib389.replica import Replicas, ReplicationMonitor, BootstrapReplicationManager, Changelog5, ChangelogLDIF, Changelog from lib389.tasks import CleanAllRUVTask, AbortCleanAllRUVTask @@ -1289,10 +1289,10 @@ def create_parser(subparsers): # Replication Configuration ############################################ - repl_parser = subparsers.add_parser('replication', aliases=['repl'], help='Manage replication for a suffix') + repl_parser = subparsers.add_parser('replication', aliases=['repl'], help='Manage replication for a suffix', formatter_class=CustomHelpFormatter) repl_subcommands = repl_parser.add_subparsers(help='Replication Configuration') - repl_enable_parser = repl_subcommands.add_parser('enable', help='Enable replication for a suffix') + repl_enable_parser = repl_subcommands.add_parser('enable', help='Enable replication for a suffix', formatter_class=CustomHelpFormatter) repl_enable_parser.set_defaults(func=enable_replication) repl_enable_parser.add_argument('--suffix', required=True, help='Sets the DN of the suffix to be enabled for replication') repl_enable_parser.add_argument('--role', required=True, help="Sets the replication role: \"supplier\", \"hub\", or \"consumer\"") @@ -1305,18 +1305,18 @@ def create_parser(subparsers): repl_enable_parser.add_argument('--bind-passwd-file', help="File containing the password") repl_enable_parser.add_argument('--bind-passwd-prompt', action='store_true', help="Prompt for password") - repl_disable_parser = repl_subcommands.add_parser('disable', help='Disable replication for a suffix') + repl_disable_parser = repl_subcommands.add_parser('disable', help='Disable replication for a suffix', formatter_class=CustomHelpFormatter) repl_disable_parser.set_defaults(func=disable_replication) repl_disable_parser.add_argument('--suffix', required=True, help='Sets the DN of the suffix to have replication disabled') - repl_ruv_parser = repl_subcommands.add_parser('get-ruv', help='Display the database RUV entry for a suffix') + repl_ruv_parser = repl_subcommands.add_parser('get-ruv', help='Display the database RUV entry for a suffix', formatter_class=CustomHelpFormatter) repl_ruv_parser.set_defaults(func=get_ruv) repl_ruv_parser.add_argument('--suffix', required=True, help='Sets the DN of the replicated suffix') - repl_list_parser = repl_subcommands.add_parser('list', help='Lists all the replicated suffixes') + repl_list_parser = repl_subcommands.add_parser('list', help='Lists all the replicated suffixes', formatter_class=CustomHelpFormatter) repl_list_parser.set_defaults(func=list_suffixes) - repl_status_parser = repl_subcommands.add_parser('status', help='Display the current status of all the replication agreements') + repl_status_parser = repl_subcommands.add_parser('status', help='Display the current status of all the replication agreements', formatter_class=CustomHelpFormatter) repl_status_parser.set_defaults(func=get_repl_status) repl_status_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") repl_status_parser.add_argument('--bind-dn', help="Sets the DN to use to authenticate to the consumer. If not set, current instance's root DN will be used. It will be used for all agreements") @@ -1333,7 +1333,7 @@ def create_parser(subparsers): repl_winsync_status_parser.add_argument('--bind-passwd-file', help="File containing the password. Currectly not used") repl_winsync_status_parser.add_argument('--bind-passwd-prompt', action='store_true', help="Prompt for password. Currectly not used") - repl_promote_parser = repl_subcommands.add_parser('promote', help='Promote a replica to a hub or supplier') + repl_promote_parser = repl_subcommands.add_parser('promote', help='Promote a replica to a hub or supplier', formatter_class=CustomHelpFormatter) repl_promote_parser.set_defaults(func=promote_replica) repl_promote_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix to promote") repl_promote_parser.add_argument('--newrole', required=True, help='Sets the new replica role to \"hub\" or \"supplier\"') @@ -1341,7 +1341,7 @@ def create_parser(subparsers): repl_promote_parser.add_argument('--bind-group-dn', help="Sets a group entry DN containing members that are \"bind/supplier\" DNs") repl_promote_parser.add_argument('--bind-dn', help="Sets the bind or supplier DN that can make replication updates") - repl_add_manager_parser = repl_subcommands.add_parser('create-manager', help='Create a replication manager entry') + repl_add_manager_parser = repl_subcommands.add_parser('create-manager', help='Create a replication manager entry', formatter_class=CustomHelpFormatter) repl_add_manager_parser.set_defaults(func=create_repl_manager) repl_add_manager_parser.add_argument('--name', help="Sets the name of the new replication manager entry.For example, " + "if the name is \"replication manager\" then the new manager " + @@ -1353,22 +1353,22 @@ def create_parser(subparsers): repl_add_manager_parser.add_argument('--suffix', help='The DN of the replication suffix whose replication ' + 'configuration you want to add this new manager to (OPTIONAL)') - repl_del_manager_parser = repl_subcommands.add_parser('delete-manager', help='Delete a replication manager entry') + repl_del_manager_parser = repl_subcommands.add_parser('delete-manager', help='Delete a replication manager entry', formatter_class=CustomHelpFormatter) repl_del_manager_parser.set_defaults(func=del_repl_manager) repl_del_manager_parser.add_argument('--name', help="Sets the name of the replication manager entry under cn=config: \"cn=NAME,cn=config\"") repl_del_manager_parser.add_argument('--suffix', help='Sets the DN of the replication suffix whose replication ' + 'configuration you want to remove this manager from (OPTIONAL)') - repl_demote_parser = repl_subcommands.add_parser('demote', help='Demote replica to a hub or consumer') + repl_demote_parser = repl_subcommands.add_parser('demote', help='Demote replica to a hub or consumer', formatter_class=CustomHelpFormatter) repl_demote_parser.set_defaults(func=demote_replica) repl_demote_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") repl_demote_parser.add_argument('--newrole', required=True, help="Sets the new replication role to \"hub\", or \"consumer\"") - repl_get_parser = repl_subcommands.add_parser('get', help='Display the replication configuration') + repl_get_parser = repl_subcommands.add_parser('get', help='Display the replication configuration', formatter_class=CustomHelpFormatter) repl_get_parser.set_defaults(func=get_repl_config) repl_get_parser.add_argument('--suffix', required=True, help='Sets the suffix DN for the replication configuration to display') - repl_set_per_backend_cl = repl_subcommands.add_parser('set-changelog', help='Set replication changelog attributes') + repl_set_per_backend_cl = repl_subcommands.add_parser('set-changelog', help='Set replication changelog attributes', formatter_class=CustomHelpFormatter) repl_set_per_backend_cl.set_defaults(func=set_per_backend_cl) repl_set_per_backend_cl.add_argument('--suffix', required=True, help='Sets the suffix that uses the changelog') repl_set_per_backend_cl.add_argument('--max-entries', help="Sets the maximum number of entries to get in the replication changelog") @@ -1381,11 +1381,11 @@ def create_parser(subparsers): help="Sets the replication changelog to not use encryption. You must export " "and import the changelog after setting this.") - repl_get_per_backend_cl = repl_subcommands.add_parser('get-changelog', help='Display replication changelog attributes') + repl_get_per_backend_cl = repl_subcommands.add_parser('get-changelog', help='Display replication changelog attributes', formatter_class=CustomHelpFormatter) repl_get_per_backend_cl.set_defaults(func=get_per_backend_cl) repl_get_per_backend_cl.add_argument('--suffix', required=True, help='Sets the suffix that uses the changelog') - repl_export_cl = repl_subcommands.add_parser('export-changelog', help='Export the Directory Server replication changelog to an LDIF file') + repl_export_cl = repl_subcommands.add_parser('export-changelog', help='Export the Directory Server replication changelog to an LDIF file', formatter_class=CustomHelpFormatter) export_subcommands = repl_export_cl.add_subparsers(help='Export replication changelog') repl_export_cl = export_subcommands.add_parser('to-ldif', help='Sets the LDIF file name. ' 'This is typically used for setting up changelog encryption') @@ -1405,7 +1405,7 @@ def create_parser(subparsers): repl_export_cl.add_argument('-r', '--replica-root', required=True, help="Specifies the replica root whose changelog you want to export") - repl_def_export_cl = export_subcommands.add_parser('default', help='Export the replication changelog to the server\'s default LDIF directory') + repl_def_export_cl = export_subcommands.add_parser('default', help='Export the replication changelog to the server\'s default LDIF directory', formatter_class=CustomHelpFormatter) repl_def_export_cl.set_defaults(func=dump_def_cl) repl_def_export_cl.add_argument('-r', '--replica-root', required=True, help="Specifies the replica root whose changelog you want to export") @@ -1413,7 +1413,7 @@ def create_parser(subparsers): repl_import_cl = repl_subcommands.add_parser('import-changelog', help='Restore/import Directory Server replication change log from an LDIF file. This is typically used when managing changelog encryption') import_subcommands = repl_import_cl.add_subparsers(help='Restore/import replication changelog') - import_ldif = import_subcommands.add_parser('from-ldif', help='Restore/import a specific single LDIF file') + import_ldif = import_subcommands.add_parser('from-ldif', help='Restore/import a specific single LDIF file', formatter_class=CustomHelpFormatter) import_ldif.set_defaults(func=restore_cl_ldif) import_ldif.add_argument('LDIF_PATH', nargs=1, help='The path of the changelog LDIF file') import_ldif.add_argument('-r', '--replica-root', required=True, @@ -1425,7 +1425,7 @@ def create_parser(subparsers): import_def_ldif.add_argument('-r', '--replica-root', required=True, help="Specifies the replica root whose changelog you want to import") - repl_set_parser = repl_subcommands.add_parser('set', help='Set an attribute in the replication configuration') + repl_set_parser = repl_subcommands.add_parser('set', help='Set an attribute in the replication configuration', formatter_class=CustomHelpFormatter) repl_set_parser.set_defaults(func=set_repl_config) repl_set_parser.add_argument('--suffix', required=True, help='Sets the DN of the replication suffix') repl_set_parser.add_argument('--repl-add-bind-dn', help="Adds a bind (supplier) DN") @@ -1449,7 +1449,7 @@ def create_parser(subparsers): "an internal update to keep the RUV from getting stale. " "The default is 1 hour (3600 seconds)") - repl_monitor_parser = repl_subcommands.add_parser('monitor', help='Display the full replication topology report') + repl_monitor_parser = repl_subcommands.add_parser('monitor', help='Display the full replication topology report', formatter_class=CustomHelpFormatter) repl_monitor_parser.set_defaults(func=get_repl_monitor_info) repl_monitor_parser.add_argument('-c', '--connections', nargs="*", help="Sets the connection values for monitoring other not connected topologies. " @@ -1464,47 +1464,47 @@ def create_parser(subparsers): # Replication Agmts ############################################ - agmt_parser = subparsers.add_parser('repl-agmt', help='Manage replication agreements') + agmt_parser = subparsers.add_parser('repl-agmt', help='Manage replication agreements', formatter_class=CustomHelpFormatter) agmt_subcommands = agmt_parser.add_subparsers(help='Replication Agreement Configuration') # List - agmt_list_parser = agmt_subcommands.add_parser('list', help='List all replication agreements') + agmt_list_parser = agmt_subcommands.add_parser('list', help='List all replication agreements', formatter_class=CustomHelpFormatter) agmt_list_parser.set_defaults(func=list_agmts) agmt_list_parser.add_argument('--suffix', required=True, help='Sets the DN of the suffix to look up replication agreements for') agmt_list_parser.add_argument('--entry', help='Returns the entire entry for each agreement') # Enable - agmt_enable_parser = agmt_subcommands.add_parser('enable', help='Enable replication agreement') + agmt_enable_parser = agmt_subcommands.add_parser('enable', help='Enable replication agreement', formatter_class=CustomHelpFormatter) agmt_enable_parser.set_defaults(func=enable_agmt) agmt_enable_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication agreement') agmt_enable_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") # Disable - agmt_disable_parser = agmt_subcommands.add_parser('disable', help='Disable replication agreement') + agmt_disable_parser = agmt_subcommands.add_parser('disable', help='Disable replication agreement', formatter_class=CustomHelpFormatter) agmt_disable_parser.set_defaults(func=disable_agmt) agmt_disable_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication agreement') agmt_disable_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") # Initialize - agmt_init_parser = agmt_subcommands.add_parser('init', help='Initialize replication agreement') + agmt_init_parser = agmt_subcommands.add_parser('init', help='Initialize replication agreement', formatter_class=CustomHelpFormatter) agmt_init_parser.set_defaults(func=init_agmt) agmt_init_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication agreement') agmt_init_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") # Check Initialization progress - agmt_check_init_parser = agmt_subcommands.add_parser('init-status', help='Check the agreement initialization status') + agmt_check_init_parser = agmt_subcommands.add_parser('init-status', help='Check the agreement initialization status', formatter_class=CustomHelpFormatter) agmt_check_init_parser.set_defaults(func=check_init_agmt) agmt_check_init_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication agreement') agmt_check_init_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") # Send Updates Now - agmt_poke_parser = agmt_subcommands.add_parser('poke', help='Trigger replication to send updates now') + agmt_poke_parser = agmt_subcommands.add_parser('poke', help='Trigger replication to send updates now', formatter_class=CustomHelpFormatter) agmt_poke_parser.set_defaults(func=poke_agmt) agmt_poke_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication agreement') agmt_poke_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") # Status - agmt_status_parser = agmt_subcommands.add_parser('status', help='Displays the current status of the replication agreement') + agmt_status_parser = agmt_subcommands.add_parser('status', help='Displays the current status of the replication agreement', formatter_class=CustomHelpFormatter) agmt_status_parser.set_defaults(func=get_agmt_status) agmt_status_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication agreement') agmt_status_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") @@ -1514,13 +1514,13 @@ def create_parser(subparsers): agmt_status_parser.add_argument('--bind-passwd-prompt', action='store_true', help="Prompt for passwords for each agreement's instance separately") # Delete - agmt_del_parser = agmt_subcommands.add_parser('delete', help='Delete replication agreement') + agmt_del_parser = agmt_subcommands.add_parser('delete', help='Delete replication agreement', formatter_class=CustomHelpFormatter) agmt_del_parser.set_defaults(func=delete_agmt) agmt_del_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication agreement') agmt_del_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") # Create - agmt_add_parser = agmt_subcommands.add_parser('create', help='Initialize replication agreement') + agmt_add_parser = agmt_subcommands.add_parser('create', help='Initialize replication agreement', formatter_class=CustomHelpFormatter) agmt_add_parser.set_defaults(func=add_agmt) agmt_add_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication agreement') agmt_add_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") @@ -1565,7 +1565,7 @@ def create_parser(subparsers): agmt_add_parser.add_argument('--init', action='store_true', default=False, help="Initializes the agreement after creating it") # Set - Note can not use add's parent args because for "set" there are no "required=True" args - agmt_set_parser = agmt_subcommands.add_parser('set', help='Set an attribute in the replication agreement') + agmt_set_parser = agmt_subcommands.add_parser('set', help='Set an attribute in the replication agreement', formatter_class=CustomHelpFormatter) agmt_set_parser.set_defaults(func=set_agmt) agmt_set_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication agreement') agmt_set_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") @@ -1608,7 +1608,7 @@ def create_parser(subparsers): agmt_set_parser.add_argument('--bootstrap-bind-method', help="Sets the bind method: \"SIMPLE\", or \"SSLCLIENTAUTH\"") # Get - agmt_get_parser = agmt_subcommands.add_parser('get', help='Get replication configuration') + agmt_get_parser = agmt_subcommands.add_parser('get', help='Get replication configuration', formatter_class=CustomHelpFormatter) agmt_get_parser.set_defaults(func=get_repl_agmt) agmt_get_parser.add_argument('AGMT_NAME', nargs=1, help='The suffix DN for which to display the replication configuration') agmt_get_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") @@ -1617,58 +1617,58 @@ def create_parser(subparsers): # Replication Winsync Agmts ############################################ - winsync_parser = subparsers.add_parser('repl-winsync-agmt', help='Manage Winsync agreements') + winsync_parser = subparsers.add_parser('repl-winsync-agmt', help='Manage Winsync agreements', formatter_class=CustomHelpFormatter) winsync_agmt_subcommands = winsync_parser.add_subparsers(help='Replication Winsync Agreement configuration') # List - winsync_agmt_list_parser = winsync_agmt_subcommands.add_parser('list', help='List all the replication winsync agreements') + winsync_agmt_list_parser = winsync_agmt_subcommands.add_parser('list', help='List all the replication winsync agreements', formatter_class=CustomHelpFormatter) winsync_agmt_list_parser.set_defaults(func=list_winsync_agmts) winsync_agmt_list_parser.add_argument('--suffix', required=True, help='Sets the DN of the suffix to look up replication winsync agreements') # Enable - winsync_agmt_enable_parser = winsync_agmt_subcommands.add_parser('enable', help='Enable replication winsync agreement') + winsync_agmt_enable_parser = winsync_agmt_subcommands.add_parser('enable', help='Enable replication winsync agreement', formatter_class=CustomHelpFormatter) winsync_agmt_enable_parser.set_defaults(func=enable_winsync_agmt) winsync_agmt_enable_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication winsync agreement') winsync_agmt_enable_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication winsync suffix") # Disable - winsync_agmt_disable_parser = winsync_agmt_subcommands.add_parser('disable', help='Disable replication winsync agreement') + winsync_agmt_disable_parser = winsync_agmt_subcommands.add_parser('disable', help='Disable replication winsync agreement', formatter_class=CustomHelpFormatter) winsync_agmt_disable_parser.set_defaults(func=disable_winsync_agmt) winsync_agmt_disable_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication winsync agreement') winsync_agmt_disable_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication winsync suffix") # Initialize - winsync_agmt_init_parser = winsync_agmt_subcommands.add_parser('init', help='Initialize replication winsync agreement') + winsync_agmt_init_parser = winsync_agmt_subcommands.add_parser('init', help='Initialize replication winsync agreement', formatter_class=CustomHelpFormatter) winsync_agmt_init_parser.set_defaults(func=init_winsync_agmt) winsync_agmt_init_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication winsync agreement') winsync_agmt_init_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication winsync suffix") # Check Initialization progress - winsync_agmt_check_init_parser = winsync_agmt_subcommands.add_parser('init-status', help='Check the agreement initialization status') + winsync_agmt_check_init_parser = winsync_agmt_subcommands.add_parser('init-status', help='Check the agreement initialization status', formatter_class=CustomHelpFormatter) winsync_agmt_check_init_parser.set_defaults(func=check_winsync_init_agmt) winsync_agmt_check_init_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication agreement') winsync_agmt_check_init_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") # Send Updates Now - winsync_agmt_poke_parser = winsync_agmt_subcommands.add_parser('poke', help='Trigger replication to send updates now') + winsync_agmt_poke_parser = winsync_agmt_subcommands.add_parser('poke', help='Trigger replication to send updates now', formatter_class=CustomHelpFormatter) winsync_agmt_poke_parser.set_defaults(func=poke_winsync_agmt) winsync_agmt_poke_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication winsync agreement') winsync_agmt_poke_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication winsync suffix") # Status - winsync_agmt_status_parser = winsync_agmt_subcommands.add_parser('status', help='Display the current status of the replication agreement') + winsync_agmt_status_parser = winsync_agmt_subcommands.add_parser('status', help='Display the current status of the replication agreement', formatter_class=CustomHelpFormatter) winsync_agmt_status_parser.set_defaults(func=get_winsync_agmt_status) winsync_agmt_status_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication agreement') winsync_agmt_status_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") # Delete - winsync_agmt_del_parser = winsync_agmt_subcommands.add_parser('delete', help='Delete replication winsync agreement') + winsync_agmt_del_parser = winsync_agmt_subcommands.add_parser('delete', help='Delete replication winsync agreement', formatter_class=CustomHelpFormatter) winsync_agmt_del_parser.set_defaults(func=delete_winsync_agmt) winsync_agmt_del_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication winsync agreement') winsync_agmt_del_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication winsync suffix") # Create - winsync_agmt_add_parser = winsync_agmt_subcommands.add_parser('create', help='Initialize replication winsync agreement') + winsync_agmt_add_parser = winsync_agmt_subcommands.add_parser('create', help='Initialize replication winsync agreement', formatter_class=CustomHelpFormatter) winsync_agmt_add_parser.set_defaults(func=add_winsync_agmt) winsync_agmt_add_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication winsync agreement') winsync_agmt_add_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication winsync suffix") @@ -1714,7 +1714,7 @@ def create_parser(subparsers): winsync_agmt_add_parser.add_argument('--init', action='store_true', default=False, help="Initializes the agreement after creating it") # Set - Note can not use add's parent args because for "set" there are no "required=True" args - winsync_agmt_set_parser = winsync_agmt_subcommands.add_parser('set', help='Set an attribute in the replication winsync agreement') + winsync_agmt_set_parser = winsync_agmt_subcommands.add_parser('set', help='Set an attribute in the replication winsync agreement', formatter_class=CustomHelpFormatter) winsync_agmt_set_parser.set_defaults(func=set_winsync_agmt) winsync_agmt_set_parser.add_argument('AGMT_NAME', nargs=1, help='The name of the replication winsync agreement') winsync_agmt_set_parser.add_argument('--suffix', help="Sets the DN of the replication winsync suffix") @@ -1749,7 +1749,7 @@ def create_parser(subparsers): help="Sets the amount of time in seconds a supplier should wait between update sessions") # Get - winsync_agmt_get_parser = winsync_agmt_subcommands.add_parser('get', help='Display replication configuration') + winsync_agmt_get_parser = winsync_agmt_subcommands.add_parser('get', help='Display replication configuration', formatter_class=CustomHelpFormatter) winsync_agmt_get_parser.set_defaults(func=get_winsync_agmt) winsync_agmt_get_parser.add_argument('AGMT_NAME', nargs=1, help='The suffix DN for the replication configuration to display') winsync_agmt_get_parser.add_argument('--suffix', required=True, help="Sets the DN of the replication suffix") @@ -1758,29 +1758,29 @@ def create_parser(subparsers): # Replication Tasks (cleanalruv) ############################################ - tasks_parser = subparsers.add_parser('repl-tasks', help='Manage replication tasks') + tasks_parser = subparsers.add_parser('repl-tasks', help='Manage replication tasks', formatter_class=CustomHelpFormatter) task_subcommands = tasks_parser.add_subparsers(help='Replication tasks') # Cleanallruv - task_cleanallruv = task_subcommands.add_parser('cleanallruv', help='Cleanup old/removed replica IDs') + task_cleanallruv = task_subcommands.add_parser('cleanallruv', help='Cleanup old/removed replica IDs', formatter_class=CustomHelpFormatter) task_cleanallruv.set_defaults(func=run_cleanallruv) task_cleanallruv.add_argument('--suffix', required=True, help="Sets the Directory Server suffix") task_cleanallruv.add_argument('--replica-id', required=True, help="Sets the replica ID to remove/clean") task_cleanallruv.add_argument('--force-cleaning', action='store_true', default=False, help="Ignores errors and make a best attempt to clean all replicas") - task_cleanallruv_list = task_subcommands.add_parser('list-cleanruv-tasks', help='List all the running CleanAllRUV tasks') + task_cleanallruv_list = task_subcommands.add_parser('list-cleanruv-tasks', help='List all the running CleanAllRUV tasks', formatter_class=CustomHelpFormatter) task_cleanallruv_list.set_defaults(func=list_cleanallruv) task_cleanallruv_list.add_argument('--suffix', help="Lists only tasks for the specified suffix") # Abort cleanallruv - task_abort_cleanallruv = task_subcommands.add_parser('abort-cleanallruv', help='Abort cleanallruv tasks') + task_abort_cleanallruv = task_subcommands.add_parser('abort-cleanallruv', help='Abort cleanallruv tasks', formatter_class=CustomHelpFormatter) task_abort_cleanallruv.set_defaults(func=abort_cleanallruv) task_abort_cleanallruv.add_argument('--suffix', required=True, help="Sets the Directory Server suffix") task_abort_cleanallruv.add_argument('--replica-id', required=True, help="Sets the replica ID of the cleaning task to abort") task_abort_cleanallruv.add_argument('--certify', action='store_true', default=False, help="Enforces that the abort task completed on all replicas") - task_abort_cleanallruv_list = task_subcommands.add_parser('list-abortruv-tasks', help='List all the running CleanAllRUV abort tasks') + task_abort_cleanallruv_list = task_subcommands.add_parser('list-abortruv-tasks', help='List all the running CleanAllRUV abort tasks', formatter_class=CustomHelpFormatter) task_abort_cleanallruv_list.set_defaults(func=list_abort_cleanallruv) task_abort_cleanallruv_list.add_argument('--suffix', help="Lists only tasks for the specified suffix") diff --git a/src/lib389/lib389/cli_conf/saslmappings.py b/src/lib389/lib389/cli_conf/saslmappings.py index 6c11da35e2..ebef866506 100644 --- a/src/lib389/lib389/cli_conf/saslmappings.py +++ b/src/lib389/lib389/cli_conf/saslmappings.py @@ -18,6 +18,7 @@ _get_arg, _get_attributes, _warn, + CustomHelpFormatter ) SINGULAR = SaslMapping @@ -96,30 +97,30 @@ def sasl_get_available(inst, basedn, log, args): def create_parser(subparsers): - sasl_parser = subparsers.add_parser('sasl', help='Manage SASL mappings') + sasl_parser = subparsers.add_parser('sasl', help='Manage SASL mappings', formatter_class=CustomHelpFormatter) subcommands = sasl_parser.add_subparsers(help='sasl') - list_mappings_parser = subcommands.add_parser('list', help='Display available SASL mappings') + list_mappings_parser = subcommands.add_parser('list', help='Display available SASL mappings', formatter_class=CustomHelpFormatter) list_mappings_parser.set_defaults(func=sasl_map_list) list_mappings_parser.add_argument('--details', action='store_true', default=False, help="Displays each SASL mapping in detail") - get_mech_parser= subcommands.add_parser('get-mechs', help='Display the SASL mechanisms that the server will accept') + get_mech_parser= subcommands.add_parser('get-mechs', help='Display the SASL mechanisms that the server will accept', formatter_class=CustomHelpFormatter) get_mech_parser.set_defaults(func=sasl_get_supported) - get_mech_parser= subcommands.add_parser('get-available-mechs', help='Display the SASL mechanisms that are available to the server') + get_mech_parser= subcommands.add_parser('get-available-mechs', help='Display the SASL mechanisms that are available to the server', formatter_class=CustomHelpFormatter) get_mech_parser.set_defaults(func=sasl_get_available) - get_parser = subcommands.add_parser('get', help='Displays SASL mappings') + get_parser = subcommands.add_parser('get', help='Displays SASL mappings', formatter_class=CustomHelpFormatter) get_parser.set_defaults(func=sasl_map_get) get_parser.add_argument('selector', nargs='?', help='The SASL mapping name to display') - create_parser = subcommands.add_parser('create', help='Create a SASL mapping ') + create_parser = subcommands.add_parser('create', help='Create a SASL mapping ', formatter_class=CustomHelpFormatter) create_parser.set_defaults(func=sasl_map_create) populate_attr_arguments(create_parser, SaslMapping._must_attributes) - delete_parser = subcommands.add_parser('delete', help='Deletes the SASL object') + delete_parser = subcommands.add_parser('delete', help='Deletes the SASL object', formatter_class=CustomHelpFormatter) delete_parser.set_defaults(func=sasl_map_delete) delete_parser.add_argument('map_name', help='The SASL mapping name ("cn" value)') diff --git a/src/lib389/lib389/cli_conf/schema.py b/src/lib389/lib389/cli_conf/schema.py index 60bfa02d8e..577b4cea06 100644 --- a/src/lib389/lib389/cli_conf/schema.py +++ b/src/lib389/lib389/cli_conf/schema.py @@ -8,7 +8,7 @@ # --- END COPYRIGHT BLOCK --- from json import dumps as dump_json -from lib389.cli_base import _get_arg +from lib389.cli_base import _get_arg, CustomHelpFormatter from lib389.schema import Schema, AttributeUsage, ObjectclassKind from lib389.migrate.openldap.config import olSchema from lib389.migrate.plan import Migration @@ -334,59 +334,59 @@ def _add_parser_args(parser, type): def create_parser(subparsers): - schema_parser = subparsers.add_parser('schema', help='Manage the directory schema') + schema_parser = subparsers.add_parser('schema', help='Manage the directory schema', formatter_class=CustomHelpFormatter) schema_subcommands = schema_parser.add_subparsers(help='schema') - schema_list_parser = schema_subcommands.add_parser('list', help='List all schema objects on this system') + schema_list_parser = schema_subcommands.add_parser('list', help='List all schema objects on this system', formatter_class=CustomHelpFormatter) schema_list_parser.set_defaults(func=list_all) - attributetypes_parser = schema_subcommands.add_parser('attributetypes', help='Work with attribute types on this system') + attributetypes_parser = schema_subcommands.add_parser('attributetypes', help='Work with attribute types on this system', formatter_class=CustomHelpFormatter) attributetypes_subcommands = attributetypes_parser.add_subparsers(help='schema') - at_get_syntaxes_parser = attributetypes_subcommands.add_parser('get_syntaxes', help='List all available attribute type syntaxes') + at_get_syntaxes_parser = attributetypes_subcommands.add_parser('get_syntaxes', help='List all available attribute type syntaxes', formatter_class=CustomHelpFormatter) at_get_syntaxes_parser.set_defaults(func=get_syntaxes) - at_list_parser = attributetypes_subcommands.add_parser('list', help='List available attribute types on this system') + at_list_parser = attributetypes_subcommands.add_parser('list', help='List available attribute types on this system', formatter_class=CustomHelpFormatter) at_list_parser.set_defaults(func=list_attributetypes) - at_query_parser = attributetypes_subcommands.add_parser('query', help='Query an attribute to determine object classes that may or must take it') + at_query_parser = attributetypes_subcommands.add_parser('query', help='Query an attribute to determine object classes that may or must take it', formatter_class=CustomHelpFormatter) at_query_parser.set_defaults(func=query_attributetype) at_query_parser.add_argument('name', nargs='?', help='Attribute type to query') - at_add_parser = attributetypes_subcommands.add_parser('add', help='Add an attribute type to this system') + at_add_parser = attributetypes_subcommands.add_parser('add', help='Add an attribute type to this system', formatter_class=CustomHelpFormatter) at_add_parser.set_defaults(func=add_attributetype) _add_parser_args(at_add_parser, 'attributetypes') at_add_parser.add_argument('--syntax', required=True, help='OID of the LDAP syntax assigned to the attribute') - at_edit_parser = attributetypes_subcommands.add_parser('replace', help='Replace an attribute type on this system') + at_edit_parser = attributetypes_subcommands.add_parser('replace', help='Replace an attribute type on this system', formatter_class=CustomHelpFormatter) at_edit_parser.set_defaults(func=edit_attributetype) _add_parser_args(at_edit_parser, 'attributetypes') at_edit_parser.add_argument('--syntax', help='OID of the LDAP syntax assigned to the attribute') - at_remove_parser = attributetypes_subcommands.add_parser('remove', help='Remove an attribute type on this system') + at_remove_parser = attributetypes_subcommands.add_parser('remove', help='Remove an attribute type on this system', formatter_class=CustomHelpFormatter) at_remove_parser.set_defaults(func=remove_attributetype) at_remove_parser.add_argument('name', help='NAME of the object') - objectclasses_parser = schema_subcommands.add_parser('objectclasses', help='Work with objectClasses on this system') + objectclasses_parser = schema_subcommands.add_parser('objectclasses', help='Work with objectClasses on this system', formatter_class=CustomHelpFormatter) objectclasses_subcommands = objectclasses_parser.add_subparsers(help='schema') - oc_list_parser = objectclasses_subcommands.add_parser('list', help='List available objectClasses on this system') + oc_list_parser = objectclasses_subcommands.add_parser('list', help='List available objectClasses on this system', formatter_class=CustomHelpFormatter) oc_list_parser.set_defaults(func=list_objectclasses) - oc_query_parser = objectclasses_subcommands.add_parser('query', help='Query an objectClass') + oc_query_parser = objectclasses_subcommands.add_parser('query', help='Query an objectClass', formatter_class=CustomHelpFormatter) oc_query_parser.set_defaults(func=query_objectclass) oc_query_parser.add_argument('name', nargs='?', help='ObjectClass to query') - oc_add_parser = objectclasses_subcommands.add_parser('add', help='Add an objectClass to this system') + oc_add_parser = objectclasses_subcommands.add_parser('add', help='Add an objectClass to this system', formatter_class=CustomHelpFormatter) oc_add_parser.set_defaults(func=add_objectclass) _add_parser_args(oc_add_parser, 'objectclasses') - oc_edit_parser = objectclasses_subcommands.add_parser('replace', help='Replace an objectClass on this system') + oc_edit_parser = objectclasses_subcommands.add_parser('replace', help='Replace an objectClass on this system', formatter_class=CustomHelpFormatter) oc_edit_parser.set_defaults(func=edit_objectclass) _add_parser_args(oc_edit_parser, 'objectclasses') - oc_remove_parser = objectclasses_subcommands.add_parser('remove', help='Remove an objectClass on this system') + oc_remove_parser = objectclasses_subcommands.add_parser('remove', help='Remove an objectClass on this system', formatter_class=CustomHelpFormatter) oc_remove_parser.set_defaults(func=remove_objectclass) oc_remove_parser.add_argument('name', help='NAME of the object') - matchingrules_parser = schema_subcommands.add_parser('matchingrules', help='Work with matching rules on this system') + matchingrules_parser = schema_subcommands.add_parser('matchingrules', help='Work with matching rules on this system', formatter_class=CustomHelpFormatter) matchingrules_subcommands = matchingrules_parser.add_subparsers(help='schema') - mr_list_parser = matchingrules_subcommands.add_parser('list', help='List available matching rules on this system') + mr_list_parser = matchingrules_subcommands.add_parser('list', help='List available matching rules on this system', formatter_class=CustomHelpFormatter) mr_list_parser.set_defaults(func=list_matchingrules) - mr_query_parser = matchingrules_subcommands.add_parser('query', help='Query a matching rule') + mr_query_parser = matchingrules_subcommands.add_parser('query', help='Query a matching rule', formatter_class=CustomHelpFormatter) mr_query_parser.set_defaults(func=query_matchingrule) mr_query_parser.add_argument('name', nargs='?', help='Matching rule to query') - reload_parser = schema_subcommands.add_parser('reload', help='Dynamically reload schema while server is running') + reload_parser = schema_subcommands.add_parser('reload', help='Dynamically reload schema while server is running', formatter_class=CustomHelpFormatter) reload_parser.set_defaults(func=reload_schema) reload_parser.add_argument('-d', '--schemadir', help="directory where schema files are located") reload_parser.add_argument('--wait', action='store_true', default=False, help="Wait for the reload task to complete") diff --git a/src/lib389/lib389/cli_conf/security.py b/src/lib389/lib389/cli_conf/security.py index db0e9cf205..eba138feb4 100644 --- a/src/lib389/lib389/cli_conf/security.py +++ b/src/lib389/lib389/cli_conf/security.py @@ -11,7 +11,7 @@ import os from lib389.config import Config, Encryption, RSA from lib389.nss_ssl import NssSsl, CERT_NAME, CA_NAME -from lib389.cli_base import _warn +from lib389.cli_base import _warn, CustomHelpFormatter Props = namedtuple('Props', ['cls', 'attr', 'help', 'values']) @@ -103,13 +103,13 @@ def _security_generic_set(inst, basedn, log, args, attrs_map): def _security_generic_get_parser(parent, attrs_map, help): - p = parent.add_parser('get', help=help) + p = parent.add_parser('get', help=help, formatter_class=CustomHelpFormatter) p.set_defaults(func=lambda *args: _security_generic_get(*args, attrs_map)) return p def _security_generic_set_parser(parent, attrs_map, help, description): - p = parent.add_parser('set', help=help, description=description) + p = parent.add_parser('set', help=help, description=description, formatter_class=CustomHelpFormatter) p.set_defaults(func=lambda *args: _security_generic_set(*args, attrs_map)) for opt, params in attrs_map.items(): p.add_argument(f'--{opt}', help=f'{params[2]} ({params[1]})') @@ -133,7 +133,7 @@ def _security_generic_toggle(inst, basedn, log, args, cls, attr, value, thing): def _security_generic_toggle_parsers(parent, cls, attr, help_pattern): def add_parser(action, value): - p = parent.add_parser(action.lower(), help=help_pattern.format(action)) + p = parent.add_parser(action.lower(), help=help_pattern.format(action), formatter_class=CustomHelpFormatter) p.set_defaults(func=lambda *args: _security_generic_toggle(*args, cls, attr, value, action)) return p @@ -476,7 +476,7 @@ def export_cert(inst, basedn, log, args): def create_parser(subparsers): - security = subparsers.add_parser('security', help='Manage security settings') + security = subparsers.add_parser('security', help='Manage security settings', formatter_class=CustomHelpFormatter) security_sub = security.add_subparsers(help='security') # Core security management @@ -499,7 +499,7 @@ def create_parser(subparsers): security_disable_plain_parser.set_defaults(func=security_disable_plaintext_port) # Server certificate management - certs = security_sub.add_parser('certificate', help='Manage TLS certificates') + certs = security_sub.add_parser('certificate', help='Manage TLS certificates', formatter_class=CustomHelpFormatter) certs_sub = certs.add_subparsers(help='certificate') cert_add_parser = certs_sub.add_parser('add', help='Add a server certificate', description=( 'Add a server certificate to the NSS database')) @@ -533,7 +533,7 @@ def create_parser(subparsers): cert_list_parser.set_defaults(func=cert_list) # CA certificate management - cacerts = security_sub.add_parser('ca-certificate', help='Manage TLS certificate authorities') + cacerts = security_sub.add_parser('ca-certificate', help='Manage TLS certificate authorities', formatter_class=CustomHelpFormatter) cacerts_sub = cacerts.add_subparsers(help='ca-certificate') cacert_add_parser = cacerts_sub.add_parser('add', help='Add a Certificate Authority', description=( 'Add a Certificate Authority to the NSS database')) @@ -566,7 +566,7 @@ def create_parser(subparsers): cacert_list_parser.set_defaults(func=cacert_list) # RSA management - rsa = security_sub.add_parser('rsa', help='Query and update RSA security options') + rsa = security_sub.add_parser('rsa', help='Query and update RSA security options', formatter_class=CustomHelpFormatter) rsa_sub = rsa.add_subparsers(help='rsa') _security_generic_set_parser(rsa_sub, RSA_ATTRS_MAP, 'Set RSA security options', ('Use this command for setting RSA (private key) related options located in cn=RSA,cn=encryption,cn=config.' @@ -575,7 +575,7 @@ def create_parser(subparsers): _security_generic_toggle_parsers(rsa_sub, RSA, 'nsSSLActivation', '{} RSA') # Cipher management - ciphers = security_sub.add_parser('ciphers', help='Manage secure ciphers') + ciphers = security_sub.add_parser('ciphers', help='Manage secure ciphers', formatter_class=CustomHelpFormatter) ciphers_sub = ciphers.add_subparsers(help='ciphers') ciphers_enable = ciphers_sub.add_parser('enable', help='Enable ciphers', description=( @@ -612,7 +612,7 @@ def create_parser(subparsers): help='Lists only supported ciphers but without enabled ciphers') # Certificate Signing Request Management - csr = security_sub.add_parser('csr', help='Manage certificate signing requests') + csr = security_sub.add_parser('csr', help='Manage certificate signing requests', formatter_class=CustomHelpFormatter) csr_sub = csr.add_subparsers(help='csr') csr_list_parser = csr_sub.add_parser('list', help='List CSRs', description=('List all CSR files in instance' @@ -633,15 +633,15 @@ def create_parser(subparsers): help="CSR alternative names. These are auto-detected if not provided") csr_req_parser.set_defaults(func=csr_gen) - csr_delete_parser = csr_sub.add_parser('del', help='Delete a CSR file', description=('Delete a CSR file')) + csr_delete_parser = csr_sub.add_parser('del', help='Delete a CSR file', description=('Delete a CSR file'), formatter_class=CustomHelpFormatter) csr_delete_parser.add_argument('name', help="Name of the CSR file to delete") csr_delete_parser.set_defaults(func=csr_del) # Key Management - key = security_sub.add_parser('key', help='Manage keys in NSS DB') + key = security_sub.add_parser('key', help='Manage keys in NSS DB', formatter_class=CustomHelpFormatter) key_sub = key.add_subparsers(help='key') - key_list_parser = key_sub.add_parser('list', help='List all keys in NSS DB') + key_list_parser = key_sub.add_parser('list', help='List all keys in NSS DB', formatter_class=CustomHelpFormatter) key_list_parser.add_argument('--orphan', action='store_true', help='List orphan keys (An orphan key is' ' a private key in the NSS DB for which there is NO cert with the corresponding ' ' public key). An orphan key is created during CSR generation, when the associated certificate is imported' diff --git a/src/lib389/lib389/cli_ctl/cockpit.py b/src/lib389/lib389/cli_ctl/cockpit.py index 22d79725e8..afc7247335 100644 --- a/src/lib389/lib389/cli_ctl/cockpit.py +++ b/src/lib389/lib389/cli_ctl/cockpit.py @@ -8,6 +8,7 @@ import os import subprocess +from lib389.cli_base import CustomHelpFormatter def enable_cockpit(inst, log, args): @@ -67,22 +68,22 @@ def close_firewall(inst, log, args): def create_parser(subparsers): - cockpit_parser = subparsers.add_parser('cockpit', help="Enable the Cockpit interface/UI") + cockpit_parser = subparsers.add_parser('cockpit', help="Enable the Cockpit interface/UI", formatter_class=CustomHelpFormatter) subcommands = cockpit_parser.add_subparsers(help="action") # Enable socket - enable_parser = subcommands.add_parser('enable', help='Enable the Cockpit socket') + enable_parser = subcommands.add_parser('enable', help='Enable the Cockpit socket', formatter_class=CustomHelpFormatter) enable_parser.set_defaults(func=enable_cockpit) # Open firewall - open_parser = subcommands.add_parser('open-firewall', help='Open the firewall for the "cockpit" service') + open_parser = subcommands.add_parser('open-firewall', help='Open the firewall for the "cockpit" service', formatter_class=CustomHelpFormatter) open_parser.add_argument('--zone', help="The firewall zone") open_parser.set_defaults(func=open_firewall) # Disable socket - disable_parser = subcommands.add_parser('disable', help='Disable the Cockpit socket') + disable_parser = subcommands.add_parser('disable', help='Disable the Cockpit socket', formatter_class=CustomHelpFormatter) disable_parser.set_defaults(func=disable_cockpit) # Close firewall - close_parser = subcommands.add_parser('close-firewall', help='Remove the "cockpit" service from the firewall settings') + close_parser = subcommands.add_parser('close-firewall', help='Remove the "cockpit" service from the firewall settings', formatter_class=CustomHelpFormatter) close_parser.set_defaults(func=close_firewall) diff --git a/src/lib389/lib389/cli_ctl/dbgen.py b/src/lib389/lib389/cli_ctl/dbgen.py index 5692aac885..950bba1e3c 100644 --- a/src/lib389/lib389/cli_ctl/dbgen.py +++ b/src/lib389/lib389/cli_ctl/dbgen.py @@ -16,6 +16,7 @@ dbgen_nested_ldif, ) from lib389.utils import is_a_dn +from lib389.cli_base import CustomHelpFormatter DEFAULT_LDIF = "/ldifgen.ldif" @@ -499,11 +500,11 @@ def dbgen_create_nested(inst, log, args): def create_parser(subparsers): - db_gen_parser = subparsers.add_parser('ldifgen', help="LDIF generator to make sample LDIF files for testing") + db_gen_parser = subparsers.add_parser('ldifgen', help="LDIF generator to make sample LDIF files for testing", formatter_class=CustomHelpFormatter) subcommands = db_gen_parser.add_subparsers(help="action") # Create just users - dbgen_users_parser = subcommands.add_parser('users', help='Generate a LDIF containing user entries') + dbgen_users_parser = subcommands.add_parser('users', help='Generate a LDIF containing user entries', formatter_class=CustomHelpFormatter) dbgen_users_parser.set_defaults(func=dbgen_create_users) dbgen_users_parser.add_argument('--number', help="The number of users to create.") dbgen_users_parser.add_argument('--suffix', help="The database suffix where the entries will be created.") @@ -515,7 +516,7 @@ def create_parser(subparsers): dbgen_users_parser.add_argument('--ldif-file', default="ldifgen.ldif", help=f"The LDIF file name. Default location is the server's LDIF directory using the name 'ldifgen.ldif'") # Create static groups - dbgen_groups_parser = subcommands.add_parser('groups', help='Generate a LDIF containing groups and members') + dbgen_groups_parser = subcommands.add_parser('groups', help='Generate a LDIF containing groups and members', formatter_class=CustomHelpFormatter) dbgen_groups_parser.set_defaults(func=dbgen_create_groups) dbgen_groups_parser.add_argument('NAME', help="The group name.") dbgen_groups_parser.add_argument('--number', default=1, help="The number of groups to create.") @@ -528,7 +529,7 @@ def create_parser(subparsers): dbgen_groups_parser.add_argument('--ldif-file', default="ldifgen.ldif", help=f"The LDIF file name. Default location is the server's LDIF directory using the name 'ldifgen.ldif'") # Create a COS definition - dbgen_cos_def_parser = subcommands.add_parser('cos-def', help='Generate a LDIF containing a COS definition (classic, pointer, or indirect)') + dbgen_cos_def_parser = subcommands.add_parser('cos-def', help='Generate a LDIF containing a COS definition (classic, pointer, or indirect)', formatter_class=CustomHelpFormatter) dbgen_cos_def_parser.set_defaults(func=dbgen_create_cos_def) dbgen_cos_def_parser.add_argument('NAME', help="The COS definition name.") dbgen_cos_def_parser.add_argument('--type', help="The COS definition type: \"classic\", \"pointer\", or \"indirect\".") @@ -540,7 +541,7 @@ def create_parser(subparsers): dbgen_cos_def_parser.add_argument('--ldif-file', default="ldifgen.ldif", help=f"The LDIF file name. Default location is the server's LDIF directory using the name 'ldifgen.ldif'") # Create a COS Template - dbgen_cos_tmp_parser = subcommands.add_parser('cos-template', help='Generate a LDIF containing a COS template') + dbgen_cos_tmp_parser = subcommands.add_parser('cos-template', help='Generate a LDIF containing a COS template', formatter_class=CustomHelpFormatter) dbgen_cos_tmp_parser.set_defaults(func=dbgen_create_cos_tmp) dbgen_cos_tmp_parser.add_argument('NAME', help="The COS template name.") dbgen_cos_tmp_parser.add_argument('--parent', help="The DN of the entry to store the COS template entry under.") @@ -550,7 +551,7 @@ def create_parser(subparsers): dbgen_cos_tmp_parser.add_argument('--ldif-file', default="ldifgen.ldif", help=f"The LDIF file name. Default location is the server's LDIF directory using the name 'ldifgen.ldif'") # Create Role entries - dbgen_roles_parser = subcommands.add_parser('roles', help='Generate a LDIF containing a role entry (managed, filtered, or indirect)') + dbgen_roles_parser = subcommands.add_parser('roles', help='Generate a LDIF containing a role entry (managed, filtered, or indirect)', formatter_class=CustomHelpFormatter) dbgen_roles_parser.set_defaults(func=dbgen_create_role) dbgen_roles_parser.add_argument('NAME', help="The Role name.") dbgen_roles_parser.add_argument('--type', help="The Role type: \"managed\", \"filtered\", or \"nested\".") @@ -561,7 +562,7 @@ def create_parser(subparsers): dbgen_roles_parser.add_argument('--ldif-file', default="ldifgen.ldif", help=f"The LDIF file name. Default location is the server's LDIF directory using the name 'ldifgen.ldif'") # Create a modification LDIF - dbgen_mod_load_parser = subcommands.add_parser('mod-load', help='Generate a LDIF containing modify operations. This is intended to be consumed by ldapmodify.') + dbgen_mod_load_parser = subcommands.add_parser('mod-load', help='Generate a LDIF containing modify operations. This is intended to be consumed by ldapmodify.', formatter_class=CustomHelpFormatter) dbgen_mod_load_parser.set_defaults(func=dbgen_create_mods) dbgen_mod_load_parser.add_argument('--create-users', action='store_true', help="Create the entries that will be modified or deleted. By default the script assumes the user entries already exist.") dbgen_mod_load_parser.add_argument('--delete-users', action='store_true', help="Delete all the user entries at the end of the LDIF.") @@ -577,7 +578,7 @@ def create_parser(subparsers): dbgen_mod_load_parser.add_argument('--ldif-file', default="ldifgen.ldif", help=f"The LDIF file name. Default location is the server's LDIF directory using the name 'ldifgen.ldif'") # Create a heavily nested LDIF - dbgen_nested_parser = subcommands.add_parser('nested', help='Generate a heavily nested database LDIF in a cascading/fractal tree design') + dbgen_nested_parser = subcommands.add_parser('nested', help='Generate a heavily nested database LDIF in a cascading/fractal tree design', formatter_class=CustomHelpFormatter) dbgen_nested_parser.set_defaults(func=dbgen_create_nested) dbgen_nested_parser.add_argument('--num-users', help="The total number of user entries to create in the entire LDIF (does not include the container entries).") dbgen_nested_parser.add_argument('--node-limit', help="The total number of user entries to create under each node/subtree") diff --git a/src/lib389/lib389/cli_ctl/dblib.py b/src/lib389/lib389/cli_ctl/dblib.py index 56559b8ab9..e9269e340b 100644 --- a/src/lib389/lib389/cli_ctl/dblib.py +++ b/src/lib389/lib389/cli_ctl/dblib.py @@ -16,6 +16,7 @@ import shutil from lib389.dseldif import DSEldif from lib389._constants import DEFAULT_LMDB_SIZE +from lib389.cli_base import CustomHelpFormatter from lib389.utils import parse_size, format_size import subprocess from errno import ENOSPC @@ -513,16 +514,16 @@ def dblib_cleanup(inst, log, args): def create_parser(subparsers): - dblib_parser = subparsers.add_parser('dblib', help="database library (i.e bdb/lmdb) migration") + dblib_parser = subparsers.add_parser('dblib', help="database library (i.e bdb/lmdb) migration", formatter_class=CustomHelpFormatter) subcommands = dblib_parser.add_subparsers(help="action") - dblib_bdb2mdb_parser = subcommands.add_parser('bdb2mdb', help='Migrate bdb databases to lmdb') + dblib_bdb2mdb_parser = subcommands.add_parser('bdb2mdb', help='Migrate bdb databases to lmdb', formatter_class=CustomHelpFormatter) dblib_bdb2mdb_parser.set_defaults(func=dblib_bdb2mdb) dblib_bdb2mdb_parser.add_argument('--tmpdir', help="ldif migration files directory path.") - dblib_mdb2bdb_parser = subcommands.add_parser('mdb2bdb', help='Migrate lmdb databases to bdb') + dblib_mdb2bdb_parser = subcommands.add_parser('mdb2bdb', help='Migrate lmdb databases to bdb', formatter_class=CustomHelpFormatter) dblib_mdb2bdb_parser.set_defaults(func=dblib_mdb2bdb) dblib_mdb2bdb_parser.add_argument('--tmpdir', help="ldif migration files directory path.") - dblib_cleanup_parser = subcommands.add_parser('cleanup', help='Remove migration ldif file and old database') + dblib_cleanup_parser = subcommands.add_parser('cleanup', help='Remove migration ldif file and old database', formatter_class=CustomHelpFormatter) dblib_cleanup_parser.set_defaults(func=dblib_cleanup) diff --git a/src/lib389/lib389/cli_ctl/dbtasks.py b/src/lib389/lib389/cli_ctl/dbtasks.py index 4bcd1f2f5b..8566396722 100644 --- a/src/lib389/lib389/cli_ctl/dbtasks.py +++ b/src/lib389/lib389/cli_ctl/dbtasks.py @@ -9,6 +9,7 @@ import os from lib389._constants import TaskWarning +from lib389.cli_base import CustomHelpFormatter from pathlib import Path @@ -126,18 +127,18 @@ def dbtasks_verify(inst, log, args): def create_parser(subcommands): - db2index_parser = subcommands.add_parser('db2index', help="Initialise a reindex of the server database. The server must be stopped for this to proceed.") + db2index_parser = subcommands.add_parser('db2index', help="Initialise a reindex of the server database. The server must be stopped for this to proceed.", formatter_class=CustomHelpFormatter) # db2index_parser.add_argument('suffix', help="The suffix to reindex. IE dc=example,dc=com.") db2index_parser.add_argument('backend', nargs="?", help="The backend to reindex. IE userRoot", default=False) db2index_parser.add_argument('--attr', nargs="*", help="The attribute's to reindex. IE --attr aci cn givenname", default=False) db2index_parser.set_defaults(func=dbtasks_db2index) - db2bak_parser = subcommands.add_parser('db2bak', help="Initialise a BDB backup of the database. The server must be stopped for this to proceed.") + db2bak_parser = subcommands.add_parser('db2bak', help="Initialise a BDB backup of the database. The server must be stopped for this to proceed.", formatter_class=CustomHelpFormatter) db2bak_parser.add_argument('archive', help="The destination for the archive. This will be created during the db2bak process.", nargs='?', default=None) db2bak_parser.set_defaults(func=dbtasks_db2bak) - db2ldif_parser = subcommands.add_parser('db2ldif', help="Initialise an LDIF dump of the database. The server must be stopped for this to proceed.") + db2ldif_parser = subcommands.add_parser('db2ldif', help="Initialise an LDIF dump of the database. The server must be stopped for this to proceed.", formatter_class=CustomHelpFormatter) db2ldif_parser.add_argument('backend', help="The backend to output as an LDIF. IE userRoot") db2ldif_parser.add_argument('ldif', help="The path to the ldif output location.", nargs='?', default=None) db2ldif_parser.add_argument('--replication', help="Export replication information, suitable for importing on a new consumer or backups.", @@ -148,15 +149,15 @@ def create_parser(subcommands): db2ldif_parser.add_argument('--encrypted', help="Export encrypted attributes", default=False, action='store_true') db2ldif_parser.set_defaults(func=dbtasks_db2ldif) - dbverify_parser = subcommands.add_parser('dbverify', help="Perform a db verification. You should only do this at direction of support") + dbverify_parser = subcommands.add_parser('dbverify', help="Perform a db verification. You should only do this at direction of support", formatter_class=CustomHelpFormatter) dbverify_parser.add_argument('backend', help="The backend to verify. IE userRoot") dbverify_parser.set_defaults(func=dbtasks_verify) - bak2db_parser = subcommands.add_parser('bak2db', help="Restore a BDB backup of the database. The server must be stopped for this to proceed.") + bak2db_parser = subcommands.add_parser('bak2db', help="Restore a BDB backup of the database. The server must be stopped for this to proceed.", formatter_class=CustomHelpFormatter) bak2db_parser.add_argument('archive', help="The archive to restore. This will erase all current server databases.") bak2db_parser.set_defaults(func=dbtasks_bak2db) - ldif2db_parser = subcommands.add_parser('ldif2db', help="Restore an LDIF dump of the database. The server must be stopped for this to proceed.") + ldif2db_parser = subcommands.add_parser('ldif2db', help="Restore an LDIF dump of the database. The server must be stopped for this to proceed.", formatter_class=CustomHelpFormatter) ldif2db_parser.add_argument('backend', help="The backend to restore from an LDIF. IE userRoot") ldif2db_parser.add_argument('ldif', help="The path to the ldif to import") ldif2db_parser.add_argument('--encrypted', help="Import encrypted attributes", default=False, action='store_true') @@ -164,10 +165,10 @@ def create_parser(subcommands): # default=False, action='store_true') ldif2db_parser.set_defaults(func=dbtasks_ldif2db) - backups_parser = subcommands.add_parser('backups', help="List backup's found in the server's default backup directory") + backups_parser = subcommands.add_parser('backups', help="List backup's found in the server's default backup directory", formatter_class=CustomHelpFormatter) backups_parser.add_argument('--delete', nargs=1, help="Delete backup directory") backups_parser.set_defaults(func=dbtasks_backups) - ldifs_parser = subcommands.add_parser('ldifs', help="List all the LDIF files located in the server's LDIF directory") + ldifs_parser = subcommands.add_parser('ldifs', help="List all the LDIF files located in the server's LDIF directory", formatter_class=CustomHelpFormatter) ldifs_parser.add_argument('--delete', nargs=1, help="Delete LDIF file") ldifs_parser.set_defaults(func=dbtasks_ldifs) diff --git a/src/lib389/lib389/cli_ctl/dsrc.py b/src/lib389/lib389/cli_ctl/dsrc.py index c352e2edc6..fc0ae12d83 100644 --- a/src/lib389/lib389/cli_ctl/dsrc.py +++ b/src/lib389/lib389/cli_ctl/dsrc.py @@ -13,6 +13,7 @@ from ldap.dn import is_dn import configparser from lib389.utils import is_a_dn +from lib389.cli_base import CustomHelpFormatter def create_dsrc(inst, log, args): @@ -377,11 +378,11 @@ def replmon_dsrc(inst, log, args): def create_parser(subparsers): - dsrc_parser = subparsers.add_parser('dsrc', help="Manage the .dsrc file") + dsrc_parser = subparsers.add_parser('dsrc', help="Manage the .dsrc file", formatter_class=CustomHelpFormatter) subcommands = dsrc_parser.add_subparsers(help="action") # Create .dsrc file - dsrc_create_parser = subcommands.add_parser('create', help='Generate the .dsrc file') + dsrc_create_parser = subcommands.add_parser('create', help='Generate the .dsrc file', formatter_class=CustomHelpFormatter) dsrc_create_parser.set_defaults(func=create_dsrc) dsrc_create_parser.add_argument('--uri', help="The URI (LDAP URL) for the Directory Server instance.") dsrc_create_parser.add_argument('--basedn', help="The default database suffix.") @@ -399,7 +400,7 @@ def create_parser(subparsers): dsrc_create_parser.add_argument('--pwdfile', help="The absolute path to a file containing the Bind DN's password.") dsrc_create_parser.add_argument('--do-it', action='store_true', help="Create the file without any confirmation.") - dsrc_modify_parser = subcommands.add_parser('modify', help='Modify the .dsrc file') + dsrc_modify_parser = subcommands.add_parser('modify', help='Modify the .dsrc file', formatter_class=CustomHelpFormatter) dsrc_modify_parser.set_defaults(func=modify_dsrc) dsrc_modify_parser.add_argument('--uri', nargs='?', const='', help="The URI (LDAP URL) for the Directory Server instance.") dsrc_modify_parser.add_argument('--basedn', nargs='?', const='', help="The default database suffix.") @@ -417,17 +418,17 @@ def create_parser(subparsers): dsrc_modify_parser.add_argument('--do-it', action='store_true', help="Update the file without any confirmation.") # Delete the instance from the .dsrc file - dsrc_delete_parser = subcommands.add_parser('delete', help='Delete instance configuration from the .dsrc file.') + dsrc_delete_parser = subcommands.add_parser('delete', help='Delete instance configuration from the .dsrc file.', formatter_class=CustomHelpFormatter) dsrc_delete_parser.set_defaults(func=delete_dsrc) dsrc_delete_parser.add_argument('--do-it', action='store_true', help="Delete this instance's configuration from the .dsrc file.") # Display .dsrc file - dsrc_display_parser = subcommands.add_parser('display', help='Display the contents of the .dsrc file.') + dsrc_display_parser = subcommands.add_parser('display', help='Display the contents of the .dsrc file.', formatter_class=CustomHelpFormatter) dsrc_display_parser.set_defaults(func=display_dsrc) # Replication Monitor actions - dsrc_replmon_parser = subcommands.add_parser('repl-mon', help='Display the contents of the .dsrc file.') + dsrc_replmon_parser = subcommands.add_parser('repl-mon', help='Display the contents of the .dsrc file.', formatter_class=CustomHelpFormatter) dsrc_replmon_parser.set_defaults(func=replmon_dsrc) dsrc_replmon_parser.add_argument('--add-conn', nargs='+', help="Add a replica connection: 'NAME:HOST:PORT:BINDDN:CREDENTIAL'") dsrc_replmon_parser.add_argument('--del-conn', nargs='+', help="delete a replica connection by its NAME") diff --git a/src/lib389/lib389/cli_ctl/health.py b/src/lib389/lib389/cli_ctl/health.py index e242a4042a..d85e3906aa 100644 --- a/src/lib389/lib389/cli_ctl/health.py +++ b/src/lib389/lib389/cli_ctl/health.py @@ -10,7 +10,7 @@ import re from lib389._mapped_object import DSLdapObjects from lib389._mapped_object_lint import DSLint -from lib389.cli_base import connect_instance, disconnect_instance +from lib389.cli_base import connect_instance, disconnect_instance, CustomHelpFormatter from lib389.cli_base.dsrc import dsrc_to_ldap, dsrc_arg_concat from lib389.backend import Backends from lib389.config import Encryption, Config diff --git a/src/lib389/lib389/cli_ctl/instance.py b/src/lib389/lib389/cli_ctl/instance.py index 97322ace88..36c4731b51 100644 --- a/src/lib389/lib389/cli_ctl/instance.py +++ b/src/lib389/lib389/cli_ctl/instance.py @@ -13,6 +13,7 @@ import time from shutil import copytree, copyfile from lib389 import DirSrv +from lib389.cli_base import CustomHelpFormatter from lib389.instance.setup import SetupDs from lib389.utils import get_instance_list from lib389.instance.remove import remove_ds_instance @@ -303,23 +304,23 @@ def instance_remove(inst, log, args): def create_parser(subcommands): - # list_parser = subcommands.add_parser('list', help="List installed instances of Directory Server") + # list_parser = subcommands.add_parser('list', help="List installed instances of Directory Server", formatter_class=CustomHelpFormatter) # list_parser.set_defaults(func=instance_list) # list_parser.set_defaults(noinst=True) - restart_parser = subcommands.add_parser('restart', help="Restart an instance of Directory Server, if it is running: else start it.") + restart_parser = subcommands.add_parser('restart', help="Restart an instance of Directory Server, if it is running: else start it.", formatter_class=CustomHelpFormatter) restart_parser.set_defaults(func=instance_restart) - start_parser = subcommands.add_parser('start', help="Start an instance of Directory Server, if it is not currently running") + start_parser = subcommands.add_parser('start', help="Start an instance of Directory Server, if it is not currently running", formatter_class=CustomHelpFormatter) start_parser.set_defaults(func=instance_start) - stop_parser = subcommands.add_parser('stop', help="Stop an instance of Directory Server, if it is currently running") + stop_parser = subcommands.add_parser('stop', help="Stop an instance of Directory Server, if it is currently running", formatter_class=CustomHelpFormatter) stop_parser.set_defaults(func=instance_stop) - status_parser = subcommands.add_parser('status', help="Check running status of an instance of Directory Server") + status_parser = subcommands.add_parser('status', help="Check running status of an instance of Directory Server", formatter_class=CustomHelpFormatter) status_parser.set_defaults(func=instance_status) - remove_parser = subcommands.add_parser('remove', help="Destroy an instance of Directory Server, and remove all data.") + remove_parser = subcommands.add_parser('remove', help="Destroy an instance of Directory Server, and remove all data.", formatter_class=CustomHelpFormatter) remove_parser.set_defaults(func=instance_remove) remove_parser.add_argument('--do-it', dest="ack", help="By default we do a dry run. This actually initiates the removal of the instance.", action='store_true', default=False) diff --git a/src/lib389/lib389/cli_ctl/nsstate.py b/src/lib389/lib389/cli_ctl/nsstate.py index 28acd99bf1..00e3d407ec 100644 --- a/src/lib389/lib389/cli_ctl/nsstate.py +++ b/src/lib389/lib389/cli_ctl/nsstate.py @@ -8,6 +8,7 @@ import json from lib389.dseldif import DSEldif +from lib389.cli_base import CustomHelpFormatter def get_nsstate(inst, log, args): diff --git a/src/lib389/lib389/cli_ctl/tls.py b/src/lib389/lib389/cli_ctl/tls.py index 9bfabd1327..8834f5758c 100644 --- a/src/lib389/lib389/cli_ctl/tls.py +++ b/src/lib389/lib389/cli_ctl/tls.py @@ -8,7 +8,7 @@ # import os from lib389.nss_ssl import NssSsl, CERT_NAME, CA_NAME -from lib389.cli_base import _warn +from lib389.cli_base import _warn, CustomHelpFormatter def show_servercert(inst, log, args): @@ -97,26 +97,27 @@ def export_cert(inst, log, args): def create_parser(subparsers): - tls_parser = subparsers.add_parser('tls', help="Manage TLS certificates") + tls_parser = subparsers.add_parser('tls', help="Manage TLS certificates", formatter_class=CustomHelpFormatter) subcommands = tls_parser.add_subparsers(help='action') - list_ca_parser = subcommands.add_parser('list-ca', help='list server certificate authorities including intermediates') + list_ca_parser = subcommands.add_parser('list-ca', help='list server certificate authorities including intermediates', formatter_class=CustomHelpFormatter) list_ca_parser.set_defaults(func=list_cas) - list_client_ca_parser = subcommands.add_parser('list-client-ca', help='list client certificate authorities including intermediates') + list_client_ca_parser = subcommands.add_parser('list-client-ca', help='list client certificate authorities including intermediates', formatter_class=CustomHelpFormatter) list_client_ca_parser.set_defaults(func=list_client_cas) - show_servercert_parser = subcommands.add_parser('show-server-cert', help='Show the active server certificate that clients will see and verify') + show_servercert_parser = subcommands.add_parser('show-server-cert', help='Show the active server certificate that clients will see and verify', formatter_class=CustomHelpFormatter) show_servercert_parser.set_defaults(func=show_servercert) - show_cert_parser = subcommands.add_parser('show-cert', help='Show a certificate\'s details referenced by it\'s nickname. This is analogous to certutil -L -d -n ') + show_cert_parser = subcommands.add_parser('show-cert', help='Show a certificate\'s details referenced by it\'s nickname. This is analogous to certutil -L -d -n ', formatter_class=CustomHelpFormatter) show_cert_parser.add_argument('nickname', help="The nickname (friendly name) of the certificate to display") show_cert_parser.set_defaults(func=show_cert) generate_server_cert_csr_parser = subcommands.add_parser( 'generate-server-cert-csr', - help="Generate a Server-Cert certificate signing request - the csr is then submitted to a CA for verification, and when signed you import with import-ca and import-server-cert" + help="Generate a Server-Cert certificate signing request - the csr is then submitted to a CA for verification, and when signed you import with import-ca and import-server-cert", + formatter_class=CustomHelpFormatter ) generate_server_cert_csr_parser.add_argument('--subject', '-s', default=None, @@ -127,7 +128,8 @@ def create_parser(subparsers): import_client_ca_parser = subcommands.add_parser( 'import-client-ca', - help="Import a CA trusted to issue user (client) certificates. This is part of how client certificate authentication functions." + help="Import a CA trusted to issue user (client) certificates. This is part of how client certificate authentication functions.", + formatter_class=CustomHelpFormatter ) import_client_ca_parser.add_argument('cert_path', help="The path to the x509 cert to import as a client trust root") @@ -137,7 +139,8 @@ def create_parser(subparsers): import_ca_parser = subcommands.add_parser( 'import-ca', help="Import a CA or intermediate CA for signing this servers certificates (aka Server-Cert). " - "You should import all the CA's in the chain as required. PEM bundles are accepted" + "You should import all the CA's in the chain as required. PEM bundles are accepted", + formatter_class=CustomHelpFormatter ) import_ca_parser.add_argument('cert_path', help="The path to the x509 cert to import as a server CA") @@ -146,7 +149,8 @@ def create_parser(subparsers): import_server_cert_parser = subcommands.add_parser( 'import-server-cert', - help="Import a new Server-Cert after the csr has been signed from a CA." + help="Import a new Server-Cert after the csr has been signed from a CA.", + formatter_class=CustomHelpFormatter ) import_server_cert_parser.add_argument('cert_path', help="The path to the x509 cert to import as Server-Cert") @@ -154,7 +158,8 @@ def create_parser(subparsers): import_server_key_cert_parser = subcommands.add_parser( 'import-server-key-cert', - help="Import a new key and Server-Cert after having been signed from a CA. This is used if you have an external csr tool or a service like lets encrypt that generates PEM keys externally." + help="Import a new key and Server-Cert after having been signed from a CA. This is used if you have an external csr tool or a service like lets encrypt that generates PEM keys externally.", + formatter_class=CustomHelpFormatter ) import_server_key_cert_parser.add_argument('cert_path', help="The path to the x509 cert to import as Server-Cert") @@ -164,14 +169,16 @@ def create_parser(subparsers): remove_cert_parser = subcommands.add_parser( 'remove-cert', - help="Delete a certificate from this database. This will remove it from acting as a CA, a client CA or the Server-Cert role." + help="Delete a certificate from this database. This will remove it from acting as a CA, a client CA or the Server-Cert role.", + formatter_class=CustomHelpFormatter ) remove_cert_parser.add_argument('nickname', help="The name of the certificate to delete") remove_cert_parser.set_defaults(func=remove_cert) export_cert_parser = subcommands.add_parser( 'export-cert', - help="Export a certificate to PEM or DER/Binary format. PEM format is the default" + help="Export a certificate to PEM or DER/Binary format. PEM format is the default", + formatter_class=CustomHelpFormatter ) export_cert_parser.add_argument('nickname', help="The name of the certificate to export") export_cert_parser.add_argument('--binary-format', action='store_true', diff --git a/src/lib389/lib389/cli_idm/__init__.py b/src/lib389/lib389/cli_idm/__init__.py index 0dab54847e..e3622246d9 100644 --- a/src/lib389/lib389/cli_idm/__init__.py +++ b/src/lib389/lib389/cli_idm/__init__.py @@ -1,15 +1,30 @@ # --- BEGIN COPYRIGHT BLOCK --- # Copyright (C) 2016, William Brown -# Copyright (C) 2023 Red Hat, Inc. +# Copyright (C) 2024 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). # See LICENSE for details. # --- END COPYRIGHT BLOCK --- +import sys import ldap from getpass import getpass import json +from lib389._mapped_object import DSLdapObject +from lib389.cli_base import _get_dn_arg +from lib389.idm.user import DEFAULT_BASEDN_RDN as DEFAULT_BASEDN_RDN_USER +from lib389.idm.group import DEFAULT_BASEDN_RDN as DEFAULT_BASEDN_RDN_GROUP +from lib389.idm.posixgroup import DEFAULT_BASEDN_RDN as DEFAULT_BASEDN_RDN_POSIXGROUP +from lib389.idm.services import DEFAULT_BASEDN_RDN as DEFAULT_BASEDN_RDN_SERVICES + +# The key is module name, the value is default RDN +BASEDN_RDNS = { + 'user': DEFAULT_BASEDN_RDN_USER, + 'group': DEFAULT_BASEDN_RDN_GROUP, + 'posixgroup': DEFAULT_BASEDN_RDN_POSIXGROUP, + 'service': DEFAULT_BASEDN_RDN_SERVICES, +} def _get_arg(args, msg=None): @@ -37,6 +52,27 @@ def _get_args(args, kws): return kwargs +def _get_basedn_arg(inst, args, log, msg=None): + basedn_arg = _get_dn_arg(args.basedn, msg="Enter basedn") + if not DSLdapObject(inst, basedn_arg).exists(): + raise ValueError(f'The base DN "{basedn_arg}" does not exist.') + + # Get the RDN based on the last part of the module name if applicable + # (lib389.cli_idm.user -> user) + try: + command_name = args.func.__module__.split('.')[-1] + object_rdn = BASEDN_RDNS[command_name] + # Check if the DN for our command exists + command_basedn = f'{object_rdn},{basedn_arg}' + if not DSLdapObject(inst, command_basedn).exists(): + errmsg = f'The DN "{command_basedn}" does not exist.' + errmsg += f' It is required for "{command_name}" subcommand. Please create it first.' + raise ValueError(errmsg) + except KeyError: + pass + return basedn_arg + + # This is really similar to get_args, but generates from an array def _get_attributes(args, attrs): kwargs = {} diff --git a/src/lib389/lib389/cli_idm/account.py b/src/lib389/lib389/cli_idm/account.py index 6c7aebce19..15f7665883 100644 --- a/src/lib389/lib389/cli_idm/account.py +++ b/src/lib389/lib389/cli_idm/account.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2023, Red Hat inc, +# Copyright (C) 2024, Red Hat inc, # Copyright (C) 2018, William Brown # All rights reserved. # @@ -20,6 +20,7 @@ _get_arg, _get_dn_arg, _warn, + CustomHelpFormatter ) from lib389.cli_idm import _generic_rename_dn @@ -90,7 +91,6 @@ def entry_status(inst, basedn, log, args): def subtree_status(inst, basedn, log, args): - basedn = _get_dn_arg(args.basedn, msg="Enter basedn to check") filter = "" scope = ldap.SCOPE_SUBTREE epoch_inactive_time = None @@ -120,7 +120,6 @@ def subtree_status(inst, basedn, log, args): def bulk_update(inst, basedn, log, args): - basedn = _get_dn_arg(args.basedn, msg="Enter basedn to search") search_filter = "(objectclass=*)" scope = ldap.SCOPE_SUBTREE scope_str = "sub" @@ -213,42 +212,42 @@ def create_parser(subparsers): subcommands = account_parser.add_subparsers(help='action') - list_parser = subcommands.add_parser('list', help='list accounts that could login to the directory') + list_parser = subcommands.add_parser('list', help='list accounts that could login to the directory', formatter_class=CustomHelpFormatter) list_parser.set_defaults(func=list) - get_dn_parser = subcommands.add_parser('get-by-dn', help='get-by-dn ') + get_dn_parser = subcommands.add_parser('get-by-dn', help='get-by-dn ', formatter_class=CustomHelpFormatter) get_dn_parser.set_defaults(func=get_dn) get_dn_parser.add_argument('dn', nargs='?', help='The dn to get and display') - modify_dn_parser = subcommands.add_parser('modify-by-dn', help='modify-by-dn :: ...') + modify_dn_parser = subcommands.add_parser('modify-by-dn', help='modify-by-dn :: ...', formatter_class=CustomHelpFormatter) modify_dn_parser.set_defaults(func=modify) modify_dn_parser.add_argument('dn', nargs=1, help='The dn to get and display') modify_dn_parser.add_argument('changes', nargs='+', help="A list of changes to apply in format: ::") - rename_dn_parser = subcommands.add_parser('rename-by-dn', help='rename the object') + rename_dn_parser = subcommands.add_parser('rename-by-dn', help='rename the object', formatter_class=CustomHelpFormatter) rename_dn_parser.set_defaults(func=rename) rename_dn_parser.add_argument('dn', help='The dn to rename') rename_dn_parser.add_argument('new_dn', help='A new role dn') rename_dn_parser.add_argument('--keep-old-rdn', action='store_true', help="Specify whether the old RDN (i.e. 'cn: old_role') should be kept as an attribute of the entry or not") - delete_parser = subcommands.add_parser('delete', help='deletes the account') + delete_parser = subcommands.add_parser('delete', help='deletes the account', formatter_class=CustomHelpFormatter) delete_parser.set_defaults(func=delete) delete_parser.add_argument('dn', nargs='?', help='The dn of the account to delete') - lock_parser = subcommands.add_parser('lock', help='lock') + lock_parser = subcommands.add_parser('lock', help='lock', formatter_class=CustomHelpFormatter) lock_parser.set_defaults(func=lock) lock_parser.add_argument('dn', nargs='?', help='The dn to lock') - unlock_parser = subcommands.add_parser('unlock', help='unlock') + unlock_parser = subcommands.add_parser('unlock', help='unlock', formatter_class=CustomHelpFormatter) unlock_parser.set_defaults(func=unlock) unlock_parser.add_argument('dn', nargs='?', help='The dn to unlock') - status_parser = subcommands.add_parser('entry-status', help='status of a single entry') + status_parser = subcommands.add_parser('entry-status', help='status of a single entry', formatter_class=CustomHelpFormatter) status_parser.set_defaults(func=entry_status) status_parser.add_argument('dn', nargs='?', help='The single entry dn to check') status_parser.add_argument('-V', '--details', action='store_true', help="Print more account policy details about the entry") - status_parser = subcommands.add_parser('subtree-status', help='status of a subtree') + status_parser = subcommands.add_parser('subtree-status', help='status of a subtree', formatter_class=CustomHelpFormatter) status_parser.set_defaults(func=subtree_status) status_parser.add_argument('basedn', help="Search base for finding entries") status_parser.add_argument('-V', '--details', action='store_true', help="Print more account policy details about the entries") @@ -258,18 +257,18 @@ def create_parser(subparsers): status_parser.add_argument('-o', '--become-inactive-on', help="Only display entries that will become inactive before specified date (in a format 2007-04-25T14:30)") - reset_pw_parser = subcommands.add_parser('reset_password', help='Reset the password of an account. This should be performed by a directory admin.') + reset_pw_parser = subcommands.add_parser('reset_password', help='Reset the password of an account. This should be performed by a directory admin.', formatter_class=CustomHelpFormatter) reset_pw_parser.set_defaults(func=reset_password) reset_pw_parser.add_argument('dn', nargs='?', help='The dn to reset the password for') reset_pw_parser.add_argument('new_password', nargs='?', help='The new password to set') - change_pw_parser = subcommands.add_parser('change_password', help='Change the password of an account. This can be performed by any user (with correct rights)') + change_pw_parser = subcommands.add_parser('change_password', help='Change the password of an account. This can be performed by any user (with correct rights)', formatter_class=CustomHelpFormatter) change_pw_parser.set_defaults(func=change_password) change_pw_parser.add_argument('dn', nargs='?', help='The dn to change the password for') change_pw_parser.add_argument('new_password', nargs='?', help='The new password to set') change_pw_parser.add_argument('current_password', nargs='?', help='The accounts current password') - bulk_update_parser = subcommands.add_parser('bulk_update', help='Perform a common operation to a set of entries') + bulk_update_parser = subcommands.add_parser('bulk_update', help='Perform a common operation to a set of entries', formatter_class=CustomHelpFormatter) bulk_update_parser.set_defaults(func=bulk_update) bulk_update_parser.add_argument('basedn', help="Search base for finding entries, only the children of this DN are processed") bulk_update_parser.add_argument('-f', '--filter', help="Search filter for finding entries, default is '(objectclass=*)'") diff --git a/src/lib389/lib389/cli_idm/client_config.py b/src/lib389/lib389/cli_idm/client_config.py index 5cb7bda0f7..d0af8ed8ed 100644 --- a/src/lib389/lib389/cli_idm/client_config.py +++ b/src/lib389/lib389/cli_idm/client_config.py @@ -10,6 +10,7 @@ from lib389.idm.group import Groups from lib389.plugins import MemberOfPlugin from lib389.utils import basedn_to_ldap_dns_uri +from lib389.cli_base import CustomHelpFormatter SSSD_CONF_TEMPLATE = """ # diff --git a/src/lib389/lib389/cli_idm/group.py b/src/lib389/lib389/cli_idm/group.py index 3aafdf72d2..08bdb36e84 100644 --- a/src/lib389/lib389/cli_idm/group.py +++ b/src/lib389/lib389/cli_idm/group.py @@ -8,7 +8,7 @@ # --- END COPYRIGHT BLOCK --- from lib389.idm.group import Group, Groups, MUST_ATTRIBUTES -from lib389.cli_base import populate_attr_arguments, _generic_modify +from lib389.cli_base import populate_attr_arguments, _generic_modify, CustomHelpFormatter from lib389.cli_idm import ( _generic_list, _generic_get, @@ -103,46 +103,46 @@ def create_parser(subparsers): '"member"') subcommands = group_parser.add_subparsers(help='action') - list_parser = subcommands.add_parser('list', help='list') + list_parser = subcommands.add_parser('list', help='list', formatter_class=CustomHelpFormatter) list_parser.set_defaults(func=list) - get_parser = subcommands.add_parser('get', help='get') + get_parser = subcommands.add_parser('get', help='get', formatter_class=CustomHelpFormatter) get_parser.set_defaults(func=get) get_parser.add_argument('selector', nargs='?', help='The term to search for') - get_dn_parser = subcommands.add_parser('get_dn', help='get_dn') + get_dn_parser = subcommands.add_parser('get_dn', help='get_dn', formatter_class=CustomHelpFormatter) get_dn_parser.set_defaults(func=get_dn) get_dn_parser.add_argument('dn', nargs='?', help='The dn to get') - create_parser = subcommands.add_parser('create', help='create') + create_parser = subcommands.add_parser('create', help='create', formatter_class=CustomHelpFormatter) create_parser.set_defaults(func=create) populate_attr_arguments(create_parser, MUST_ATTRIBUTES) - delete_parser = subcommands.add_parser('delete', help='deletes the object') + delete_parser = subcommands.add_parser('delete', help='deletes the object', formatter_class=CustomHelpFormatter) delete_parser.set_defaults(func=delete) delete_parser.add_argument('dn', nargs='?', help='The dn to delete') - modify_parser = subcommands.add_parser('modify', help='modify :: ...') + modify_parser = subcommands.add_parser('modify', help='modify :: ...', formatter_class=CustomHelpFormatter) modify_parser.set_defaults(func=modify) modify_parser.add_argument('selector', nargs=1, help='The %s to modify' % RDN) modify_parser.add_argument('changes', nargs='+', help="A list of changes to apply in format: ::") - rename_parser = subcommands.add_parser('rename', help='rename the object') + rename_parser = subcommands.add_parser('rename', help='rename the object', formatter_class=CustomHelpFormatter) rename_parser.set_defaults(func=rename) rename_parser.add_argument('selector', help='The %s to rename' % RDN) rename_parser.add_argument('new_name', help='A new group name') rename_parser.add_argument('--keep-old-rdn', action='store_true', help="Specify whether the old RDN (i.e. 'cn: old_group') should be kept as an attribute of the entry or not") - members_parser = subcommands.add_parser('members', help="List member dns of a group") + members_parser = subcommands.add_parser('members', help="List member dns of a group", formatter_class=CustomHelpFormatter) members_parser.set_defaults(func=members) members_parser.add_argument('cn', nargs='?', help="cn of group to list members of") - add_member_parser = subcommands.add_parser('add_member', help="Add a member to a group") + add_member_parser = subcommands.add_parser('add_member', help="Add a member to a group", formatter_class=CustomHelpFormatter) add_member_parser.set_defaults(func=add_member) add_member_parser.add_argument('cn', nargs='?', help="cn of group to add member to") add_member_parser.add_argument('dn', nargs='?', help="dn of object to add to group as member") - remove_member_parser = subcommands.add_parser('remove_member', help="Remove a member from a group") + remove_member_parser = subcommands.add_parser('remove_member', help="Remove a member from a group", formatter_class=CustomHelpFormatter) remove_member_parser.set_defaults(func=remove_member) remove_member_parser.add_argument('cn', nargs='?', help="cn of group to remove member from") remove_member_parser.add_argument('dn', nargs='?', help="dn of object to remove from group as member") diff --git a/src/lib389/lib389/cli_idm/initialise.py b/src/lib389/lib389/cli_idm/initialise.py index e0c1239d35..dcbb131b59 100644 --- a/src/lib389/lib389/cli_idm/initialise.py +++ b/src/lib389/lib389/cli_idm/initialise.py @@ -8,6 +8,7 @@ from lib389._constants import INSTALL_LATEST_CONFIG from lib389.configurations import get_sample_entries +from lib389.cli_base import CustomHelpFormatter def initialise(inst, basedn, log, args): sample_entries = get_sample_entries(args.version) @@ -16,7 +17,7 @@ def initialise(inst, basedn, log, args): s_ent.apply() def create_parser(subparsers): - initialise_parser = subparsers.add_parser('initialise', aliases=['init'], help="Initialise a backend with domain information and sample entries") + initialise_parser = subparsers.add_parser('initialise', aliases=['init'], help="Initialise a backend with domain information and sample entries", formatter_class=CustomHelpFormatter) initialise_parser.set_defaults(func=initialise) initialise_parser.add_argument('--version', help="The version of entries to create.", default=INSTALL_LATEST_CONFIG) diff --git a/src/lib389/lib389/cli_idm/organizationalunit.py b/src/lib389/lib389/cli_idm/organizationalunit.py index 66edc31784..014f256ea8 100644 --- a/src/lib389/lib389/cli_idm/organizationalunit.py +++ b/src/lib389/lib389/cli_idm/organizationalunit.py @@ -7,7 +7,7 @@ # --- END COPYRIGHT BLOCK --- from lib389.idm.organizationalunit import OrganizationalUnit, OrganizationalUnits, MUST_ATTRIBUTES -from lib389.cli_base import populate_attr_arguments, _generic_modify +from lib389.cli_base import populate_attr_arguments, _generic_modify, CustomHelpFormatter from lib389.cli_idm import ( _generic_list, _generic_get, @@ -56,35 +56,35 @@ def rename(inst, basedn, log, args, warn=True): _generic_rename(inst, basedn, log.getChild('_generic_rename'), MANY, rdn, args) def create_parser(subparsers): - ou_parser = subparsers.add_parser('organizationalunit', aliases=['ou'], help='Manage organizational units') + ou_parser = subparsers.add_parser('organizationalunit', aliases=['ou'], help='Manage organizational units', formatter_class=CustomHelpFormatter) subcommands = ou_parser.add_subparsers(help='action') - list_parser = subcommands.add_parser('list', help='list') + list_parser = subcommands.add_parser('list', help='list', formatter_class=CustomHelpFormatter) list_parser.set_defaults(func=list) - get_parser = subcommands.add_parser('get', help='get') + get_parser = subcommands.add_parser('get', help='get', formatter_class=CustomHelpFormatter) get_parser.set_defaults(func=get) get_parser.add_argument('selector', nargs='?', help='The term to search for') - get_dn_parser = subcommands.add_parser('get_dn', help='get_dn') + get_dn_parser = subcommands.add_parser('get_dn', help='get_dn', formatter_class=CustomHelpFormatter) get_dn_parser.set_defaults(func=get_dn) get_dn_parser.add_argument('dn', nargs='?', help='The dn to get') - create_parser = subcommands.add_parser('create', help='create') + create_parser = subcommands.add_parser('create', help='create', formatter_class=CustomHelpFormatter) create_parser.set_defaults(func=create) populate_attr_arguments(create_parser, MUST_ATTRIBUTES) - delete_parser = subcommands.add_parser('delete', help='deletes the object') + delete_parser = subcommands.add_parser('delete', help='deletes the object', formatter_class=CustomHelpFormatter) delete_parser.set_defaults(func=delete) delete_parser.add_argument('dn', nargs='?', help='The dn to delete') - modify_parser = subcommands.add_parser('modify', help='modify :: ...') + modify_parser = subcommands.add_parser('modify', help='modify :: ...', formatter_class=CustomHelpFormatter) modify_parser.set_defaults(func=modify) modify_parser.add_argument('selector', nargs=1, help='The %s to modify' % RDN) modify_parser.add_argument('changes', nargs='+', help="A list of changes to apply in format: ::") - rename_parser = subcommands.add_parser('rename', help='rename the object') + rename_parser = subcommands.add_parser('rename', help='rename the object', formatter_class=CustomHelpFormatter) rename_parser.set_defaults(func=rename) rename_parser.add_argument('selector', help='The %s to rename' % RDN) rename_parser.add_argument('new_name', help='A new organizational unit name') diff --git a/src/lib389/lib389/cli_idm/posixgroup.py b/src/lib389/lib389/cli_idm/posixgroup.py index 2f5381a560..0b71d97c08 100644 --- a/src/lib389/lib389/cli_idm/posixgroup.py +++ b/src/lib389/lib389/cli_idm/posixgroup.py @@ -8,7 +8,7 @@ # --- END COPYRIGHT BLOCK --- from lib389.idm.posixgroup import PosixGroup, PosixGroups, MUST_ATTRIBUTES -from lib389.cli_base import populate_attr_arguments, _generic_modify +from lib389.cli_base import populate_attr_arguments, _generic_modify, CustomHelpFormatter from lib389.cli_idm import ( _generic_list, _generic_get, @@ -69,31 +69,31 @@ def create_parser(subparsers): 'ou=groups") needs to exist prior to managing posix groups.') subcommands = posixgroup_parser.add_subparsers(help='action') - list_parser = subcommands.add_parser('list', help='list') + list_parser = subcommands.add_parser('list', help='list', formatter_class=CustomHelpFormatter) list_parser.set_defaults(func=list) - get_parser = subcommands.add_parser('get', help='get') + get_parser = subcommands.add_parser('get', help='get', formatter_class=CustomHelpFormatter) get_parser.set_defaults(func=get) get_parser.add_argument('selector', nargs='?', help='The term to search for') - get_dn_parser = subcommands.add_parser('get_dn', help='get_dn') + get_dn_parser = subcommands.add_parser('get_dn', help='get_dn', formatter_class=CustomHelpFormatter) get_dn_parser.set_defaults(func=get_dn) get_dn_parser.add_argument('dn', nargs='?', help='The dn to get') - create_group_parser = subcommands.add_parser('create', help='create') + create_group_parser = subcommands.add_parser('create', help='create', formatter_class=CustomHelpFormatter) create_group_parser.set_defaults(func=create) populate_attr_arguments(create_group_parser, MUST_ATTRIBUTES) - delete_parser = subcommands.add_parser('delete', help='deletes the object') + delete_parser = subcommands.add_parser('delete', help='deletes the object', formatter_class=CustomHelpFormatter) delete_parser.set_defaults(func=delete) delete_parser.add_argument('dn', nargs='?', help='The dn to delete') - modify_parser = subcommands.add_parser('modify', help='modify :: ...') + modify_parser = subcommands.add_parser('modify', help='modify :: ...', formatter_class=CustomHelpFormatter) modify_parser.set_defaults(func=modify) modify_parser.add_argument('selector', nargs=1, help='The %s to modify' % RDN) modify_parser.add_argument('changes', nargs='+', help="A list of changes to apply in format: ::") - rename_parser = subcommands.add_parser('rename', help='rename the object') + rename_parser = subcommands.add_parser('rename', help='rename the object', formatter_class=CustomHelpFormatter) rename_parser.set_defaults(func=rename) rename_parser.add_argument('selector', help='The %s to rename' % RDN) rename_parser.add_argument('new_name', help='A new posix group name') diff --git a/src/lib389/lib389/cli_idm/role.py b/src/lib389/lib389/cli_idm/role.py index ebaa8b72bb..71dad94d08 100644 --- a/src/lib389/lib389/cli_idm/role.py +++ b/src/lib389/lib389/cli_idm/role.py @@ -31,6 +31,7 @@ _generic_create, _get_dn_arg, _warn, + CustomHelpFormatter ) from lib389.cli_idm import _generic_rename_dn @@ -133,61 +134,61 @@ def unlock(inst, basedn, log, args): def create_parser(subparsers): - role_parser = subparsers.add_parser('role', help='''Manage roles.''') + role_parser = subparsers.add_parser('role', help='''Manage roles.''', formatter_class=CustomHelpFormatter) subcommands = role_parser.add_subparsers(help='action') - list_parser = subcommands.add_parser('list', help='list roles that could login to the directory') + list_parser = subcommands.add_parser('list', help='list roles that could login to the directory', formatter_class=CustomHelpFormatter) list_parser.set_defaults(func=list) - get_parser = subcommands.add_parser('get', help='get') + get_parser = subcommands.add_parser('get', help='get', formatter_class=CustomHelpFormatter) get_parser.set_defaults(func=get) get_parser.add_argument('selector', nargs='?', help='The term to search for') - get_dn_parser = subcommands.add_parser('get-by-dn', help='get-by-dn ') + get_dn_parser = subcommands.add_parser('get-by-dn', help='get-by-dn ', formatter_class=CustomHelpFormatter) get_dn_parser.set_defaults(func=get_dn) get_dn_parser.add_argument('dn', nargs='?', help='The dn to get and display') - create_managed_parser = subcommands.add_parser('create-managed', help='create') + create_managed_parser = subcommands.add_parser('create-managed', help='create', formatter_class=CustomHelpFormatter) create_managed_parser.set_defaults(func=create_managed) populate_attr_arguments(create_managed_parser, MUST_ATTRIBUTES) - create_filtered_parser = subcommands.add_parser('create-filtered', help='create') + create_filtered_parser = subcommands.add_parser('create-filtered', help='create', formatter_class=CustomHelpFormatter) create_filtered_parser.set_defaults(func=create_filtered) populate_attr_arguments(create_filtered_parser, MUST_ATTRIBUTES) - create_nested_parser = subcommands.add_parser('create-nested', help='create') + create_nested_parser = subcommands.add_parser('create-nested', help='create', formatter_class=CustomHelpFormatter) create_nested_parser.set_defaults(func=create_nested) populate_attr_arguments(create_nested_parser, MUST_ATTRIBUTES_NESTED) - modify_dn_parser = subcommands.add_parser('modify-by-dn', help='modify-by-dn :: ...') + modify_dn_parser = subcommands.add_parser('modify-by-dn', help='modify-by-dn :: ...', formatter_class=CustomHelpFormatter) modify_dn_parser.set_defaults(func=modify) modify_dn_parser.add_argument('dn', nargs=1, help='The dn to modify') modify_dn_parser.add_argument('changes', nargs='+', help="A list of changes to apply in format: ::") - rename_dn_parser = subcommands.add_parser('rename-by-dn', help='rename the object') + rename_dn_parser = subcommands.add_parser('rename-by-dn', help='rename the object', formatter_class=CustomHelpFormatter) rename_dn_parser.set_defaults(func=rename) rename_dn_parser.add_argument('dn', help='The dn to rename') rename_dn_parser.add_argument('new_dn', help='A new account dn') rename_dn_parser.add_argument('--keep-old-rdn', action='store_true', help="Specify whether the old RDN (i.e. 'cn: old_account') should be kept as an attribute of the entry or not") - delete_parser = subcommands.add_parser('delete', help='deletes the role') + delete_parser = subcommands.add_parser('delete', help='deletes the role', formatter_class=CustomHelpFormatter) delete_parser.set_defaults(func=delete) delete_parser.add_argument('dn', nargs='?', help='The dn of the role to delete') - lock_parser = subcommands.add_parser('lock', help='lock') + lock_parser = subcommands.add_parser('lock', help='lock', formatter_class=CustomHelpFormatter) lock_parser.set_defaults(func=lock) lock_parser.add_argument('dn', nargs='?', help='The dn to lock') - unlock_parser = subcommands.add_parser('unlock', help='unlock') + unlock_parser = subcommands.add_parser('unlock', help='unlock', formatter_class=CustomHelpFormatter) unlock_parser.set_defaults(func=unlock) unlock_parser.add_argument('dn', nargs='?', help='The dn to unlock') - status_parser = subcommands.add_parser('entry-status', help='status of a single entry') + status_parser = subcommands.add_parser('entry-status', help='status of a single entry', formatter_class=CustomHelpFormatter) status_parser.set_defaults(func=entry_status) status_parser.add_argument('dn', nargs='?', help='The single entry dn to check') - status_parser = subcommands.add_parser('subtree-status', help='status of a subtree') + status_parser = subcommands.add_parser('subtree-status', help='status of a subtree', formatter_class=CustomHelpFormatter) status_parser.set_defaults(func=subtree_status) status_parser.add_argument('basedn', help="Search base for finding entries") status_parser.add_argument('-f', '--filter', help="Search filter for finding entries") diff --git a/src/lib389/lib389/cli_idm/service.py b/src/lib389/lib389/cli_idm/service.py index da2342d124..c2b2c8c844 100644 --- a/src/lib389/lib389/cli_idm/service.py +++ b/src/lib389/lib389/cli_idm/service.py @@ -8,7 +8,7 @@ # --- END COPYRIGHT BLOCK --- from lib389.idm.services import ServiceAccount, ServiceAccounts -from lib389.cli_base import populate_attr_arguments, _generic_modify +from lib389.cli_base import populate_attr_arguments, _generic_modify, CustomHelpFormatter from lib389.cli_idm import ( _generic_list, _generic_get, @@ -57,37 +57,39 @@ def rename(inst, basedn, log, args, warn=True): _generic_rename(inst, basedn, log.getChild('_generic_rename'), MANY, rdn, args) def create_parser(subparsers): - service_parser = subparsers.add_parser('service', help='Manage service accounts') + service_parser = subparsers.add_parser('service', + help='Manage service accounts. The organizationalUnit (by default "ou=Services") ' + 'needs to exist prior to managing service accounts.', formatter_class=CustomHelpFormatter) subcommands = service_parser.add_subparsers(help='action') - list_parser = subcommands.add_parser('list', help='list') + list_parser = subcommands.add_parser('list', help='list', formatter_class=CustomHelpFormatter) list_parser.set_defaults(func=list) - get_parser = subcommands.add_parser('get', help='get') + get_parser = subcommands.add_parser('get', help='get', formatter_class=CustomHelpFormatter) get_parser.set_defaults(func=get) get_parser.add_argument('selector', nargs='?', help='The term to search for') - get_dn_parser = subcommands.add_parser('get_dn', help='get_dn') + get_dn_parser = subcommands.add_parser('get_dn', help='get_dn', formatter_class=CustomHelpFormatter) get_dn_parser.set_defaults(func=get_dn) get_dn_parser.add_argument('dn', nargs='?', help='The dn to get') - create_parser = subcommands.add_parser('create', help='create') + create_parser = subcommands.add_parser('create', help='create', formatter_class=CustomHelpFormatter) create_parser.set_defaults(func=create) populate_attr_arguments(create_parser, SINGULAR._must_attributes) - modify_parser = subcommands.add_parser('modify', help='modify :: ...') + modify_parser = subcommands.add_parser('modify', help='modify :: ...', formatter_class=CustomHelpFormatter) modify_parser.set_defaults(func=modify) modify_parser.add_argument('selector', nargs=1, help='The %s to modify' % RDN) modify_parser.add_argument('changes', nargs='+', help="A list of changes to apply in format: ::") - rename_parser = subcommands.add_parser('rename', help='rename the object') + rename_parser = subcommands.add_parser('rename', help='rename the object', formatter_class=CustomHelpFormatter) rename_parser.set_defaults(func=rename) rename_parser.add_argument('selector', help='The %s to modify' % RDN) rename_parser.add_argument('new_name', help='A new service name') rename_parser.add_argument('--keep-old-rdn', action='store_true', help="Specify whether the old RDN (i.e. 'cn: old_service') should be kept as an attribute of the entry or not") - delete_parser = subcommands.add_parser('delete', help='deletes the object') + delete_parser = subcommands.add_parser('delete', help='deletes the object', formatter_class=CustomHelpFormatter) delete_parser.set_defaults(func=delete) delete_parser.add_argument('dn', nargs='?', help='The dn to delete') diff --git a/src/lib389/lib389/cli_idm/uniquegroup.py b/src/lib389/lib389/cli_idm/uniquegroup.py index 19cabd5702..fc3d6ae368 100644 --- a/src/lib389/lib389/cli_idm/uniquegroup.py +++ b/src/lib389/lib389/cli_idm/uniquegroup.py @@ -7,7 +7,7 @@ # --- END COPYRIGHT BLOCK --- from lib389.idm.group import UniqueGroup, UniqueGroups, MUST_ATTRIBUTES -from lib389.cli_base import populate_attr_arguments, _generic_modify +from lib389.cli_base import populate_attr_arguments, _generic_modify, CustomHelpFormatter from lib389.cli_idm import ( _generic_list, _generic_get, @@ -102,46 +102,46 @@ def create_parser(subparsers): '"uniquemember"') subcommands = group_parser.add_subparsers(help='action') - list_parser = subcommands.add_parser('list', help='list') + list_parser = subcommands.add_parser('list', help='list', formatter_class=CustomHelpFormatter) list_parser.set_defaults(func=list) - get_parser = subcommands.add_parser('get', help='get') + get_parser = subcommands.add_parser('get', help='get', formatter_class=CustomHelpFormatter) get_parser.set_defaults(func=get) get_parser.add_argument('selector', nargs='?', help='The term to search for') - get_dn_parser = subcommands.add_parser('get_dn', help='get_dn') + get_dn_parser = subcommands.add_parser('get_dn', help='get_dn', formatter_class=CustomHelpFormatter) get_dn_parser.set_defaults(func=get_dn) get_dn_parser.add_argument('dn', nargs='?', help='The dn to get') - create_parser = subcommands.add_parser('create', help='create') + create_parser = subcommands.add_parser('create', help='create', formatter_class=CustomHelpFormatter) create_parser.set_defaults(func=create) populate_attr_arguments(create_parser, MUST_ATTRIBUTES) - delete_parser = subcommands.add_parser('delete', help='deletes the object') + delete_parser = subcommands.add_parser('delete', help='deletes the object', formatter_class=CustomHelpFormatter) delete_parser.set_defaults(func=delete) delete_parser.add_argument('dn', nargs='?', help='The dn to delete') - modify_parser = subcommands.add_parser('modify', help='modify :: ...') + modify_parser = subcommands.add_parser('modify', help='modify :: ...', formatter_class=CustomHelpFormatter) modify_parser.set_defaults(func=modify) modify_parser.add_argument('selector', nargs=1, help='The %s to modify' % RDN) modify_parser.add_argument('changes', nargs='+', help="A list of changes to apply in format: ::") - rename_parser = subcommands.add_parser('rename', help='rename the object') + rename_parser = subcommands.add_parser('rename', help='rename the object', formatter_class=CustomHelpFormatter) rename_parser.set_defaults(func=rename) rename_parser.add_argument('selector', help='The %s to rename' % RDN) rename_parser.add_argument('new_name', help='A new group name') rename_parser.add_argument('--keep-old-rdn', action='store_true', help="Specify whether the old RDN (i.e. 'cn: old_group') should be kept as an attribute of the entry or not") - members_parser = subcommands.add_parser('members', help="List member dns of a group") + members_parser = subcommands.add_parser('members', help="List member dns of a group", formatter_class=CustomHelpFormatter) members_parser.set_defaults(func=members) members_parser.add_argument('cn', nargs='?', help="cn of group to list members of") - add_member_parser = subcommands.add_parser('add_member', help="Add a member to a group") + add_member_parser = subcommands.add_parser('add_member', help="Add a member to a group", formatter_class=CustomHelpFormatter) add_member_parser.set_defaults(func=add_member) add_member_parser.add_argument('cn', nargs='?', help="cn of group to add member to") add_member_parser.add_argument('dn', nargs='?', help="dn of object to add to group as member") - remove_member_parser = subcommands.add_parser('remove_member', help="Remove a member from a group") + remove_member_parser = subcommands.add_parser('remove_member', help="Remove a member from a group", formatter_class=CustomHelpFormatter) remove_member_parser.set_defaults(func=remove_member) remove_member_parser.add_argument('cn', nargs='?', help="cn of group to remove member from") remove_member_parser.add_argument('dn', nargs='?', help="dn of object to remove from group as member") diff --git a/src/lib389/lib389/cli_idm/user.py b/src/lib389/lib389/cli_idm/user.py index e25dec3477..a29d8a4793 100644 --- a/src/lib389/lib389/cli_idm/user.py +++ b/src/lib389/lib389/cli_idm/user.py @@ -8,7 +8,7 @@ # --- END COPYRIGHT BLOCK --- from lib389.idm.user import nsUserAccount, nsUserAccounts -from lib389.cli_base import populate_attr_arguments, _generic_modify +from lib389.cli_base import populate_attr_arguments, _generic_modify, CustomHelpFormatter from lib389.cli_idm import ( _generic_list, _generic_get, @@ -71,33 +71,33 @@ def create_parser(subparsers): subcommands = user_parser.add_subparsers(help='action') - list_parser = subcommands.add_parser('list', help='list') + list_parser = subcommands.add_parser('list', help='list', formatter_class=CustomHelpFormatter) list_parser.set_defaults(func=list) - get_parser = subcommands.add_parser('get', help='get') + get_parser = subcommands.add_parser('get', help='get', formatter_class=CustomHelpFormatter) get_parser.set_defaults(func=get) get_parser.add_argument('selector', nargs='?', help='The term to search for') - get_dn_parser = subcommands.add_parser('get_dn', help='get_dn') + get_dn_parser = subcommands.add_parser('get_dn', help='get_dn', formatter_class=CustomHelpFormatter) get_dn_parser.set_defaults(func=get_dn) get_dn_parser.add_argument('dn', nargs='?', help='The dn to get') - create_user_parser = subcommands.add_parser('create', help='create') + create_user_parser = subcommands.add_parser('create', help='create', formatter_class=CustomHelpFormatter) create_user_parser.set_defaults(func=create) populate_attr_arguments(create_user_parser, SINGULAR._must_attributes) - modify_parser = subcommands.add_parser('modify', help='modify :: ...') + modify_parser = subcommands.add_parser('modify', help='modify :: ...', formatter_class=CustomHelpFormatter) modify_parser.set_defaults(func=modify) modify_parser.add_argument('selector', nargs=1, help='The %s to modify' % RDN) modify_parser.add_argument('changes', nargs='+', help="A list of changes to apply in format: ::") - rename_parser = subcommands.add_parser('rename', help='rename the object') + rename_parser = subcommands.add_parser('rename', help='rename the object', formatter_class=CustomHelpFormatter) rename_parser.set_defaults(func=rename) rename_parser.add_argument('selector', help='The %s to modify' % RDN) rename_parser.add_argument('new_name', help='A new user name') rename_parser.add_argument('--keep-old-rdn', action='store_true', help="Specify whether the old RDN (i.e. 'cn: old_user') should be kept as an attribute of the entry or not") - delete_parser = subcommands.add_parser('delete', help='deletes the object') + delete_parser = subcommands.add_parser('delete', help='deletes the object', formatter_class=CustomHelpFormatter) delete_parser.set_defaults(func=delete) delete_parser.add_argument('dn', nargs='?', help='The dn to delete') diff --git a/src/lib389/lib389/config.py b/src/lib389/lib389/config.py index 23a60d979e..09056cee1c 100644 --- a/src/lib389/lib389/config.py +++ b/src/lib389/lib389/config.py @@ -70,9 +70,9 @@ def replace(self, key, value): if selinux_present() and (key.lower() == 'nsslapd-secureport' or key.lower() == 'nsslapd-port'): # Get old port and remove label old_port = self.get_attr_val_utf8(key) - self.log.debug("Removing old port's selinux label...") + self.log.debug("Removing old port's SELinux label...") selinux_label_port(old_port, remove_label=True) - self.log.debug("Setting new port's selinux label...") + self.log.debug("Setting new port's SELinux label...") selinux_label_port(value) super(Config, self).replace(key, value) diff --git a/src/lib389/lib389/idm/group.py b/src/lib389/lib389/idm/group.py index 560a2c6974..1e6c2a3ef2 100644 --- a/src/lib389/lib389/idm/group.py +++ b/src/lib389/lib389/idm/group.py @@ -1,6 +1,6 @@ # --- BEGIN COPYRIGHT BLOCK --- # Copyright (C) 2016, William Brown -# Copyright (C) 2023 Red Hat, Inc. +# Copyright (C) 2024 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -16,6 +16,8 @@ 'cn', ] RDN = 'cn' +DEFAULT_BASEDN_RDN = 'ou=Groups' +DEFAULT_BASEDN_RDN_ADMIN_GROUPS = 'ou=People' class Group(DSLdapObject): @@ -93,7 +95,7 @@ class Groups(DSLdapObjects): :type basedn: str """ - def __init__(self, instance, basedn, rdn='ou=Groups'): + def __init__(self, instance, basedn, rdn=DEFAULT_BASEDN_RDN): super(Groups, self).__init__(instance) self._objectclasses = [ 'groupOfNames', @@ -140,7 +142,7 @@ def remove_member(self, dn): class UniqueGroups(DSLdapObjects): # WARNING!!! # Use group, not unique group!!! - def __init__(self, instance, basedn, rdn='ou=Groups'): + def __init__(self, instance, basedn, rdn=DEFAULT_BASEDN_RDN): super(UniqueGroups, self).__init__(instance) self._objectclasses = [ 'groupOfUniqueNames', @@ -203,7 +205,7 @@ class nsAdminGroups(DSLdapObjects): :type rdn: str """ - def __init__(self, instance, basedn, rdn='ou=People'): + def __init__(self, instance, basedn, rdn=DEFAULT_BASEDN_RDN_ADMIN_GROUPS): super(nsAdminGroups, self).__init__(instance) self._objectclasses = [ 'nsAdminGroup' diff --git a/src/lib389/lib389/idm/posixgroup.py b/src/lib389/lib389/idm/posixgroup.py index 90fb00fb62..e1dba10704 100644 --- a/src/lib389/lib389/idm/posixgroup.py +++ b/src/lib389/lib389/idm/posixgroup.py @@ -1,6 +1,6 @@ # --- BEGIN COPYRIGHT BLOCK --- # Copyright (C) 2016, William Brown -# Copyright (C) 2023 Red Hat, Inc. +# Copyright (C) 2024 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -17,6 +17,7 @@ 'gidNumber', ] RDN = 'cn' +DEFAULT_BASEDN_RDN = 'ou=Groups' class PosixGroup(DSLdapObject): @@ -72,7 +73,7 @@ class PosixGroups(DSLdapObjects): :type basedn: str """ - def __init__(self, instance, basedn, rdn='ou=Groups'): + def __init__(self, instance, basedn, rdn=DEFAULT_BASEDN_RDN): super(PosixGroups, self).__init__(instance) self._objectclasses = [ 'groupOfNames', diff --git a/src/lib389/lib389/idm/services.py b/src/lib389/lib389/idm/services.py index 0439cf8f31..74b389a51f 100644 --- a/src/lib389/lib389/idm/services.py +++ b/src/lib389/lib389/idm/services.py @@ -1,6 +1,6 @@ # --- BEGIN COPYRIGHT BLOCK --- # Copyright (C) 2016, William Brown -# Copyright (C) 2021 Red Hat, Inc. +# Copyright (C) 2024 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -16,6 +16,7 @@ MUST_ATTRIBUTES = [ 'cn', ] +DEFAULT_BASEDN_RDN = 'ou=Services' class ServiceAccount(Account): """A single instance of Service entry @@ -59,7 +60,7 @@ class ServiceAccounts(DSLdapObjects): :type basedn: str """ - def __init__(self, instance, basedn, rdn='ou=Services'): + def __init__(self, instance, basedn, rdn=DEFAULT_BASEDN_RDN): super(ServiceAccounts, self).__init__(instance) self._objectclasses = [ 'applicationProcess', diff --git a/src/lib389/lib389/idm/user.py b/src/lib389/lib389/idm/user.py index 1206a6e082..3b21ccf1c2 100644 --- a/src/lib389/lib389/idm/user.py +++ b/src/lib389/lib389/idm/user.py @@ -1,6 +1,6 @@ # --- BEGIN COPYRIGHT BLOCK --- # Copyright (C) 2016, William Brown -# Copyright (C) 2023 Red Hat, Inc. +# Copyright (C) 2024 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -23,6 +23,7 @@ 'homeDirectory', ] RDN = 'uid' +DEFAULT_BASEDN_RDN = 'ou=People' TEST_USER_PROPERTIES = { 'uid': 'testuser', @@ -201,7 +202,7 @@ class UserAccounts(DSLdapObjects): :type rdn: str """ - def __init__(self, instance, basedn, rdn='ou=People'): + def __init__(self, instance, basedn, rdn=DEFAULT_BASEDN_RDN): super(UserAccounts, self).__init__(instance) self._objectclasses = [ 'account', diff --git a/src/lib389/lib389/instance/remove.py b/src/lib389/lib389/instance/remove.py index 6f31f2364f..9e41fb5bec 100644 --- a/src/lib389/lib389/instance/remove.py +++ b/src/lib389/lib389/instance/remove.py @@ -122,7 +122,7 @@ def remove_ds_instance(dirsrv, force=False): except OSError as e: _log.debug("Failed to remove tmpfile: " + str(e)) - # Nor can we assume we have selinux. Try docker sometime ;) + # Nor can we assume we have SELinux. if dirsrv.ds_paths.with_selinux: # Remove selinux port label _log.debug("Removing the port labels") @@ -133,7 +133,7 @@ def remove_ds_instance(dirsrv, force=False): selinux_label_port(dirsrv.sslport, remove_label=True) # If this was the last instance, remove the ssca instance - # and all ds related selinux customizations + # and all ds related SELinux customizations insts = dirsrv.list(all=True) if len(insts) == 0: ssca = NssSsl(dbpath=dirsrv.get_ssca_dir()) diff --git a/src/lib389/lib389/instance/setup.py b/src/lib389/lib389/instance/setup.py index 1cdb47348f..01027bc7e6 100644 --- a/src/lib389/lib389/instance/setup.py +++ b/src/lib389/lib389/instance/setup.py @@ -318,7 +318,7 @@ def create_from_cli(self): # Let them know about the selinux status if not selinux_present(): - val = input('\nSelinux support will be disabled, continue? [yes]: ') + val = input('\nSELinux labels will not be applied, continue? [yes]: ') if val.strip().lower().startswith('n'): return diff --git a/src/lib389/lib389/tools.py b/src/lib389/lib389/tools.py index 7e47d373d6..df6ba79238 100644 --- a/src/lib389/lib389/tools.py +++ b/src/lib389/lib389/tools.py @@ -410,7 +410,7 @@ def setupSSL(dirsrv, secport=636, sourcedir=None, secargs=None): certdir = e_config.getValue('nsslapd-certdir') # have to stop the server before replacing any security files DirSrvTools.stop(dirsrv) - # allow secport for selinux + # allow secport for SELinux if secport != 636: try: log.debug("Configuring SELinux on port: %s", str(secport)) diff --git a/src/lib389/lib389/utils.py b/src/lib389/lib389/utils.py index 963ed2324f..4f39678893 100644 --- a/src/lib389/lib389/utils.py +++ b/src/lib389/lib389/utils.py @@ -194,7 +194,7 @@ def wait(self): def selinux_present(): """ - Determine if selinux libraries are on a system, and if so, if we are in + Determine if SELinux libraries are on a system, and if so, if we are in a state to consume them (enabled, disabled). :returns: bool @@ -204,20 +204,20 @@ def selinux_present(): try: import selinux if selinux.is_selinux_enabled(): - # We have selinux, lets see if we are allowed to configure it. + # We have SELinux, lets see if we are allowed to configure it. # (just checking the uid for now - we may rather check if semanage command success) if os.geteuid() != 0: - log.info('Non privileged user cannot use semanage, will not relabel ports or files.' ) + log.info('Non-privileged user cannot use semanage, will not relabel ports or files.' ) elif not os.path.exists('/usr/sbin/semanage'): log.info('semanage command is not installed, will not relabel ports or files. Please install policycoreutils-python-utils.' ) else: status = True else: # We have the module, but it's disabled. - log.info('selinux is disabled, will not relabel ports or files.' ) + log.info('SELinux is disabled, will not relabel ports or files.' ) except ImportError: # No python module, so who knows what state we are in. - log.error('selinux python module not found, will not relabel files.' ) + log.error('SELinux python module not found, will not relabel files.' ) return status @@ -233,11 +233,11 @@ def selinux_restorecon(path): try: import selinux except ImportError: - log.debug('selinux python module not found, skipping relabel path %s' % path) + log.debug('SELinux python module not found, skipping relabel path %s' % path) return if not selinux.is_selinux_enabled(): - log.debug('selinux is disabled, skipping relabel path %s' % path) + log.debug('SELinux is disabled, skipping relabel path %s' % path) return try: @@ -320,7 +320,7 @@ def selinux_label_file(path, label): rc = 0 for i in range(5): try: - log.debug(f"Setting label {label} in SELinux file context {path}. Attempt {i}") + log.debug(f"Setting label {label} in SELinux file context {path}. Attempt {i}") result = subprocess.run(["semanage", "fcontext", "-a", "-t", label, path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -375,7 +375,7 @@ def selinux_clean_ports_label(): def _get_selinux_port_policies(port): - """Get a list of selinux port policies for the specified port, 'tcp' protocol and + """Get a list of SELinux port policies for the specified port, 'tcp' protocol and excluding 'unreserved_port_t', 'reserved_port_t', 'ephemeral_port_t' labels""" # [2:] - cut first lines containing the headers. [:-1] - empty line @@ -413,11 +413,11 @@ def selinux_label_port(port, remove_label=False): try: import selinux except ImportError: - log.debug('selinux python module not found, skipping port labeling.') + log.debug('SELinux python module not found, skipping port labeling.') return if not selinux_present(): - log.debug('selinux is disabled, skipping port relabel') + log.debug('SELinux is disabled, skipping port relabel') return # We only label ports that ARE NOT in the default policy that comes with @@ -618,7 +618,7 @@ def valgrind_enable(sbin_dir, wrapper=None): (making a backup of the original ns-slapd binary). The script calling valgrind_enable() must be run as the 'root' user - as selinux needs to be disabled for valgrind to work + as SELinux needs to be disabled for valgrind to work The server instance(s) should be stopped prior to calling this function. Then after calling valgrind_enable(): @@ -685,7 +685,7 @@ def valgrind_enable(sbin_dir, wrapper=None): raise IOError('failed to copy valgrind wrapper to ns-slapd, error: %s' % e.strerror) - # Disable selinux + # Disable SELinux if os.geteuid() == 0: os.system('setenforce 0') @@ -709,7 +709,7 @@ def valgrind_disable(sbin_dir): Restore the ns-slapd binary to its original state - the server instances are expected to be stopped. - Note - selinux is enabled at the end of this process. + Note - SELinux is enabled at the end of this process. :param sbin_dir - the location of the ns-slapd binary (e.g. /usr/sbin) :raise ValueError @@ -742,7 +742,7 @@ def valgrind_disable(sbin_dir): raise ValueError('Failed to delete backup ns-slapd, error: %s' % e.strerror) - # Enable selinux + # Enable SELinux if os.geteuid() == 0: os.system('setenforce 1')