From 446107f1cbb04636826973c25a76dd94aead1ab7 Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:26:48 +0100 Subject: [PATCH 01/17] ansible_ipa_server: Fix ansible-test fake execution test findings All imports that are only available after installing IPA need to be in a try exception clause to be able to pass the fake execution test. The old workaround "if 'ansible.executor' in sys.modules:" is not working with this test anymore. If the imports can not be done, all used and needed attributes are defines with the value None. The new function check_imports has been added to fail with module.fail_json if an import exception occured and ANSIBLE_IPA_SERVER_MODULE_IMPORT_ERROR is not None. This function needs to be called in all modules. The `copyright` date is extended with `-2022`. --- .../module_utils/ansible_ipa_server.py | 507 +++++++++--------- 1 file changed, 265 insertions(+), 242 deletions(-) diff --git a/roles/ipaserver/module_utils/ansible_ipa_server.py b/roles/ipaserver/module_utils/ansible_ipa_server.py index f1f4972b..6dec4bc2 100644 --- a/roles/ipaserver/module_utils/ansible_ipa_server.py +++ b/roles/ipaserver/module_utils/ansible_ipa_server.py @@ -3,9 +3,9 @@ # Authors: # Thomas Woerner # -# Based on ipa-client-install code +# Based on ipa-server-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -23,12 +23,12 @@ from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +__metaclass__ = type # pylint: disable=invalid-name __all__ = ["IPAChangeConf", "certmonger", "sysrestore", "root_logger", "ipa_generate_password", "run", "ScriptError", "services", "tasks", "errors", "x509", "DOMAIN_LEVEL_0", "MIN_DOMAIN_LEVEL", - "validate_domain_name", + "MAX_DOMAIN_LEVEL", "validate_domain_name", "no_matching_interface_for_ip_address_warning", "check_zone_overlap", "timeconf", "ntpinstance", "adtrust", "bindinstance", "ca", "dns", "httpinstance", "installutils", @@ -41,45 +41,42 @@ __all__ = ["IPAChangeConf", "certmonger", "sysrestore", "root_logger", "adtrustinstance", "IPAAPI_USER", "sync_time", "PKIIniLoader", "default_subject_base", "default_ca_subject_dn", "check_ldap_conf", "encode_certificate", "decode_certificate", - "check_available_memory", "getargspec", "get_min_idstart"] + "check_available_memory", "getargspec", "get_min_idstart", + "paths", "api", "ipautil", "adtrust_imported", "NUM_VERSION", + "time_service", "kra_imported", "dsinstance", "IPA_PYTHON_VERSION", + "NUM_VERSION"] import sys +import logging -# HACK: workaround for Ansible 2.9 -# https://github.com/ansible/ansible/issues/68361 -if 'ansible.executor' in sys.modules: - for attr in __all__: - setattr(sys.modules[__name__], attr, None) +# Import getargspec from inspect or provide own getargspec for +# Python 2 compatibility with Python 3.11+. +try: + from inspect import getargspec +except ImportError: + from collections import namedtuple + from inspect import getfullargspec -else: + # The code is copied from Python 3.10 inspect.py + # Authors: Ka-Ping Yee + # Yury Selivanov + ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults') - import logging + def getargspec(func): + args, varargs, varkw, defaults, kwonlyargs, _kwonlydefaults, \ + ann = getfullargspec(func) + if kwonlyargs or ann: + raise ValueError( + "Function has keyword-only parameters or annotations" + ", use inspect.signature() API which can support them") + return ArgSpec(args, varargs, varkw, defaults) + + +try: from contextlib import contextmanager as contextlib_contextmanager from ansible.module_utils import six import base64 - # Import getargspec from inspect or provide own getargspec for - # Python 2 compatibility with Python 3.11+. - try: - from inspect import getargspec - except ImportError: - from collections import namedtuple - from inspect import getfullargspec - - # The code is copied from Python 3.10 inspect.py - # Authors: Ka-Ping Yee - # Yury Selivanov - ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults') - - def getargspec(func): - args, varargs, varkw, defaults, kwonlyargs, _kwonlydefaults, \ - ann = getfullargspec(func) - if kwonlyargs or ann: - raise ValueError( - "Function has keyword-only parameters or annotations" - ", use inspect.signature() API which can support them") - return ArgSpec(args, varargs, varkw, defaults) - from ipapython.version import NUM_VERSION, VERSION if NUM_VERSION < 30201: @@ -211,223 +208,249 @@ else: raise Exception("freeipa version '%s' is too old" % VERSION) - logger = logging.getLogger("ipa-server-install") +except ImportError as _err: + ANSIBLE_IPA_SERVER_MODULE_IMPORT_ERROR = str(_err) - def setup_logging(): - # logger.setLevel(logging.DEBUG) - standard_logging_setup( - paths.IPASERVER_INSTALL_LOG, verbose=False, debug=False, - filemode='a', console_format='%(message)s') + for attr in __all__: + setattr(sys.modules[__name__], attr, None) +else: + ANSIBLE_IPA_SERVER_MODULE_IMPORT_ERROR = None - @contextlib_contextmanager - def redirect_stdout(stream): - sys.stdout = stream + +logger = logging.getLogger("ipa-server-install") + + +def setup_logging(): + # logger.setLevel(logging.DEBUG) + standard_logging_setup( + paths.IPASERVER_INSTALL_LOG, verbose=False, debug=False, + filemode='a', console_format='%(message)s') + + +@contextlib_contextmanager +def redirect_stdout(stream): + sys.stdout = stream + try: + yield stream + finally: + sys.stdout = sys.__stdout__ + + +class AnsibleModuleLog(): + def __init__(self, module): + self.module = module + _ansible_module_log = self + + class AnsibleLoggingHandler(logging.Handler): + def emit(self, record): + _ansible_module_log.write(self.format(record)) + + self.logging_handler = AnsibleLoggingHandler() + logger.setLevel(logging.DEBUG) + logger.root.addHandler(self.logging_handler) + + def close(self): + self.flush() + + def flush(self): + pass + + def log(self, msg): + # self.write(msg+"\n") + self.write(msg) + + def debug(self, msg): + self.module.debug(msg) + + def info(self, msg): + self.module.debug(msg) + + @staticmethod + def isatty(): + return False + + def write(self, msg): + self.module.debug(msg) + # self.module.warn(msg) + + +# pylint: disable=too-few-public-methods, useless-object-inheritance +# pylint: disable=too-many-instance-attributes +class options_obj(object): # pylint: disable=invalid-name + def __init__(self): + self._replica_install = False + self.dnssec_master = False # future unknown + self.disable_dnssec_master = False # future unknown + self.domainlevel = MAX_DOMAIN_LEVEL # deprecated + self.domain_level = self.domainlevel # deprecated + self.interactive = False + self.unattended = not self.interactive + + # def __getattribute__(self, attr): + # logger.info(" <-- Accessing options.%s" % attr) + # return super(options_obj, self).__getattribute__(attr) + + # def __getattr__(self, attr): + # logger.info(" --> Adding missing options.%s" % attr) + # setattr(self, attr, None) + # return getattr(self, attr) + + def knobs(self): + for name in self.__dict__: + yield self, name + + +# pylint: enable=too-few-public-methods, useless-object-inheritance + + +# pylint: enable=too-many-instance-attributes +options = options_obj() +installer = options + +# pylint: disable=attribute-defined-outside-init + +# ServerMasterInstall +options.add_sids = True +options.add_agents = False + +# Installable +options.uninstalling = False + +# ServerInstallInterface +options.description = "Server" + +options.kinit_attempts = 1 +options.fixed_primary = True +options.permit = False +options.enable_dns_updates = False +options.no_krb5_offline_passwords = False +options.preserve_sssd = False +options.no_sssd = False + +# ServerMasterInstall +options.force_join = False +options.servers = None +options.no_wait_for_dns = True +options.host_password = None +options.keytab = None +options.setup_ca = True +# always run sidgen task and do not allow adding agents on first master +options.add_sids = True +options.add_agents = False + +# ADTrustInstallInterface +# no_msdcs is deprecated +options.no_msdcs = False + +# For pylint +options.external_cert_files = None +options.dirsrv_cert_files = None + +# Uninstall +options.ignore_topology_disconnect = False +options.ignore_last_of_role = False + +# pylint: enable=attribute-defined-outside-init + + +# pylint: disable=invalid-name +def api_Backend_ldap2(host_name, setup_ca, connect=False): + # we are sure we have the configuration file ready. + cfg = dict(context='installer', confdir=paths.ETC_IPA, in_server=True, + host=host_name) + if setup_ca: + # we have an IPA-integrated CA + cfg['ca_host'] = host_name + + api.bootstrap(**cfg) + api.finalize() + if connect: + api.Backend.ldap2.connect() + + +# pylint: enable=invalid-name + + +def ds_init_info(ansible_log, fstore, domainlevel, dirsrv_config_file, + realm_name, host_name, domain_name, dm_password, + idstart, idmax, subject_base, ca_subject, + _no_hbac_allow, dirsrv_pkcs12_info, no_pkinit): + + if not options.external_cert_files: + _ds = dsinstance.DsInstance(fstore=fstore, domainlevel=domainlevel, + config_ldif=dirsrv_config_file) + _ds.set_output(ansible_log) + + if options.dirsrv_cert_files: + _dirsrv_pkcs12_info = dirsrv_pkcs12_info + else: + _dirsrv_pkcs12_info = None + + with redirect_stdout(ansible_log): + _ds.init_info(realm_name, host_name, domain_name, dm_password, + subject_base, ca_subject, idstart, idmax, + # hbac_allow=not no_hbac_allow, + _dirsrv_pkcs12_info, setup_pkinit=not no_pkinit) + else: + _ds = dsinstance.DsInstance(fstore=fstore, domainlevel=domainlevel) + _ds.set_output(ansible_log) + + with redirect_stdout(ansible_log): + _ds.init_info(realm_name, host_name, domain_name, dm_password, + subject_base, ca_subject, 1101, 1100, None, + setup_pkinit=not no_pkinit) + + return _ds + + +def ansible_module_get_parsed_ip_addresses(ansible_module, + param='ip_addresses'): + ip_addrs = [] + for _ip in ansible_module.params.get(param): try: - yield stream - finally: - sys.stdout = sys.__stdout__ + ip_parsed = ipautil.CheckedIPAddress(_ip) + except Exception as err: + ansible_module.fail_json( + msg="Invalid IP Address %s: %s" % (_ip, err)) + ip_addrs.append(ip_parsed) + return ip_addrs - class AnsibleModuleLog(): - def __init__(self, module): - self.module = module - _ansible_module_log = self - class AnsibleLoggingHandler(logging.Handler): - def emit(self, record): - _ansible_module_log.write(self.format(record)) +def encode_certificate(cert): + """ + Encode a certificate using base64. - self.logging_handler = AnsibleLoggingHandler() - logger.setLevel(logging.DEBUG) - logger.root.addHandler(self.logging_handler) + It also takes FreeIPA and Python versions into account. + """ + if isinstance(cert, (str, bytes)): + encoded = base64.b64encode(cert) + else: + encoded = base64.b64encode(cert.public_bytes(Encoding.DER)) + if not six.PY2: + encoded = encoded.decode('ascii') + return encoded - def close(self): - self.flush() - def flush(self): - pass +def decode_certificate(cert): + """ + Decode a certificate using base64. - def log(self, msg): - # self.write(msg+"\n") - self.write(msg) + It also takes FreeIPA versions into account and returns a + IPACertificate for newer IPA versions. + """ + if hasattr(x509, "IPACertificate"): + cert = cert.strip() + if not cert.startswith("-----BEGIN CERTIFICATE-----"): + cert = "-----BEGIN CERTIFICATE-----\n" + cert + if not cert.endswith("-----END CERTIFICATE-----"): + cert += "\n-----END CERTIFICATE-----" - def debug(self, msg): - self.module.debug(msg) + cert = certificate_loader(cert.encode('utf-8')) + else: + cert = base64.b64decode(cert) + return cert - def info(self, msg): - self.module.debug(msg) - @staticmethod - def isatty(): - return False - - def write(self, msg): - self.module.debug(msg) - # self.module.warn(msg) - - # pylint: disable=too-few-public-methods, useless-object-inheritance - # pylint: disable=too-many-instance-attributes - class options_obj(object): # pylint: disable=invalid-name - def __init__(self): - self._replica_install = False - self.dnssec_master = False # future unknown - self.disable_dnssec_master = False # future unknown - self.domainlevel = MAX_DOMAIN_LEVEL # deprecated - self.domain_level = self.domainlevel # deprecated - self.interactive = False - self.unattended = not self.interactive - - # def __getattribute__(self, attr): - # logger.info(" <-- Accessing options.%s" % attr) - # return super(options_obj, self).__getattribute__(attr) - - # def __getattr__(self, attr): - # logger.info(" --> Adding missing options.%s" % attr) - # setattr(self, attr, None) - # return getattr(self, attr) - - def knobs(self): - for name in self.__dict__: - yield self, name - - # pylint: enable=too-few-public-methods, useless-object-inheritance - - # pylint: enable=too-many-instance-attributes - options = options_obj() - installer = options - - # pylint: disable=attribute-defined-outside-init - - # ServerMasterInstall - options.add_sids = True - options.add_agents = False - - # Installable - options.uninstalling = False - - # ServerInstallInterface - options.description = "Server" - - options.kinit_attempts = 1 - options.fixed_primary = True - options.permit = False - options.enable_dns_updates = False - options.no_krb5_offline_passwords = False - options.preserve_sssd = False - options.no_sssd = False - - # ServerMasterInstall - options.force_join = False - options.servers = None - options.no_wait_for_dns = True - options.host_password = None - options.keytab = None - options.setup_ca = True - # always run sidgen task and do not allow adding agents on first master - options.add_sids = True - options.add_agents = False - - # ADTrustInstallInterface - # no_msdcs is deprecated - options.no_msdcs = False - - # For pylint - options.external_cert_files = None - options.dirsrv_cert_files = None - - # Uninstall - options.ignore_topology_disconnect = False - options.ignore_last_of_role = False - - # pylint: enable=attribute-defined-outside-init - - # pylint: disable=invalid-name - def api_Backend_ldap2(host_name, setup_ca, connect=False): - # we are sure we have the configuration file ready. - cfg = dict(context='installer', confdir=paths.ETC_IPA, in_server=True, - host=host_name) - if setup_ca: - # we have an IPA-integrated CA - cfg['ca_host'] = host_name - - api.bootstrap(**cfg) - api.finalize() - if connect: - api.Backend.ldap2.connect() - - # pylint: enable=invalid-name - - def ds_init_info(ansible_log, fstore, domainlevel, dirsrv_config_file, - realm_name, host_name, domain_name, dm_password, - idstart, idmax, subject_base, ca_subject, - _no_hbac_allow, dirsrv_pkcs12_info, no_pkinit): - - if not options.external_cert_files: - _ds = dsinstance.DsInstance(fstore=fstore, domainlevel=domainlevel, - config_ldif=dirsrv_config_file) - _ds.set_output(ansible_log) - - if options.dirsrv_cert_files: - _dirsrv_pkcs12_info = dirsrv_pkcs12_info - else: - _dirsrv_pkcs12_info = None - - with redirect_stdout(ansible_log): - _ds.init_info(realm_name, host_name, domain_name, dm_password, - subject_base, ca_subject, idstart, idmax, - # hbac_allow=not no_hbac_allow, - _dirsrv_pkcs12_info, setup_pkinit=not no_pkinit) - else: - _ds = dsinstance.DsInstance(fstore=fstore, domainlevel=domainlevel) - _ds.set_output(ansible_log) - - with redirect_stdout(ansible_log): - _ds.init_info(realm_name, host_name, domain_name, dm_password, - subject_base, ca_subject, 1101, 1100, None, - setup_pkinit=not no_pkinit) - - return _ds - - def ansible_module_get_parsed_ip_addresses(ansible_module, - param='ip_addresses'): - ip_addrs = [] - for _ip in ansible_module.params.get(param): - try: - ip_parsed = ipautil.CheckedIPAddress(_ip) - except Exception as err: - ansible_module.fail_json( - msg="Invalid IP Address %s: %s" % (_ip, err)) - ip_addrs.append(ip_parsed) - return ip_addrs - - def encode_certificate(cert): - """ - Encode a certificate using base64. - - It also takes FreeIPA and Python versions into account. - """ - if isinstance(cert, (str, bytes)): - encoded = base64.b64encode(cert) - else: - encoded = base64.b64encode(cert.public_bytes(Encoding.DER)) - if not six.PY2: - encoded = encoded.decode('ascii') - return encoded - - def decode_certificate(cert): - """ - Decode a certificate using base64. - - It also takes FreeIPA versions into account and returns a - IPACertificate for newer IPA versions. - """ - if hasattr(x509, "IPACertificate"): - cert = cert.strip() - if not cert.startswith("-----BEGIN CERTIFICATE-----"): - cert = "-----BEGIN CERTIFICATE-----\n" + cert - if not cert.endswith("-----END CERTIFICATE-----"): - cert += "\n-----END CERTIFICATE-----" - - cert = certificate_loader(cert.encode('utf-8')) - else: - cert = base64.b64decode(cert) - return cert +def check_imports(module): + if ANSIBLE_IPA_SERVER_MODULE_IMPORT_ERROR is not None: + module.fail_json(msg=ANSIBLE_IPA_SERVER_MODULE_IMPORT_ERROR) From 62d49e4e9ecf650828cc679b1fca98c98aed8ff2 Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:27:44 +0100 Subject: [PATCH 02/17] ipaserver_enable_ipa: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `required` tags need to be fixed according to the `argument_spec` - `type` tag needs to match `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` argument_spec - `type='str'` needs to be set for string parameters A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- roles/ipaserver/library/ipaserver_enable_ipa.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_enable_ipa.py b/roles/ipaserver/library/ipaserver_enable_ipa.py index 332c72ff..0292a658 100644 --- a/roles/ipaserver/library/ipaserver_enable_ipa.py +++ b/roles/ipaserver/library/ipaserver_enable_ipa.py @@ -5,7 +5,7 @@ # # Based on ipa-server-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,15 +39,18 @@ description: Enable IPA options: hostname: description: Fully qualified name of this host - required: yes + type: str + required: no setup_dns: description: Configure bind with our zone - required: no + type: bool + required: yes setup_ca: description: Configure a dogtag CA - required: no + type: bool + required: yes author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -58,6 +61,7 @@ RETURN = ''' from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( + check_imports, AnsibleModuleLog, setup_logging, options, paths, api, sysrestore, tasks, service, bindinstance, redirect_stdout, services ) @@ -66,13 +70,14 @@ from ansible.module_utils.ansible_ipa_server import ( def main(): ansible_module = AnsibleModule( argument_spec=dict( - hostname=dict(required=False), + hostname=dict(required=False, type='str'), setup_dns=dict(required=True, type='bool'), setup_ca=dict(required=True, type='bool'), ), ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module) From 03e9dd3f007828da50249037e43d57a6bb2620be Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:29:29 +0100 Subject: [PATCH 03/17] ipaserver_load_cache: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `required` tags need to be fixed according to the `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` argument_spec - `type='str'` needs to be set for string parameters A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- roles/ipaserver/library/ipaserver_load_cache.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_load_cache.py b/roles/ipaserver/library/ipaserver_load_cache.py index e3f6fd32..0806c1d1 100644 --- a/roles/ipaserver/library/ipaserver_load_cache.py +++ b/roles/ipaserver/library/ipaserver_load_cache.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,9 +39,10 @@ description: Load cache file options: dm_password: description: Directory Manager password - required: no + type: str + required: yes author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -54,7 +55,7 @@ import os from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( - setup_logging, options, paths, read_cache + check_imports, setup_logging, options, paths, read_cache ) @@ -62,11 +63,12 @@ def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic - dm_password=dict(required=True, no_log=True), + dm_password=dict(required=True, type='str', no_log=True), ), ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() # set values ############################################################ From 2a817a989d9049c861e9bea4910262a7c951a9d8 Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:30:34 +0100 Subject: [PATCH 04/17] ipaserver_master_password: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `required` tags need to be fixed according to the `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` RETURN section - `type: str` needs to be used for string parameters argument_spec - `type='str'` needs to be set for string parameters supports_check_mode is turned off as it is not supported. A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- .../library/ipaserver_master_password.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_master_password.py b/roles/ipaserver/library/ipaserver_master_password.py index 3021498b..d048a839 100644 --- a/roles/ipaserver/library/ipaserver_master_password.py +++ b/roles/ipaserver/library/ipaserver_master_password.py @@ -5,7 +5,7 @@ # # Based on ipa-server-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -40,12 +40,14 @@ description: options: dm_password: description: Directory Manager password - required: no + type: str + required: yes master_password: description: kerberos master password (normally autogenerated) - required: yes + type: str + required: no author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -54,6 +56,7 @@ EXAMPLES = ''' RETURN = ''' password: description: The master password + type: str returned: always ''' @@ -61,6 +64,7 @@ import os from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( + check_imports, setup_logging, options, paths, read_cache, ipa_generate_password ) @@ -69,13 +73,14 @@ def main(): module = AnsibleModule( argument_spec=dict( # basic - dm_password=dict(required=True, no_log=True), - master_password=dict(required=False, no_log=True), + dm_password=dict(required=True, type='str', no_log=True), + master_password=dict(required=False, type='str', no_log=True), ), - supports_check_mode=True, + supports_check_mode=False, ) module._ansible_debug = True + check_imports(module) setup_logging() options.dm_password = module.params.get('dm_password') From c2475304ecaa003df8ba3bd32b74abef82dcc248 Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:31:55 +0100 Subject: [PATCH 05/17] ipaserver_prepare: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `type: list` needs to be set for list parameters - `elements: str` needs to be given for list of string parameters - `required` tags need to be fixed according to the `argument_spec` - `type` tag needs to match `argument_spec` - `default` tag needs to match `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` argument_spec - `type='str'` needs to be set for string parameters - `elements='str'` needs to be added to all list of string parameters supports_check_mode is turned off as it is not supported. A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- roles/ipaserver/library/ipaserver_prepare.py | 177 +++++++++++++------ 1 file changed, 122 insertions(+), 55 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_prepare.py b/roles/ipaserver/library/ipaserver_prepare.py index 7a65a9f5..f8277c11 100644 --- a/roles/ipaserver/library/ipaserver_prepare.py +++ b/roles/ipaserver/library/ipaserver_prepare.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,116 +39,176 @@ description: Prepare IPA server deployment options: force: description: Installer force parameter - required: yes + type: bool + default: no + required: no dm_password: description: Directory Manager password - required: no + type: str + required: yes password: description: Admin user kerberos password - required: no + type: str + required: yes ip_addresses: description: List of Master Server IP Addresses - required: yes + type: list + elements: str + required: no domain: description: Primary DNS domain of the IPA deployment - required: no + type: str + required: yes realm: description: Kerberos realm name of the IPA deployment - required: no + type: str + required: yes hostname: description: Fully qualified name of this host - required: yes + type: str + required: no ca_cert_files: description: List of files containing CA certificates for the service certificate files - required: yes + type: list + elements: str + required: no no_host_dns: description: Do not use DNS for hostname lookup during installation - required: yes + type: bool + default: no + required: no setup_adtrust: description: Configure AD trust capability - required: yes + type: bool + default: no + required: no setup_kra: description: Configure a dogtag KRA - required: yes + type: bool + default: no + required: no setup_dns: description: Configure bind with our zone - required: yes + type: bool + default: no + required: no external_ca: description: External ca setting - required: yes + type: bool + required: no external_ca_type: description: Type of the external CA - required: yes + type: str + required: no external_ca_profile: description: Specify the certificate profile/template to use at the external CA - required: yes + type: str + required: no external_cert_files: description: File containing the IPA CA certificate and the external CA certificate chain - required: yes + type: list + elements: str + required: no subject_base: description: The certificate subject base (default O=). RDNs are in LDAP order (most specific RDN first). - required: yes + type: str + required: no ca_subject: description: The installer ca_subject setting - required: yes + type: str + required: no allow_zone_overlap: description: Create DNS zone even if it already exists - required: yes + type: bool + default: no + required: no reverse_zones: description: The reverse DNS zones to use - required: yes + type: list + elements: str + required: no no_reverse: description: Do not create new reverse DNS zone - required: yes + type: bool + default: no + required: no auto_reverse: description: Create necessary reverse zones - required: yes + type: bool + default: no + required: no forwarders: description: Add DNS forwarders - required: yes + type: list + elements: str + required: no no_forwarders: description: Do not add any DNS forwarders, use root servers instead - required: yes + type: bool + default: no + required: no auto_forwarders: description: Use DNS forwarders configured in /etc/resolv.conf - required: yes + type: bool + default: no + required: no forward_policy: description: DNS forwarding policy for global forwarders - required: yes + type: str + choices: ['first', 'only'] + required: no no_dnssec_validation: description: Disable DNSSEC validation - required: yes + type: bool + default: no + required: no enable_compat: description: Enable support for trusted domains for old clients - required: yes + type: bool + default: no + required: no netbios_name: description: NetBIOS name of the IPA domain - required: yes + type: str + required: no rid_base: description: Start value for mapping UIDs and GIDs to RIDs - required: yes + type: int + required: no secondary_rid_base: description: Start value of the secondary range for mapping UIDs and GIDs to RIDs - required: yes + type: int + required: no setup_ca: description: Configure a dogtag CA - required: yes + type: bool + default: no + required: no + random_serial_numbers: + description: Enable random serial numbers + type: bool + default: no + required: no sid_generation_always: description: Enable SID generation always - required: yes + type: bool + default: no + required: no _hostname_overridden: description: The installer _hostname_overridden setting - required: yes + type: bool + default: no + required: no author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -161,8 +221,8 @@ import os from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( - AnsibleModuleLog, setup_logging, options, sysrestore, paths, - ansible_module_get_parsed_ip_addresses, + check_imports, AnsibleModuleLog, setup_logging, options, sysrestore, + paths, ansible_module_get_parsed_ip_addresses, redirect_stdout, adtrust, api, default_subject_base, default_ca_subject_dn, ipautil, installutils, ca, kra, dns, get_server_ip_address, no_matching_interface_for_ip_address_warning, @@ -175,13 +235,15 @@ def main(): argument_spec=dict( # basic force=dict(required=False, type='bool', default=False), - dm_password=dict(required=True, no_log=True), - password=dict(required=True, no_log=True), - ip_addresses=dict(required=False, type='list', default=[]), - domain=dict(required=True), - realm=dict(required=True), - hostname=dict(required=False), - ca_cert_files=dict(required=False, type='list', default=[]), + dm_password=dict(required=True, type='str', no_log=True), + password=dict(required=True, type='str', no_log=True), + ip_addresses=dict(required=False, type='list', elements='str', + default=[]), + domain=dict(required=True, type='str'), + realm=dict(required=True, type='str'), + hostname=dict(required=False, type='str'), + ca_cert_files=dict(required=False, type='list', elements='str', + default=[]), no_host_dns=dict(required=False, type='bool', default=False), # server setup_adtrust=dict(required=False, type='bool', default=False), @@ -191,26 +253,30 @@ def main(): # client # certificate system external_ca=dict(required=False, type='bool'), - external_ca_type=dict(required=False), - external_ca_profile=dict(required=False), - external_cert_files=dict(required=False, type='list', default=[]), - subject_base=dict(required=False), - ca_subject=dict(required=False), + external_ca_type=dict(required=False, type='str'), + external_ca_profile=dict(required=False, type='str'), + external_cert_files=dict(required=False, type='list', + elements='str', default=[]), + subject_base=dict(required=False, type='str'), + ca_subject=dict(required=False, type='str'), # dns allow_zone_overlap=dict(required=False, type='bool', default=False), - reverse_zones=dict(required=False, type='list', default=[]), + reverse_zones=dict(required=False, type='list', elements='str', + default=[]), no_reverse=dict(required=False, type='bool', default=False), auto_reverse=dict(required=False, type='bool', default=False), - forwarders=dict(required=False, type='list', default=[]), + forwarders=dict(required=False, type='list', elements='str', + default=[]), no_forwarders=dict(required=False, type='bool', default=False), auto_forwarders=dict(required=False, type='bool', default=False), - forward_policy=dict(default=None, choices=['first', 'only']), + forward_policy=dict(required=False, type='str', + choices=['first', 'only'], default=None), no_dnssec_validation=dict(required=False, type='bool', default=False), # ad trust enable_compat=dict(required=False, type='bool', default=False), - netbios_name=dict(required=False), + netbios_name=dict(required=False, type='str'), rid_base=dict(required=False, type='int'), secondary_rid_base=dict(required=False, type='int'), @@ -223,10 +289,11 @@ def main(): _hostname_overridden=dict(required=False, type='bool', default=False), ), - supports_check_mode=True, + supports_check_mode=False, ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module) From 9f3a2d42d00f5b51abd9e30ef606b6da1665c34a Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:33:12 +0100 Subject: [PATCH 06/17] ipaserver_set_ds_password: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `type: list` needs to be set for list parameters - `elements: str` needs to be given for list of string parameters - `required` tags need to be fixed according to the `argument_spec` - `type` tag needs to match `argument_spec` - `default` tag needs to match `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` argument_spec - `type='str'` needs to be set for string parameters - `elements='str'` needs to be added to all list of string parameters A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- .../library/ipaserver_set_ds_password.py | 87 ++++++++++++------- 1 file changed, 57 insertions(+), 30 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_set_ds_password.py b/roles/ipaserver/library/ipaserver_set_ds_password.py index f4d767be..f339fbc4 100644 --- a/roles/ipaserver/library/ipaserver_set_ds_password.py +++ b/roles/ipaserver/library/ipaserver_set_ds_password.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,64 +39,86 @@ description: Set DS password options: dm_password: description: Directory Manager password - required: no + type: str + required: yes password: description: Admin user kerberos password - required: no + type: str + required: yes domain: description: Primary DNS domain of the IPA deployment - required: no + type: str + required: yes realm: description: Kerberos realm name of the IPA deployment - required: no + type: str + required: yes hostname: description: Fully qualified name of this host - required: no + type: str + required: yes setup_ca: description: Configure a dogtag CA - required: no + type: bool + required: yes idstart: description: The starting value for the IDs range (default random) - required: no + type: int + required: yes idmax: description: The max value for the IDs range (default idstart+199999) - required: no + type: int + required: yes no_hbac_allow: description: Don't install allow_all HBAC rule - required: yes + type: bool + default: no + required: no no_pkinit: description: Disable pkinit setup steps - required: yes + type: bool + default: no + required: no dirsrv_config_file: description: The path to LDIF file that will be used to modify configuration of dse.ldif during installation of the directory server instance - required: yes + type: str + required: no _dirsrv_pkcs12_info: description: The installer _dirsrv_pkcs12_info setting - required: yes + type: list + elements: str + required: no dirsrv_cert_files: description: Files containing the Directory Server SSL certificate and private key - required: yes + type: list + elements: str + required: no subject_base: description: The certificate subject base (default O=). RDNs are in LDAP order (most specific RDN first). - required: yes + type: str + required: no ca_subject: description: The installer ca_subject setting - required: yes + type: str + required: no external_cert_files: description: File containing the IPA CA certificate and the external CA certificate chain - required: yes + type: list + elements: str + required: no domainlevel: description: The domain level - required: yes + type: int + required: no author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -107,6 +129,7 @@ RETURN = ''' from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( + check_imports, MAX_DOMAIN_LEVEL, AnsibleModuleLog, options, sysrestore, paths, api_Backend_ldap2, ds_init_info, redirect_stdout, setup_logging ) @@ -116,25 +139,28 @@ def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic - dm_password=dict(required=True, no_log=True), - password=dict(required=True, no_log=True), - domain=dict(required=True), - realm=dict(required=True), - hostname=dict(required=True), + dm_password=dict(required=True, type='str', no_log=True), + password=dict(required=True, type='str', no_log=True), + domain=dict(required=True, type='str'), + realm=dict(required=True, type='str'), + hostname=dict(required=True, type='str'), # server setup_ca=dict(required=True, type='bool'), idstart=dict(required=True, type='int'), idmax=dict(required=True, type='int'), no_hbac_allow=dict(required=False, type='bool', default=False), no_pkinit=dict(required=False, type='bool', default=False), - dirsrv_config_file=dict(required=False), - _dirsrv_pkcs12_info=dict(required=False, type='list'), + dirsrv_config_file=dict(required=False, type='str'), + _dirsrv_pkcs12_info=dict(required=False, type='list', + elements='str'), # ssl certificate - dirsrv_cert_files=dict(required=False, type='list', default=[]), - subject_base=dict(required=False), - ca_subject=dict(required=False), + dirsrv_cert_files=dict(required=False, type='list', elements='str', + default=[]), + subject_base=dict(required=False, type='str'), + ca_subject=dict(required=False, type='str'), # certificate system - external_cert_files=dict(required=False, type='list', default=[]), + external_cert_files=dict(required=False, type='list', + elements='str', default=[]), # additional domainlevel=dict(required=False, type='int', default=MAX_DOMAIN_LEVEL), @@ -142,6 +168,7 @@ def main(): ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module) From 0faf8c86ca7e2229e89643d98075b30af64946a9 Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:35:06 +0100 Subject: [PATCH 07/17] ipaserver_setup_adtrust: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `required` tags need to be fixed according to the `argument_spec` - `type` tag needs to match `argument_spec` - `default` tag needs to match `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` argument_spec - `type='str'` needs to be set for string parameters A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- .../library/ipaserver_setup_adtrust.py | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_setup_adtrust.py b/roles/ipaserver/library/ipaserver_setup_adtrust.py index 428d2528..820748be 100644 --- a/roles/ipaserver/library/ipaserver_setup_adtrust.py +++ b/roles/ipaserver/library/ipaserver_setup_adtrust.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,31 +39,42 @@ description: Setup trust ad options: hostname: description: Fully qualified name of this host - required: yes + type: str + required: no setup_ca: description: Configure a dogtag CA - required: yes + type: bool + default: no + required: no setup_adtrust: description: Configure AD trust capability - required: yes + type: bool + default: no + required: no enable_compat: description: Enable support for trusted domains for old clients - required: yes + type: bool + default: no + required: no rid_base: description: Start value for mapping UIDs and GIDs to RIDs - required: yes + type: int + required: no secondary_rid_base: description: Start value of the secondary range for mapping UIDs and GIDs to RIDs - required: yes + type: int + required: no adtrust_netbios_name: description: The adtrust netbios_name setting - required: no + type: str + required: yes adtrust_reset_netbios_name: description: The adtrust reset_netbios_name setting - required: no + type: bool + required: yes author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -74,7 +85,7 @@ RETURN = ''' from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( - AnsibleModuleLog, setup_logging, options, sysrestore, paths, + check_imports, AnsibleModuleLog, setup_logging, options, sysrestore, paths, api_Backend_ldap2, redirect_stdout, adtrust, api ) @@ -83,7 +94,7 @@ def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic - hostname=dict(required=False), + hostname=dict(required=False, type='str'), setup_ca=dict(required=False, type='bool', default=False), setup_adtrust=dict(required=False, type='bool', default=False), # ad trust @@ -91,12 +102,13 @@ def main(): rid_base=dict(required=False, type='int'), secondary_rid_base=dict(required=False, type='int'), # additional - adtrust_netbios_name=dict(required=True), + adtrust_netbios_name=dict(required=True, type='str'), adtrust_reset_netbios_name=dict(required=True, type='bool'), ), ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module) From 9eb07f70243a8a7d82864210baa90bff6ce80a19 Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:36:51 +0100 Subject: [PATCH 08/17] ipaserver_setup_ca: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `type: list` needs to be set for list parameters - `elements: str` needs to be given for list of string parameters - `required` tags need to be fixed according to the `argument_spec` - `type` tag needs to match `argument_spec` - `default` tag needs to match `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` argument_spec - `type='str'` needs to be set for string parameters - `elements='str'` needs to be added to all list of string parameters A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- roles/ipaserver/library/ipaserver_setup_ca.py | 171 ++++++++++++------ 1 file changed, 113 insertions(+), 58 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_setup_ca.py b/roles/ipaserver/library/ipaserver_setup_ca.py index 8c01e3c9..815edca7 100644 --- a/roles/ipaserver/library/ipaserver_setup_ca.py +++ b/roles/ipaserver/library/ipaserver_setup_ca.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,119 +39,169 @@ description: Setup CA options: dm_password: description: Directory Manager password - required: no + type: str + required: yes password: description: Admin user kerberos password - required: no + type: str + required: yes master_password: description: kerberos master password (normally autogenerated) - required: no + type: str + required: yes ip_addresses: description: List of Master Server IP Addresses - required: yes + type: list + elements: str + required: no domain: description: Primary DNS domain of the IPA deployment - required: no + type: str + required: yes realm: description: Kerberos realm name of the IPA deployment - required: no + type: str + required: yes hostname: description: Fully qualified name of this host - required: yes + type: str + required: no no_host_dns: description: Do not use DNS for hostname lookup during installation - required: yes + type: bool + default: no + required: no pki_config_override: description: Path to ini file with config overrides - required: yes + type: str + required: no setup_adtrust: description: Configure AD trust capability - required: yes + type: bool + default: no + required: no setup_kra: description: Configure a dogtag KRA - required: yes + type: bool + default: no + required: no setup_dns: description: Configure bind with our zone - required: yes + type: bool + default: no + required: no setup_ca: description: Configure a dogtag CA - required: yes + type: bool + default: no + required: no idstart: description: The starting value for the IDs range (default random) - required: no + type: int + required: yes idmax: description: The max value for the IDs range (default idstart+199999) - required: no + type: int + required: yes no_hbac_allow: description: Don't install allow_all HBAC rule - required: yes + type: bool + default: no + required: no no_pkinit: description: Disable pkinit setup steps - required: yes + type: bool + default: no + required: no dirsrv_config_file: description: The path to LDIF file that will be used to modify configuration of dse.ldif during installation of the directory server instance - required: yes + type: str + required: no dirsrv_cert_files: description: Files containing the Directory Server SSL certificate and private key - required: yes + type: list + elements: str + required: no _dirsrv_pkcs12_info: description: The installer _dirsrv_pkcs12_info setting - required: yes + type: list + elements: str + required: no external_ca: description: External ca setting - required: yes + type: bool + default: no + required: no external_ca_type: description: Type of the external CA - required: yes + type: str + required: no external_ca_profile: description: Specify the certificate profile/template to use at the external CA - required: yes + type: str + required: no external_cert_files: description: File containing the IPA CA certificate and the external CA certificate chain - required: yes + type: list + elements: str + required: no subject_base: description: The certificate subject base (default O=). RDNs are in LDAP order (most specific RDN first). - required: yes + type: str + required: no _subject_base: description: The installer _subject_base setting - required: yes + type: str + required: no ca_subject: description: The installer ca_subject setting - required: yes + type: str + required: no _ca_subject: description: The installer _ca_subject setting - required: yes + type: str + required: no ca_signing_algorithm: description: Signing algorithm of the IPA CA certificate - required: yes + type: str + required: no _random_serial_numbers: description: The installer _random_serial_numbers setting + type: bool required: yes reverse_zones: description: The reverse DNS zones to use - required: yes + type: list + elements: str + required: no no_reverse: description: Do not create new reverse DNS zone - required: yes + type: bool + default: no + required: no auto_forwarders: description: Use DNS forwarders configured in /etc/resolv.conf - required: yes + type: bool + default: no + required: no domainlevel: description: The domain level - required: yes + type: int + required: no _http_ca_cert: description: The installer _http_ca_cert setting - required: yes + type: str + required: no author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -164,7 +214,7 @@ import os from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( - AnsibleModuleLog, setup_logging, options, sysrestore, paths, + check_imports, AnsibleModuleLog, setup_logging, options, sysrestore, paths, ansible_module_get_parsed_ip_addresses, api_Backend_ldap2, redirect_stdout, ca, installutils, ds_init_info, custodiainstance, write_cache, x509, decode_certificate @@ -175,15 +225,16 @@ def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic - dm_password=dict(required=True, no_log=True), - password=dict(required=True, no_log=True), - master_password=dict(required=True, no_log=True), - ip_addresses=dict(required=False, type='list', default=[]), - domain=dict(required=True), - realm=dict(required=True), - hostname=dict(required=False), + dm_password=dict(required=True, type='str', no_log=True), + password=dict(required=True, type='str', no_log=True), + master_password=dict(required=True, type='str', no_log=True), + ip_addresses=dict(required=False, type='list', elements='str', + default=[]), + domain=dict(required=True, type='str'), + realm=dict(required=True, type='str'), + hostname=dict(required=False, type='str'), no_host_dns=dict(required=False, type='bool', default=False), - pki_config_override=dict(required=False), + pki_config_override=dict(required=False, type='str'), # server setup_adtrust=dict(required=False, type='bool', default=False), setup_kra=dict(required=False, type='bool', default=False), @@ -193,32 +244,36 @@ def main(): idmax=dict(required=True, type='int'), no_hbac_allow=dict(required=False, type='bool', default=False), no_pkinit=dict(required=False, type='bool', default=False), - dirsrv_config_file=dict(required=False), - dirsrv_cert_files=dict(required=False, type='list'), - _dirsrv_pkcs12_info=dict(required=False, type='list'), + dirsrv_config_file=dict(required=False, type='str'), + dirsrv_cert_files=dict(required=False, type='list', + elements='str'), + _dirsrv_pkcs12_info=dict(required=False, type='list', + elements='str'), # certificate system external_ca=dict(required=False, type='bool', default=False), - external_ca_type=dict(required=False), - external_ca_profile=dict(required=False), + external_ca_type=dict(required=False, type='str'), + external_ca_profile=dict(required=False, type='str'), external_cert_files=dict(required=False, type='list', - default=None), - subject_base=dict(required=False), - _subject_base=dict(required=False), - ca_subject=dict(required=False), - _ca_subject=dict(required=False), - ca_signing_algorithm=dict(required=False), + elements='str', default=None), + subject_base=dict(required=False, type='str'), + _subject_base=dict(required=False, type='str'), + ca_subject=dict(required=False, type='str'), + _ca_subject=dict(required=False, type='str'), + ca_signing_algorithm=dict(required=False, type='str'), _random_serial_numbers=dict(required=True, type='bool'), # dns - reverse_zones=dict(required=False, type='list', default=[]), + reverse_zones=dict(required=False, type='list', elements='str', + default=[]), no_reverse=dict(required=False, type='bool', default=False), auto_forwarders=dict(required=False, type='bool', default=False), # additional domainlevel=dict(required=False, type='int'), - _http_ca_cert=dict(required=False), + _http_ca_cert=dict(required=False, type='str'), ), ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module) From 1148476cf503b3e033ea74a63070ddc1474501c4 Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:38:14 +0100 Subject: [PATCH 09/17] ipaserver_setup_custodia: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `required` tags need to be fixed according to the `argument_spec` - `type` tag needs to match `argument_spec` - `default` tag needs to match `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` argument_spec - `type='str'` needs to be set for string parameters A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- .../library/ipaserver_setup_custodia.py | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_setup_custodia.py b/roles/ipaserver/library/ipaserver_setup_custodia.py index a788ad12..be337c1d 100644 --- a/roles/ipaserver/library/ipaserver_setup_custodia.py +++ b/roles/ipaserver/library/ipaserver_setup_custodia.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,15 +39,19 @@ description: Setup custodia options: realm: description: Kerberos realm name of the IPA deployment - required: no + type: str + required: yes hostname: description: Fully qualified name of this host - required: yes + type: str + required: no setup_ca: description: Configure a dogtag CA - required: yes + type: bool + default: no + required: no author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -58,7 +62,7 @@ RETURN = ''' from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( - setup_logging, AnsibleModuleLog, options, + check_imports, setup_logging, AnsibleModuleLog, options, api_Backend_ldap2, custodiainstance, redirect_stdout ) @@ -68,13 +72,14 @@ def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic - realm=dict(required=True), - hostname=dict(required=False), + realm=dict(required=True, type='str'), + hostname=dict(required=False, type='str'), setup_ca=dict(required=False, type='bool', default=False), ), ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module) From 1062e0fe99d260215ffe77c5f8bc11c1c21492c9 Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:40:39 +0100 Subject: [PATCH 10/17] ipaserver_setup_dns: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `type: list` needs to be set for list parameters - `elements: str` needs to be given for list of string parameters - `required` tags need to be fixed according to the `argument_spec` - `type` tag needs to match `argument_spec` - `default` tag needs to match `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` - `choices` needs to match `argument_spec` argument_spec - `type='str'` needs to be set for string parameters - `elements='str'` needs to be added to all list of string parameters A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- .../ipaserver/library/ipaserver_setup_dns.py | 70 ++++++++++++------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_setup_dns.py b/roles/ipaserver/library/ipaserver_setup_dns.py index 1ed1fe4f..cf31eda9 100644 --- a/roles/ipaserver/library/ipaserver_setup_dns.py +++ b/roles/ipaserver/library/ipaserver_setup_dns.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,42 +39,61 @@ description: Setup DNS options: ip_addresses: description: List of Master Server IP Addresses - required: yes + type: list + elements: str + required: no domain: description: Primary DNS domain of the IPA deployment - required: no + type: str + required: yes realm: description: Kerberos realm name of the IPA deployment - required: no + type: str + required: yes hostname: description: Fully qualified name of this host - required: no + type: str + required: yes setup_dns: description: Configure bind with our zone - required: no + type: bool + required: yes setup_ca: description: Configure a dogtag CA - required: no + type: bool + required: yes zonemgr: description: DNS zone manager e-mail address. Defaults to hostmaster@DOMAIN - required: yes + type: str + required: no forwarders: description: Add DNS forwarders - required: no + type: list + elements: str + required: yes forward_policy: description: DNS forwarding policy for global forwarders - required: yes + type: str + choices: ['first', 'only'] + default: 'first' + required: no no_dnssec_validation: description: Disable DNSSEC validation - required: yes + type: bool + default: no + required: no dns_ip_addresses: description: The dns ip_addresses setting - required: no + type: list + elements: str + required: yes dns_reverse_zones: description: The dns reverse_zones setting - required: no + type: list + elements: str + required: yes author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -85,7 +104,7 @@ RETURN = ''' from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( - AnsibleModuleLog, setup_logging, options, paths, dns, + check_imports, AnsibleModuleLog, setup_logging, options, paths, dns, ansible_module_get_parsed_ip_addresses, sysrestore, api_Backend_ldap2, redirect_stdout, bindinstance ) @@ -95,26 +114,29 @@ def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic - ip_addresses=dict(required=False, type='list', default=[]), - domain=dict(required=True), - realm=dict(required=True), - hostname=dict(required=True), + ip_addresses=dict(required=False, type='list', elements='str', + default=[]), + domain=dict(required=True, type='str'), + realm=dict(required=True, type='str'), + hostname=dict(required=True, type='str'), # server setup_dns=dict(required=True, type='bool'), setup_ca=dict(required=True, type='bool'), # dns - zonemgr=dict(required=False), - forwarders=dict(required=True, type='list'), - forward_policy=dict(default='first', choices=['first', 'only']), + zonemgr=dict(required=False, type='str'), + forwarders=dict(required=True, type='list', elements='str'), + forward_policy=dict(required=False, choices=['first', 'only'], + default='first'), no_dnssec_validation=dict(required=False, type='bool', default=False), # additional - dns_ip_addresses=dict(required=True, type='list'), - dns_reverse_zones=dict(required=True, type='list'), + dns_ip_addresses=dict(required=True, type='list', elements='str'), + dns_reverse_zones=dict(required=True, type='list', elements='str'), ), ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module) From b22207d6ee34f57420e169e05fbe2d1c17ed252a Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:41:56 +0100 Subject: [PATCH 11/17] ipaserver_setup_ds: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `type: list` needs to be set for list parameters - `elements: str` needs to be given for list of string parameters - `required` tags need to be fixed according to the `argument_spec` - `type` tag needs to match `argument_spec` - `default` tag needs to match `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` argument_spec - `type='str'` needs to be set for string parameters - `elements='str'` needs to be added to all list of string parameters A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- roles/ipaserver/library/ipaserver_setup_ds.py | 86 ++++++++++++------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_setup_ds.py b/roles/ipaserver/library/ipaserver_setup_ds.py index 76fb4b73..4479daaa 100644 --- a/roles/ipaserver/library/ipaserver_setup_ds.py +++ b/roles/ipaserver/library/ipaserver_setup_ds.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,61 +39,83 @@ description: Configure directory server options: dm_password: description: Directory Manager password - required: no + type: str + required: yes password: description: Admin user kerberos password - required: no + type: str + required: yes domain: description: Primary DNS domain of the IPA deployment - required: no + type: str + required: yes realm: description: Kerberos realm name of the IPA deployment - required: no + type: str + required: yes hostname: description: Fully qualified name of this host - required: yes + type: str + required: no idstart: description: The starting value for the IDs range (default random) - required: no + type: int + required: yes idmax: description: The max value for the IDs range (default idstart+199999) - required: no + type: int + required: yes no_hbac_allow: description: Don't install allow_all HBAC rule - required: yes + type: bool + default: no + required: no no_pkinit: description: Disable pkinit setup steps - required: yes + type: bool + default: no + required: no dirsrv_config_file: description: The path to LDIF file that will be used to modify configuration of dse.ldif during installation of the directory server instance - required: yes + type: str + required: no dirsrv_cert_files: description: Files containing the Directory Server SSL certificate and private key - required: yes + type: list + elements: str + required: no _dirsrv_pkcs12_info: description: The installer _dirsrv_pkcs12_info setting - required: yes + type: list + elements: str + required: no external_cert_files: description: File containing the IPA CA certificate and the external CA certificate chain - required: yes + type: list + elements: str + required: no subject_base: description: The certificate subject base (default O=). RDNs are in LDAP order (most specific RDN first). - required: yes + type: str + required: no ca_subject: description: The installer ca_subject setting - required: yes + type: str + required: no setup_ca: description: Configure a dogtag CA - required: yes + type: bool + default: no + required: no author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -104,7 +126,7 @@ RETURN = ''' from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( - AnsibleModuleLog, setup_logging, options, sysrestore, paths, + check_imports, AnsibleModuleLog, setup_logging, options, sysrestore, paths, api_Backend_ldap2, redirect_stdout, api, NUM_VERSION, tasks, dsinstance, ntpinstance, IPAAPI_USER ) @@ -114,24 +136,27 @@ def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic - dm_password=dict(required=True, no_log=True), - password=dict(required=True, no_log=True), - domain=dict(required=True), - realm=dict(required=True), - hostname=dict(required=False), + dm_password=dict(required=True, type='str', no_log=True), + password=dict(required=True, type='str', no_log=True), + domain=dict(required=True, type='str'), + realm=dict(required=True, type='str'), + hostname=dict(required=False, type='str'), # server idstart=dict(required=True, type='int'), idmax=dict(required=True, type='int'), no_hbac_allow=dict(required=False, type='bool', default=False), no_pkinit=dict(required=False, type='bool', default=False), - dirsrv_config_file=dict(required=False), + dirsrv_config_file=dict(required=False, type='str'), # ssl certificate - dirsrv_cert_files=dict(required=False, type='list', default=[]), - _dirsrv_pkcs12_info=dict(required=False, type='list'), + dirsrv_cert_files=dict(required=False, type='list', elements='str', + default=[]), + _dirsrv_pkcs12_info=dict(required=False, type='list', + elements='str'), # certificate system - external_cert_files=dict(required=False, type='list', default=[]), - subject_base=dict(required=False), - ca_subject=dict(required=False), + external_cert_files=dict(required=False, type='list', + elements='str', default=[]), + subject_base=dict(required=False, type='str'), + ca_subject=dict(required=False, type='str'), # additional setup_ca=dict(required=False, type='bool', default=False), @@ -139,6 +164,7 @@ def main(): ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module) From 66dbfce0f7cd292b509ee4da48674195ca65994e Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:43:46 +0100 Subject: [PATCH 12/17] ipaserver_setup_http: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `type: list` needs to be set for list parameters - `elements: str` needs to be given for list of string parameters - `required` tags need to be fixed according to the `argument_spec` - `type` tag needs to match `argument_spec` - `default` tag needs to match `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` argument_spec - `type='str'` needs to be set for string parameters - `elements='str'` needs to be added to all list of string parameters A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- .../ipaserver/library/ipaserver_setup_http.py | 158 ++++++++++++------ 1 file changed, 107 insertions(+), 51 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_setup_http.py b/roles/ipaserver/library/ipaserver_setup_http.py index 5f72b1cb..cd6478ee 100644 --- a/roles/ipaserver/library/ipaserver_setup_http.py +++ b/roles/ipaserver/library/ipaserver_setup_http.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,107 +39,155 @@ description: Setup HTTP options: dm_password: description: Directory Manager password - required: no + type: str + required: yes password: description: Admin user kerberos password - required: no + type: str + required: yes master_password: description: kerberos master password (normally autogenerated) - required: no + type: str + required: yes domain: description: Primary DNS domain of the IPA deployment - required: no + type: str + required: yes realm: description: Kerberos realm name of the IPA deployment - required: no + type: str + required: yes hostname: description: Fully qualified name of this host - required: yes + type: str + required: no ip_addresses: description: List of Master Server IP Addresses - required: yes + type: list + elements: str + required: no reverse_zones: description: The reverse DNS zones to use - required: yes + type: list + elements: str + required: no http_cert_files: description: File containing the Apache Server SSL certificate and private key - required: yes + type: list + elements: str + required: no setup_adtrust: description: Configure AD trust capability - required: yes + type: bool + default: no + required: no setup_kra: description: Configure a dogtag KRA - required: yes + type: bool + default: no + required: no setup_dns: description: Configure bind with our zone - required: yes + type: bool + default: no + required: no setup_ca: description: Configure a dogtag CA - required: yes + type: bool + default: no + required: no no_host_dns: description: Do not use DNS for hostname lookup during installation - required: yes + type: bool + default: no + required: no no_pkinit: description: Disable pkinit setup steps - required: yes + type: bool + default: no + required: no no_hbac_allow: description: Don't install allow_all HBAC rule - required: yes + type: bool + default: no + required: no no_ui_redirect: description: Do not automatically redirect to the Web UI - required: yes + type: bool + default: no + required: no external_cert_files: description: File containing the IPA CA certificate and the external CA certificate chain - required: yes + type: list + elements: str + required: no subject_base: description: The certificate subject base (default O=). RDNs are in LDAP order (most specific RDN first). - required: yes + type: str + required: no _subject_base: description: The installer _subject_base setting - required: yes + type: str + required: no ca_subject: description: The installer ca_subject setting - required: yes + type: str + required: no _ca_subject: description: The installer _ca_subject setting - required: yes + type: str + required: no idstart: description: The starting value for the IDs range (default random) - required: no + type: int + required: yes idmax: description: The max value for the IDs range (default idstart+199999) - required: no + type: int + required: yes domainlevel: description: The domain level - required: yes + type: int + required: no dirsrv_config_file: description: The path to LDIF file that will be used to modify configuration of dse.ldif during installation of the directory server instance - required: yes + type: str + required: no dirsrv_cert_files: description: Files containing the Directory Server SSL certificate and private key - required: yes + type: list + elements: str + required: no no_reverse: description: Do not create new reverse DNS zone - required: yes + type: bool + default: no + required: no auto_forwarders: description: Use DNS forwarders configured in /etc/resolv.conf - required: yes + type: bool + default: no + required: no _dirsrv_pkcs12_info: description: The installer _dirsrv_pkcs12_info setting - required: yes + type: list + elements: str + required: no _http_pkcs12_info: description: The installer _http_pkcs12_info setting - required: yes + type: list + elements: str + required: no author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -150,7 +198,7 @@ RETURN = ''' from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( - AnsibleModuleLog, setup_logging, options, sysrestore, paths, + check_imports, AnsibleModuleLog, setup_logging, options, sysrestore, paths, ansible_module_get_parsed_ip_addresses, api_Backend_ldap2, redirect_stdout, ds_init_info, krbinstance, httpinstance, ca, service, tasks @@ -161,16 +209,19 @@ def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic - dm_password=dict(required=True, no_log=True), - password=dict(required=True, no_log=True), - master_password=dict(required=True, no_log=True), - domain=dict(required=True), - realm=dict(required=True), - hostname=dict(required=False), + dm_password=dict(required=True, type='str', no_log=True), + password=dict(required=True, type='str', no_log=True), + master_password=dict(required=True, type='str', no_log=True), + domain=dict(required=True, type='str'), + realm=dict(required=True, type='str'), + hostname=dict(required=False, type='str'), - ip_addresses=dict(required=False, type='list', default=[]), - reverse_zones=dict(required=False, type='list', default=[]), - http_cert_files=dict(required=False, type='list', default=[]), + ip_addresses=dict(required=False, type='list', elements='str', + default=[]), + reverse_zones=dict(required=False, type='list', elements='str', + default=[]), + http_cert_files=dict(required=False, type='list', elements='str', + default=[]), setup_adtrust=dict(required=False, type='bool', default=False), setup_kra=dict(required=False, type='bool', default=False), @@ -183,29 +234,34 @@ def main(): no_ui_redirect=dict(required=False, type='bool', default=False), - external_cert_files=dict(required=False, type='list', default=[]), - subject_base=dict(required=False), - _subject_base=dict(required=False), - ca_subject=dict(required=False), - _ca_subject=dict(required=False), + external_cert_files=dict(required=False, type='list', + elements='str', default=[]), + subject_base=dict(required=False, type='str'), + _subject_base=dict(required=False, type='str'), + ca_subject=dict(required=False, type='str'), + _ca_subject=dict(required=False, type='str'), idstart=dict(required=True, type='int'), idmax=dict(required=True, type='int'), domainlevel=dict(required=False, type='int'), dirsrv_config_file=dict(required=False), - dirsrv_cert_files=dict(required=False, type='list', default=[]), + dirsrv_cert_files=dict(required=False, type='list', elements='str', + default=[]), no_reverse=dict(required=False, type='bool', default=False), auto_forwarders=dict(required=False, type='bool', default=False), # _update_hosts_file=dict(required=False, type='bool', # default=False), - _dirsrv_pkcs12_info=dict(required=False, type='list'), - _http_pkcs12_info=dict(required=False, type='list'), + _dirsrv_pkcs12_info=dict(required=False, type='list', + elements='str'), + _http_pkcs12_info=dict(required=False, type='list', + elements='str'), ), ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module) From d962939a6134768946f28f9b2a97add1830cd6c8 Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:45:12 +0100 Subject: [PATCH 13/17] ipaserver_setup_kra: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `required` tags need to be fixed according to the `argument_spec` - `type` tag needs to match `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` argument_spec - `type='str'` needs to be set for string parameters A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- .../ipaserver/library/ipaserver_setup_kra.py | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_setup_kra.py b/roles/ipaserver/library/ipaserver_setup_kra.py index 78f1fe26..9f05ef5a 100644 --- a/roles/ipaserver/library/ipaserver_setup_kra.py +++ b/roles/ipaserver/library/ipaserver_setup_kra.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,24 +39,30 @@ description: Setup KRA options: dm_password: description: Directory Manager password - required: no + type: str + required: yes hostname: description: Fully qualified name of this host - required: no + type: str + required: yes setup_ca: description: Configure a dogtag CA - required: no + type: bool + required: yes setup_kra: description: Configure a dogtag KRA - required: no + type: bool + required: yes realm: description: Kerberos realm name of the IPA deployment - required: no + type: str + required: yes pki_config_override: description: Path to ini file with config overrides - required: yes + type: str + required: no author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -67,7 +73,7 @@ RETURN = ''' from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( - AnsibleModuleLog, setup_logging, options, + check_imports, AnsibleModuleLog, setup_logging, options, api_Backend_ldap2, redirect_stdout, api, custodiainstance, kra ) @@ -76,16 +82,17 @@ def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic - dm_password=dict(required=True, no_log=True), - hostname=dict(required=True), + dm_password=dict(required=True, type='str', no_log=True), + hostname=dict(required=True, type='str'), setup_ca=dict(required=True, type='bool'), setup_kra=dict(required=True, type='bool'), - realm=dict(required=True), - pki_config_override=dict(required=False), + realm=dict(required=True, type='str'), + pki_config_override=dict(required=False, type='str'), ), ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module) From 15454c3a486ee5215d41f368546cc305067e9ab3 Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:46:11 +0100 Subject: [PATCH 14/17] ipaserver_setup_krb: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `type: list` needs to be set for list parameters - `elements: str` needs to be given for list of string parameters - `required` tags need to be fixed according to the `argument_spec` - `type` tag needs to match `argument_spec` - `default` tag needs to match `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` argument_spec - `type='str'` needs to be set for string parameters - `elements='str'` needs to be added to all list of string parameters A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- .../ipaserver/library/ipaserver_setup_krb.py | 117 ++++++++++++------ 1 file changed, 79 insertions(+), 38 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_setup_krb.py b/roles/ipaserver/library/ipaserver_setup_krb.py index 70daab25..df37ed31 100644 --- a/roles/ipaserver/library/ipaserver_setup_krb.py +++ b/roles/ipaserver/library/ipaserver_setup_krb.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,79 +39,115 @@ description: Setup KRB options: dm_password: description: Directory Manager password - required: no + type: str + required: yes password: description: Admin user kerberos password - required: no + type: str + required: yes master_password: description: kerberos master password (normally autogenerated) - required: no + type: str + required: yes domain: description: Primary DNS domain of the IPA deployment - required: no + type: str + required: yes realm: description: Kerberos realm name of the IPA deployment - required: no + type: str + required: yes hostname: description: Fully qualified name of this host - required: yes + type: str + required: no ip_addresses: description: List of Master Server IP Addresses - required: yes + type: list + elements: str + required: no reverse_zones: description: The reverse DNS zones to use - required: yes + type: list + elements: str + required: no setup_adtrust: description: Configure AD trust capability - required: yes + type: bool + default: no + required: no setup_kra: description: Configure a dogtag KRA - required: yes + type: bool + default: no + required: no setup_dns: description: Configure bind with our zone - required: yes + type: bool + default: no + required: no setup_ca: description: Configure a dogtag CA - required: yes + type: bool + default: no + required: no no_host_dns: description: Do not use DNS for hostname lookup during installation - required: yes + type: bool + default: no + required: no no_pkinit: description: Disable pkinit setup steps - required: yes + type: bool + default: no + required: no no_hbac_allow: description: Don't install allow_all HBAC rule - required: yes + type: bool + default: no + required: no external_cert_files: description: File containing the IPA CA certificate and the external CA certificate chain - required: yes + type: list + elements: str + required: no subject_base: description: The certificate subject base (default O=). RDNs are in LDAP order (most specific RDN first). - required: yes + type: str + required: no ca_subject: description: The installer ca_subject setting - required: yes + type: str + required: no idstart: description: The starting value for the IDs range (default random) - required: no + type: int + required: yes idmax: description: The max value for the IDs range (default idstart+199999) - required: no + type: int + required: yes no_reverse: description: Do not create new reverse DNS zone - required: yes + type: bool + default: no + required: no auto_forwarders: description: Use DNS forwarders configured in /etc/resolv.conf - required: yes + type: bool + default: no + required: no _pkinit_pkcs12_info: description: The installer _pkinit_pkcs12_info setting - required: yes + type: list + elements: str + required: no author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -122,7 +158,7 @@ RETURN = ''' from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( - AnsibleModuleLog, setup_logging, options, sysrestore, paths, + check_imports, AnsibleModuleLog, setup_logging, options, sysrestore, paths, ansible_module_get_parsed_ip_addresses, api_Backend_ldap2, redirect_stdout, krbinstance ) @@ -132,15 +168,17 @@ def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic - dm_password=dict(required=True, no_log=True), - password=dict(required=True, no_log=True), - master_password=dict(required=True, no_log=True), - domain=dict(required=True), - realm=dict(required=True), - hostname=dict(required=False), + dm_password=dict(required=True, type='str', no_log=True), + password=dict(required=True, type='str', no_log=True), + master_password=dict(required=True, type='str', no_log=True), + domain=dict(required=True, type='str'), + realm=dict(required=True, type='str'), + hostname=dict(required=False, type='str'), - ip_addresses=dict(required=False, type='list', default=[]), - reverse_zones=dict(required=False, type='list', default=[]), + ip_addresses=dict(required=False, type='list', elements='str', + default=[]), + reverse_zones=dict(required=False, type='list', elements='str', + default=[]), setup_adtrust=dict(required=False, type='bool', default=False), setup_kra=dict(required=False, type='bool', default=False), @@ -151,9 +189,10 @@ def main(): no_pkinit=dict(required=False, type='bool', default=False), no_hbac_allow=dict(required=False, type='bool', default=False), - external_cert_files=dict(required=False, type='list', default=[]), - subject_base=dict(required=False), - ca_subject=dict(required=False), + external_cert_files=dict(required=False, type='list', + elements='str', default=[]), + subject_base=dict(required=False, type='str'), + ca_subject=dict(required=False, type='str'), idstart=dict(required=True, type='int'), idmax=dict(required=True, type='int'), @@ -161,11 +200,13 @@ def main(): no_reverse=dict(required=False, type='bool', default=False), auto_forwarders=dict(required=False, type='bool', default=False), - _pkinit_pkcs12_info=dict(required=False, type='list'), + _pkinit_pkcs12_info=dict(required=False, type='list', + elements='str'), ), ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module) From 300292c050b48558d8d7d1352698523ddb0ac661 Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:47:25 +0100 Subject: [PATCH 15/17] ipaserver_setup_ntp: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `type: list` needs to be set for list parameters - `elements: str` needs to be given for list of string parameters - `required` tags need to be fixed according to the `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` argument_spec - `type='str'` needs to be set for string parameters - `elements='str'` needs to be added to all list of string parameters A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- .../ipaserver/library/ipaserver_setup_ntp.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_setup_ntp.py b/roles/ipaserver/library/ipaserver_setup_ntp.py index 9efad213..eac722b5 100644 --- a/roles/ipaserver/library/ipaserver_setup_ntp.py +++ b/roles/ipaserver/library/ipaserver_setup_ntp.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,12 +39,15 @@ description: Setup NTP options: ntp_servers: description: ntp servers to use - required: yes + type: list + elements: str + required: no ntp_pool: description: ntp server pool to use - required: yes + type: str + required: no author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -55,7 +58,7 @@ RETURN = ''' from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( - AnsibleModuleLog, setup_logging, options, sysrestore, paths, + check_imports, AnsibleModuleLog, setup_logging, options, sysrestore, paths, redirect_stdout, time_service, sync_time, ntpinstance, timeconf, getargspec ) @@ -64,12 +67,14 @@ from ansible.module_utils.ansible_ipa_server import ( def main(): ansible_module = AnsibleModule( argument_spec=dict( - ntp_servers=dict(required=False, type='list', default=None), - ntp_pool=dict(required=False, default=None), + ntp_servers=dict(required=False, type='list', elements='str', + default=None), + ntp_pool=dict(required=False, type='str', default=None), ), ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module) From 165c3f06b749da4c61ede15c15b4f3c2de657f0c Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:48:27 +0100 Subject: [PATCH 16/17] ipaserver_setup_otpd: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `required` tags need to be fixed according to the `argument_spec` - `type` tag needs to match `argument_spec` - `default` tag needs to match `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` argument_spec - `type='str'` needs to be set for string parameters A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- .../ipaserver/library/ipaserver_setup_otpd.py | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_setup_otpd.py b/roles/ipaserver/library/ipaserver_setup_otpd.py index ca1e06c4..f8968118 100644 --- a/roles/ipaserver/library/ipaserver_setup_otpd.py +++ b/roles/ipaserver/library/ipaserver_setup_otpd.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,15 +39,19 @@ description: Setup OTPD options: realm: description: Kerberos realm name of the IPA deployment - required: no + type: str + required: yes hostname: description: Fully qualified name of this host - required: yes + type: str + required: no setup_ca: description: Configure a dogtag CA - required: yes + type: bool + default: no + required: no author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -58,7 +62,7 @@ RETURN = ''' from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ansible_ipa_server import ( - AnsibleModuleLog, setup_logging, options, + check_imports, AnsibleModuleLog, setup_logging, options, api_Backend_ldap2, redirect_stdout, otpdinstance, ipautil ) @@ -67,13 +71,14 @@ def main(): ansible_module = AnsibleModule( argument_spec=dict( # basic - realm=dict(required=True), - hostname=dict(required=False), + realm=dict(required=True, type='str'), + hostname=dict(required=False, type='str'), setup_ca=dict(required=False, type='bool', default=False), ), ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module) From 57c303d816c9a3bd493c8fe533b66c38575a1ab4 Mon Sep 17 00:00:00 2001 From: Thomas Woerner Date: Tue, 8 Nov 2022 16:50:07 +0100 Subject: [PATCH 17/17] ipaserver_test: Fix documentation sections and agument spec ansible-test with ansible-2.14 is adding a lot of new tests to ensure that the documentation section and the agument spec is complete. Needed changes: DOCUMENTATION section - `type: str` needs to be set for string parameters - `type: list` needs to be set for list parameters - `elements: str` needs to be given for list of string parameters - `required` tags need to be fixed according to the `argument_spec` - `type` tag needs to match `argument_spec` - `default` tag needs to match `argument_spec` - `author` needs to be given with the github user also: `Name (@user)` - `choices` needs to match `argument_spec` argument_spec - `type='str'` needs to be set for string parameters - `elements='str'` needs to be added to all list of string parameters supports_check_mode is turned off as it is not supported. A call to ansible_ipa_server.check_imports has been added to check for import errors. The `copyright` date is extended with `-2022`. --- roles/ipaserver/library/ipaserver_test.py | 253 +++++++++++++++------- 1 file changed, 170 insertions(+), 83 deletions(-) diff --git a/roles/ipaserver/library/ipaserver_test.py b/roles/ipaserver/library/ipaserver_test.py index f830f37d..cf5b7c8f 100644 --- a/roles/ipaserver/library/ipaserver_test.py +++ b/roles/ipaserver/library/ipaserver_test.py @@ -5,7 +5,7 @@ # # Based on ipa-client-install code # -# Copyright (C) 2017 Red Hat +# Copyright (C) 2017-2022 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify @@ -39,169 +39,246 @@ description: IPA server test options: force: description: Installer force parameter - required: yes + type: bool + default: no + required: no dm_password: description: Directory Manager password - required: no + type: str + required: yes password: description: Admin user kerberos password - required: no + type: str + required: yes master_password: description: kerberos master password (normally autogenerated) - required: yes + type: str + required: no domain: description: Primary DNS domain of the IPA deployment - required: yes + type: str + required: no realm: description: Kerberos realm name of the IPA deployment - required: yes + type: str + required: no hostname: description: Fully qualified name of this host - required: yes + type: str + required: no ca_cert_files: description: List of files containing CA certificates for the service certificate files - required: yes + type: list + elements: str + required: no no_host_dns: description: Do not use DNS for hostname lookup during installation - required: yes + type: bool + default: no + required: no pki_config_override: description: Path to ini file with config overrides - required: yes + type: str + required: no skip_mem_check: description: Skip checking for minimum required memory - required: yes + type: bool + default: no + required: no setup_adtrust: description: Configure AD trust capability - required: yes + type: bool + default: no + required: no setup_kra: description: Configure a dogtag KRA - required: yes + type: bool + default: no + required: no setup_dns: description: Configure bind with our zone - required: yes + type: bool + default: no + required: no idstart: description: The starting value for the IDs range (default random) - required: yes + type: int + required: no idmax: description: The max value for the IDs range (default idstart+199999) - required: yes + type: int + required: no no_pkinit: description: Disable pkinit setup steps - required: yes + type: bool + default: no + required: no dirsrv_config_file: description: The path to LDIF file that will be used to modify configuration of dse.ldif during installation of the directory server instance - required: yes + type: str + required: no dirsrv_cert_files: description: Files containing the Directory Server SSL certificate and private key - required: yes + type: list + elements: str + required: no http_cert_files: description: File containing the Apache Server SSL certificate and private key - required: yes + type: list + elements: str + required: no pkinit_cert_files: description: File containing the Kerberos KDC SSL certificate and private key - required: yes + type: list + elements: str + required: no dirsrv_pin: description: The password to unlock the Directory Server private key - required: yes + type: str + required: no http_pin: description: The password to unlock the Apache Server private key - required: yes + type: str + required: no pkinit_pin: description: The password to unlock the Kerberos KDC private key - required: yes + type: str + required: no dirsrv_cert_name: description: Name of the Directory Server SSL certificate to install - required: yes + type: str + required: no http_cert_name: description: Name of the Apache Server SSL certificate to install - required: yes + type: str + required: no pkinit_cert_name: description: Name of the Kerberos KDC SSL certificate to install - required: yes + type: str + required: no ntp_servers: description: ntp servers to use - required: yes + type: list + elements: str + required: no ntp_pool: description: ntp server pool to use - required: yes + type: str + required: no no_ntp: description: Do not configure ntp - required: yes + type: bool + default: no + required: no external_ca: description: External ca setting - required: yes + type: bool + default: no + required: no external_ca_type: description: Type of the external CA - required: yes + type: str + required: no external_ca_profile: description: Specify the certificate profile/template to use at the external CA - required: yes + type: str + required: no external_cert_files: description: File containing the IPA CA certificate and the external CA certificate chain - required: yes + type: list + elements: str + required: no subject_base: description: The certificate subject base (default O=). RDNs are in LDAP order (most specific RDN first). - required: yes + type: str + required: no ca_subject: description: The installer ca_subject setting - required: yes + type: str + required: no allow_zone_overlap: description: Create DNS zone even if it already exists - required: yes + type: bool + default: no + required: no reverse_zones: description: The reverse DNS zones to use - required: yes + type: list + elements: str + required: no no_reverse: description: Do not create new reverse DNS zone - required: yes + type: bool + default: no + required: no auto_reverse: description: Create necessary reverse zones - required: yes + type: bool + default: no + required: no zonemgr: description: DNS zone manager e-mail address. Defaults to hostmaster@DOMAIN - required: yes + type: str + required: no forwarders: description: Add DNS forwarders - required: yes + type: list + elements: str + required: no no_forwarders: description: Do not add any DNS forwarders, use root servers instead - required: yes + type: bool + default: no + required: no auto_forwarders: description: Use DNS forwarders configured in /etc/resolv.conf - required: yes + type: bool + default: no + required: no forward_policy: description: DNS forwarding policy for global forwarders - required: yes + type: str + choices: ['first', 'only'] + required: no no_dnssec_validation: description: Disable DNSSEC validation - required: yes + type: bool + default: no + required: no enable_compat: description: Enable support for trusted domains for old clients - required: yes + type: bool + default: no + required: no netbios_name: description: NetBIOS name of the IPA domain - required: yes + type: str + required: no rid_base: description: Start value for mapping UIDs and GIDs to RIDs - required: yes + type: int + default: 1000 + required: no secondary_rid_base: description: Start value of the secondary range for mapping UIDs and GIDs to RIDs - required: yes + type: int + default: 100000000 + required: no author: - - Thomas Woerner + - Thomas Woerner (@t-woerner) ''' EXAMPLES = ''' @@ -218,6 +295,7 @@ from shutil import copyfile from ansible.module_utils.basic import AnsibleModule from ansible.module_utils._text import to_native from ansible.module_utils.ansible_ipa_server import ( + check_imports, AnsibleModuleLog, setup_logging, options, adtrust_imported, kra_imported, PKIIniLoader, MIN_DOMAIN_LEVEL, MAX_DOMAIN_LEVEL, check_zone_overlap, redirect_stdout, validate_dm_password, validate_admin_password, @@ -239,15 +317,16 @@ def main(): argument_spec=dict( # basic force=dict(required=False, type='bool', default=False), - dm_password=dict(required=True, no_log=True), - password=dict(required=True, no_log=True), - master_password=dict(required=False, no_log=True), - domain=dict(required=False), - realm=dict(required=False), - hostname=dict(required=False), - ca_cert_files=dict(required=False, type='list', default=[]), + dm_password=dict(required=True, type='str', no_log=True), + password=dict(required=True, type='str', no_log=True), + master_password=dict(required=False, type='str', no_log=True), + domain=dict(required=False, type='str'), + realm=dict(required=False, type='str'), + hostname=dict(required=False, type='str'), + ca_cert_files=dict(required=False, type='list', elements='str', + default=[]), no_host_dns=dict(required=False, type='bool', default=False), - pki_config_override=dict(required=False), + pki_config_override=dict(required=False, type='str'), skip_mem_check=dict(required=False, type='bool', default=False), # server setup_adtrust=dict(required=False, type='bool', default=False), @@ -258,21 +337,25 @@ def main(): # no_hbac_allow no_pkinit=dict(required=False, type='bool', default=False), # no_ui_redirect - dirsrv_config_file=dict(required=False), + dirsrv_config_file=dict(required=False, type='str'), # ssl certificate - dirsrv_cert_files=dict(required=False, type='list', default=None), - http_cert_files=dict(required=False, type='list', default=None), - pkinit_cert_files=dict(required=False, type='list', default=None), - dirsrv_pin=dict(required=False), - http_pin=dict(required=False), - pkinit_pin=dict(required=False), - dirsrv_cert_name=dict(required=False), - http_cert_name=dict(required=False), - pkinit_cert_name=dict(required=False), + dirsrv_cert_files=dict(required=False, type='list', elements='str', + default=None), + http_cert_files=dict(required=False, type='list', elements='str', + default=None), + pkinit_cert_files=dict(required=False, type='list', elements='str', + default=None), + dirsrv_pin=dict(required=False, type='str'), + http_pin=dict(required=False, type='str'), + pkinit_pin=dict(required=False, type='str'), + dirsrv_cert_name=dict(required=False, type='str'), + http_cert_name=dict(required=False, type='str'), + pkinit_cert_name=dict(required=False, type='str'), # client # mkhomedir - ntp_servers=dict(required=False, type='list', default=None), - ntp_pool=dict(required=False, default=None), + ntp_servers=dict(required=False, type='list', elements='str', + default=None), + ntp_pool=dict(required=False, type='str', default=None), no_ntp=dict(required=False, type='bool', default=False), # ssh_trust_dns # no_ssh @@ -280,38 +363,42 @@ def main(): # no_dns_sshfp # certificate system external_ca=dict(required=False, type='bool', default=False), - external_ca_type=dict(required=False), - external_ca_profile=dict(required=False), + external_ca_type=dict(required=False, type='str'), + external_ca_profile=dict(required=False, type='str'), external_cert_files=dict(required=False, type='list', - default=None), - subject_base=dict(required=False), - ca_subject=dict(required=False), + elements='str', default=None), + subject_base=dict(required=False, type='str'), + ca_subject=dict(required=False, type='str'), # ca_signing_algorithm # dns allow_zone_overlap=dict(required=False, type='bool', default=False), - reverse_zones=dict(required=False, type='list', default=[]), + reverse_zones=dict(required=False, type='list', elements='str', + default=[]), no_reverse=dict(required=False, type='bool', default=False), auto_reverse=dict(required=False, type='bool', default=False), - zonemgr=dict(required=False), - forwarders=dict(required=False, type='list', default=[]), + zonemgr=dict(required=False, type='str'), + forwarders=dict(required=False, type='list', elements='str', + default=[]), no_forwarders=dict(required=False, type='bool', default=False), auto_forwarders=dict(required=False, type='bool', default=False), - forward_policy=dict(default=None, choices=['first', 'only']), + forward_policy=dict(required=False, type='str', + choices=['first', 'only'], default=None), no_dnssec_validation=dict(required=False, type='bool', default=False), # ad trust enable_compat=dict(required=False, type='bool', default=False), - netbios_name=dict(required=False), + netbios_name=dict(required=False, type='str'), rid_base=dict(required=False, type='int', default=1000), secondary_rid_base=dict(required=False, type='int', default=100000000), # additional ), - supports_check_mode=True, + supports_check_mode=False, ) ansible_module._ansible_debug = True + check_imports(ansible_module) setup_logging() ansible_log = AnsibleModuleLog(ansible_module)