From 45463c7c1f59b8406e23509f53c6e8bfdc0fc7fd Mon Sep 17 00:00:00 2001 From: William Brown Date: Feb 02 2018 05:35:35 +0000 Subject: Ticket 49544 - cli release preperation Bug Description: Improvements to the cli getting ready for user testing. Fixes for output rendering (verbose vs normal), automatic help display, raising assertion messages properly during setup when constraints are violated, capturing output correctly from subcommands. Fix Description: Improve the logging handler by wrapping a custom setup function that can purge and reset handlers. Add automatic help display if not action selected. Add assert_c for compiled asserts. python removes assert in optimised builds, and we need custom messages for the frontend anyway. Some commands would display to stderr, capture that. https://pagure.io/389-ds-base/issue/49544 Author: wibrown Review by: spichugi (thanks) --- diff --git a/src/lib389/cli/dsconf b/src/lib389/cli/dsconf index b13183c..23a1c6f 100755 --- a/src/lib389/cli/dsconf +++ b/src/lib389/cli/dsconf @@ -32,7 +32,7 @@ from lib389.cli_base import disconnect_instance, connect_instance from lib389.cli_base.dsrc import dsrc_to_ldap, dsrc_arg_concat -log = logging.getLogger("dsconf") +from lib389.cli_base import reset_get_logger if __name__ == '__main__': @@ -78,11 +78,7 @@ if __name__ == '__main__': args = parser.parse_args() - if args.verbose: - log.setLevel(logging.DEBUG) - else: - # We aren't verbose, so fix our formatter up to be more minimal ... - log.setLevel(logging.INFO) + log = reset_get_logger('dsconf', args.verbose) log.debug("The 389 Directory Server Configuration Tool") # Leave this comment here: UofA let me take this code with me provided @@ -101,8 +97,8 @@ if __name__ == '__main__': # Assert we have a resources to work on. if not hasattr(args, 'func'): - log.error("No resource provided to act upon") - log.error("USAGE: dsconf [options] [action options]") + log.error("No action provided, here is some --help.") + parser.print_help() sys.exit(1) # Connect diff --git a/src/lib389/cli/dscreate b/src/lib389/cli/dscreate index 4743003..9664799 100755 --- a/src/lib389/cli/dscreate +++ b/src/lib389/cli/dscreate @@ -12,13 +12,9 @@ import argparse import logging import sys -# This has to happen before we import DirSrv else it tramples our config ... :( -logging.basicConfig(format='%(message)s') - from lib389 import DirSrv from lib389.cli_ctl import instance as cli_instance - -log = logging.getLogger("dscreate") +from lib389.cli_base import reset_get_logger if __name__ == '__main__': @@ -47,10 +43,7 @@ By setting this value you acknowledge and take responsibility for the fact this args = parser.parse_args() - if args.verbose: - log.setLevel(logging.DEBUG) - else: - log.setLevel(logging.INFO) + log = reset_get_logger("dscreate", args.verbose) log.debug("The 389 Directory Server Creation Tool") # Leave this comment here: UofA let me take this code with me provided @@ -59,6 +52,12 @@ By setting this value you acknowledge and take responsibility for the fact this log.debug("Called with: %s", args) + # Assert we have a resources to work on. + if not hasattr(args, 'func'): + log.error("No action provided, here is some --help.") + parser.print_help() + sys.exit(1) + inst = DirSrv(verbose=args.verbose) result = False diff --git a/src/lib389/cli/dsctl b/src/lib389/cli/dsctl index 02a1cff..7f37f4c 100755 --- a/src/lib389/cli/dsctl +++ b/src/lib389/cli/dsctl @@ -19,9 +19,7 @@ from lib389.cli_base import _get_arg from lib389 import DirSrv from lib389.cli_ctl import instance as cli_instance from lib389.cli_ctl import dbtasks as cli_dbtasks -from lib389.cli_base import disconnect_instance - -log = logging.getLogger("dsctl") +from lib389.cli_base import disconnect_instance, reset_get_logger if __name__ == '__main__': @@ -46,10 +44,7 @@ if __name__ == '__main__': args = parser.parse_args() - if args.verbose: - log.setLevel(logging.DEBUG) - else: - log.setLevel(logging.INFO) + log = reset_get_logger('dsctl', args.verbose) log.debug("The 389 Directory Server Administration Tool") # Leave this comment here: UofA let me take this code with me provided @@ -60,8 +55,8 @@ if __name__ == '__main__': # Assert we have a resources to work on. if not hasattr(args, 'func'): - log.error("No action provided") - log.error("USAGE: dsctl [options] [action options]") + log.error("No action provided, here is some --help.") + parser.print_help() sys.exit(1) # Connect @@ -71,9 +66,18 @@ if __name__ == '__main__': result = True # Allocate the instance based on name - insts = inst.list(serverid=args.instance) + insts = [] + if args.verbose: + insts = inst.list(serverid=args.instance) + else: + try: + insts = inst.list(serverid=args.instance) + except PermissionError: + log.error("Unable to access instance information. Are you running as root or dirsrv?") + sys.exit(1) if len(insts) != 1: - raise ValueError("No such instance %s" % args.instance) + log.error("No such instance %s" % args.instance) + sys.exit(1) inst.allocate(insts[0]) log.debug('Instance allocated') diff --git a/src/lib389/cli/dsidm b/src/lib389/cli/dsidm index 9bb21e1..4581cb3 100755 --- a/src/lib389/cli/dsidm +++ b/src/lib389/cli/dsidm @@ -25,12 +25,10 @@ from lib389.cli_idm import group as cli_group from lib389.cli_idm import posixgroup as cli_posixgroup from lib389.cli_idm import user as cli_user -from lib389.cli_base import connect_instance, disconnect_instance +from lib389.cli_base import connect_instance, disconnect_instance, reset_get_logger from lib389.cli_base.dsrc import dsrc_to_ldap, dsrc_arg_concat -log = logging.getLogger("dsidm") - if __name__ == '__main__': defbase = ldap.get_option(ldap.OPT_DEFBASE) @@ -72,10 +70,7 @@ if __name__ == '__main__': # argcomplete.autocomplete(parser) args = parser.parse_args() - if args.verbose: - log.setLevel(logging.DEBUG) - else: - log.setLevel(logging.INFO) + log = reset_get_logger('dsidm', args.verbose) log.debug("The 389 Directory Server Identity Manager") # Leave this comment here: UofA let me take this code with me provided @@ -92,6 +87,12 @@ if __name__ == '__main__': log.debug("Called with: %s", args) log.debug("Instance details: %s" % dsrc_inst) + # Assert we have a resources to work on. + if not hasattr(args, 'func'): + log.error("No action provided, here is some --help.") + parser.print_help() + sys.exit(1) + if dsrc_inst['basedn'] is None: log.error("Must provide a basedn!") diff --git a/src/lib389/lib389/__init__.py b/src/lib389/lib389/__init__.py index 5509c5a..f15e183 100644 --- a/src/lib389/lib389/__init__.py +++ b/src/lib389/lib389/__init__.py @@ -1200,17 +1200,19 @@ class DirSrv(SimpleLDAPObject, object): # This means the server is probably ready to go .... env = {} if self.has_asan(): - self.log.error("NOTICE: Starting instance with ASAN options") - self.log.error("This is probably not what you want. Please contact support.") - self.log.error("ASAN options will be copied from your environment") + self.log.warning("WARNING: Starting instance with ASAN options. This is probably not what you want. Please contact support.") + self.log.info("INFO: ASAN options will be copied from your environment") env['ASAN_SYMBOLIZER_PATH'] = "/usr/bin/llvm-symbolizer" env['ASAN_OPTIONS'] = "symbolize=1 detect_deadlocks=1 log_path=%s/ns-slapd-%s.asan" % (self.ds_paths.run_dir, self.serverid) env.update(os.environ) - subprocess.check_call(["%s/ns-slapd" % self.get_sbin_dir(), - "-D", - self.ds_paths.config_dir, - "-i", - self.ds_paths.pid_file], env=env) + try: + output = subprocess.check_output(["%s/ns-slapd" % self.get_sbin_dir(), + "-D", + self.ds_paths.config_dir, + "-i", + self.ds_paths.pid_file], env=env, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError: + self.log.error(output) count = timeout pid = pid_from_file(self.ds_paths.pid_file) while (pid is None) and count > 0: diff --git a/src/lib389/lib389/cli_ctl/instance.py b/src/lib389/lib389/cli_ctl/instance.py index 42f1d0f..507a457 100644 --- a/src/lib389/lib389/cli_ctl/instance.py +++ b/src/lib389/lib389/cli_ctl/instance.py @@ -47,35 +47,6 @@ def instance_status(inst, log, args): log.info("Instance is not running") def instance_create(inst, log, args): - if not args.ack: - sys.exit(0) - else: - log.info(""" - _________________________________________ -/ If this is not what you want, press \\ -\ ctrl-c now ... / - ----------------------------------------- - \\ / \\ //\\ - \\ |\\___/| / \\// \\\\ - /0 0 \\__ / // | \\ \\ - / / \\/_/ // | \\ \\ - @_^_@'/ \\/_ // | \\ \\ - //_^_/ \\/_ // | \\ \\ - ( //) | \\/// | \\ \\ - ( / /) _|_ / ) // | \\ _\\ - ( // /) '/,_ _ _/ ( ; -. | _ _\\.-~ .-~~~^-. - (( / / )) ,-{ _ `-.|.-~-. .~ `. - (( // / )) '/\\ / ~-. _ .-~ .-~^-. \\ - (( /// )) `. { } / \\ \\ - (( / )) .----~-.\\ \\-' .~ \\ `. \\^-. - ///.----..> \\ _ -~ `. ^-` ^-_ - ///-._ _ _ _ _ _ _}^ - - - - ~ ~-- ,.-~ - /.-~ - """) - for i in range(1,6): - log.info('%s ...' % (5 - int(i))) - time.sleep(1) - log.info('Launching ...') if args.containerised: log.debug("Containerised features requested.") sd = SetupDs(args.verbose, args.dryrun, log, args.containerised) @@ -117,30 +88,13 @@ def instance_example(inst, log, args): def instance_remove(inst, log, args): if not args.ack: + log.info("""Not removing: if you are sure, add --doit""") sys.exit(0) else: log.info(""" - _________________________________________ -/ If this is not what you want, press \\ -\ ctrl-c now ... / - ----------------------------------------- - \\ / \\ //\\ - \\ |\\___/| / \\// \\\\ - /0 0 \\__ / // | \\ \\ - / / \\/_/ // | \\ \\ - @_^_@'/ \\/_ // | \\ \\ - //_^_/ \\/_ // | \\ \\ - ( //) | \\/// | \\ \\ - ( / /) _|_ / ) // | \\ _\\ - ( // /) '/,_ _ _/ ( ; -. | _ _\\.-~ .-~~~^-. - (( / / )) ,-{ _ `-.|.-~-. .~ `. - (( // / )) '/\\ / ~-. _ .-~ .-~^-. \\ - (( /// )) `. { } / \\ \\ - (( / )) .----~-.\\ \\-' .~ \\ `. \\^-. - ///.----..> \\ _ -~ `. ^-` ^-_ - ///-._ _ _ _ _ _ _}^ - - - - ~ ~-- ,.-~ - /.-~ - """) +About to remove instance %s! +If this is not what you want, press ctrl-c now ... + """ % inst.serverid) for i in range(1,6): log.info('%s ...' % (5 - int(i))) time.sleep(1) diff --git a/src/lib389/lib389/cli_idm/user.py b/src/lib389/lib389/cli_idm/user.py index b2f71d9..ef6921f 100644 --- a/src/lib389/lib389/cli_idm/user.py +++ b/src/lib389/lib389/cli_idm/user.py @@ -89,7 +89,7 @@ def create_parser(subparsers): create_parser = subcommands.add_parser('create', help='create') create_parser.set_defaults(func=create) - populate_attr_arguments(create_parser, MUST_ATTRIBUTES) + populate_attr_arguments(create_parser, SINGULAR._must_attributes) delete_parser = subcommands.add_parser('delete', help='deletes the object') delete_parser.set_defaults(func=delete) diff --git a/src/lib389/lib389/instance/setup.py b/src/lib389/lib389/instance/setup.py index fa5d99b..4b64b66 100644 --- a/src/lib389/lib389/instance/setup.py +++ b/src/lib389/lib389/instance/setup.py @@ -31,6 +31,7 @@ from lib389.instance.options import General2Base, Slapd2Base # The poc backend api from lib389.backend import Backends from lib389.utils import ( + assert_c, is_a_dn, ensure_bytes, ensure_str, @@ -116,7 +117,7 @@ class SetupDs(object): pass def _validate_ds_2_config(self, config): - assert config.has_section('slapd') + assert_c(config.has_section('slapd'), "Missing configuration section [slapd]") # Extract them in a way that create can understand. general_options = General2Base(self.log) @@ -154,16 +155,15 @@ class SetupDs(object): # This will move to lib389 later. # Check we have all the sections. # Make sure we have needed keys. - assert(config.has_section('general')) - assert(config.has_option('general', 'config_version')) - assert(config.get('general', 'config_version') >= '2') + assert_c(config.has_section('general'), "Missing configuration section [general]") + assert_c(config.has_option('general', 'config_version'), "Missing configuration config_version in section [general]") + assert_c(config.get('general', 'config_version') >= '2', "config_version in section [general] should be 2 or greater") if config.get('general', 'config_version') == '2': # Call our child api to validate itself from the inf. self._validate_config_2(config) return self._validate_ds_2_config(config) else: - self.log.info("Failed to validate configuration version.") - assert(False) + assert_c(False, "Unsupported config_version in section [general]") def create_from_inf(self, inf_path): """ @@ -195,40 +195,40 @@ class SetupDs(object): def _prepare_ds(self, general, slapd, backends): - assert(general['defaults'] is not None) + assert_c(general['defaults'] is not None, "Configuration defaults in section [general] not found") if self.verbose: self.log.info("PASSED: using config settings %s" % general['defaults']) # Validate our arguments. - assert(slapd['user'] is not None) + assert_c(slapd['user'] is not None, "Configuration user in section [slapd] not found") # check the user exists - assert(pwd.getpwnam(slapd['user'])) + assert_c(pwd.getpwnam(slapd['user']), "user %s not found on system" % slapd['user']) slapd['user_uid'] = pwd.getpwnam(slapd['user']).pw_uid - assert(slapd['group'] is not None) - assert(grp.getgrnam(slapd['group'])) + assert_c(slapd['group'] is not None, "Configuration group in section [slapd] not found") + assert_c(grp.getgrnam(slapd['group']), "group %s not found on system" % slapd['group']) slapd['group_gid'] = grp.getgrnam(slapd['group']).gr_gid # check this group exists # Check that we are running as this user / group, or that we are root. - assert(os.geteuid() == 0 or getpass.getuser() == slapd['user']) + assert_c(os.geteuid() == 0 or getpass.getuser() == slapd['user'], "Not running as user root or %s, may not have permission to continue" % slapd['user']) if self.verbose: self.log.info("PASSED: user / group checking") - assert(general['full_machine_name'] is not None) - assert(general['strict_host_checking'] is not None) + assert_c(general['full_machine_name'] is not None, "Configuration full_machine_name in section [general] not found") + assert_c(general['strict_host_checking'] is not None, "Configuration strict_host_checking in section [general] not found") if general['strict_host_checking'] is True: # Check it resolves with dns - assert(socket.gethostbyname(general['full_machine_name'])) + assert_c(socket.gethostbyname(general['full_machine_name']), "Strict hostname check failed. Check your DNS records for %s" % general['full_machine_name']) if self.verbose: self.log.info("PASSED: Hostname strict checking") - assert(slapd['prefix'] is not None) + assert_c(slapd['prefix'] is not None, "Configuration prefix in section [slapd] not found") if (slapd['prefix'] != ""): - assert(os.path.exists(slapd['prefix'])) + assert_c(os.path.exists(slapd['prefix']), "Prefix location '%s' not found" % slapd['prefix']) if self.verbose: self.log.info("PASSED: prefix checking") # We need to know the prefix before we can do the instance checks - assert(slapd['instance_name'] is not None) + assert_c(slapd['instance_name'] is not None, "Configuration instance_name in section [slapd] not found") # Check if the instance exists or not. # Should I move this import? I think this prevents some recursion from lib389 import DirSrv @@ -236,15 +236,15 @@ class SetupDs(object): ds.containerised = self.containerised ds.prefix = slapd['prefix'] insts = ds.list(serverid=slapd['instance_name']) - assert(len(insts) == 0) + assert_c(len(insts) == 0, "Another instance named '%s' may already exist" % slapd['instance_name']) if self.verbose: self.log.info("PASSED: instance checking") - assert(slapd['root_dn'] is not None) + assert_c(slapd['root_dn'] is not None, "Configuration root_dn in section [slapd] not found") # Assert this is a valid DN - assert(is_a_dn(slapd['root_dn'])) - assert(slapd['root_password'] is not None) + assert_c(is_a_dn(slapd['root_dn']), "root_dn in section [slapd] is not a well formed LDAP DN") + assert_c(slapd['root_password'] is not None, "Configuration root_password in section [slapd] not found") # Check if pre-hashed or not. # !!!!!!!!!!!!!! @@ -268,17 +268,17 @@ class SetupDs(object): self.log.info("INFO: temp root password set to %s" % self._raw_secure_password) self.log.info("PASSED: root user checking") - assert(slapd['port'] is not None) - assert(socket_check_open('::1', slapd['port']) is False) + assert_c(slapd['port'] is not None, "Configuration port in section [slapd] not found") + assert_c(socket_check_open('::1', slapd['port']) is False, "port %s is already in use" % slapd['port']) # We enable secure port by default. - assert(slapd['secure_port'] is not None) - assert(socket_check_open('::1', slapd['secure_port']) is False) + assert_c(slapd['secure_port'] is not None, "Configuration secure_port in section [slapd] not found") + assert_c(socket_check_open('::1', slapd['secure_port']) is False, "secure_port %s is already in use" % slapd['secure_port']) if self.verbose: self.log.info("PASSED: network avaliability checking") - # Make assertions of the paths? + # Make assert_cions of the paths? - # Make assertions of the backends? + # Make assert_cions of the backends? def create_from_args(self, general, slapd, backends=[], extra=None): """ @@ -286,29 +286,27 @@ class SetupDs(object): """ # Check we have privs to run - if self.verbose: - self.log.info("READY: preparing installation for %s" % slapd['instance_name']) + self.log.info("READY: Preparing installation for %s" % slapd['instance_name']) self._prepare_ds(general, slapd, backends) # Call our child api to prepare itself. self._prepare(extra) - if self.verbose: - self.log.info("READY: beginning installation for %s" % slapd['instance_name']) + self.log.info("READY: Beginning installation for %s" % slapd['instance_name']) if self.dryrun: - self.log.info("NOOP: dry run requested") + self.log.info("NOOP: Dry run requested") else: # Actually trigger the installation. self._install_ds(general, slapd, backends) # Call the child api to do anything it needs. self._install(extra) - self.log.info("FINISH: completed installation for %s" % slapd['instance_name']) + self.log.info("FINISH: Completed installation for %s" % slapd['instance_name']) def _install_ds(self, general, slapd, backends): """ Actually install the Ds from the dicts provided. - You should never call this directly, as it bypasses assertions. + You should never call this directly, as it bypasses assert_cions. """ # register the instance to /etc/sysconfig # We do this first so that we can trick remove-ds.pl if needed. @@ -430,7 +428,8 @@ class SetupDs(object): ds_instance.allocate(args) # Does this work? - assert(ds_instance.exists()) + assert_c(ds_instance.exists(), "Instance failed to install, does not exist when expected") + # Create a certificate database. tlsdb = NssSsl(dbpath=slapd['cert_dir']) diff --git a/src/lib389/lib389/nss_ssl.py b/src/lib389/lib389/nss_ssl.py index 1cb22ef..f8f2f2f 100644 --- a/src/lib389/lib389/nss_ssl.py +++ b/src/lib389/lib389/nss_ssl.py @@ -19,7 +19,8 @@ import time import shutil import logging # from nss import nss -from subprocess import check_call, check_output +import subprocess +from subprocess import check_output from lib389.passwd import password_generate from lib389.utils import ensure_str, ensure_bytes @@ -132,7 +133,7 @@ class NssSsl(object): cmd = ['/usr/bin/certutil', '-N', '-d', self._certdb, '-f', '%s/%s' % (self._certdb, PWD_TXT)] self._generate_noise('%s/noise.txt' % self._certdb) self.log.debug("nss cmd: %s" % cmd) - result = ensure_str(check_output(cmd)) + result = ensure_str(check_output(cmd, stderr=subprocess.STDOUT)) self.log.debug("nss output: %s" % result) return True @@ -183,7 +184,7 @@ class NssSsl(object): '%s/%s' % (self._certdb, PWD_TXT), ] self.log.debug("nss cmd: %s" % cmd) - result = ensure_str(check_output(cmd)) + result = ensure_str(check_output(cmd, stderr=subprocess.STDOUT)) self.log.debug("nss output: %s" % result) # Now extract the CAcert to a well know place. # This allows us to point the cacert dir here and it "just works" @@ -197,10 +198,10 @@ class NssSsl(object): '-a', ] self.log.debug("nss cmd: %s" % cmd) - certdetails = check_output(cmd) + certdetails = check_output(cmd, stderr=subprocess.STDOUT) with open('%s/ca.crt' % self._certdb, 'w') as f: f.write(ensure_str(certdetails)) - check_output(['/usr/sbin/cacertdir_rehash', self._certdb]) + check_output(['/usr/sbin/cacertdir_rehash', self._certdb], stderr=subprocess.STDOUT) return True def _rsa_cert_list(self): @@ -212,7 +213,7 @@ class NssSsl(object): '-f', '%s/%s' % (self._certdb, PWD_TXT), ] - result = ensure_str(check_output(cmd)) + result = ensure_str(check_output(cmd, stderr=subprocess.STDOUT)) # We can skip the first few lines. They are junk # IE ['', @@ -239,7 +240,7 @@ class NssSsl(object): '-f', '%s/%s' % (self._certdb, PWD_TXT), ] - result = ensure_str(check_output(cmd)) + result = ensure_str(check_output(cmd, stderr=subprocess.STDOUT)) lines = result.split('\n')[1:-1] key_list = [] @@ -343,7 +344,7 @@ class NssSsl(object): ] self.log.debug("nss cmd: %s" % cmd) - result = ensure_str(check_output(cmd)) + result = ensure_str(check_output(cmd, stderr=subprocess.STDOUT)) self.log.debug("nss output: %s" % result) return True @@ -391,7 +392,7 @@ class NssSsl(object): ] self.log.debug("nss cmd: %s" % cmd) - check_call(cmd) + check_output(cmd, stderr=subprocess.STDOUT) return csr_path @@ -402,7 +403,7 @@ class NssSsl(object): crt_path = 'crt'.join(csr_path.rsplit('csr', 1)) ca_path = '%s/ca.crt' % self._certdb - check_call([ + check_output([ '/usr/bin/certutil', '-C', '-d', @@ -413,7 +414,7 @@ class NssSsl(object): '-i', csr_path, '-o', crt_path, '-c', CA_NAME, - ]) + ], stderr=subprocess.STDOUT) return (ca_path, crt_path) @@ -422,8 +423,8 @@ class NssSsl(object): to our database. """ shutil.copyfile(ca, '%s/ca.crt' % self._certdb) - check_output(['/usr/sbin/cacertdir_rehash', self._certdb]) - check_call([ + check_output(['/usr/sbin/cacertdir_rehash', self._certdb], stderr=subprocess.STDOUT) + check_output([ '/usr/bin/certutil', '-A', '-n', CA_NAME, @@ -433,8 +434,8 @@ class NssSsl(object): '-d', self._certdb, '-f', '%s/%s' % (self._certdb, PWD_TXT), - ]) - check_call([ + ], stderr=subprocess.STDOUT) + check_output([ '/usr/bin/certutil', '-A', '-n', CERT_NAME, @@ -444,14 +445,14 @@ class NssSsl(object): '-d', self._certdb, '-f', '%s/%s' % (self._certdb, PWD_TXT), - ]) - check_call([ + ], stderr=subprocess.STDOUT) + check_output([ '/usr/bin/certutil', '-V', '-d', self._certdb, '-n', CERT_NAME, '-u', 'YCV' - ]) + ], stderr=subprocess.STDOUT) def create_rsa_user(self, name): """ @@ -494,21 +495,21 @@ class NssSsl(object): '%s/%s' % (self._certdb, PWD_TXT), ] - result = ensure_str(check_output(cmd)) + result = ensure_str(check_output(cmd, stderr=subprocess.STDOUT)) self.log.debug("nss output: %s" % result) # Now extract this into PEM files that we can use. # pk12util -o user-william.p12 -d . -k pwdfile.txt -n user-william -W '' - check_call([ + check_output([ 'pk12util', '-d', self._certdb, '-o', '%s/%s%s.p12' % (self._certdb, USER_PREFIX, name), '-k', '%s/%s' % (self._certdb, PWD_TXT), '-n', '%s%s' % (USER_PREFIX, name), '-W', '""' - ]) + ], stderr=subprocess.STDOUT) # openssl pkcs12 -in user-william.p12 -passin pass:'' -out file.pem -nocerts -nodes # Extract the key - check_call([ + check_output([ 'openssl', 'pkcs12', '-in', '%s/%s%s.p12' % (self._certdb, USER_PREFIX, name), @@ -516,9 +517,9 @@ class NssSsl(object): '-out', '%s/%s%s.key' % (self._certdb, USER_PREFIX, name), '-nocerts', '-nodes' - ]) + ], stderr=subprocess.STDOUT) # Extract the cert - check_call([ + check_output([ 'openssl', 'pkcs12', '-in', '%s/%s%s.p12' % (self._certdb, USER_PREFIX, name), @@ -527,16 +528,16 @@ class NssSsl(object): '-nokeys', '-clcerts', '-nodes' - ]) + ], stderr=subprocess.STDOUT) # Convert the cert for userCertificate attr - check_call([ + check_output([ 'openssl', 'x509', '-inform', 'PEM', '-outform', 'DER', '-in', '%s/%s%s.crt' % (self._certdb, USER_PREFIX, name), '-out', '%s/%s%s.der' % (self._certdb, USER_PREFIX, name), - ]) + ], stderr=subprocess.STDOUT) return subject diff --git a/src/lib389/lib389/utils.py b/src/lib389/lib389/utils.py index 74a7d21..c74ecfc 100644 --- a/src/lib389/lib389/utils.py +++ b/src/lib389/lib389/utils.py @@ -981,3 +981,11 @@ def pseudolocalize(string): except KeyError: pseudo_string += char return pseudo_string + +def assert_c(condition, msg="Assertion Failed"): + """This is the same as assert, but assert is compiled out + when optimisation is enabled. This prevents compiling out. + """ + if not condition: + raise AssertionError(msg) +