ansible_ipa_replica: 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_REPLICA_MODULE_IMPORT_ERROR is
not None. This function needs to be called in all modules.

The `copyright` date is extended with `-2022`.
This commit is contained in:
Thomas Woerner
2022-11-08 12:09:24 +01:00
parent 0f0c098fa2
commit d4c34a28df

View File

@@ -5,7 +5,7 @@
# #
# Based on ipa-replica-install code # Based on ipa-replica-install code
# #
# Copyright (C) 2018 Red Hat # Copyright (C) 2018-2022 Red Hat
# see file 'COPYING' for use and warranty information # see file 'COPYING' for use and warranty information
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@@ -47,24 +47,18 @@ __all__ = ["contextlib", "dnsexception", "dnsresolver", "dnsreversename",
"check_domain_level_is_supported", "promotion_check_ipa_domain", "check_domain_level_is_supported", "promotion_check_ipa_domain",
"SSSDConfig", "CalledProcessError", "timeconf", "ntpinstance", "SSSDConfig", "CalledProcessError", "timeconf", "ntpinstance",
"dnsname", "kernel_keyring", "krbinstance", "getargspec", "dnsname", "kernel_keyring", "krbinstance", "getargspec",
"adtrustinstance"] "adtrustinstance", "paths", "api", "dsinstance", "ipaldap", "Env",
"ipautil", "installutils", "IPA_PYTHON_VERSION", "NUM_VERSION",
"ReplicaConfig", "create_api"]
import sys import sys
import logging
# HACK: workaround for Ansible 2.9 # Import getargspec from inspect or provide own getargspec for
# https://github.com/ansible/ansible/issues/68361 # Python 2 compatibility with Python 3.11+.
if 'ansible.executor' in sys.modules: try:
for attr in __all__:
setattr(sys.modules[__name__], attr, None)
else:
import logging
from contextlib import contextmanager as contextlib_contextmanager
# Import getargspec from inspect or provide own getargspec for
# Python 2 compatibility with Python 3.11+.
try:
from inspect import getargspec from inspect import getargspec
except ImportError: except ImportError:
from collections import namedtuple from collections import namedtuple
from inspect import getfullargspec from inspect import getfullargspec
@@ -82,6 +76,9 @@ else:
", use inspect.signature() API which can support them") ", use inspect.signature() API which can support them")
return ArgSpec(args, varargs, varkw, defaults) return ArgSpec(args, varargs, varkw, defaults)
try:
from contextlib import contextmanager as contextlib_contextmanager
from ipapython.version import NUM_VERSION, VERSION from ipapython.version import NUM_VERSION, VERSION
if NUM_VERSION < 30201: if NUM_VERSION < 30201:
@@ -177,23 +174,36 @@ else:
raise Exception("freeipa version '%s' is too old" % VERSION) raise Exception("freeipa version '%s' is too old" % VERSION)
logger = logging.getLogger("ipa-server-install") except ImportError as _err:
ANSIBLE_IPA_REPLICA_MODULE_IMPORT_ERROR = str(_err)
def setup_logging(): for attr in __all__:
setattr(sys.modules[__name__], attr, None)
else:
ANSIBLE_IPA_REPLICA_MODULE_IMPORT_ERROR = None
logger = logging.getLogger("ipa-server-install")
def setup_logging():
# logger.setLevel(logging.DEBUG) # logger.setLevel(logging.DEBUG)
standard_logging_setup( standard_logging_setup(
paths.IPAREPLICA_INSTALL_LOG, verbose=False, debug=False, paths.IPAREPLICA_INSTALL_LOG, verbose=False, debug=False,
filemode='a', console_format='%(message)s') filemode='a', console_format='%(message)s')
@contextlib_contextmanager
def redirect_stdout(stream): @contextlib_contextmanager
def redirect_stdout(stream):
sys.stdout = stream sys.stdout = stream
try: try:
yield stream yield stream
finally: finally:
sys.stdout = sys.__stdout__ sys.stdout = sys.__stdout__
class AnsibleModuleLog():
class AnsibleModuleLog():
def __init__(self, module): def __init__(self, module):
self.module = module self.module = module
_ansible_module_log = self _ansible_module_log = self
@@ -230,8 +240,9 @@ else:
self.module.debug(msg) self.module.debug(msg)
# self.module.warn(msg) # self.module.warn(msg)
# pylint: disable=too-many-instance-attributes, useless-object-inheritance
class installer_obj(object): # pylint: disable=invalid-name # pylint: disable=too-many-instance-attributes, useless-object-inheritance
class installer_obj(object): # pylint: disable=invalid-name
def __init__(self): def __init__(self):
# CompatServerReplicaInstall # CompatServerReplicaInstall
self.ca_cert_files = None self.ca_cert_files = None
@@ -287,28 +298,31 @@ else:
for name in self.__dict__: for name in self.__dict__:
yield self, name yield self, name
# pylint: enable=too-many-instance-attributes, useless-object-inheritance
# pylint: disable=attribute-defined-outside-init # pylint: enable=too-many-instance-attributes, useless-object-inheritance
installer = installer_obj()
options = installer
# DNSInstallInterface
options.dnssec_master = False
options.disable_dnssec_master = False
options.kasp_db_file = None
options.force = False
# ServerMasterInstall # pylint: disable=attribute-defined-outside-init
options.add_sids = False installer = installer_obj()
options.add_agents = False options = installer
# ServerReplicaInstall # DNSInstallInterface
options.subject_base = None options.dnssec_master = False
options.ca_subject = None options.disable_dnssec_master = False
# pylint: enable=attribute-defined-outside-init options.kasp_db_file = None
options.force = False
def gen_env_boostrap_finalize_core(etc_ipa, default_config): # ServerMasterInstall
options.add_sids = False
options.add_agents = False
# ServerReplicaInstall
options.subject_base = None
options.ca_subject = None
# pylint: enable=attribute-defined-outside-init
def gen_env_boostrap_finalize_core(etc_ipa, default_config):
env = Env() env = Env()
# env._bootstrap(context='installer', confdir=paths.ETC_IPA, log=None) # env._bootstrap(context='installer', confdir=paths.ETC_IPA, log=None)
# env._finalize_core(**dict(constants.DEFAULT_CONFIG)) # env._finalize_core(**dict(constants.DEFAULT_CONFIG))
@@ -316,7 +330,8 @@ else:
env._finalize_core(**dict(default_config)) env._finalize_core(**dict(default_config))
return env return env
def api_bootstrap_finalize(env):
def api_bootstrap_finalize(env):
# pylint: disable=no-member # pylint: disable=no-member
xmlrpc_uri = \ xmlrpc_uri = \
'https://{}/ipa/xml'.format(ipautil.format_netloc(env.host)) 'https://{}/ipa/xml'.format(ipautil.format_netloc(env.host))
@@ -328,7 +343,8 @@ else:
# pylint: enable=no-member # pylint: enable=no-member
api.finalize() api.finalize()
def gen_ReplicaConfig(): # pylint: disable=invalid-name
def gen_ReplicaConfig(): # pylint: disable=invalid-name
# pylint: disable=too-many-instance-attributes # pylint: disable=too-many-instance-attributes
class ExtendedReplicaConfig(ReplicaConfig): class ExtendedReplicaConfig(ReplicaConfig):
# pylint: disable=useless-super-delegation # pylint: disable=useless-super-delegation
@@ -381,7 +397,8 @@ else:
return config return config
def replica_ds_init_info(ansible_log,
def replica_ds_init_info(ansible_log,
config, options_, ca_is_configured, remote_api, config, options_, ca_is_configured, remote_api,
ds_ca_subject, ca_file, ds_ca_subject, ca_file,
promote=False, pkcs12_info=None): promote=False, pkcs12_info=None):
@@ -446,7 +463,8 @@ else:
return ds return ds
def ansible_module_get_parsed_ip_addresses(ansible_module,
def ansible_module_get_parsed_ip_addresses(ansible_module,
param='ip_addresses'): param='ip_addresses'):
ip_addrs = [] ip_addrs = []
for ip in ansible_module.params.get(param): for ip in ansible_module.params.get(param):
@@ -458,7 +476,8 @@ else:
ip_addrs.append(ip_parsed) ip_addrs.append(ip_parsed)
return ip_addrs return ip_addrs
def gen_remote_api(master_host_name, etc_ipa):
def gen_remote_api(master_host_name, etc_ipa):
ldapuri = 'ldaps://%s' % ipautil.format_netloc(master_host_name) ldapuri = 'ldaps://%s' % ipautil.format_netloc(master_host_name)
xmlrpc_uri = 'https://{}/ipa/xml'.format( xmlrpc_uri = 'https://{}/ipa/xml'.format(
ipautil.format_netloc(master_host_name)) ipautil.format_netloc(master_host_name))
@@ -470,3 +489,8 @@ else:
xmlrpc_uri=xmlrpc_uri) xmlrpc_uri=xmlrpc_uri)
remote_api.finalize() remote_api.finalize()
return remote_api return remote_api
def check_imports(module):
if ANSIBLE_IPA_REPLICA_MODULE_IMPORT_ERROR is not None:
module.fail_json(msg=ANSIBLE_IPA_REPLICA_MODULE_IMPORT_ERROR)