mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-08-01 12:24:43 +00:00
workaround 2.9 controller import issues
* prevents failures on Ansible 2.9 during module build due to https://github.com/ansible/ansible/issues/68361 * fixes https://github.com/freeipa/ansible-freeipa/issues/315
This commit is contained in:
@@ -22,20 +22,32 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
import sys
|
__all__ = ["gssapi", "netaddr", "api", "ipalib_errors", "Env",
|
||||||
import operator
|
"DEFAULT_CONFIG", "LDAP_GENERALIZED_TIME_FORMAT",
|
||||||
import os
|
"kinit_password", "kinit_keytab", "run", "DN", "VERSION",
|
||||||
import uuid
|
"paths", "get_credentials_if_valid", "Encoding",
|
||||||
import tempfile
|
"load_pem_x509_certificate"]
|
||||||
import shutil
|
|
||||||
import netaddr
|
|
||||||
import gssapi
|
|
||||||
from datetime import datetime
|
|
||||||
from pprint import pformat
|
|
||||||
|
|
||||||
try:
|
import sys
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
else:
|
||||||
|
import operator
|
||||||
|
import os
|
||||||
|
import uuid
|
||||||
|
import tempfile
|
||||||
|
import shutil
|
||||||
|
import netaddr
|
||||||
|
import gssapi
|
||||||
|
from datetime import datetime
|
||||||
|
from pprint import pformat
|
||||||
|
|
||||||
|
try:
|
||||||
from packaging import version
|
from packaging import version
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# If `packaging` not found, split version string for creating version
|
# If `packaging` not found, split version string for creating version
|
||||||
# object. Although it is not PEP 440 compliant, it will work for stable
|
# object. Although it is not PEP 440 compliant, it will work for stable
|
||||||
# FreeIPA releases.
|
# FreeIPA releases.
|
||||||
@@ -51,50 +63,50 @@ except ImportError:
|
|||||||
"""
|
"""
|
||||||
return tuple(re.split("[-_\.]", version_str)) # noqa: W605
|
return tuple(re.split("[-_\.]", version_str)) # noqa: W605
|
||||||
|
|
||||||
from ipalib import api
|
from ipalib import api
|
||||||
from ipalib import errors as ipalib_errors # noqa
|
from ipalib import errors as ipalib_errors # noqa
|
||||||
from ipalib.config import Env
|
from ipalib.config import Env
|
||||||
from ipalib.constants import DEFAULT_CONFIG, LDAP_GENERALIZED_TIME_FORMAT
|
from ipalib.constants import DEFAULT_CONFIG, LDAP_GENERALIZED_TIME_FORMAT
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ipalib.install.kinit import kinit_password, kinit_keytab
|
from ipalib.install.kinit import kinit_password, kinit_keytab
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from ipapython.ipautil import kinit_password, kinit_keytab
|
from ipapython.ipautil import kinit_password, kinit_keytab
|
||||||
from ipapython.ipautil import run
|
from ipapython.ipautil import run
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
from ipapython.version import VERSION
|
from ipapython.version import VERSION
|
||||||
from ipaplatform.paths import paths
|
from ipaplatform.paths import paths
|
||||||
from ipalib.krb_utils import get_credentials_if_valid
|
from ipalib.krb_utils import get_credentials_if_valid
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils._text import to_text
|
from ansible.module_utils._text import to_text
|
||||||
from ansible.module_utils.common.text.converters import jsonify
|
from ansible.module_utils.common.text.converters import jsonify
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ipalib.x509 import Encoding
|
from ipalib.x509 import Encoding
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from cryptography.hazmat.primitives.serialization import Encoding
|
from cryptography.hazmat.primitives.serialization import Encoding
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ipalib.x509 import load_pem_x509_certificate
|
from ipalib.x509 import load_pem_x509_certificate
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from ipalib.x509 import load_certificate
|
from ipalib.x509 import load_certificate
|
||||||
load_pem_x509_certificate = None
|
load_pem_x509_certificate = None
|
||||||
|
|
||||||
import socket
|
import socket
|
||||||
import base64
|
import base64
|
||||||
import six
|
import six
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from collections.abc import Mapping # noqa
|
from collections.abc import Mapping # noqa
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from collections import Mapping # noqa
|
from collections import Mapping # noqa
|
||||||
|
|
||||||
|
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
unicode = str
|
unicode = str
|
||||||
|
|
||||||
|
|
||||||
def valid_creds(module, principal): # noqa
|
def valid_creds(module, principal): # noqa
|
||||||
"""Get valid credentials matching the princial, try GSSAPI first."""
|
"""Get valid credentials matching the princial, try GSSAPI first."""
|
||||||
if "KRB5CCNAME" in os.environ:
|
if "KRB5CCNAME" in os.environ:
|
||||||
ccache = os.environ["KRB5CCNAME"]
|
ccache = os.environ["KRB5CCNAME"]
|
||||||
@@ -132,7 +144,7 @@ def valid_creds(module, principal): # noqa
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def temp_kinit(principal, password):
|
def temp_kinit(principal, password):
|
||||||
"""Kinit with password using a temporary ccache."""
|
"""Kinit with password using a temporary ccache."""
|
||||||
if not password:
|
if not password:
|
||||||
raise RuntimeError("The password is not set")
|
raise RuntimeError("The password is not set")
|
||||||
@@ -151,7 +163,7 @@ def temp_kinit(principal, password):
|
|||||||
return ccache_dir, ccache_name
|
return ccache_dir, ccache_name
|
||||||
|
|
||||||
|
|
||||||
def temp_kdestroy(ccache_dir, ccache_name):
|
def temp_kdestroy(ccache_dir, ccache_name):
|
||||||
"""Destroy temporary ticket and remove temporary ccache."""
|
"""Destroy temporary ticket and remove temporary ccache."""
|
||||||
if ccache_name is not None:
|
if ccache_name is not None:
|
||||||
run([paths.KDESTROY, '-c', ccache_name], raiseonerr=False)
|
run([paths.KDESTROY, '-c', ccache_name], raiseonerr=False)
|
||||||
@@ -160,7 +172,7 @@ def temp_kdestroy(ccache_dir, ccache_name):
|
|||||||
shutil.rmtree(ccache_dir, ignore_errors=True)
|
shutil.rmtree(ccache_dir, ignore_errors=True)
|
||||||
|
|
||||||
|
|
||||||
def api_connect(context=None):
|
def api_connect(context=None):
|
||||||
"""
|
"""
|
||||||
Initialize IPA API with the provided context.
|
Initialize IPA API with the provided context.
|
||||||
|
|
||||||
@@ -189,27 +201,27 @@ def api_connect(context=None):
|
|||||||
backend.connect(ccache=os.environ.get('KRB5CCNAME', None))
|
backend.connect(ccache=os.environ.get('KRB5CCNAME', None))
|
||||||
|
|
||||||
|
|
||||||
def api_command(module, command, name, args):
|
def api_command(module, command, name, args):
|
||||||
"""Call ipa.Command."""
|
"""Call ipa.Command."""
|
||||||
return api.Command[command](name, **args)
|
return api.Command[command](name, **args)
|
||||||
|
|
||||||
|
|
||||||
def api_command_no_name(module, command, args):
|
def api_command_no_name(module, command, args):
|
||||||
"""Call ipa.Command without a name."""
|
"""Call ipa.Command without a name."""
|
||||||
return api.Command[command](**args)
|
return api.Command[command](**args)
|
||||||
|
|
||||||
|
|
||||||
def api_check_command(command):
|
def api_check_command(command):
|
||||||
"""Return if command exists in command list."""
|
"""Return if command exists in command list."""
|
||||||
return command in api.Command
|
return command in api.Command
|
||||||
|
|
||||||
|
|
||||||
def api_check_param(command, name):
|
def api_check_param(command, name):
|
||||||
"""Check if param exists in command param list."""
|
"""Check if param exists in command param list."""
|
||||||
return name in api.Command[command].params
|
return name in api.Command[command].params
|
||||||
|
|
||||||
|
|
||||||
def api_check_ipa_version(oper, requested_version):
|
def api_check_ipa_version(oper, requested_version):
|
||||||
"""
|
"""
|
||||||
Compare the installed IPA version against a requested version.
|
Compare the installed IPA version against a requested version.
|
||||||
|
|
||||||
@@ -229,7 +241,7 @@ def api_check_ipa_version(oper, requested_version):
|
|||||||
return operation(version.parse(VERSION), version.parse(requested_version))
|
return operation(version.parse(VERSION), version.parse(requested_version))
|
||||||
|
|
||||||
|
|
||||||
def execute_api_command(module, principal, password, command, name, args):
|
def execute_api_command(module, principal, password, command, name, args):
|
||||||
"""
|
"""
|
||||||
Execute an API command.
|
Execute an API command.
|
||||||
|
|
||||||
@@ -251,7 +263,7 @@ def execute_api_command(module, principal, password, command, name, args):
|
|||||||
temp_kdestroy(ccache_dir, ccache_name)
|
temp_kdestroy(ccache_dir, ccache_name)
|
||||||
|
|
||||||
|
|
||||||
def date_format(value):
|
def date_format(value):
|
||||||
accepted_date_formats = [
|
accepted_date_formats = [
|
||||||
LDAP_GENERALIZED_TIME_FORMAT, # generalized time
|
LDAP_GENERALIZED_TIME_FORMAT, # generalized time
|
||||||
'%Y-%m-%dT%H:%M:%SZ', # ISO 8601, second precision
|
'%Y-%m-%dT%H:%M:%SZ', # ISO 8601, second precision
|
||||||
@@ -269,7 +281,7 @@ def date_format(value):
|
|||||||
raise ValueError("Invalid date '%s'" % value)
|
raise ValueError("Invalid date '%s'" % value)
|
||||||
|
|
||||||
|
|
||||||
def compare_args_ipa(module, args, ipa): # noqa
|
def compare_args_ipa(module, args, ipa): # noqa
|
||||||
"""Compare IPA obj attrs with the command args.
|
"""Compare IPA obj attrs with the command args.
|
||||||
|
|
||||||
This function compares IPA objects attributes with the args the
|
This function compares IPA objects attributes with the args the
|
||||||
@@ -331,7 +343,7 @@ def compare_args_ipa(module, args, ipa): # noqa
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _afm_convert(value):
|
def _afm_convert(value):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
return [_afm_convert(x) for x in value]
|
return [_afm_convert(x) for x in value]
|
||||||
@@ -345,15 +357,15 @@ def _afm_convert(value):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def module_params_get(module, name):
|
def module_params_get(module, name):
|
||||||
return _afm_convert(module.params.get(name))
|
return _afm_convert(module.params.get(name))
|
||||||
|
|
||||||
|
|
||||||
def api_get_realm():
|
def api_get_realm():
|
||||||
return api.env.realm
|
return api.env.realm
|
||||||
|
|
||||||
|
|
||||||
def gen_add_del_lists(user_list, res_list):
|
def gen_add_del_lists(user_list, res_list):
|
||||||
"""Generate the lists for the addition and removal of members."""
|
"""Generate the lists for the addition and removal of members."""
|
||||||
# The user list is None, therefore the parameter should not be touched
|
# The user list is None, therefore the parameter should not be touched
|
||||||
if user_list is None:
|
if user_list is None:
|
||||||
@@ -365,7 +377,7 @@ def gen_add_del_lists(user_list, res_list):
|
|||||||
return add_list, del_list
|
return add_list, del_list
|
||||||
|
|
||||||
|
|
||||||
def encode_certificate(cert):
|
def encode_certificate(cert):
|
||||||
"""
|
"""
|
||||||
Encode a certificate using base64.
|
Encode a certificate using base64.
|
||||||
|
|
||||||
@@ -380,7 +392,7 @@ def encode_certificate(cert):
|
|||||||
return encoded
|
return encoded
|
||||||
|
|
||||||
|
|
||||||
def load_cert_from_str(cert):
|
def load_cert_from_str(cert):
|
||||||
cert = cert.strip()
|
cert = cert.strip()
|
||||||
if not cert.startswith("-----BEGIN CERTIFICATE-----"):
|
if not cert.startswith("-----BEGIN CERTIFICATE-----"):
|
||||||
cert = "-----BEGIN CERTIFICATE-----\n" + cert
|
cert = "-----BEGIN CERTIFICATE-----\n" + cert
|
||||||
@@ -394,7 +406,7 @@ def load_cert_from_str(cert):
|
|||||||
return cert
|
return cert
|
||||||
|
|
||||||
|
|
||||||
def DN_x500_text(text):
|
def DN_x500_text(text):
|
||||||
if hasattr(DN, "x500_text"):
|
if hasattr(DN, "x500_text"):
|
||||||
return DN(text).x500_text()
|
return DN(text).x500_text()
|
||||||
else:
|
else:
|
||||||
@@ -404,7 +416,7 @@ def DN_x500_text(text):
|
|||||||
return str(dn)
|
return str(dn)
|
||||||
|
|
||||||
|
|
||||||
def is_valid_port(port):
|
def is_valid_port(port):
|
||||||
if not isinstance(port, int):
|
if not isinstance(port, int):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -414,7 +426,7 @@ def is_valid_port(port):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def is_ip_address(ipaddr):
|
def is_ip_address(ipaddr):
|
||||||
"""Test if given IP address is a valid IPv4 or IPv6 address."""
|
"""Test if given IP address is a valid IPv4 or IPv6 address."""
|
||||||
try:
|
try:
|
||||||
netaddr.IPAddress(str(ipaddr))
|
netaddr.IPAddress(str(ipaddr))
|
||||||
@@ -423,7 +435,7 @@ def is_ip_address(ipaddr):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def is_ip_network_address(ipaddr):
|
def is_ip_network_address(ipaddr):
|
||||||
"""Test if given IP address is a valid IPv4 or IPv6 address."""
|
"""Test if given IP address is a valid IPv4 or IPv6 address."""
|
||||||
try:
|
try:
|
||||||
netaddr.IPNetwork(str(ipaddr))
|
netaddr.IPNetwork(str(ipaddr))
|
||||||
@@ -432,7 +444,7 @@ def is_ip_network_address(ipaddr):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def is_ipv4_addr(ipaddr):
|
def is_ipv4_addr(ipaddr):
|
||||||
"""Test if given IP address is a valid IPv4 address."""
|
"""Test if given IP address is a valid IPv4 address."""
|
||||||
try:
|
try:
|
||||||
socket.inet_pton(socket.AF_INET, ipaddr)
|
socket.inet_pton(socket.AF_INET, ipaddr)
|
||||||
@@ -441,7 +453,7 @@ def is_ipv4_addr(ipaddr):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def is_ipv6_addr(ipaddr):
|
def is_ipv6_addr(ipaddr):
|
||||||
"""Test if given IP address is a valid IPv6 address."""
|
"""Test if given IP address is a valid IPv6 address."""
|
||||||
try:
|
try:
|
||||||
socket.inet_pton(socket.AF_INET6, ipaddr)
|
socket.inet_pton(socket.AF_INET6, ipaddr)
|
||||||
@@ -450,7 +462,7 @@ def is_ipv6_addr(ipaddr):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def exit_raw_json(module, **kwargs):
|
def exit_raw_json(module, **kwargs):
|
||||||
"""
|
"""
|
||||||
Print the raw parameters in JSON format, without masking.
|
Print the raw parameters in JSON format, without masking.
|
||||||
|
|
||||||
@@ -470,7 +482,7 @@ def exit_raw_json(module, **kwargs):
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
class AnsibleFreeIPAParams(Mapping):
|
class AnsibleFreeIPAParams(Mapping):
|
||||||
def __init__(self, ansible_module):
|
def __init__(self, ansible_module):
|
||||||
self.mapping = ansible_module.params
|
self.mapping = ansible_module.params
|
||||||
self.ansible_module = ansible_module
|
self.ansible_module = ansible_module
|
||||||
@@ -494,7 +506,7 @@ class AnsibleFreeIPAParams(Mapping):
|
|||||||
return self.get(name)
|
return self.get(name)
|
||||||
|
|
||||||
|
|
||||||
class FreeIPABaseModule(AnsibleModule):
|
class FreeIPABaseModule(AnsibleModule):
|
||||||
"""
|
"""
|
||||||
Base class for FreeIPA Ansible modules.
|
Base class for FreeIPA Ansible modules.
|
||||||
|
|
||||||
|
|||||||
@@ -45,17 +45,25 @@ __all__ = ["gssapi", "version", "ipadiscovery", "api", "errors", "x509",
|
|||||||
"configure_firefox", "sync_time", "check_ldap_conf",
|
"configure_firefox", "sync_time", "check_ldap_conf",
|
||||||
"sssd_enable_ifp"]
|
"sssd_enable_ifp"]
|
||||||
|
|
||||||
from ipapython.version import NUM_VERSION, VERSION
|
import sys
|
||||||
|
|
||||||
if NUM_VERSION < 30201:
|
# 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)
|
||||||
|
|
||||||
|
else:
|
||||||
|
from ipapython.version import NUM_VERSION, VERSION
|
||||||
|
|
||||||
|
if NUM_VERSION < 30201:
|
||||||
# See ipapython/version.py
|
# See ipapython/version.py
|
||||||
IPA_MAJOR, IPA_MINOR, IPA_RELEASE = [int(x) for x in VERSION.split(".", 2)]
|
IPA_MAJOR, IPA_MINOR, IPA_RELEASE = [int(x) for x in VERSION.split(".", 2)]
|
||||||
IPA_PYTHON_VERSION = IPA_MAJOR*10000 + IPA_MINOR*100 + IPA_RELEASE
|
IPA_PYTHON_VERSION = IPA_MAJOR*10000 + IPA_MINOR*100 + IPA_RELEASE
|
||||||
else:
|
else:
|
||||||
IPA_PYTHON_VERSION = NUM_VERSION
|
IPA_PYTHON_VERSION = NUM_VERSION
|
||||||
|
|
||||||
|
|
||||||
class installer_obj(object):
|
class installer_obj(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -84,14 +92,14 @@ class installer_obj(object):
|
|||||||
yield self, name
|
yield self, name
|
||||||
|
|
||||||
|
|
||||||
# Initialize installer settings
|
# Initialize installer settings
|
||||||
installer = installer_obj()
|
installer = installer_obj()
|
||||||
# Create options
|
# Create options
|
||||||
options = installer
|
options = installer
|
||||||
options.interactive = False
|
options.interactive = False
|
||||||
options.unattended = not options.interactive
|
options.unattended = not options.interactive
|
||||||
|
|
||||||
if NUM_VERSION >= 40400:
|
if NUM_VERSION >= 40400:
|
||||||
# IPA version >= 4.4
|
# IPA version >= 4.4
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
@@ -264,7 +272,7 @@ if NUM_VERSION >= 40400:
|
|||||||
logger = logging.getLogger("ipa-client-install")
|
logger = logging.getLogger("ipa-client-install")
|
||||||
root_logger = logger
|
root_logger = logger
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# IPA version < 4.4
|
# IPA version < 4.4
|
||||||
|
|
||||||
raise Exception("freeipa version '%s' is too old" % VERSION)
|
raise Exception("freeipa version '%s' is too old" % VERSION)
|
||||||
|
|||||||
@@ -46,21 +46,27 @@ __all__ = ["contextlib", "dnsexception", "dnsresolver", "dnsreversename",
|
|||||||
"dnsname", "kernel_keyring", "krbinstance"]
|
"dnsname", "kernel_keyring", "krbinstance"]
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import logging
|
|
||||||
from contextlib import contextmanager as contextlib_contextmanager
|
# 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)
|
||||||
|
else:
|
||||||
|
import logging
|
||||||
|
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:
|
||||||
# See ipapython/version.py
|
# See ipapython/version.py
|
||||||
IPA_MAJOR, IPA_MINOR, IPA_RELEASE = [int(x) for x in VERSION.split(".", 2)]
|
IPA_MAJOR, IPA_MINOR, IPA_RELEASE = [int(x) for x in VERSION.split(".", 2)]
|
||||||
IPA_PYTHON_VERSION = IPA_MAJOR*10000 + IPA_MINOR*100 + IPA_RELEASE
|
IPA_PYTHON_VERSION = IPA_MAJOR*10000 + IPA_MINOR*100 + IPA_RELEASE
|
||||||
else:
|
else:
|
||||||
IPA_PYTHON_VERSION = NUM_VERSION
|
IPA_PYTHON_VERSION = NUM_VERSION
|
||||||
|
|
||||||
|
|
||||||
if NUM_VERSION >= 40600:
|
if NUM_VERSION >= 40600:
|
||||||
# IPA version >= 4.6
|
# IPA version >= 4.6
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
@@ -137,24 +143,24 @@ if NUM_VERSION >= 40600:
|
|||||||
time_service = "ntpd"
|
time_service = "ntpd"
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# IPA version < 4.6
|
# IPA version < 4.6
|
||||||
|
|
||||||
raise Exception("freeipa version '%s' is too old" % VERSION)
|
raise Exception("freeipa version '%s' is too old" % VERSION)
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger("ipa-server-install")
|
logger = logging.getLogger("ipa-server-install")
|
||||||
|
|
||||||
|
|
||||||
def setup_logging():
|
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
|
@contextlib_contextmanager
|
||||||
def redirect_stdout(f):
|
def redirect_stdout(f):
|
||||||
sys.stdout = f
|
sys.stdout = f
|
||||||
try:
|
try:
|
||||||
yield f
|
yield f
|
||||||
@@ -162,7 +168,7 @@ def redirect_stdout(f):
|
|||||||
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
|
||||||
@@ -196,7 +202,7 @@ class AnsibleModuleLog():
|
|||||||
# self.module.warn(msg)
|
# self.module.warn(msg)
|
||||||
|
|
||||||
|
|
||||||
class installer_obj(object):
|
class installer_obj(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# CompatServerReplicaInstall
|
# CompatServerReplicaInstall
|
||||||
self.ca_cert_files = None
|
self.ca_cert_files = None
|
||||||
@@ -251,25 +257,25 @@ class installer_obj(object):
|
|||||||
yield self, name
|
yield self, name
|
||||||
|
|
||||||
|
|
||||||
installer = installer_obj()
|
installer = installer_obj()
|
||||||
options = installer
|
options = installer
|
||||||
|
|
||||||
# DNSInstallInterface
|
# DNSInstallInterface
|
||||||
options.dnssec_master = False
|
options.dnssec_master = False
|
||||||
options.disable_dnssec_master = False
|
options.disable_dnssec_master = False
|
||||||
options.kasp_db_file = None
|
options.kasp_db_file = None
|
||||||
options.force = False
|
options.force = False
|
||||||
|
|
||||||
# ServerMasterInstall
|
# ServerMasterInstall
|
||||||
options.add_sids = False
|
options.add_sids = False
|
||||||
options.add_agents = False
|
options.add_agents = False
|
||||||
|
|
||||||
# ServerReplicaInstall
|
# ServerReplicaInstall
|
||||||
options.subject_base = None
|
options.subject_base = None
|
||||||
options.ca_subject = None
|
options.ca_subject = None
|
||||||
|
|
||||||
|
|
||||||
def gen_env_boostrap_finalize_core(etc_ipa, default_config):
|
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))
|
||||||
@@ -278,7 +284,7 @@ def gen_env_boostrap_finalize_core(etc_ipa, 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 = 'https://{}/ipa/xml'.format(ipautil.format_netloc(env.host))
|
xmlrpc_uri = 'https://{}/ipa/xml'.format(ipautil.format_netloc(env.host))
|
||||||
api.bootstrap(in_server=True,
|
api.bootstrap(in_server=True,
|
||||||
@@ -290,7 +296,7 @@ def api_bootstrap_finalize(env):
|
|||||||
api.finalize()
|
api.finalize()
|
||||||
|
|
||||||
|
|
||||||
def gen_ReplicaConfig():
|
def gen_ReplicaConfig():
|
||||||
class ExtendedReplicaConfig(ReplicaConfig):
|
class ExtendedReplicaConfig(ReplicaConfig):
|
||||||
def __init__(self, top_dir=None):
|
def __init__(self, top_dir=None):
|
||||||
super(ExtendedReplicaConfig, self).__init__(top_dir)
|
super(ExtendedReplicaConfig, self).__init__(top_dir)
|
||||||
@@ -333,7 +339,7 @@ def gen_ReplicaConfig():
|
|||||||
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):
|
||||||
@@ -398,7 +404,7 @@ def replica_ds_init_info(ansible_log,
|
|||||||
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):
|
||||||
@@ -410,7 +416,7 @@ def ansible_module_get_parsed_ip_addresses(ansible_module,
|
|||||||
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))
|
||||||
|
|||||||
@@ -41,23 +41,31 @@ __all__ = ["IPAChangeConf", "certmonger", "sysrestore", "root_logger",
|
|||||||
"check_available_memory"]
|
"check_available_memory"]
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import logging
|
|
||||||
from contextlib import contextmanager as contextlib_contextmanager
|
# HACK: workaround for Ansible 2.9 https://github.com/ansible/ansible/issues/68361
|
||||||
import six
|
if 'ansible.executor' in sys.modules:
|
||||||
import base64
|
for attr in __all__:
|
||||||
|
setattr(sys.modules[__name__], attr, None)
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from contextlib import contextmanager as contextlib_contextmanager
|
||||||
|
import six
|
||||||
|
import base64
|
||||||
|
|
||||||
|
|
||||||
from ipapython.version import NUM_VERSION, VERSION
|
from ipapython.version import NUM_VERSION, VERSION
|
||||||
|
|
||||||
if NUM_VERSION < 30201:
|
if NUM_VERSION < 30201:
|
||||||
# See ipapython/version.py
|
# See ipapython/version.py
|
||||||
IPA_MAJOR, IPA_MINOR, IPA_RELEASE = [int(x) for x in VERSION.split(".", 2)]
|
IPA_MAJOR, IPA_MINOR, IPA_RELEASE = [int(x) for x in VERSION.split(".", 2)]
|
||||||
IPA_PYTHON_VERSION = IPA_MAJOR*10000 + IPA_MINOR*100 + IPA_RELEASE
|
IPA_PYTHON_VERSION = IPA_MAJOR*10000 + IPA_MINOR*100 + IPA_RELEASE
|
||||||
else:
|
else:
|
||||||
IPA_PYTHON_VERSION = NUM_VERSION
|
IPA_PYTHON_VERSION = NUM_VERSION
|
||||||
|
|
||||||
|
|
||||||
if NUM_VERSION >= 40500:
|
if NUM_VERSION >= 40500:
|
||||||
# IPA version >= 4.5
|
# IPA version >= 4.5
|
||||||
|
|
||||||
from ipaclient.install.ipachangeconf import IPAChangeConf
|
from ipaclient.install.ipachangeconf import IPAChangeConf
|
||||||
@@ -167,24 +175,24 @@ if NUM_VERSION >= 40500:
|
|||||||
from ipalib.x509 import load_certificate
|
from ipalib.x509 import load_certificate
|
||||||
load_pem_x509_certificate = None
|
load_pem_x509_certificate = None
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# IPA version < 4.5
|
# IPA version < 4.5
|
||||||
|
|
||||||
raise Exception("freeipa version '%s' is too old" % VERSION)
|
raise Exception("freeipa version '%s' is too old" % VERSION)
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger("ipa-server-install")
|
logger = logging.getLogger("ipa-server-install")
|
||||||
|
|
||||||
|
|
||||||
def setup_logging():
|
def setup_logging():
|
||||||
# logger.setLevel(logging.DEBUG)
|
# logger.setLevel(logging.DEBUG)
|
||||||
standard_logging_setup(
|
standard_logging_setup(
|
||||||
paths.IPASERVER_INSTALL_LOG, verbose=False, debug=False,
|
paths.IPASERVER_INSTALL_LOG, verbose=False, debug=False,
|
||||||
filemode='a', console_format='%(message)s')
|
filemode='a', console_format='%(message)s')
|
||||||
|
|
||||||
|
|
||||||
@contextlib_contextmanager
|
@contextlib_contextmanager
|
||||||
def redirect_stdout(f):
|
def redirect_stdout(f):
|
||||||
sys.stdout = f
|
sys.stdout = f
|
||||||
try:
|
try:
|
||||||
yield f
|
yield f
|
||||||
@@ -192,7 +200,7 @@ def redirect_stdout(f):
|
|||||||
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
|
||||||
@@ -226,7 +234,7 @@ class AnsibleModuleLog():
|
|||||||
# self.module.warn(msg)
|
# self.module.warn(msg)
|
||||||
|
|
||||||
|
|
||||||
class options_obj(object):
|
class options_obj(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._replica_install = False
|
self._replica_install = False
|
||||||
self.dnssec_master = False # future unknown
|
self.dnssec_master = False # future unknown
|
||||||
@@ -250,53 +258,53 @@ class options_obj(object):
|
|||||||
yield self, name
|
yield self, name
|
||||||
|
|
||||||
|
|
||||||
options = options_obj()
|
options = options_obj()
|
||||||
installer = options
|
installer = options
|
||||||
|
|
||||||
# ServerMasterInstall
|
# ServerMasterInstall
|
||||||
options.add_sids = True
|
options.add_sids = True
|
||||||
options.add_agents = False
|
options.add_agents = False
|
||||||
|
|
||||||
|
|
||||||
# Installable
|
# Installable
|
||||||
options.uninstalling = False
|
options.uninstalling = False
|
||||||
|
|
||||||
# ServerInstallInterface
|
# ServerInstallInterface
|
||||||
options.description = "Server"
|
options.description = "Server"
|
||||||
|
|
||||||
options.kinit_attempts = 1
|
options.kinit_attempts = 1
|
||||||
options.fixed_primary = True
|
options.fixed_primary = True
|
||||||
options.permit = False
|
options.permit = False
|
||||||
options.enable_dns_updates = False
|
options.enable_dns_updates = False
|
||||||
options.no_krb5_offline_passwords = False
|
options.no_krb5_offline_passwords = False
|
||||||
options.preserve_sssd = False
|
options.preserve_sssd = False
|
||||||
options.no_sssd = False
|
options.no_sssd = False
|
||||||
|
|
||||||
# ServerMasterInstall
|
# ServerMasterInstall
|
||||||
options.force_join = False
|
options.force_join = False
|
||||||
options.servers = None
|
options.servers = None
|
||||||
options.no_wait_for_dns = True
|
options.no_wait_for_dns = True
|
||||||
options.host_password = None
|
options.host_password = None
|
||||||
options.keytab = None
|
options.keytab = None
|
||||||
options.setup_ca = True
|
options.setup_ca = True
|
||||||
# always run sidgen task and do not allow adding agents on first master
|
# always run sidgen task and do not allow adding agents on first master
|
||||||
options.add_sids = True
|
options.add_sids = True
|
||||||
options.add_agents = False
|
options.add_agents = False
|
||||||
|
|
||||||
# ADTrustInstallInterface
|
# ADTrustInstallInterface
|
||||||
# no_msdcs is deprecated
|
# no_msdcs is deprecated
|
||||||
options.no_msdcs = False
|
options.no_msdcs = False
|
||||||
|
|
||||||
# For pylint
|
# For pylint
|
||||||
options.external_cert_files = None
|
options.external_cert_files = None
|
||||||
options.dirsrv_cert_files = None
|
options.dirsrv_cert_files = None
|
||||||
|
|
||||||
# Uninstall
|
# Uninstall
|
||||||
options.ignore_topology_disconnect = False
|
options.ignore_topology_disconnect = False
|
||||||
options.ignore_last_of_role = False
|
options.ignore_last_of_role = False
|
||||||
|
|
||||||
|
|
||||||
def api_Backend_ldap2(host_name, setup_ca, connect=False):
|
def api_Backend_ldap2(host_name, setup_ca, connect=False):
|
||||||
# we are sure we have the configuration file ready.
|
# we are sure we have the configuration file ready.
|
||||||
cfg = dict(context='installer', confdir=paths.ETC_IPA, in_server=True,
|
cfg = dict(context='installer', confdir=paths.ETC_IPA, in_server=True,
|
||||||
host=host_name)
|
host=host_name)
|
||||||
@@ -310,7 +318,7 @@ def api_Backend_ldap2(host_name, setup_ca, connect=False):
|
|||||||
api.Backend.ldap2.connect()
|
api.Backend.ldap2.connect()
|
||||||
|
|
||||||
|
|
||||||
def ds_init_info(ansible_log, fstore, domainlevel, dirsrv_config_file,
|
def ds_init_info(ansible_log, fstore, domainlevel, dirsrv_config_file,
|
||||||
realm_name, host_name, domain_name, dm_password,
|
realm_name, host_name, domain_name, dm_password,
|
||||||
idstart, idmax, subject_base, ca_subject,
|
idstart, idmax, subject_base, ca_subject,
|
||||||
no_hbac_allow, dirsrv_pkcs12_info, no_pkinit):
|
no_hbac_allow, dirsrv_pkcs12_info, no_pkinit):
|
||||||
@@ -342,7 +350,7 @@ def ds_init_info(ansible_log, fstore, domainlevel, dirsrv_config_file,
|
|||||||
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):
|
||||||
@@ -354,7 +362,7 @@ def ansible_module_get_parsed_ip_addresses(ansible_module,
|
|||||||
return ip_addrs
|
return ip_addrs
|
||||||
|
|
||||||
|
|
||||||
def encode_certificate(cert):
|
def encode_certificate(cert):
|
||||||
"""
|
"""
|
||||||
Encode a certificate using base64.
|
Encode a certificate using base64.
|
||||||
|
|
||||||
@@ -369,7 +377,7 @@ def encode_certificate(cert):
|
|||||||
return encoded
|
return encoded
|
||||||
|
|
||||||
|
|
||||||
def decode_certificate(cert):
|
def decode_certificate(cert):
|
||||||
"""
|
"""
|
||||||
Decode a certificate using base64.
|
Decode a certificate using base64.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user