From 079049fa6630a43898a025fd7f7d98346adadf8b Mon Sep 17 00:00:00 2001 From: Thomas Woerner <twoerner@redhat.com> Date: Fri, 1 Dec 2017 13:15:34 +0100 Subject: [PATCH] New role for ipaserver installation The support for external cert files is not complete yet. --- install-server.yml | 8 + module_utils/ansible_ipa_server.py | 219 +++++ roles/ipaserver/defaults/main.yml | 40 + roles/ipaserver/files/py3test.py | 9 + roles/ipaserver/library/ipaserver.py | 536 ++++++++++++ .../ipaserver/library/ipaserver_enable_ipa.py | 96 +++ .../ipaserver/library/ipaserver_load_cache.py | 94 +++ .../library/ipaserver_master_password.py | 93 +++ roles/ipaserver/library/ipaserver_prepare.py | 262 ++++++ .../library/ipaserver_set_ds_password.py | 138 ++++ .../library/ipaserver_setup_adtrust.py | 88 ++ roles/ipaserver/library/ipaserver_setup_ca.py | 223 +++++ .../library/ipaserver_setup_custodia.py | 93 +++ .../ipaserver/library/ipaserver_setup_dns.py | 119 +++ roles/ipaserver/library/ipaserver_setup_ds.py | 171 ++++ .../ipaserver/library/ipaserver_setup_http.py | 206 +++++ .../ipaserver/library/ipaserver_setup_kra.py | 90 ++ .../ipaserver/library/ipaserver_setup_krb.py | 155 ++++ .../ipaserver/library/ipaserver_setup_ntp.py | 79 ++ .../ipaserver/library/ipaserver_setup_otpd.py | 91 ++ roles/ipaserver/library/ipaserver_test.py | 777 ++++++++++++++++++ roles/ipaserver/meta/main.yml | 27 + roles/ipaserver/tasks/install-1.yml | 153 ++++ roles/ipaserver/tasks/install-2.yml | 88 ++ roles/ipaserver/tasks/install-ipaserver.yml | 215 +++++ roles/ipaserver/tasks/install-test.yml | 31 + roles/ipaserver/tasks/install.yml | 428 ++++++++++ roles/ipaserver/tasks/install_cache.yml | 566 +++++++++++++ roles/ipaserver/tasks/main.yml | 18 + roles/ipaserver/tasks/python_2_3_test.yml | 19 + roles/ipaserver/tasks/uninstall.yml | 24 + roles/ipaserver/tasks/uninstall.yml.old | 19 + roles/ipaserver/vars/Fedora-25.yml | 3 + roles/ipaserver/vars/Fedora-26.yml | 3 + roles/ipaserver/vars/Fedora.yml | 3 + roles/ipaserver/vars/RedHat-7.3.yml | 5 + roles/ipaserver/vars/RedHat-7.yml | 5 + roles/ipaserver/vars/default.yml | 5 + uninstall-server.yml | 8 + 39 files changed, 5207 insertions(+) create mode 100644 install-server.yml create mode 100644 module_utils/ansible_ipa_server.py create mode 100644 roles/ipaserver/defaults/main.yml create mode 100644 roles/ipaserver/files/py3test.py create mode 100644 roles/ipaserver/library/ipaserver.py create mode 100644 roles/ipaserver/library/ipaserver_enable_ipa.py create mode 100644 roles/ipaserver/library/ipaserver_load_cache.py create mode 100644 roles/ipaserver/library/ipaserver_master_password.py create mode 100644 roles/ipaserver/library/ipaserver_prepare.py create mode 100644 roles/ipaserver/library/ipaserver_set_ds_password.py create mode 100644 roles/ipaserver/library/ipaserver_setup_adtrust.py create mode 100644 roles/ipaserver/library/ipaserver_setup_ca.py create mode 100644 roles/ipaserver/library/ipaserver_setup_custodia.py create mode 100644 roles/ipaserver/library/ipaserver_setup_dns.py create mode 100644 roles/ipaserver/library/ipaserver_setup_ds.py create mode 100644 roles/ipaserver/library/ipaserver_setup_http.py create mode 100644 roles/ipaserver/library/ipaserver_setup_kra.py create mode 100644 roles/ipaserver/library/ipaserver_setup_krb.py create mode 100644 roles/ipaserver/library/ipaserver_setup_ntp.py create mode 100644 roles/ipaserver/library/ipaserver_setup_otpd.py create mode 100644 roles/ipaserver/library/ipaserver_test.py create mode 100644 roles/ipaserver/meta/main.yml create mode 100644 roles/ipaserver/tasks/install-1.yml create mode 100644 roles/ipaserver/tasks/install-2.yml create mode 100644 roles/ipaserver/tasks/install-ipaserver.yml create mode 100644 roles/ipaserver/tasks/install-test.yml create mode 100644 roles/ipaserver/tasks/install.yml create mode 100644 roles/ipaserver/tasks/install_cache.yml create mode 100644 roles/ipaserver/tasks/main.yml create mode 100644 roles/ipaserver/tasks/python_2_3_test.yml create mode 100644 roles/ipaserver/tasks/uninstall.yml create mode 100644 roles/ipaserver/tasks/uninstall.yml.old create mode 100644 roles/ipaserver/vars/Fedora-25.yml create mode 100644 roles/ipaserver/vars/Fedora-26.yml create mode 100644 roles/ipaserver/vars/Fedora.yml create mode 100644 roles/ipaserver/vars/RedHat-7.3.yml create mode 100644 roles/ipaserver/vars/RedHat-7.yml create mode 100644 roles/ipaserver/vars/default.yml create mode 100644 uninstall-server.yml diff --git a/install-server.yml b/install-server.yml new file mode 100644 index 00000000..711d6961 --- /dev/null +++ b/install-server.yml @@ -0,0 +1,8 @@ +--- +- name: Playbook to configure IPA servers + hosts: ipaserver + become: true + + roles: + - role: ipaserver + state: present diff --git a/module_utils/ansible_ipa_server.py b/module_utils/ansible_ipa_server.py new file mode 100644 index 00000000..8da79a1c --- /dev/null +++ b/module_utils/ansible_ipa_server.py @@ -0,0 +1,219 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import os +import sys +import logging +#import fcntl +from contextlib import contextmanager as contextlib_contextmanager + + +from ipapython.version import NUM_VERSION, VERSION + +if NUM_VERSION < 30201: + # See ipapython/version.py + 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 +else: + IPA_PYTHON_VERSION = NUM_VERSION + + +if NUM_VERSION >= 40600: + # IPA version >= 4.6 + + import errno + import pickle + import shutil + import tempfile + import textwrap + import random + + import six + + from ipalib.install import certmonger, sysrestore + from ipapython import ipautil + from ipapython.ipautil import ( + format_netloc, ipa_generate_password, run, user_input) + from ipapython.admintool import ScriptError + from ipaplatform import services + from ipaplatform.paths import paths + from ipaplatform.tasks import tasks + from ipalib import api, errors, x509 + from ipalib.constants import DOMAIN_LEVEL_0, MIN_DOMAIN_LEVEL, MAX_DOMAIN_LEVEL + from ipalib.util import ( + validate_domain_name, + no_matching_interface_for_ip_address_warning, + ) + from ipapython.dnsutil import check_zone_overlap + from ipaclient.install import ntpconf + from ipaserver.install import ( + adtrust, bindinstance, ca, dns, dsinstance, + httpinstance, installutils, kra, krbinstance, + ntpinstance, otpdinstance, custodiainstance, replication, service, + sysupgrade) + adtrust_imported = True + kra_imported = True + from ipaserver.install.installutils import ( + IPA_MODULES, BadHostError, get_fqdn, get_server_ip_address, + is_ipa_configured, load_pkcs12, read_password, verify_fqdn, + update_hosts_file) + from ipaserver.install.server.install import ( + check_dirsrv, validate_admin_password, validate_dm_password, + write_cache) + try: + from ipaserver.install.installutils import default_subject_base + except ImportError: + def default_subject_base(realm_name): + return DN(('O', realm_name)) + try: + from ipaserver.install.installutils import default_ca_subject_dn + except ImportError: + def default_ca_subject_dn(subject_base): + return DN(('CN', 'Certificate Authority'), subject_base) + + if six.PY3: + unicode = str + + try: + from ipaserver.install import adtrustinstance + _server_trust_ad_installed = True + except ImportError: + _server_trust_ad_installed = False + +else: + # IPA version < 4.6 + + raise Exception("freeipa version '%s' is too old" % VERSION) + + +logger = logging.getLogger("ipa-server-install") +logger.setLevel(logging.DEBUG) + + +@contextlib_contextmanager +def redirect_stdout(f): + sys.stdout = f + try: + yield f + 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 write(self, msg): + # self.module.debug(msg) + self.module.warn(msg) + + +class options_obj(object): + 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 + + +options = options_obj() +installer = options + + +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() + + +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 diff --git a/roles/ipaserver/defaults/main.yml b/roles/ipaserver/defaults/main.yml new file mode 100644 index 00000000..ae106aa8 --- /dev/null +++ b/roles/ipaserver/defaults/main.yml @@ -0,0 +1,40 @@ +--- +# defaults file for ipaserver + +### basic ### +ipaserver_no_host_dns: no +### server ### +ipaserver_setup_adtrust: no +ipaserver_setup_kra: no +ipaserver_setup_dns: no +ipaserver_no_hbac_allow: no +ipaserver_no_pkinit: no +ipaserver_no_ui_redirect: no +### ssl certificate ### +### client ### +ipaserver_mkhomedir: no +ipaserver_no_ntp: no +#ipaserver_ssh_trust_dns: no +#ipaserver_no_ssh: no +#ipaserver_no_sshd: no +#ipaserver_no_dns_sshfp: no +### certificate system ### +ipaserver_external_ca: no +### dns ### +ipaserver_allow_zone_overlap: no +ipaserver_no_reverse: no +ipaserver_auto_reverse: no +ipaserver_no_forwarders: no +ipaserver_auto_forwarders: no +ipaserver_no_dnssec_validation: no +### ad trust ### +ipaserver_enable_compat: no +ipaserver_setup_ca: yes + +### additional ### +ipaserver_allow_repair: no +ipaserver_allow_missing: [ ] + +### uninstall ### +ipaserver_ignore_topology_disconnect: no +ipaserver_ignore_last_of_role: no diff --git a/roles/ipaserver/files/py3test.py b/roles/ipaserver/files/py3test.py new file mode 100644 index 00000000..8f5c2d85 --- /dev/null +++ b/roles/ipaserver/files/py3test.py @@ -0,0 +1,9 @@ +#!/usr/bin/python3 + +# Test ipaerver python3 binding +from ipaserver.install.server.install import install_check + +# Check ipapython version to be >= 4.6 +from ipapython.version import NUM_VERSION, VERSION +if NUM_VERSION < 40590: + raise Exception("ipa %s not usable with python3" % VERSION) diff --git a/roles/ipaserver/library/ipaserver.py b/roles/ipaserver/library/ipaserver.py new file mode 100644 index 00000000..6b0e04d1 --- /dev/null +++ b/roles/ipaserver/library/ipaserver.py @@ -0,0 +1,536 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Florence Blanc-Renaud <frenaud@redhat.com> +# Thomas Woerner <twoerner@redhat.com> +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = ''' +--- +module: ipaserver +short description: Configures a server machine as IPA server +description: + Configures a server machine to use IPA for authentication and + identity services. + The enrollment requires one authentication method among the 3 following: + - Kerberos principal and password (principal/password) + - Kerberos keytab file (keytab) + - One-Time-Password (otp) +options: + state: + description: the server state + required: false + default: present + choices: [ "present", "absent" ] + domain: + description: The primary DNS domain of an existing IPA deployment + required: true + realm: + description: The Kerberos realm of an existing IPA deployment + required: true + password: + description: The password for the kerberos admin + required: true + dm_password: + description: The password for the Directory Manager + required: true + +# ip_addresses: +# description: Master Server IP Addresses +# required: false +# hostname: +# description: Fully qualified name of this host +# required: false + + mkhomedir: + description: Create home directories for users on their first login + required: false + default: no + setup_dns: + description: Configure bind with our zone + required: false + default: no + no_host_dns: + description: Do not use DNS for hostname lookup during installation + required: false + default: no + no_ntp: + description: Do not configure ntp + required: false + default: no + + idstart: + description: The starting value for the IDs range (default random) + required: false + idmax: + description: The max value for the IDs range (default: idstart+199999) + required: false + no_hbac_allow: + description: Don't install allow_all HBAC rule + required: false + default: no +# ignore_topology_disconnect: +# description: Do not check whether server uninstall disconnects the topology (domain level 1+) +# required: false +# default: no +# ignore_last_of_role: +# description: Do not check whether server uninstall removes last CA/DNS server or DNSSec master (domain level 1+) +# required: false + no_pkinit: + description: Disables pkinit setup steps + required: false + no_ui_redirect: + description: Do not automatically redirect to the Web UI + required: false + + ssh_trust_dns: + description: Configure OpenSSH client to trust DNS SSHFP records + required: false + no_ssh: + description: Do not configure OpenSSH client + required: false + no_sshd: + description: Do not configure OpenSSH server + required: false + no_dns_sshfp: + description: Do not automatically create DNS SSHFP records + required: false + 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: false + + external_ca: + description: Generate a CSR for the IPA CA certificate to be signed by an external CA + required: false + external_ca_type: + description: Type of the external CA + required: false + external_cert_files: + description: File containing the IPA CA certificate and the external CA certificate chain + required: false + + dirsrv_cert_files: + description: File containing the Directory Server SSL certificate and private key + required: false + dirsrv_pin: + description: The password to unlock the Directory Server private key + required: false + dirsrv_cert_name: + description: Name of the Directory Server SSL certificate to install + required: false + + http_cert_files: + description: File containing the Apache Server SSL certificate and private key + required: false + http_pin: + description: The password to unlock the Apache Server private key + required: false + http_cert_name: + description: Name of the Apache Server SSL certificate to install + required: false + + pkinit_cert_files: + description: File containing the Kerberos KDC SSL certificate and private key + required: false + pkinit_pin: + description: The password to unlock the Kerberos KDC private key + required: false + pkinit_cert_name: + description: Name of the Kerberos KDC SSL certificate to install + required: false + + ca_cert_files: + description: File containing CA certificates for the service certificate files + required: false + subject: + description: The certificate subject base (default O=<realm-name>) + required: false + ca_signing_algorithm: + description: Signing algorithm of the IPA CA certificate + required: false + + forwarders: + description: Add DNS forwarders + required: false + + + +author: + - Florence Blanc-Renaud + - Thomas Woerner +''' + +EXAMPLES = ''' +# Example from Ansible Playbooks +# Unenroll server +- ipaserver: + state: absent + +# Enroll server using admin credentials, with auto-discovery +- ipaserver: + password: MySecretPassword + dm_password: MySecretPassword +''' + +RETURN = ''' +tbd +''' + +import os +from six.moves.configparser import RawConfigParser +from ansible.module_utils.basic import AnsibleModule +try: + from ipalib.install.sysrestore import SYSRESTORE_STATEFILE +except ImportError: + from ipapython.sysrestore import SYSRESTORE_STATEFILE +from ipaplatform.paths import paths + + +def is_server_configured(): + """ + Check if ipa server is configured. + + IPA server is configured when /etc/ipa/default.conf exists and + /var/lib/ipa/sysrestore/sysrestore.state exists. + + :returns: boolean + """ + + return (os.path.isfile(paths.IPA_DEFAULT_CONF) and + os.path.isfile(os.path.join(paths.SYSRESTORE, + SYSRESTORE_STATEFILE))) + + +def get_ipa_conf(): + """ + Return IPA configuration read from /etc/ipa/default.conf + + :returns: dict containing key,value + """ + + parser = RawConfigParser() + parser.read(paths.IPA_DEFAULT_CONF) + result = dict() + for item in ['basedn', 'realm', 'domain', 'server', 'host', 'xmlrpc_uri']: + if parser.has_option('global', item): + value = parser.get('global', item) + else: + value = None + if value: + result[item] = value + + return result + + +def main(): + module = AnsibleModule( + supports_check_mode=True, + argument_spec=dict( + state=dict(default='present', choices=['present', 'absent']), + # basic + dm_password=dict(required=False, no_log=True), + password=dict(required=False, no_log=True), +# ip_addresses=dict(required=False, type='list'), + domain=dict(required=True), + realm=dict(required=True), +# hostname=dict(required=False), + ca_cert_files=dict(required=False, type='list'), + no_host_dns=dict(required=False, type='bool', default=False), + # server +# setup_adtrust=dict(required=False, type='bool', default=F#alse), +# setup_kra=dict(required=False, type='bool', default=False), + setup_dns=dict(required=False, type='bool', default=False), + idstart=dict(required=False, type='int', default=0), + idmax=dict(required=False, type='int', default=0), + no_hbac_allow=dict(required=False, type='bool', default=False), + no_pkinit=dict(required=False, type='bool', default=False), + no_ui_redirect=dict(required=False, type='bool', default=False), + dirsrv_config_file=dict(required=False), + # ssl certificate + dirsrv_cert_files=dict(required=False, type='list'), + dirsrv_pin=dict(required=False), + dirsrv_cert_name=dict(required=False), + http_cert_files=dict(required=False, type='list'), + http_pin=dict(required=False), + http_cert_name=dict(required=False), + pkinit_cert_files=dict(required=False, type='list'), + pkinit_pin=dict(required=False), + pkinit_cert_name=dict(required=False), + # client + mkhomedir=dict(required=False, type='bool', default=False), + no_ntp=dict(required=False, type='bool', default=False), + ssh_trust_dns=dict(required=False, type='bool', default=False), + no_ssh=dict(required=False, type='bool', default=False), + no_sshd=dict(required=False, type='bool', default=False), + no_dns_sshfp=dict(required=False, type='bool', default=False), + # certificate system + external_ca=dict(required=False), + external_ca_type=dict(default='generic', + choices=['generic', 'ms-cs']), + external_cert_files=dict(required=False, type='list'), + subject_base=dict(required=False), + ca_signing_algorithm=dict(required=False), + + # dns + allow_zone_overlap=dict(required=False, type='bool', default=False), + reverse_zones=dict(required=False, type='list'), + no_reverse=dict(required=False, type='bool', default=False), + auto_reverse=dict(required=False, type='bool', default=False), + zone_manager=dict(required=False), + forwarders=dict(required=False, type='list'), + no_forwarders=dict(required=False, type='bool', default=False), + auto_forwarders=dict(required=False, type='bool', default=False), + forward_policy=dict(default='first', choices=['first', 'only']), + 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), + rid_base=dict(required=False), + secondary_rid_base=dict(required=False), + ), + ) + + module._ansible_debug = True + state = module.params.get('state') + + domain = module.params.get('domain') + realm = module.params.get('realm') + password = module.params.get('password') + dm_password = module.params.get('dm_password') + + #ip_addresses = module.params.get('ip_addresses') + #hostname = module.params.get('hostname') + + mkhomedir = module.params.get('mkhomedir') + setup_dns = module.params.get('setup_dns') + no_host_dns = module.params.get('no_host_dns') + no_ntp = module.params.get('no_ntp') + + idstart = module.params.get('idstart') + idmax = module.params.get('idmax') + no_hbac_allow = module.params.get('no_hbac_allow') + ignore_topology_disconnect = module.params.get('ignore_topology_disconnect') + ignore_last_of_role = module.params.get('ignore_last_of_role') + no_pkinit = module.params.get('no_pkinit') + no_ui_redirect = module.params.get('no_ui_redirect') + + ssh_trust_dns = module.params.get('ssh_trust_dns') + no_ssh = module.params.get('no_ssh') + no_sshd = module.params.get('no_sshd') + no_dns_sshfp = module.params.get('no_dns_sshfp') + dirsrv_config_file = module.params.get('dirsrv_config_file') + + external_ca = module.params.get('external_ca') + external_ca_type = module.params.get('external_ca_type') + external_cert_files = module.params.get('external_cert_files') + + dirsrv_cert_files=module.params.get('dirsrv_cert_files') + dirsrv_pin=module.params.get('dirsrv_pin') + dirsrv_cert_name=module.params.get('dirsrv_cert_name') + + http_cert_files=module.params.get('http_cert_files') + http_pin=module.params.get('http_pin') + http_cert_name=module.params.get('http_cert_name') + + pkinit_cert_files=module.params.get('pkinit_cert_files') + pkinit_pin=module.params.get('pkinit_pin') + pkinit_cert_name=module.params.get('pkinit_cert_name') + + ca_cert_files=module.params.get('ca_cert_files') + subject=module.params.get('subject') + ca_signing_algorithm=module.params.get('ca_signing_algorithm') + + forwarders = module.params.get('forwarders') + + if state == 'present': + if not password or not dm_password: + module.fail_json( + msg="Password and dm password need to be specified") + + # Check if ipa server is already configured + if is_server_configured(): + # Check that realm and domain match + current_config = get_ipa_conf() + if domain and domain != current_config.get('domain'): + module.fail_json(msg="IPA server already installed " + "with a conflicting domain") + if realm and realm != current_config.get('realm'): + module.fail_json(msg="IPA server already installed " + "with a conflicting realm") + + # server is already configured and no inconsistency + # detected + return module.exit_json(changed=False, domain=domain, realm=realm) + + # ipa server not installed + if module.check_mode: + # Do nothing, just return changed=True + return module.exit_json(changed=True) + + # basic options + cmd = [ + module.get_bin_path("ipa-server-install"), + "-U", + "--ds-password", dm_password, + "--admin-password", password, + "--domain", domain, + "--realm", realm, + ] + + #for ip in ip_addresses: + # cmd.append("--ip-address=%s" % ip) + #if hostname: + # cmd.append("--hostname=%s" % hostname) + + for cert_file in ca_cert_files: + cmd.append("--ca-cert-file=%s" % cert_file) + if no_host_dns: + cmd.append("--no-host-dns") + + # server options + #if setup_adtrust: + # cmd.append("--setup-adtrust") + #if setup_kra: + # cmd.append("--setup-kra") + if setup_dns: + cmd.append("--setup-dns") + if idstart: + cmd.append("--idstart=%d", idstart) + if idmax: + cmd.append("--idstart=%d", idmax) + if no_hbac_allow: + cmd.append("--no_hbac_allow") + if no_pkinit: + cmd.append("--no-pkinit") + if no_ui_redirect: + cmd.append("--no-ui-redirect") + if dirsrv_config_file: + cmd.append("--dirsrv-config-file=%s" % dirsrv_config_file) + + # ssl certificate options + for cert_file in dirsrv_cert_files: + cmd.append("--dirsrv-cert-file=%s" % cert_file) + if dirsrv_pin: + cmd.append("--dirsrv-pin=%s" % dirserv_pin) + if dirsrv_cert_name: + cmd.append("--dirsrv-cert-name=%s" % dirsrv_cert_name) + for cert_file in http_cert_files: + cmd.append("--http-cert-file=%s" % cert_file) + if http_pin: + cmd.append("--http-pin=%s" % http_pin) + if http_cert_name: + cmd.append("--http-cert-name=%s" % http_cert_name) + for cert_file in pkinit_cert_files: + cmd.append("--pkinit-cert-file=%s" % cert_file) + if pkinit_pin: + cmd.append("--pkinit-pin=%s" % pkinit_pin) + if pkinit_cert_name: + cmd.append("--pkinit-cert-name=%s" % pkinit_cert_name) + + # client options + if mkhomedir: + cmd.append("--mkhomedir") + if no_ntp: + cmd.append("--no-ntp") + if ssh_trust_dns: + cmd.append("--ssh-trust-dns") + if no_ssh: + cmd.append("--no-ssh") + if no_sshd: + cmd.append("--no-sshd") + if no_dns_sshfp: + cmd.append("--no-dns-sshfp") + + # certificate system options + if external_ca: + cmd.append("--external-ca") + if external_ca_type: + cmd.append("--external-ca-type=%s" % external_ca_type) + for cert_file in external_cert_files: + cmd.append("--external-cert-file=%s" % cert_file) + if subject_base: + cmd.append("--subject=%s" % subject) + if ca_signing_algorithm: + cmd.append("--ca-signing-algorithm=%s" % ca_signing_algorithm) + + # dns options + if allow_zone_overlop: + cmd.append("--allow-zone-overlap") + for reverse_zone in reverse_zones: + cmd.append("--reverse-zone=%s" % reverse_zone) + if no_reverse: + cmd.append("--no-reverse") + if auto_reverse: + cmd.append("--auto-reverse") + if zonemgr: + cmd.append("--zonemgr=%s" % zonemgr) + for forwarder in forwarders: + cmd.append("--forwarder=%s" % forwarder) + if no_forwarders: + cmd.append("--no-forwarders") + if auto_forwarders: + cmd.append("--auto-forwarders") + if forward_policy: + cmd.append("--forward-policy=%s" % forward_policy) + if no_dnssec_validation: + cmd.append("--no-dnssec-validation") + + # ad trust options + #if enable_compat: + # cmd.append("--enable-compat") + #if netbios_name: + # cmd.append("--netbios-name=%s" % netbios_name) + #if rid_base: + # cmd.append("--rid-base=%s" % rid_base) + #if secondary_rid_base: + # cmd.append("--secondary-rid-base=%s" % rid_base) + + else: # state == adsent + if not is_server_configured(): + # Nothing to do + module.exit_json(changed=False) + + # Server is configured + # If in check mode, do nothing but return changed=True + if module.check_mode: + module.exit_json(changed=True) + + cmd = [ + module.get_bin_path('ipa-server-install'), + "--uninstall", + "-U", + ] + + if ignore_topology_disconnect: + cmd.append("--ignore-topology-disconnect") + if ignore_last_of_role: + cmd.append("--ignore-last-of-role") + + retcode, stdout, stderr = module.run_command(cmd) + if retcode != 0: + module.fail_json(msg="Failed to uninstall IPA server: %s" % stderr) + + module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_enable_ipa.py b/roles/ipaserver/library/ipaserver_enable_ipa.py new file mode 100644 index 00000000..d964ce9c --- /dev/null +++ b/roles/ipaserver/library/ipaserver_enable_ipa.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: enable_ipa +short description: +description: +options: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +def main(): + ansible_module = AnsibleModule( + argument_spec = dict( + hostname=dict(required=False), + setup_ca=dict(required=True, type='bool'), + ), + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values ############################################################# + + options.host_name = ansible_module.params.get('hostname') + options.setup_ca = ansible_module.params.get('setup_ca') + + # Configuration for ipalib, we will bootstrap and finalize later, after + # we are sure we have the configuration file ready. + cfg = dict( + context='installer', + confdir=paths.ETC_IPA, + in_server=True, + # make sure host name specified by user is used instead of default + host=options.host_name, + ) + if options.setup_ca: + # we have an IPA-integrated CA + cfg['ca_host'] = options.host_name + + api.bootstrap(**cfg) + api.finalize() + api.Backend.ldap2.connect() + + # setup ds ###################################################### + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + sstore = sysrestore.StateFile(paths.SYSRESTORE) + + with redirect_stdout(ansible_log): + services.knownservices.ipa.enable() + + ansible_module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_load_cache.py b/roles/ipaserver/library/ipaserver_load_cache.py new file mode 100644 index 00000000..ae805d3f --- /dev/null +++ b/roles/ipaserver/library/ipaserver_load_cache.py @@ -0,0 +1,94 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: ipaserver_load_cache +short description: +description: +options: + dm_password: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +def main(): + ansible_module = AnsibleModule( + argument_spec = dict( + ### basic ### + dm_password=dict(required=True, no_log=True), + ), + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values ############################################################ + + ### basic ### + options.dm_password = ansible_module.params.get('dm_password') + + # restore cache ######################################################### + + if ipautil.file_exists(paths.ROOT_IPA_CACHE): + if options.dm_password is None: + ansible_module.fail_json(msg="Directory Manager password required") + try: + cache_vars = read_cache(dm_password) + options.__dict__.update(cache_vars) + if cache_vars.get('external_ca', False): + options.external_ca = False + options.interactive = False + except Exception as e: + ansible_module.fail_json( + msg="Cannot process the cache file: %s" % str(e)) + + kwargs = { "changed": True } + for name in options.__dict__: + kwargs[name] = options.__dict__[name] + ansible_module.exit_json(kwargs) + + # done ################################################################## + + ansible_module.exit_json(changed=False) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_master_password.py b/roles/ipaserver/library/ipaserver_master_password.py new file mode 100644 index 00000000..f6f15dc8 --- /dev/null +++ b/roles/ipaserver/library/ipaserver_master_password.py @@ -0,0 +1,93 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: master_password +short description: Generate kerberos master password if not given +description: + Generate kerberos master password if not given +options: + master_password: + description: kerberos master password (normally autogenerated) + required: false +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +value: + description: The master password + returned: always +''' + +import os + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +def main(): + module = AnsibleModule( + argument_spec = dict( + #basic + dm_password=dict(required=True, no_log=True), + master_password=dict(required=False, no_log=True), + ), + supports_check_mode = True, + ) + + module._ansible_debug = True + + options.dm_password = module.params.get('dm_password') + options.master_password = module.params.get('master_password') + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + sstore = sysrestore.StateFile(paths.SYSRESTORE) + + # This will override any settings passed in on the cmdline + if os.path.isfile(paths.ROOT_IPA_CACHE): + # dm_password check removed, checked already + try: + cache_vars = read_cache(options.dm_password) + options.__dict__.update(cache_vars) + except Exception as e: + module.fail_json(msg="Cannot process the cache file: %s" % str(e)) + + if not options.master_password: + options.master_password = ipa_generate_password() + + module.exit_json(changed=True, + value=options.master_password) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_prepare.py b/roles/ipaserver/library/ipaserver_prepare.py new file mode 100644 index 00000000..44c533ba --- /dev/null +++ b/roles/ipaserver/library/ipaserver_prepare.py @@ -0,0 +1,262 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: ipaserver_prepare +short description: +description: +options: + dm_password: + password: + ip_addresses: + domain: + realm: + hostname: + ca_cert_files: + no_host_dns: + setup_adtrust: + setup_kra: + setup_dns: + external_ca: + external_cert_files: + subject_base: + ca_subject: + reverse_zones: + no_reverse: + auto_reverse: + forwarders: + no_forwarders: + auto_forwarders: + forward_policy: + enable_compat: + netbios_name: + rid_base: + secondary_rid_base: + setup_ca: + _hostname_overridden: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +def main(): + ansible_module = AnsibleModule( + argument_spec = dict( + ### basic ### + 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=[]), + no_host_dns=dict(required=False, type='bool', default=False), + ### server ### + setup_adtrust=dict(required=False, type='bool', default=False), + setup_kra=dict(required=False, type='bool', default=False), + setup_dns=dict(required=False, type='bool', default=False), + ### ssl certificate ### + ### client ### + ### certificate system ### + external_ca=dict(required=False), + external_cert_files=dict(required=False, type='list', default=[]), + subject_base=dict(required=False), + ca_subject=dict(required=False), + ### dns ### + reverse_zones=dict(required=False, type='list', 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=[]), + no_forwarders=dict(required=False, type='bool', default=False), + auto_forwarders=dict(required=False, type='bool', default=False), + forward_policy=dict(required=False), + ### ad trust ### + enable_compat=dict(required=False, type='bool', default=False), + netbios_name=dict(required=False), + rid_base=dict(required=False, type='int'), + secondary_rid_base=dict(required=False, type='int'), + + ### additional ### + setup_ca=dict(required=False, type='bool', default=False), + _hostname_overridden=dict(required=False, type='bool', + default=False), + ), + supports_check_mode = True, + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values #################################################### + + options.dm_password = ansible_module.params.get('dm_password') + options.admin_password = ansible_module.params.get('password') + options.ip_addresses = ansible_module.params.get('ip_addresses') + options.domain_name = ansible_module.params.get('domain') + options.realm_name = ansible_module.params.get('realm') + options.host_name = ansible_module.params.get('hostname') + options.ca_cert_files = ansible_module.params.get('ca_cert_files') + options.no_host_dns = ansible_module.params.get('no_host_dns') + ### server ### + options.setup_adtrust = ansible_module.params.get('setup_adtrust') + options.setup_kra = ansible_module.params.get('setup_kra') + options.setup_dns = ansible_module.params.get('setup_dns') + #options.no_pkinit = ansible_module.params.get('no_pkinit') + ### ssl certificate ### + #options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') + ### client ### + #options.no_ntp = ansible_module.params.get('no_ntp') + ### certificate system ### + options.external_ca = ansible_module.params.get('external_ca') + options.external_cert_files = ansible_module.params.get( + 'external_cert_files') + options.subject_base = ansible_module.params.get('subject_base') + options.ca_subject = ansible_module.params.get('ca_subject') + ### dns ### + options.reverse_zones = ansible_module.params.get('reverse_zones') + options.no_reverse = ansible_module.params.get('no_reverse') + options.auto_reverse = ansible_module.params.get('auto_reverse') + options.forwarders = ansible_module.params.get('forwarders') + options.no_forwarders = ansible_module.params.get('no_forwarders') + options.auto_forwarders = ansible_module.params.get('auto_forwarders') + options.forward_policy = ansible_module.params.get('forward_policy') + + ### additional ### + options.setup_ca = ansible_module.params.get('setup_ca') + options._host_name_overridden = ansible_module.params.get( + '_hostname_overridden') + + # init ################################################################## + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + sstore = sysrestore.StateFile(paths.SYSRESTORE) + + # Configuration for ipalib, we will bootstrap and finalize later, after + # we are sure we have the configuration file ready. + cfg = dict( + context='installer', + confdir=paths.ETC_IPA, + in_server=True, + # make sure host name specified by user is used instead of default + host=options.host_name, + ) + if options.setup_ca: + # we have an IPA-integrated CA + cfg['ca_host'] = options.host_name + + # Create the management framework config file and finalize api + target_fname = paths.IPA_DEFAULT_CONF + fd = open(target_fname, "w") + fd.write("[global]\n") + fd.write("host=%s\n" % options.host_name) + fd.write("basedn=%s\n" % ipautil.realm_to_suffix(options.realm_name)) + fd.write("realm=%s\n" % options.realm_name) + fd.write("domain=%s\n" % options.domain_name) + fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % \ + format_netloc(options.host_name)) + fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % \ + installutils.realm_to_serverid(options.realm_name)) + if options.setup_ca: + fd.write("enable_ra=True\n") + fd.write("ra_plugin=dogtag\n") + fd.write("dogtag_version=10\n") + else: + fd.write("enable_ra=False\n") + fd.write("ra_plugin=none\n") + fd.write("mode=production\n") + fd.close() + + # Must be readable for everyone + os.chmod(target_fname, 0o644) + + api.bootstrap(**cfg) + api.finalize() + + if options.setup_ca: + with redirect_stdout(ansible_log): + ca.install_check(False, None, options) + if options.setup_kra: + with redirect_stdout(ansible_log): + kra.install_check(api, None, options) + + if options.setup_dns: + with redirect_stdout(ansible_log): + dns.install_check(False, api, False, options, options.host_name) + ip_addresses = dns.ip_addresses + else: + ip_addresses = get_server_ip_address(options.host_name, + not options.interactive, False, + options.ip_addresses) + + # check addresses here, dns module is doing own check + no_matching_interface_for_ip_address_warning(ip_addresses) + options.ip_addresses = ip_addresses + options.reverse_zones = dns.reverse_zones + + instance_name = "-".join(options.realm_name.split(".")) + dirsrv = services.knownservices.dirsrv + if (options.external_cert_files + and dirsrv.is_installed(instance_name) + and not dirsrv.is_running(instance_name)): + logger.debug('Starting Directory Server') + services.knownservices.dirsrv.start(instance_name) + + if options.setup_adtrust: + with redirect_stdout(ansible_log): + adtrust.install_check(False, options, api) + + _update_hosts_file = False + # options needs to update hosts file when DNS subsystem will be + # installed or custom addresses are used + if options.ip_addresses or options.setup_dns: + _update_hosts_file = True + + if options._host_name_overridden: + tasks.backup_hostname(fstore, sstore) + tasks.set_hostname(options.host_name) + + if _update_hosts_file: + update_hosts_file(ip_addresses, options.host_name, fstore) + + ansible_module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_set_ds_password.py b/roles/ipaserver/library/ipaserver_set_ds_password.py new file mode 100644 index 00000000..70425858 --- /dev/null +++ b/roles/ipaserver/library/ipaserver_set_ds_password.py @@ -0,0 +1,138 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: set_ds_password +short description: +description: +options: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +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), + ### 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), + ### ssl certificate ### + dirsrv_cert_files=dict(required=False, type='list', default=[]), + subject_base=dict(required=False), + ca_subject=dict(required=False), + ### certificate system ### + external_cert_files=dict(required=False, type='list', default=[]), + ### additional ### + domainlevel=dict(required=False, type='int', + default=MAX_DOMAIN_LEVEL), + ), + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values #################################################### + + ### basic ### + options.dm_password = ansible_module.params.get('dm_password') + options.admin_password = ansible_module.params.get('password') + options.domain_name = ansible_module.params.get('domain') + options.realm_name = ansible_module.params.get('realm') + options.host_name = ansible_module.params.get('hostname') + ### server ### + options.setup_ca = ansible_module.params.get('setup_ca') + options.idstart = ansible_module.params.get('idstart') + options.idmax = ansible_module.params.get('idmax') + options.no_hbac_allow = ansible_module.params.get('no_hbac_allow') + options.no_pkinit = ansible_module.params.get('no_pkinit') + options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file') + options._dirsrv_pkcs12_info = ansible_module.params.get( + '_dirsrv_pkcs12_info') + ### ssl certificate ### + options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') + options.subject_base = ansible_module.params.get('subject_base') + options.ca_subject = ansible_module.params.get('ca_subject') + ### certificate system ### + options.external_cert_files = ansible_module.params.get( + 'external_cert_files') + ### additional ### + options.domainlevel = ansible_module.params.get('domainlevel') + options.domain_level = options.domainlevel + + # init ########################################################## + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + sstore = sysrestore.StateFile(paths.SYSRESTORE) + + api_Backend_ldap2(options.host_name, options.setup_ca, connect=True) + + ds = ds_init_info(ansible_log, fstore, + options.domainlevel, options.dirsrv_config_file, + options.realm_name, options.host_name, + options.domain_name, options.dm_password, + options.idstart, options.idmax, + options.subject_base, options.ca_subject, + options.no_hbac_allow, options._dirsrv_pkcs12_info, + options.no_pkinit) + + # set ds password ############################################### + + with redirect_stdout(ansible_log): + ds.change_admin_password(options.admin_password) + + # done ########################################################## + + ansible_module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_setup_adtrust.py b/roles/ipaserver/library/ipaserver_setup_adtrust.py new file mode 100644 index 00000000..954e1dfa --- /dev/null +++ b/roles/ipaserver/library/ipaserver_setup_adtrust.py @@ -0,0 +1,88 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: setup_adtrust +short description: +description: +options: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +def main(): + ansible_module = AnsibleModule( + argument_spec = dict( + # basic + hostname=dict(required=False), + setup_ca=dict(required=True, type='bool', default=False), + setup_adtrust=dict(required=True, type='bool', default=False), + ), + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values #################################################### + + options.host_name = ansible_module.params.get('hostname') + options.setup_ca = ansible_module.params.get('setup_ca') + options.setup_adtrust = ansible_module.params.get('setup_adtrust') + + # init ########################################################## + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + sstore = sysrestore.StateFile(paths.SYSRESTORE) + + api_Backend_ldap2_connect(options.host_name, options.setup_ca) + + # setup ds ###################################################### + + with redirect_stdout(ansible_log): + adtrust.install(False, options, fstore, api) + + # done ########################################################## + + ansible_module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_setup_ca.py b/roles/ipaserver/library/ipaserver_setup_ca.py new file mode 100644 index 00000000..d8e11398 --- /dev/null +++ b/roles/ipaserver/library/ipaserver_setup_ca.py @@ -0,0 +1,223 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: ipaserver_setup_ca +short description: +description: +options: + dm_password: + password: + master_password: + ip_addresses: + domain: + realm: + hostname: + no_host_dns: + setup_adtrust: + setup_kra: + setup_dns: + setup_ca: + idstart: + idmax: + no_hbac_allow: + no_pkinit: + dirsrv_config_file: + dirsrv_cert_files: + _dirsrv_pkcs12_info: + external_ca: + subject_base: + _subject_base: + ca_subject: + _ca_subject: + ca_signing_algorithm: + reverse_zones: + no_reverse: + auto_forwarders: + domainlevel: + _http_ca_cert: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +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), + no_host_dns=dict(required=False, type='bool', default=False), + ### server ### + setup_adtrust=dict(required=False, type='bool', default=False), + setup_kra=dict(required=False, type='bool', default=False), + setup_dns=dict(required=False, type='bool', default=False), + setup_ca=dict(required=False, type='bool', default=False), + 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_cert_files=dict(required=False), + _dirsrv_pkcs12_info=dict(required=False), + ### certificate system ### + external_ca=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), + ca_signing_algorithm=dict(required=False), + ### dns ### + reverse_zones=dict(required=False, type='list', 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), + ), + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values ############################################################ + + ### basic ### + options.dm_password = ansible_module.params.get('dm_password') + options.admin_password = ansible_module.params.get('password') + options.master_password = ansible_module.params.get('master_password') + options.ip_addresses = ansible_module.params.get('ip_addresses') + options.domain_name = ansible_module.params.get('domain') + options.realm_name = ansible_module.params.get('realm') + options.host_name = ansible_module.params.get('hostname') + options.no_host_dns = ansible_module.params.get('no_host_dns') + ### server ### + options.setup_adtrust = ansible_module.params.get('setup_adtrust') + options.setup_kra = ansible_module.params.get('setup_kra') + options.setup_dns = ansible_module.params.get('setup_dns') + options.setup_ca = ansible_module.params.get('setup_ca') + options.idstart = ansible_module.params.get('idstart') + options.idmax = ansible_module.params.get('idmax') + options.no_hbac_allow = ansible_module.params.get('no_hbac_allow') + options.no_pkinit = ansible_module.params.get('no_pkinit') + options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file') + options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') + options._dirsrv_pkcs12_info = ansible_module.params.get( + '_dirsrv_pkcs12_info') + ### certificate system ### + options.external_ca = ansible_module.params.get('external_ca') + options.external_cert_files = ansible_module.params.get( + 'external_cert_files') + options.subject_base = ansible_module.params.get('subject_base') + options._subject_base = ansible_module.params.get('_subject_base') + options.ca_subject = ansible_module.params.get('ca_subject') + options._ca_subject = ansible_module.params.get('_ca_subject') + options.ca_signing_algorithm = ansible_module.params.get( + 'ca_signing_algorithm') + ### dns ### + options.reverse_zones = ansible_module.params.get('reverse_zones') + options.no_reverse = ansible_module.params.get('no_reverse') + options.auto_forwarders = ansible_module.params.get('auto_forwarders') + ### additional ### + options.domainlevel = ansible_module.params.get('domainlevel') + options._http_ca_cert = ansible_module.params.get('_http_ca_cert') + #options._update_hosts_file = ansible_module.params.get('update_hosts_file') + + # init ################################################################# + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + + api_Backend_ldap2(options.host_name, options.setup_ca, connect=True) + + ds = ds_init_info(ansible_log, fstore, + options.domainlevel, options.dirsrv_config_file, + options.realm_name, options.host_name, + options.domain_name, options.dm_password, + options.idstart, options.idmax, + options.subject_base, options.ca_subject, + options.no_hbac_allow, options._dirsrv_pkcs12_info, + options.no_pkinit) + + # setup CA ############################################################## + + with redirect_stdout(ansible_log): + if options.setup_ca: + if not options.external_cert_files and options.external_ca: + # stage 1 of external CA installation + cache_vars = {n: options.__dict__[n] for o, n in options.knobs() + if n in options.__dict__} + write_cache(cache_vars) + + ca.install_step_0(False, None, options) + else: + # Put the CA cert where other instances expect it + x509.write_certificate(options._http_ca_cert, paths.IPA_CA_CRT) + os.chmod(paths.IPA_CA_CRT, 0o444) + + if not options.no_pkinit: + x509.write_certificate(options._http_ca_cert, + paths.KDC_CA_BUNDLE_PEM) + else: + with open(paths.KDC_CA_BUNDLE_PEM, 'w'): + pass + os.chmod(paths.KDC_CA_BUNDLE_PEM, 0o444) + + x509.write_certificate(options._http_ca_cert, paths.CA_BUNDLE_PEM) + os.chmod(paths.CA_BUNDLE_PEM, 0o444) + + with redirect_stdout(ansible_log): + # we now need to enable ssl on the ds + ds.enable_ssl() + + if options.setup_ca: + with redirect_stdout(ansible_log): + ca.install_step_1(False, None, options) + + ansible_module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_setup_custodia.py b/roles/ipaserver/library/ipaserver_setup_custodia.py new file mode 100644 index 00000000..2ab04a26 --- /dev/null +++ b/roles/ipaserver/library/ipaserver_setup_custodia.py @@ -0,0 +1,93 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: ipaserver_setup_custodia +short description: +description: +options: + realm: + hostname: + setup_ca: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +def main(): + ansible_module = AnsibleModule( + argument_spec = dict( + # basic + realm=dict(required=True), + hostname=dict(required=False), + setup_ca=dict(required=False, type='bool', default=False), + ), + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values ############################################################ + + options.realm_name = ansible_module.params.get('realm') + options.host_name = ansible_module.params.get('hostname') + options.setup_ca = ansible_module.params.get('setup_ca') + + # init ################################################################## + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + + api_Backend_ldap2(options.host_name, options.setup_ca, connect=True) + + # setup custodia ######################################################## + + custodia = custodiainstance.CustodiaInstance(options.host_name, + options.realm_name) + custodia.set_output(ansible_log) + with redirect_stdout(ansible_log): + custodia.create_instance() + + # done ################################################################## + + ansible_module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_setup_dns.py b/roles/ipaserver/library/ipaserver_setup_dns.py new file mode 100644 index 00000000..90605c8f --- /dev/null +++ b/roles/ipaserver/library/ipaserver_setup_dns.py @@ -0,0 +1,119 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: setup_dns +short description: +description: +options: + hostname: + setup_dns: + setup_ca: + zonemgr: + forwarders: + forward_policy: + no_dnssec_validation: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +def main(): + ansible_module = AnsibleModule( + argument_spec = dict( + ### basic ### + hostname=dict(required=True), + ### 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']), + no_dnssec_validation=dict(required=False, type='bool', + default=False), + ), + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values ############################################################ + + ### basic ### + options.host_name = ansible_module.params.get('hostname') + ### server ### + options.setup_dns = ansible_module.params.get('setup_dns') + options.setup_ca = ansible_module.params.get('setup_ca') + ### dns ### + options.zonemgr = ansible_module.params.get('zonemgr') + options.forwarders = ansible_module.params.get('forwarders') + options.forward_policy = ansible_module.params.get('forward_policy') + options.no_dnssec_validation = ansible_module.params.get( + 'no_dnssec_validation') + + # init ################################################################## + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + + api_Backend_ldap2(options.host_name, options.setup_ca, connect=True) + + # setup dns ############################################################# + + with redirect_stdout(ansible_log): + if options.setup_dns: + dns.install(False, False, options) + else: + # Create a BIND instance + bind = bindinstance.BindInstance(fstore) + bind.set_output(ansible_log) + bind.setup(host_name, ip_addresses, realm_name, + domain_name, (), 'first', (), + zonemgr=options.zonemgr, + no_dnssec_validation=options.no_dnssec_validation) + bind.create_file_with_system_records() + + # done ################################################################## + + ansible_module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_setup_ds.py b/roles/ipaserver/library/ipaserver_setup_ds.py new file mode 100644 index 00000000..60ec2c28 --- /dev/null +++ b/roles/ipaserver/library/ipaserver_setup_ds.py @@ -0,0 +1,171 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: ipaserver_setup_ds +short description: +description: +options: + dm_password: + password: + domain: + realm: + hostname: + idstart: + idmax: + no_pkinit: + no_hbac_allow: + subject_base: + ca_subject: + setup_ca +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +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), + ### 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), + ### ssl certificate ### + dirsrv_cert_files=dict(required=False, type='list', default=[]), + ### certificate system ### + external_cert_files=dict(required=False, type='list', default=[]), + subject_base=dict(required=False), + ca_subject=dict(required=False), + + ### additional ### + setup_ca=dict(required=False, type='bool', default=False), + ), + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values ############################################################ + + ### basic ### + options.dm_password = ansible_module.params.get('dm_password') + options.domain_name = ansible_module.params.get('domain') + options.realm_name = ansible_module.params.get('realm') + options.host_name = ansible_module.params.get('hostname') + ### server ### + options.idstart = ansible_module.params.get('idstart') + options.idmax = ansible_module.params.get('idmax') + options.no_pkinit = ansible_module.params.get('no_pkinit') + options.no_hbac_allow = ansible_module.params.get('no_hbac_allow') + options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file') + ### ssl certificate ### + options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') + ### certificate system ### + options.external_cert_files = ansible_module.params.get( + 'external_cert_files') + options.subject_base = ansible_module.params.get('subject_base') + options.ca_subject = ansible_module.params.get('ca_subject') + + ### additional ### + options.setup_ca = ansible_module.params.get('setup_ca') + + # init ################################################################## + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + + # api Backend connect only if external_cert_files is not set + api_Backend_ldap2(options.host_name, options.setup_ca, connect=False) + + # setup DS ############################################################## + + # Create a directory server instance + if not options.external_cert_files: + ds = dsinstance.DsInstance(fstore=fstore, + domainlevel=options.domainlevel, + config_ldif=options.dirsrv_config_file) + ds.set_output(ansible_log) + + if options.dirsrv_cert_files: + _dirsrv_pkcs12_info=options.dirsrv_pkcs12_info + else: + _dirsrv_pkcs12_info=None + + with redirect_stdout(ansible_log): + ds.create_instance(options.realm_name, options.host_name, + options.domain_name, + options.dm_password, _dirsrv_pkcs12_info, + idstart=options.idstart, idmax=options.idmax, + subject_base=options.subject_base, + ca_subject=options.ca_subject, + hbac_allow=not options.no_hbac_allow, + setup_pkinit=not options.no_pkinit) + if not options.dirsrv_cert_files: + ntpinstance.ntp_ldap_enable(options.host_name, ds.suffix, + options.realm_name) + + else: + api.Backend.ldap2.connect() + + ds = dsinstance.DsInstance(fstore=fstore, + domainlevel=options.domainlevel) + ds.set_output(ansible_log) + + with redirect_stdout(ansible_log): + ds.init_info( + options.realm_name, options.host_name, options.domain_name, + options.dm_password, + options.subject_base, options.ca_subject, 1101, 1100, None, + setup_pkinit=not options.no_pkinit) + + # done ################################################################## + + ansible_module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_setup_http.py b/roles/ipaserver/library/ipaserver_setup_http.py new file mode 100644 index 00000000..987fc416 --- /dev/null +++ b/roles/ipaserver/library/ipaserver_setup_http.py @@ -0,0 +1,206 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: setup_ds +short description: +description: +options: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +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), + + 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=[]), + + setup_adtrust=dict(required=False, type='bool', default=False), + setup_kra=dict(required=False, type='bool', default=False), + setup_dns=dict(required=False, type='bool', default=False), + setup_ca=dict(required=False, type='bool', default=False), + + no_host_dns=dict(required=False, type='bool', default=False), + no_pkinit=dict(required=False, type='bool', default=False), + no_hbac_allow=dict(required=False, type='bool', default=False), + + 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), + + 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=[]), + + 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), + ), + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values ############################################################ + + options.dm_password = ansible_module.params.get('dm_password') + options.admin_password = ansible_module.params.get('password') + options.master_password = ansible_module.params.get('master_password') + options.domain_name = ansible_module.params.get('domain') + options.realm_name = ansible_module.params.get('realm') + options.host_name = ansible_module.params.get('hostname') + + options.ip_addresses = ansible_module.params.get('ip_addresses') + options.reverse_zones = ansible_module.params.get('reverse_zones') + options.http_cert_files = ansible_module.params.get('http_cert_files') + + options.setup_adtrust = ansible_module.params.get('setup_adtrust') + options.setup_kra = ansible_module.params.get('setup_kra') + options.setup_dns = ansible_module.params.get('setup_dns') + options.setup_ca = ansible_module.params.get('setup_ca') + + options.no_host_dns = ansible_module.params.get('no_host_dns') + options.no_pkinit = ansible_module.params.get('no_pkinit') + options.no_hbac_allow = ansible_module.params.get('no_hbac_allow') + options.no_ui_redirect = ansible_module.params.get('no_ui_redirect') + + options.external_cert_files = ansible_module.params.get( + 'external_cert_files') + options.subject_base = ansible_module.params.get('subject_base') + options._subject_base = ansible_module.params.get('_subject_base') + options.ca_subject = ansible_module.params.get('ca_subject') + options._ca_subject = ansible_module.params.get('_ca_subject') + + options.no_reverse = ansible_module.params.get('no_reverse') + options.auto_forwarders = ansible_module.params.get('auto_forwarders') + + options.idstart = ansible_module.params.get('idstart') + options.idmax = ansible_module.params.get('idmax') + options.domainlevel = ansible_module.params.get('domainlevel') + options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file') + options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') + + #options._update_hosts_file = ansible_module.params.get('_update_hosts_file') + options._dirsrv_pkcs12_info = ansible_module.params.get( + '_dirsrv_pkcs12_info') + + # init ################################################################## + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + + api_Backend_ldap2(options.host_name, options.setup_ca, connect=True) + + ds = ds_init_info(ansible_log, fstore, + options.domainlevel, options.dirsrv_config_file, + options.realm_name, options.host_name, + options.domain_name, options.dm_password, + options.idstart, options.idmax, + options.subject_base, options.ca_subject, + options.no_hbac_allow, options._dirsrv_pkcs12_info, + options.no_pkinit) + + # krb + krb = krbinstance.KrbInstance(fstore) + krb.set_output(ansible_log) + with redirect_stdout(ansible_log): + krb.init_info(options.realm_name, options.host_name, + setup_pkinit=not options.no_pkinit, + subject_base=options.subject_base) + + # setup HTTP ############################################################ + + # Create a HTTP instance + http = httpinstance.HTTPInstance(fstore) + http.set_output(ansible_log) + with redirect_stdout(ansible_log): + if options.http_cert_files: + http.create_instance( + options.realm_name, options.host_name, options.domain_name, options.dm_password, + pkcs12_info=options._http_pkcs12_info, subject_base=options.subject_base, + auto_redirect=not options.no_ui_redirect, + ca_is_configured=options.setup_ca) + else: + http.create_instance( + options.realm_name, options.host_name, options.domain_name, options.dm_password, + subject_base=options.subject_base, + auto_redirect=not options.no_ui_redirect, + ca_is_configured=options.setup_ca) + tasks.restore_context(paths.CACHE_IPA_SESSIONS) + + ca.set_subject_base_in_config(options.subject_base) + + # configure PKINIT now that all required services are in place + krb.enable_ssl() + + # Apply any LDAP updates. Needs to be done after the configuration file + # is created. DS is restarted in the process. + service.print_msg("Applying LDAP updates") + ds.apply_updates() + + # Restart krb after configurations have been changed + service.print_msg("Restarting the KDC") + krb.restart() + + # done ################################################################## + + ansible_module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_setup_kra.py b/roles/ipaserver/library/ipaserver_setup_kra.py new file mode 100644 index 00000000..3958d7aa --- /dev/null +++ b/roles/ipaserver/library/ipaserver_setup_kra.py @@ -0,0 +1,90 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: setup_kra +short description: +description: +options: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +def main(): + ansible_module = AnsibleModule( + argument_spec = dict( + # basic + dm_password=dict(required=True, no_log=True), + hostname=dict(required=True), + setup_ca=dict(required=True, type='bool'), + setup_kra=dict(required=True, type='bool'), + ), + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values #################################################### + + options.dm_password = ansible_module.params.get('dm_password') + options.host_name = ansible_module.params.get('hostname') + options.setup_ca = ansible_module.params.get('setup_ca') + options.setup_kra = ansible_module.params.get('setup_kra') + + # init ########################################################## + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + sstore = sysrestore.StateFile(paths.SYSRESTORE) + + api_Backend_ldap2(options.host_name, options.setup_ca, connect=True) + + # setup kra ##################################################### + + with redirect_stdout(ansible_log): + kra.install(api, None, options) + + # done ########################################################## + + ansible_module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_setup_krb.py b/roles/ipaserver/library/ipaserver_setup_krb.py new file mode 100644 index 00000000..31591275 --- /dev/null +++ b/roles/ipaserver/library/ipaserver_setup_krb.py @@ -0,0 +1,155 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: setup_ds +short description: +description: +options: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +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), + + ip_addresses=dict(required=False, type='list', default=[]), + reverse_zones=dict(required=False, type='list', default=[]), + + setup_adtrust=dict(required=False, type='bool', default=False), + setup_kra=dict(required=False, type='bool', default=False), + setup_dns=dict(required=False, type='bool', default=False), + setup_ca=dict(required=False, type='bool', default=False), + + no_host_dns=dict(required=False, type='bool', default=False), + 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), + + idstart=dict(required=True, type='int'), + idmax=dict(required=True, type='int'), + + no_reverse=dict(required=False, type='bool', default=False), + auto_forwarders=dict(required=False, type='bool', default=False), + + _pkinit_pkcs12_info=dict(required=False), + ), + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values ############################################################ + + options.dm_password = ansible_module.params.get('dm_password') + options.admin_password = ansible_module.params.get('password') + options.master_password = ansible_module.params.get('master_password') + options.domain_name = ansible_module.params.get('domain') + options.realm_name = ansible_module.params.get('realm') + options.host_name = ansible_module.params.get('hostname') + + options.ip_addresses = ansible_module.params.get('ip_addresses') + options.reverse_zones = ansible_module.params.get('reverse_zones') + + options.setup_adtrust = ansible_module.params.get('setup_adtrust') + options.setup_kra = ansible_module.params.get('setup_kra') + options.setup_dns = ansible_module.params.get('setup_dns') + options.setup_ca = ansible_module.params.get('setup_ca') + + options.no_host_dns = ansible_module.params.get('no_host_dns') + options.no_pkinit = ansible_module.params.get('no_pkinit') + options.no_hbac_allow = ansible_module.params.get('no_hbac_allow') + + options.external_cert_files = ansible_module.params.get( + 'external_cert_files') + options.subject_base = ansible_module.params.get('subject_base') + options.ca_subject = ansible_module.params.get('ca_subject') + + options.no_reverse = ansible_module.params.get('no_reverse') + options.auto_forwarders = ansible_module.params.get('auto_forwarders') + + options.idstart = ansible_module.params.get('idstart') + options.idmax = ansible_module.params.get('idmax') + + options._pkinit_pkcs12_info = ansible_module.params.get( + '_pkinit_pkcs12_info') + + #options._update_hosts_file = ansible_module.params.get('update_hosts_file') + + # init ################################################################## + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + + api_Backend_ldap2(options.host_name, options.setup_ca, connect=True) + + # setup KRB ############################################################# + + krb = krbinstance.KrbInstance(fstore) + krb.set_output(ansible_log) + with redirect_stdout(ansible_log): + if not options.external_cert_files: + krb.create_instance(options.realm_name, options.host_name, + options.domain_name, + options.dm_password, options.master_password, + setup_pkinit=not options.no_pkinit, + pkcs12_info=options._pkinit_pkcs12_info, + subject_base=options.subject_base) + else: + krb.init_info(options.realm_name, options.host_name, + setup_pkinit=not options.no_pkinit, + subject_base=options.subject_base) + + ansible_module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_setup_ntp.py b/roles/ipaserver/library/ipaserver_setup_ntp.py new file mode 100644 index 00000000..3de34ca9 --- /dev/null +++ b/roles/ipaserver/library/ipaserver_setup_ntp.py @@ -0,0 +1,79 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: setup_ntp +short description: +description: +options: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +def main(): + ansible_module = AnsibleModule( + argument_spec = dict(), + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # init ########################################################## + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + sstore = sysrestore.StateFile(paths.SYSRESTORE) + + # setup NTP ##################################################### + + ntpconf.force_ntpd(sstore) + ntp = ntpinstance.NTPInstance(fstore) + ntp.set_output(ansible_log) + with redirect_stdout(ansible_log): + if not ntp.is_configured(): + ntp.create_instance() + + # done ########################################################## + + ansible_module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_setup_otpd.py b/roles/ipaserver/library/ipaserver_setup_otpd.py new file mode 100644 index 00000000..dc895c72 --- /dev/null +++ b/roles/ipaserver/library/ipaserver_setup_otpd.py @@ -0,0 +1,91 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from __future__ import print_function + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: setup_otpd +short description: +description: +options: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +def main(): + ansible_module = AnsibleModule( + argument_spec = dict( + # basic + realm=dict(required=True), + hostname=dict(required=False), + setup_ca=dict(required=False, type='bool', default=False), + ), + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values #################################################### + + options.realm_name = ansible_module.params.get('realm') + options.host_name = ansible_module.params.get('hostname') + options.setup_ca = ansible_module.params.get('setup_ca') + + # init ########################################################## + + fstore = sysrestore.FileStore(paths.SYSRESTORE) + sstore = sysrestore.StateFile(paths.SYSRESTORE) + + api_Backend_ldap2(options.host_name, options.setup_ca, connect=True) + + # setup ds ###################################################### + + otpd = otpdinstance.OtpdInstance() + otpd.set_output(ansible_log) + with redirect_stdout(ansible_log): + otpd.create_instance('OTPD', options.host_name, + ipautil.realm_to_suffix(options.realm_name)) + + # done ########################################################## + + ansible_module.exit_json(changed=True) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/library/ipaserver_test.py b/roles/ipaserver/library/ipaserver_test.py new file mode 100644 index 00000000..cc0cf4c8 --- /dev/null +++ b/roles/ipaserver/library/ipaserver_test.py @@ -0,0 +1,777 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Thomas Woerner <twoerner@redhat.com> +# +# Based on ipa-client-install code +# +# Copyright (C) 2017 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +ANSIBLE_METADATA = { + 'metadata_version': '1.0', + 'supported_by': 'community', + 'status': ['preview'], +} + +DOCUMENTATION = ''' +--- +module: ipaserver_test +short description: +description: +options: +author: + - Thomas Woerner +''' + +EXAMPLES = ''' +''' + +RETURN = ''' +''' + +import os +import sys +import logging +import tempfile, shutil + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_ipa_server import * + +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=False, no_log=True), + ip_addresses=dict(required=False, type='list', default=[]), + domain=dict(required=False), + realm=dict(required=False), + hostname=dict(required=False), + ca_cert_files=dict(required=False, type='list', default=[]), + # no_host_dns=dict(required=False, type='bool', default=False), + ### server ### + setup_adtrust=dict(required=False, type='bool', default=False), + setup_kra=dict(required=False, type='bool', default=False), + setup_dns=dict(required=False, type='bool', default=False), + idstart=dict(required=False, type='int'), + idmax=dict(required=False, type='int'), + # no_hbac_allow + no_pkinit=dict(required=False, type='bool', default=False), + # no_ui_redirect + dirsrv_config_file=dict(required=False), + ### ssl certificate ### + dirsrv_cert_files=dict(required=False, type='list', default=[]), + http_cert_files=dict(required=False, type='list', default=[]), + pkinit_cert_files=dict(required=False, type='list', default=[]), + # dirsrv_pin + # http_pin + # pkinit_pin + # dirsrv_name + # http_name + # pkinit_name + ### client ### + # mkhomedir + no_ntp=dict(required=False, type='bool', default=False), + # ssh_trust_dns + # no_ssh + # no_sshd + # no_dns_sshfp + ### certificate system ### + external_ca=dict(required=False, type='bool', default=False), + external_ca_type=dict(required=False), + external_cert_files=dict(required=False, type='list', default=[]), + subject_base=dict(required=False), + ca_subject=dict(required=False), + # ca_signing_algorithm + ### dns ### + allow_zone_overlap=dict(required=False, type='bool', default=False), + reverse_zones=dict(required=False, type='list', 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=[]), + no_forwarders=dict(required=False, type='bool', default=False), + auto_forwarders=dict(required=False, type='bool', default=False), + forward_policy=dict(default='first', choices=['first', 'only']), + 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), + rid_base=dict(required=False, type='int'), + secondary_rid_base=dict(required=False, type='int'), + + ### additional ### + allow_repair=dict(required=False, type='bool', default=False), + ), + supports_check_mode = True, + ) + + ansible_module._ansible_debug = True + ansible_log = AnsibleModuleLog(ansible_module) + + # set values ############################################################ + + ### basic ### + options.dm_password = ansible_module.params.get('dm_password') + options.admin_password = ansible_module.params.get('password') + options.master_password = ansible_module.params.get('master_password') + options.ip_addresses = ansible_module.params.get('ip_addresses') + options.domain_name = ansible_module.params.get('domain') + options.realm_name = ansible_module.params.get('realm') + options.host_name = ansible_module.params.get('hostname') + options.ca_cert_files = ansible_module.params.get('ca_cert_files') + # no_host_dns + ### server ### + options.setup_adtrust = ansible_module.params.get('setup_adtrust') + options.setup_dns = ansible_module.params.get('setup_dns') + options.setup_kra = ansible_module.params.get('setup_kra') + options.idstart = ansible_module.params.get('idstart') + options.idmax = ansible_module.params.get('idmax') + # no_hbac_allow + options.no_pkinit = ansible_module.params.get('no_pkinit') + # no_ui_redirect + options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file') + ### ssl certificate ### + options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') + options.http_cert_files = ansible_module.params.get('http_cert_files') + options.pkinit_cert_files = ansible_module.params.get('pkinit_cert_files') + # dirsrv_pin + # http_pin + # pkinit_pin + # dirsrv_name + # http_name + # pkinit_name + ### client ### + # mkhomedir + options.no_ntp = ansible_module.params.get('no_ntp') + # ssh_trust_dns + # no_ssh + # no_sshd + # no_dns_sshfp + ### certificate system ### + options.external_ca = ansible_module.params.get('external_ca') + options.external_ca_type = ansible_module.params.get('external_ca_type') + options.external_cert_files = ansible_module.params.get( + 'external_cert_files') + options.subject_base = ansible_module.params.get('subject_base') + options.ca_subject = ansible_module.params.get('ca_subject') + # ca_signing_algorithm + ### dns ### + options.allow_zone_overlap= ansible_module.params.get('allow_zone_overlap') + options.reverse_zones = ansible_module.params.get('reverse_zones') + options.no_reverse = ansible_module.params.get('no_reverse') + options.auto_reverse = ansible_module.params.get('auto_reverse') + options.zonemgr = ansible_module.params.get('zonemgr') + options.forwarders = ansible_module.params.get('forwarders') + options.no_forwarders = ansible_module.params.get('no_forwarders') + options.auto_forwarders = ansible_module.params.get('auto_forwarders') + options.forward_policy = ansible_module.params.get('forward_policy') + options.no_dnssec_validation = ansible_module.params.get( + 'no_dnssec_validation') + ### ad trust ### + options.enable_compat = ansible_module.params.get('enable_compat') + options.netbios_name = ansible_module.params.get('netbios_name') + options.rid_base = ansible_module.params.get('rid_base') + options.secondary_rid_base = ansible_module.params.get('secondary_rid_base') + + ### additional ### + allow_repair = ansible_module.params.get('allow_repair') + + # version specific ###################################################### + + if options.setup_adtrust and not adtrust_imported: + #if "adtrust" not in options._allow_missing: + ansible_module.fail_json(msg="adtrust can not be imported") + #else: + # options.setup_adtrust = False + # ansible_module.warn(msg="adtrust is not supported, disabling") + + if options.setup_kra and not kra_imported: + #if "kra" not in options._allow_missing: + ansible_module.fail_json(msg="kra can not be imported") + #else: + # options.setup_kra = False + # ansible_module.warn(msg="kra is not supported, disabling") + + # validation ############################################################# + + if options.dm_password is None: + ansible_module.fail_json(msg="Directory Manager password required") + + if options.admin_password is None: + ansible_module.fail_json(msg="IPA admin password required") + + # This will override any settings passed in on the cmdline + if os.path.isfile(paths.ROOT_IPA_CACHE): + # dm_password check removed, checked already + try: + cache_vars = read_cache(options.dm_password) + options.__dict__.update(cache_vars) + if cache_vars.get('external_ca', False): + options.external_ca = False + options.interactive = False + except Exception as e: + ansible_module.fail_json(msg="Cannot process the cache file: %s" % str(e)) + # default values ######################################################## + + # idstart and idmax + if options.idstart is None: + options.idstart = random.randint(1, 10000) * 200000 + if options.idmax is None or options.idmax == 0: + options.idmax = options.idstart + 199999 + + # validation ############################################################ + + # domain_level + if options.domain_level < MIN_DOMAIN_LEVEL: + ansible_module.fail_json( + msg="Domain Level cannot be lower than %d" % MIN_DOMAIN_LEVEL) + elif options.domain_level > MAX_DOMAIN_LEVEL: + ansible_module.fail_json( + msg="Domain Level cannot be higher than %d" % MAX_DOMAIN_LEVEL) + + # dirsrv_config_file + if options.dirsrv_config_file is not None: + if not os.path.exists(options.dirsrv_config_file): + ansible_module.fail_json( + msg="File %s does not exist." % options.dirsrv_config_file) + + # domain_name + if (options.setup_dns and not options.allow_zone_overlap): + check_zone_overlap(options.domain_name, False) + + # dm_password + with redirect_stdout(ansible_log): + validate_dm_password(options.dm_password) + + # admin_password + with redirect_stdout(ansible_log): + validate_admin_password(options.admin_password) + + # pkinit is not supported on DL0, don't allow related options + + # replica install: if not self.replica_file is None: + if (not options._replica_install and \ + not options.domain_level > DOMAIN_LEVEL_0) or \ + (options._replica_install and self.replica_file is not None): + if (options.no_pkinit or options.pkinit_cert_files is not None or + options.pkinit_pin is not None): + ansible_module.fail_json( + msg="pkinit on domain level 0 is not supported. Please " + "don't use any pkinit-related options.") + options.no_pkinit = True + + # If any of the key file options are selected, all are required. + cert_file_req = (options.dirsrv_cert_files, options.http_cert_files) + cert_file_opt = (options.pkinit_cert_files,) + if not options.no_pkinit: + cert_file_req += cert_file_opt + if options.no_pkinit and options.pkinit_cert_files: + ansible_module.fail_json( + msg="no-pkinit and pkinit-cert-file cannot be specified together" + ) + if any(cert_file_req + cert_file_opt) and not all(cert_file_req): + ansible_module.fail_json( + msg="dirsrv-cert-file, http-cert-file, and pkinit-cert-file " + "or no-pkinit are required if any key file options are used." + ) + + if not options.interactive: + if options.dirsrv_cert_files and options.dirsrv_pin is None: + ansible_module.fail_json( + msg="You must specify dirsrv-pin with dirsrv-cert-file") + if options.http_cert_files and options.http_pin is None: + ansible_module.fail_json( + msg="You must specify http-pin with http-cert-file") + if options.pkinit_cert_files and options.pkinit_pin is None: + ansible_module.fail_json( + msg="You must specify pkinit-pin with pkinit-cert-file") + + if not options.setup_dns: + # lists + for x in [ "forwarders", "reverse_zones" ]: + if len(getattr(options, x)) > 1: + ansible_module.fail_json( + msg="You cannot specify %s without setting setup-dns" % x) + # bool and str values + for x in [ "auto_forwarders", "no_forwarders", + "auto_reverse", "no_reverse", "no_dnssec_validation", + "forward_policy" ]: + if getattr(options, x) == True: + ansible_module.fail_json( + msg="You cannot specify %s without setting setup-dns" % x) + + elif len(options.forwarders) > 0 and options.no_forwarders: + ansible_module.fail_json( + msg="You cannot specify forwarders together with no-forwarders") + elif options.auto_forwarders and options.no_forwarders: + ansible_module.fail_json( + msg="You cannot specify auto-forwarders together with no-forwarders") + elif len(options.reverse_zones) > 0 and options.no_reverse: + ansible_module.fail_json( + msg="You cannot specify reverse-zones together with no-reverse") + elif options.auto_reverse and options.no_reverse: + ansible_module.fail_json( + msg="You cannot specify auto-reverse together with no-reverse") + + if not options._replica_install: + if options.external_cert_files and options.dirsrv_cert_files: + ansible_module.fail_json( + msg="Service certificate file options cannot be used with the " + "external CA options.") + + if options.external_ca_type and not options.external_ca: + ansible_module.fail_json( + msg="You cannot specify external-ca-type without external-ca") + + #if options.uninstalling: + # if (options.realm_name or options.admin_password or + # options.master_password): + # ansible_module.fail_json( + # msg="In uninstall mode, -a, -r and -P options are not " + # "allowed") + #elif not options.interactive: + # if (not options.realm_name or not options.dm_password or + # not options.admin_password): + # ansible_module.fail_json(msg= + # "In unattended mode you need to provide at least -r, " + # "-p and -a options") + # if options.setup_dns: + # if (not options.forwarders and + # not options.no_forwarders and + # not options.auto_forwarders): + # ansible_module.fail_json(msg= + # "You must specify at least one of --forwarder, " + # "--auto-forwarders, or --no-forwarders options") + if (not options.realm_name or not options.dm_password or + not options.admin_password): + ansible_module.fail_json( + msg="You need to provide at least realm_name, dm_password " + "and admin_password") + if options.setup_dns: + if len(options.forwarders) < 1 and not options.no_forwarders and \ + not options.auto_forwarders: + ansible_module.fail_json( + msg="You must specify at least one of forwarders, " + "auto-forwarders or no-forwarders") + + #any_ignore_option_true = any( + # [options.ignore_topology_disconnect, options.ignore_last_of_role]) + #if any_ignore_option_true and not options.uninstalling: + # ansible_module.fail_json( + # msg="ignore-topology-disconnect and ignore-last-of-role " + # "can be used only during uninstallation") + + if options.idmax < options.idstart: + ansible_module.fail_json( + msg="idmax (%s) cannot be smaller than idstart (%s)" % + (options.idmax, options.idstart)) + else: + # replica install + if options.replica_file is None: + if options.servers and not options.domain_name: + ansible_module.fail_json( + msg="servers cannot be used without providing domain") + + else: + if not ipautil.file_exists(options.replica_file): + ansible_module.fail_json( + msg="Replica file %s does not exist" % options.replica_file) + + if any(cert_file_req + cert_file_opt): + ansible_module.fail_json( + msg="You cannot specify dirsrv-cert-file, http-cert-file, " + "or pkinit-cert-file together with replica file") + + conflicting = { "realm": options.realm_name, + "domain": options.domain_name, + "hostname": options.host_name, + "servers": options.servers, + "principal": options.principal } + conflicting_names = [ name for name in conflicting + if conflicting[name] is not None ] + if len(conflicting_names) > 0: + ansible_module.fail_json( + msg="You cannot specify %s option(s) with replica file." % \ + ", ".join(conflicting_names)) + + if options.setup_dns: + if len(options.forwarders) < 1 and not options.no_forwarders and \ + not options.auto_forwarders: + ansible_module.fail_json( + msg="You must specify at least one of forwarders, " + "auto-forwarders or no-forwarders") + + if NUM_VERSION >= 40200 and options.master_password: + ansible_module.warn("Specifying master-password is deprecated") + + options._installation_cleanup = True + if not options.external_ca and len(options.external_cert_files) < 1 and \ + is_ipa_configured() and not allow_repair: + options._installation_cleanup = False + ansible_module.fail_json(msg= + "IPA server is already configured on this system. If you want " + "to reinstall the IPA server, please uninstall it first.") + + client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) + if client_fstore.has_files() and not allow_repair: + options._installation_cleanup = False + ansible_module.fail_json( + msg="IPA client is already configured on this system. " + "Please uninstall it before configuring the IPA server.") + + # validate reverse_zones + if not options.allow_zone_overlap: + for zone in options.reverse_zones: + with redirect_stdout(ansible_log): + dnsutil.check_zone_overlap(zone) + + # validate zonemgr + if options.zonemgr: + try: + # IDNA support requires unicode + encoding = getattr(sys.stdin, 'encoding', None) + if encoding is None: + encoding = 'utf-8' + value = options.zonemgr.decode(encoding) + with redirect_stdout(ansible_log): + bindinstance.validate_zonemgr_str(value) + except ValueError as e: + # FIXME we can do this in better way + # https://fedorahosted.org/freeipa/ticket/4804 + # decode to proper stderr encoding + stderr_encoding = getattr(sys.stderr, 'encoding', None) + if stderr_encoding is None: + stderr_encoding = 'utf-8' + error = unicode(e).encode(stderr_encoding) + ansible_module.fail_json(msg=error) + + # external cert file paths are absolute + for path in options.external_cert_files: + if not os.path.isabs(path): + ansible_module.fail_json( + msg="External cert file '%s' must use an absolute path" % path) + + options.setup_ca = True + # We only set up the CA if the PKCS#12 options are not given. + if options.dirsrv_cert_files and len(options.dirsrv_cert_files) > 0: + options.setup_ca = False + else: + options.setup_ca = True + + if not options.setup_ca and options.ca_subject: + ansible_module.fail_json(msg= + "--ca-subject cannot be used with CA-less installation") + if not options.setup_ca and options.subject_base: + ansible_module.fail_json(msg= + "--subject-base cannot be used with CA-less installation") + if not options.setup_ca and options.setup_kra: + ansible_module.fail_json(msg= + "--setup-kra cannot be used with CA-less installation") + + # ca_subject + if options.ca_subject: + subject_validator(VALID_SUBJECT_ATTRS, options.ca_subject) + + # IPv6 and SELinux check + + tasks.check_ipv6_stack_enabled() + tasks.check_selinux_status() + + _installation_cleanup = True + if (not options.external_ca and not options.external_cert_files and + is_ipa_configured() and not allow_repair): + _installation_cleanup = False + ansible_module.fail_json(msg="IPA server is already configured on this system.") + + if not options.no_ntp: + try: + ntpconf.check_timedate_services() + except ntpconf.NTPConflictingService as e: + ansible_module.log("Conflicting time&date synchronization service '%s'" + " will be disabled in favor of ntpd" % \ + e.conflicting_service) + except ntpconf.NTPConfigurationError: + pass + + # Check to see if httpd is already configured to listen on 443 + if httpinstance.httpd_443_configured(): + ansible_module.fail_json(msg="httpd is already configured to listen on 443.") + + if not options.external_cert_files: + # Make sure the 389-ds ports are available + try: + check_dirsrv(True) + except ScriptError as e: + if not allow_repair: + ansible_module.fail_json(msg=e) + + if not options.no_ntp: + try: + ntpconf.check_timedate_services() + except ntpconf.NTPConflictingService as e: + ansible_module.warn( + "Conflicting time&date synchronization service " + "'%s' will be disabled" % e.conflicting_service) + except ntpconf.NTPConfigurationError: + pass + + # Check to see if httpd is already configured to listen on 443 + if httpinstance.httpd_443_configured() and not allow_repair: + ansible_module.fail_json(msg="httpd is already configured to listen on 443.") + + # check bind packages are installed + if options.setup_dns: + # Don't require an external DNS to say who we are if we are + # setting up a local DNS server. + options.no_host_dns = True + + # host name + if options.host_name: + options.host_default = options.host_name + else: + options.host_default = get_fqdn() + + _host_name_overridden = False + try: + verify_fqdn(options.host_default, options.no_host_dns) + options.host_name = options.host_default + if options.host_default != get_fqdn(): + _host_name_overridden = True + except BadHostError as e: + ansible_module.fail_json(msg=e) + options.host_name = options.host_name.lower() + + if not options.domain_name: + options.domain_name = options.host_name[options.host_name.find(".")+1:] + try: + validate_domain_name(options.domain_name) + except ValueError as e: + ansible_module.fail_json(msg="Invalid domain name: %s" % unicode(e)) + options.domain_name = options.domain_name.lower() + + if not options.realm_name: + options.realm_name = options.domain_name + options.realm_name = options.realm_name.upper() + + if not options.setup_adtrust: + # If domain name and realm does not match, IPA server will not be able + # to establish trust with Active Directory. Fail. + + if options.domain_name.upper() != options.realm_name: + ansible_module.fail_json( + msg="Realm name does not match the domain name: " + "You will not be able to establish trusts with Active " + "Directory.") + + ######################################################################### + + http_pkcs12_file = None + http_pkcs12_info = None + http_ca_cert = None + dirsrv_pkcs12_file = None + dirsrv_pkcs12_info = None + dirsrv_ca_cert = None + pkinit_pkcs12_file = None + pkinit_pkcs12_info = None + pkinit_ca_cert = None + + if options.http_cert_files: + if options.http_pin is None: + ansible_module.fail_json(msg= + "Apache Server private key unlock password required") + http_pkcs12_file, http_pin, http_ca_cert = load_pkcs12( + cert_files=options.http_cert_files, + key_password=options.http_pin, + key_nickname=options.http_cert_name, + ca_cert_files=options.ca_cert_files, + host_name=options.host_name) + http_pkcs12_info = (http_pkcs12_file.name, options.http_pin) + + if options.dirsrv_cert_files: + if options.dirsrv_pin is None: + ansible_module.fail_json(msg= + "Directory Server private key unlock password required") + dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = load_pkcs12( + cert_files=options.dirsrv_cert_files, + key_password=options.dirsrv_pin, + key_nickname=options.dirsrv_cert_name, + ca_cert_files=options.ca_cert_files, + host_name=options.host_name) + dirsrv_pkcs12_info = (dirsrv_pkcs12_file.name, options.dirsrv_pin) + + if options.pkinit_cert_files: + if options.pkinit_pin is None: + ansible_module.fail_json(msg= + "Kerberos KDC private key unlock password required") + pkinit_pkcs12_file, pkinit_pin, pkinit_ca_cert = load_pkcs12( + cert_files=options.pkinit_cert_files, + key_password=options.pkinit_pin, + key_nickname=options.pkinit_cert_name, + ca_cert_files=options.ca_cert_files, + realm_name=options.realm_name) + pkinit_pkcs12_info = (pkinit_pkcs12_file.name, options.pkinit_pin) + + if (options.http_cert_files and options.dirsrv_cert_files and + http_ca_cert != dirsrv_ca_cert): + ansible_module.fail_json(msg= + "Apache Server SSL certificate and Directory Server SSL " + "certificate are not signed by the same CA certificate") + + if (options.http_cert_files and options.pkinit_cert_files and + http_ca_cert != pkinit_ca_cert): + ansible_module.fail_json(msg= + "Apache Server SSL certificate and PKINIT KDC " + "certificate are not signed by the same CA certificate") + + # subject_base + if not options.subject_base: + options.subject_base = str(default_subject_base(options.realm_name)) + # set options.subject for old ipa releases + options.subject = options.subject_base + + if not options.ca_subject: + options.ca_subject = str(default_ca_subject_dn(options.subject_base)) + + # temporary ipa configuration ########################################### + + ipa_tempdir = tempfile.mkdtemp(prefix="ipaconf") + try: + # Configuration for ipalib, we will bootstrap and finalize later, after + # we are sure we have the configuration file ready. + cfg = dict( + context='installer', + confdir=ipa_tempdir, + in_server=True, + # make sure host name specified by user is used instead of default + host=options.host_name, + ) + if options.setup_ca: + # we have an IPA-integrated CA + cfg['ca_host'] = options.host_name + + # Create the management framework config file and finalize api + target_fname = "%s/default.conf" % ipa_tempdir + fd = open(target_fname, "w") + fd.write("[global]\n") + fd.write("host=%s\n" % options.host_name) + fd.write("basedn=%s\n" % ipautil.realm_to_suffix(options.realm_name)) + fd.write("realm=%s\n" % options.realm_name) + fd.write("domain=%s\n" % options.domain_name) + fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % format_netloc(options.host_name)) + fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % + installutils.realm_to_serverid(options.realm_name)) + if options.setup_ca: + fd.write("enable_ra=True\n") + fd.write("ra_plugin=dogtag\n") + fd.write("dogtag_version=10\n") + else: + fd.write("enable_ra=False\n") + fd.write("ra_plugin=none\n") + fd.write("mode=production\n") + fd.close() + + # Must be readable for everyone + os.chmod(target_fname, 0o644) + + api.bootstrap(**cfg) + api.finalize() + + # install checks #################################################### + + if options.setup_ca: + ca.install_check(False, None, options) + + if options.setup_kra: + kra.install_check(api, None, options) + + if options.setup_dns: + with redirect_stdout(ansible_log): + dns.install_check(False, api, False, options, options.host_name) + ip_addresses = dns.ip_addresses + else: + ip_addresses = get_server_ip_address(options.host_name, + False, False, + options.ip_addresses) + + # check addresses here, dns ansible_module is doing own check + no_matching_interface_for_ip_address_warning(ip_addresses) + + options.ip_addresses = ip_addresses + options.reverse_zones = dns.reverse_zones + instance_name = "-".join(options.realm_name.split(".")) + dirsrv = services.knownservices.dirsrv + if (options.external_cert_files + and dirsrv.is_installed(instance_name) + and not dirsrv.is_running(instance_name)): + logger.debug('Starting Directory Server') + services.knownservices.dirsrv.start(instance_name) + + if options.setup_adtrust: + adtrust.install_check(False, options, api) + + finally: + try: + shutil.rmtree(ipa_tempdir, ignore_errors=True) + except OSError: + ansible_module.fail_json(msg="Could not remove %s" % ipa_tempdir) + + # done ################################################################## + + ansible_module.exit_json(changed=True, + ipa_python_version=IPA_PYTHON_VERSION, + ### basic ### + domain=options.domain_name, + realm=options.realm_name, + ip_addresses=[ str(ip) for ip in ip_addresses ], + hostname=options.host_name, + _hostname_overridden=_host_name_overridden, + no_host_dns=options.no_host_dns, + ### server ### + setup_adtrust=options.setup_adtrust, + setup_kra=options.setup_kra, + setup_ca=options.setup_ca, + idstart=options.idstart, + idmax=options.idmax, + no_pkinit=options.no_pkinit, + ### ssl certificate ### + _dirsrv_pkcs12_file=dirsrv_pkcs12_file, + _dirsrv_pkcs12_info=dirsrv_pkcs12_info, + _dirsrv_ca_cert=dirsrv_ca_cert, + _http_pkcs12_file=http_pkcs12_file, + _http_pkcs12_info=http_pkcs12_info, + _http_ca_cert=http_ca_cert, + _pkinit_pkcs12_file=pkinit_pkcs12_file, + _pkinit_pkcs12_info=pkinit_pkcs12_info, + _pkinit_ca_cert=pkinit_ca_cert, + ### certificate system ### + subject_base=options.subject_base, + _subject_base=options._subject_base, + ca_subject=options.ca_subject, + _ca_subject=options._ca_subject, + ### dns ### + reverse_zones=options.reverse_zones, + forwarders=options.forwarders, + ### additional ### + _installation_cleanup=_installation_cleanup, + domainlevel=options.domainlevel) + +if __name__ == '__main__': + main() diff --git a/roles/ipaserver/meta/main.yml b/roles/ipaserver/meta/main.yml new file mode 100644 index 00000000..0ec6c29b --- /dev/null +++ b/roles/ipaserver/meta/main.yml @@ -0,0 +1,27 @@ +galaxy_info: + author: Thomas Woerner + description: A role to setup an iPA domain server + company: Red Hat, Inc + + # issue_tracker_url: http://example.com/issue/tracker + + license: GPLv3 + + min_ansible_version: 2.0 + + #github_branch: + + platforms: + - name: Fedora + versions: + - 25 + - 26 + - 27 + - name: rhel + versions: + - 7.3 + - 7.4 + + galaxy_tags: [ 'identity', 'ipa'] + +dependencies: [] diff --git a/roles/ipaserver/tasks/install-1.yml b/roles/ipaserver/tasks/install-1.yml new file mode 100644 index 00000000..7af5dfab --- /dev/null +++ b/roles/ipaserver/tasks/install-1.yml @@ -0,0 +1,153 @@ +--- +# tasks file for ipaserver + +- name: Install - Install IPA server package + package: + name: "{{ item }}" + state: present + with_items: "{{ ipaserver_packages }}" + +- name: Install - Include Python2/3 import test + include: "{{role_path}}/tasks/python_2_3_test.yml" + static: yes + +- name: Install - Server installation test + server_test: + # basic + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" +# ip_addresses: "{{ ipaserver_ip_addresses | default([]) }}" + domain: "{{ ipaserver_domain | default(omit)}}" + realm: "{{ ipaserver_realm | default(omit)}}" + hostname: "{{ ipaserver_hostname | default(ansible_fqdn) }}" + ca_cert_file: "{{ ipaserver_ca_cert_file | default(omit) }}" + no_host_dns: "{{ ipaserver_no_host_dns }}" + # + setup_adtrust: "{{ ipaserver_setup_adtrust }}" + setup_kra: "{{ ipaserver_setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + # + no_pkinit: "{{ ipaserver_no_pkinit }}" + dirserv_config_file: "{{ ipaserver_dirserv_config_file | default(omit) }}" + # ssl certificate + dirserv_cert_file: "{{ ipaserver_dirserv_cert_file | default(omit) }}" + dirserv_pin: "{{ ipaserver_dirserv_pin | default(omit) }}" + dirserv_cert_name: "{{ ipaserver_dirserv_cert_name | default(omit) }}" + http_cert_file: "{{ ipaserver_http_cert_file | default(omit) }}" + http_pin: "{{ ipaserver_http_pin | default(omit) }}" + http_cert_name: "{{ ipaserver_http_cert_name | default(omit) }}" + pkinit_cert_file: "{{ ipaserver_pkinit_cert_file | default(omit) }}" + pkinit_pin: "{{ ipaserver_pkinit_pin | default(omit) }}" + pkinit_cert_name: "{{ ipaserver_pkinit_cert_name | default(omit) }}" + # client + no_ntp: "{{ ipaserver_no_ntp }}" + # certificate system + external_ca: "{{ ipaserver_external_ca | default(omit) }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_subject_base | default(omit) }}" + ca_subject: "{{ ipaserver_ca_subject | default(omit) }}" + # dns + allow_zone_overlap: "{{ ipaserver_allow_zone_overlap }}" + reverse_zones: "{{ ipaserver_reverse_zones | default([]) }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_reverse: "{{ ipaserver_auto_reverse }}" + zonemgr: "{{ ipaserver_zonemgr | default(omit) }}" + forwarders: "{{ ipaserver_forwarders | default([]) }}" + no_forwarders: "{{ ipaserver_no_forwarders }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + forward_policy: "{{ ipaserver_forward_policy | default(first) }}" + # repair + allow_repair: "{{ ipaserver_allow_repair }}" +# # compat_mode +# compat_mode: "{{ ipaserver_compat_mode }}" + register: server_test + +## + +- block: + + - name: Install - Master password passthrough or creation + no_log: yes + master_password: + dm_password: "{{ ipaserver_dm_password }}" + master_password: "{{ ipaserver_master_password | default(omit) }}" + register: master_password + +# - name: Install - Create directory server instance +# create_ds: + + - name: Install - Install + server_install: + # basic + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + master_password: "{{ master_password.value }}" +# ip_addresses: "{{ ipaserver_ip_addresses | default([]) }}" + ip_addresses: "{{ server_test.ip_addresses }}" + domain: "{{ server_test.domain }}" + realm: "{{ server_test.realm }}" + hostname: "{{ server_test.hostname }}" + ca_cert_file: "{{ ipaserver_ca_cert_file | default(omit) }}" + no_host_dns: "{{ server_test.no_host_dns }}" + # server + setup_adtrust: "{{ server_test.setup_adtrust }}" + setup_kra: "{{ server_test.setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + idstart: "{{ ipaserver_idstart | default(omit) }}" + idmax: "{{ ipaserver_idmax | default(omit) }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + no_pkinit: "{{ ipaserver_no_pkinit }}" + no_ui_redirect: "{{ ipaserver_no_ui_redirect }}" + dirserv_config_file: "{{ ipaserver_dirserv_config_file | default(omit) }}" + # ssl certificate + dirserv_cert_file: "{{ ipaserver_dirserv_cert_file | default(omit) }}" + dirserv_pin: "{{ ipaserver_dirserv_pin | default(omit) }}" + dirserv_cert_name: "{{ ipaserver_dirserv_cert_name | default(omit) }}" + http_cert_file: "{{ ipaserver_http_cert_file | default(omit) }}" + http_pin: "{{ ipaserver_http_pin | default(omit) }}" + http_cert_name: "{{ ipaserver_http_cert_name | default(omit) }}" + pkinit_cert_file: "{{ ipaserver_pkinit_cert_file | default(omit) }}" + pkinit_pin: "{{ ipaserver_pkinit_pin | default(omit) }}" + pkinit_cert_name: "{{ ipaserver_pkinit_cert_name | default(omit) }}" + # client + mkhomedir: "{{ ipaserver_mkhomedir }}" + no_ntp: "{{ ipaserver_no_ntp }}" + ssh_trust_dns: "{{ ipaserver_ssh_trust_dns }}" + no_ssh: "{{ ipaserver_no_ssh }}" + no_sshd: "{{ ipaserver_no_sshd }}" + no_dns_sshfp: "{{ ipaserver_no_dns_sshfp }}" + # certificate system + external_ca: "{{ ipaserver_external_ca | default(omit) }}" + external_ca_type: "{{ ipaserver_external_ca_type | default('generic') }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_subject_base | default(omit) }}" + ca_subject: "{{ server_test.ca_subject | default(omit) }}" + ca_signing_algorithm: "{{ ipaserver_ca_signing_algorithm | default(omit) }}" + # dns + allow_zone_overlap: "{{ ipaserver_allow_zone_overlap }}" + reverse_zone: "{{ ipaserver_reverse_zone | default(omit) }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_reverse: "{{ ipaserver_auto_reverse }}" + zonemgr: "{{ ipaserver_zonemgr | default(omit) }}" + forwarders: "{{ ipaserver_forwarders | default([]) }}" + no_forwarders: "{{ ipaserver_no_forwarders }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + forward_policy: "{{ ipaserver_forward_policy | default(first) }}" + no_dnssec_validation: "{{ ipaserver_no_dnssec_validation }}" + # ad trust + enable_compat: "{{ ipaserver_enable_compat }}" + netbios_name: "{{ ipaserver_netbios_name | default(omit) }}" + rid_base: "{{ ipaserver_rid_base | default(omit) }}" + secondary_rid_base: "{{ ipaserver_secondary_rid_base | default(omit) }}" + + # additional + hostname_overridden: "{{ server_test.hostname_overridden }}" + update_hosts_file: "{{ server_test.update_hosts_file }}" + setup_ca: "{{ server_test.setup_ca }}" + allow_repair: "{{ ipaserver_allow_repair }}" + reverse_zones: "{{ server_test.reverse_zones }}" + + - name: Install - Cleanup root IPA cache + file: + path: "/root/.ipa_cache" + state: absent diff --git a/roles/ipaserver/tasks/install-2.yml b/roles/ipaserver/tasks/install-2.yml new file mode 100644 index 00000000..83afb294 --- /dev/null +++ b/roles/ipaserver/tasks/install-2.yml @@ -0,0 +1,88 @@ +--- +# tasks file for ipaserver + +- name: Install - Install IPA server package + package: + name: "{{ item }}" + state: present + with_items: "{{ ipaserver_packages }}" + +- name: Install - Include Python2/3 import test + include: "{{role_path}}/tasks/python_2_3_test.yml" + static: yes + +- name: Install - Server installation + server_install: + # basic + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + ip_addresses: "{{ ipaserver_ip_addresses | default([]) }}" + domain: "{{ ipaserver_domain | default(omit)}}" + realm: "{{ ipaserver_realm | default(omit)}}" + hostname: "{{ ipaserver_hostname | default(ansible_fqdn) }}" + ca_cert_file: "{{ ipaserver_ca_cert_file | default(omit) }}" + no_host_dns: "{{ ipaserver_no_host_dns }}" + # + setup_adtrust: "{{ ipaserver_setup_adtrust }}" + setup_kra: "{{ ipaserver_setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + idstart: "{{ ipaserver_idstart | default(omit) }}" + idmax: "{{ ipaserver_idmax | default(omit) }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + no_pkinit: "{{ ipaserver_no_pkinit }}" + no_ui_redirect: "{{ ipaserver_no_ui_redirect }}" + dirserv_config_file: "{{ ipaserver_dirserv_config_file | default(omit) }}" + # ssl certificate + dirserv_cert_file: "{{ ipaserver_dirserv_cert_file | default(omit) }}" + dirserv_pin: "{{ ipaserver_dirserv_pin | default(omit) }}" + dirserv_cert_name: "{{ ipaserver_dirserv_cert_name | default(omit) }}" + http_cert_file: "{{ ipaserver_http_cert_file | default(omit) }}" + http_pin: "{{ ipaserver_http_pin | default(omit) }}" + http_cert_name: "{{ ipaserver_http_cert_name | default(omit) }}" + pkinit_cert_file: "{{ ipaserver_pkinit_cert_file | default(omit) }}" + pkinit_pin: "{{ ipaserver_pkinit_pin | default(omit) }}" + pkinit_cert_name: "{{ ipaserver_pkinit_cert_name | default(omit) }}" + # client + mkhomedir: "{{ ipaserver_mkhomedir }}" + no_ntp: "{{ ipaserver_no_ntp }}" + ssh_trust_dns: "{{ ipaserver_ssh_trust_dns }}" + no_ssh: "{{ ipaserver_no_ssh }}" + no_sshd: "{{ ipaserver_no_sshd }}" + no_dns_sshfp: "{{ ipaserver_no_dns_sshfp }}" + # certificate system + external_ca: "{{ ipaserver_external_ca | default(omit) }}" + external_ca_type: "{{ ipaserver_external_ca_type | default('generic') }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_subject_base | default(omit) }}" + ca_subject: "{{ ipaserver_ca_subject | default(omit) }}" + ca_signing_algorithm: "{{ ipaserver_ca_signing_algorithm | default(omit) }}" + # dns + allow_zone_overlap: "{{ ipaserver_allow_zone_overlap }}" + reverse_zone: "{{ ipaserver_reverse_zone | default(omit) }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_reverse: "{{ ipaserver_auto_reverse }}" + zonemgr: "{{ ipaserver_zonemgr | default(omit) }}" + forwarders: "{{ ipaserver_forwarders | default([]) }}" + no_forwarders: "{{ ipaserver_no_forwarders }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + forward_policy: "{{ ipaserver_forward_policy | default(first) }}" + no_dnssec_validation: "{{ ipaserver_no_dnssec_validation }}" + # ad trust + enable_compat: "{{ ipaserver_enable_compat }}" + netbios_name: "{{ ipaserver_netbios_name | default(omit) }}" + rid_base: "{{ ipaserver_rid_base | default(omit) }}" + secondary_rid_base: "{{ ipaserver_secondary_rid_base | default(omit) }}" + # additional + #hostname_overridden: "{{ server_test.hostname_overridden }}" + #update_hosts_file: "{{ server_test.update_hosts_file }}" + #setup_ca: "{{ server_test.setup_ca }}" + #allow_repair: "{{ ipaserver_allow_repair }}" + #reverse_zones: "{{ server_test.reverse_zones }}" + register: server_install + +## + +- name: Install - Cleanup root IPA cache + file: + path: "/root/.ipa_cache" + state: absent diff --git a/roles/ipaserver/tasks/install-ipaserver.yml b/roles/ipaserver/tasks/install-ipaserver.yml new file mode 100644 index 00000000..1ad9881c --- /dev/null +++ b/roles/ipaserver/tasks/install-ipaserver.yml @@ -0,0 +1,215 @@ +--- +# tasks file for ipaserver + +- name: Install - Install IPA server package + package: + name: "{{ item }}" + state: present + with_items: "{{ ipaserver_packages }}" + +- name: Install - Include Python2/3 import test + include: "{{role_path}}/tasks/python_2_3_test.yml" + static: yes + +- name: Install - Server installation test + server_test: + # basic + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" +# ip_addresses: "{{ ipaserver_ip_addresses }}" + domain: "{{ ipaserver_domain | default(omit)}}" + realm: "{{ ipaserver_realm | default(omit)}}" + hostname: "{{ ipaserver_hostname | default(ansible_fqdn) }}" + ca_cert_file: "{{ ipaserver_ca_cert_file | default(omit) }}" + no_host_dns: "{{ ipaserver_no_host_dns }}" + # +# setup_adtrust: "{{ ipaserver_setup_adtrust }}" +# setup_kra: "{{ ipaserver_setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + # + no_pkinit: "{{ ipaserver_no_pkinit }}" + dirserv_config_file: "{{ ipaserver_dirserv_config_file | default(omit) }}" + # ssl certificate + dirserv_cert_file: "{{ ipaserver_dirserv_cert_file | default(omit) }}" + dirserv_pin: "{{ ipaserver_dirserv_pin | default(omit) }}" + dirserv_cert_name: "{{ ipaserver_dirserv_cert_name | default(omit) }}" + http_cert_file: "{{ ipaserver_http_cert_file | default(omit) }}" + http_pin: "{{ ipaserver_http_pin | default(omit) }}" + http_cert_name: "{{ ipaserver_http_cert_name | default(omit) }}" + pkinit_cert_file: "{{ ipaserver_pkinit_cert_file | default(omit) }}" + pkinit_pin: "{{ ipaserver_pkinit_pin | default(omit) }}" + pkinit_cert_name: "{{ ipaserver_pkinit_cert_name | default(omit) }}" + # client + no_ntp: "{{ ipaserver_no_ntp }}" + # certificate system + external_ca: "{{ ipaserver_external_ca | default(omit) }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_subject_base | default(omit) }}" + ca_subject: "{{ ipaserver_ca_subject | default(omit) }}" + # dns + allow_zone_overlap: "{{ ipaserver_allow_zone_overlap }}" + reverse_zones: "{{ ipaserver_reverse_zones | default([]) }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_reverse: "{{ ipaserver_auto_reverse }}" + zonemgr: "{{ ipaserver_zonemgr | default(omit) }}" + forwarders: "{{ ipaserver_forwarders | default([]) }}" + no_forwarders: "{{ ipaserver_no_forwarders }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + forward_policy: "{{ ipaserver_forward_policy | default(first) }}" + # repair + allow_repair: "{{ ipaserver_allow_repair }}" + register: server_test + +## + +- block: + + - name: Install - Master password passthrough or creation + no_log: yes + master_password: + dm_password: "{{ ipaserver_dm_password }}" + master_password: "{{ ipaserver_master_password | default(omit) }}" + register: master_password + + - name: Install - Install + master_password: + # basic + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" +# ip_addresses: "{{ ipaserver_ip_addresses }}" + domain: "{{ ipaserver_domain }}" + realm: "{{ ipaserver_realm }}" +# hostname: "{{ ansible_fqdn }}" + ca_cert_file: "{{ ipaserver_ca_cert_file | default(omit) }}" + no_host_dns: "{{ ipaserver_no_host_dns }}" + # server +# setup_adtrust: "{{ ipaserver_setup_adtrust }}" +# setup_kra: "{{ ipaserver_setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + idstart: "{{ ipaserver_idstart | default(omit) }}" + idmax: "{{ ipaserver_idmax | default(omit) }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + no_pkinit: "{{ ipaserver_no_pkinit }}" + no_ui_redirect: "{{ ipaserver_no_ui_redirect }}" + dirserv_config_file: "{{ ipaserver_dirserv_config_file | default(omit) }}" + # ssl certificate + dirserv_cert_file: "{{ ipaserver_dirserv_cert_file | default(omit) }}" + dirserv_pin: "{{ ipaserver_dirserv_pin | default(omit) }}" + dirserv_cert_name: "{{ ipaserver_dirserv_cert_name | default(omit) }}" + http_cert_file: "{{ ipaserver_http_cert_file | default(omit) }}" + http_pin: "{{ ipaserver_http_pin | default(omit) }}" + http_cert_name: "{{ ipaserver_http_cert_name | default(omit) }}" + pkinit_cert_file: "{{ ipaserver_pkinit_cert_file | default(omit) }}" + pkinit_pin: "{{ ipaserver_pkinit_pin | default(omit) }}" + pkinit_cert_name: "{{ ipaserver_pkinit_cert_name | default(omit) }}" + # client + mkhomedir: "{{ ipaserver_mkhomedir }}" + no_ntp: "{{ ipaserver_no_ntp }}" + ssh_trust_dns: "{{ ipaserver_ssh_trust_dns }}" + no_ssh: "{{ ipaserver_no_ssh }}" + no_sshd: "{{ ipaserver_no_sshd }}" + no_dns_sshfp: "{{ ipaserver_no_dns_sshfp }}" + # certificate system + external_ca: "{{ ipaserver_external_ca | default(omit) }}" + external_ca_type: "{{ ipaserver_external_ca_type | default(generic) }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_subject_base | default(omit) }}" + ca_subject: "{{ ipaserver_ca_subject | default(omit) }}" + ca_signing_algorithm: "{{ ipaserver_ca_signing_algorithm | default(omit) }}" + # dns + allow_zone_overlap: "{{ ipaserver_allow_zone_overlap }}" + reverse_zone: "{{ ipaserver_reverse_zone | default(omit) }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_reverse: "{{ ipaserver_auto_reverse }}" + zonemgr: "{{ ipaserver_zonemgr | default(omit) }}" + forwarders: "{{ ipaserver_forwarders | default([]) }}" + no_forwarders: "{{ ipaserver_no_forwarders }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + forward_policy: "{{ ipaserver_forward_policy | default(first) }}" + no_dnssec_validation: "{{ ipaserver_no_dnssec_validation }}" + # ad trust + #enable_compat: "{{ ipaserver_enable_compat }}" + #netbios_name: "{{ ipaserver_netbios_name | default(omit) }}" + #rid_base: "{{ ipaserver_rid_base | default(omit) }}" + #secondary_rid_base: "{{ ipaserver_secondary_rid_base | default(omit) }}" + + + + +# - name: Install - Create directory server instance +# create_ds: + + + - fail: + + - name: Install - Install server + ipaserver: + # basic + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" +# ip_addresses: "{{ ipaserver_ip_addresses }}" + domain: "{{ ipaserver_domain }}" + realm: "{{ ipaserver_realm }}" +# hostname: "{{ ansible_fqdn }}" + ca_cert_file: "{{ ipaserver_ca_cert_file | default(omit) }}" + no_host_dns: "{{ ipaserver_no_host_dns }}" + # server +# setup_adtrust: "{{ ipaserver_setup_adtrust }}" +# setup_kra: "{{ ipaserver_setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + idstart: "{{ ipaserver_idstart | default(omit) }}" + idmax: "{{ ipaserver_idmax | default(omit) }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + no_pkinit: "{{ ipaserver_no_pkinit }}" + no_ui_redirect: "{{ ipaserver_no_ui_redirect }}" + dirserv_config_file: "{{ ipaserver_dirserv_config_file | default(omit) }}" + # ssl certificate + dirserv_cert_file: "{{ ipaserver_dirserv_cert_file | default(omit) }}" + dirserv_pin: "{{ ipaserver_dirserv_pin | default(omit) }}" + dirserv_cert_name: "{{ ipaserver_dirserv_cert_name | default(omit) }}" + http_cert_file: "{{ ipaserver_http_cert_file | default(omit) }}" + http_pin: "{{ ipaserver_http_pin | default(omit) }}" + http_cert_name: "{{ ipaserver_http_cert_name | default(omit) }}" + pkinit_cert_file: "{{ ipaserver_pkinit_cert_file | default(omit) }}" + pkinit_pin: "{{ ipaserver_pkinit_pin | default(omit) }}" + pkinit_cert_name: "{{ ipaserver_pkinit_cert_name | default(omit) }}" + # client + mkhomedir: "{{ ipaserver_mkhomedir }}" + no_ntp: "{{ ipaserver_no_ntp }}" + ssh_trust_dns: "{{ ipaserver_ssh_trust_dns }}" + no_ssh: "{{ ipaserver_no_ssh }}" + no_sshd: "{{ ipaserver_no_sshd }}" + no_dns_sshfp: "{{ ipaserver_no_dns_sshfp }}" + # certificate system + external_ca: "{{ ipaserver_external_ca | default(omit) }}" + external_ca_type: "{{ ipaserver_external_ca_type | default(generic) }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_subject_base | default(omit) }}" + ca_subject: "{{ ipaserver_ca_subject | default(omit) }}" + ca_signing_algorithm: "{{ ipaserver_ca_signing_algorithm | default(omit) }}" + # dns + allow_zone_overlap: "{{ ipaserver_allow_zone_overlap }}" + reverse_zone: "{{ ipaserver_reverse_zone | default(omit) }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_reverse: "{{ ipaserver_auto_reverse }}" + zonemgr: "{{ ipaserver_zonemgr | default(omit) }}" + forwarders: "{{ ipaserver_forwarders | default([]) }}" + no_forwarders: "{{ ipaserver_no_forwarders }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + forward_policy: "{{ ipaserver_forward_policy | default(first) }}" + no_dnssec_validation: "{{ ipaserver_no_dnssec_validation }}" + # ad trust + #enable_compat: "{{ ipaserver_enable_compat }}" + #netbios_name: "{{ ipaserver_netbios_name | default(omit) }}" + #rid_base: "{{ ipaserver_rid_base | default(omit) }}" + #secondary_rid_base: "{{ ipaserver_secondary_rid_base | default(omit) }}" + + state: present + + + + + - name: Install - Cleanup root IPA cache + file: + path: "/root/.ipa_cache" + state: absent diff --git a/roles/ipaserver/tasks/install-test.yml b/roles/ipaserver/tasks/install-test.yml new file mode 100644 index 00000000..3d338ed1 --- /dev/null +++ b/roles/ipaserver/tasks/install-test.yml @@ -0,0 +1,31 @@ +--- +# tasks file for ipaserver + +- name: Install - Install IPA server package + package: + name: "{{ item }}" + state: present + with_items: "{{ ipaserver_packages }}" + +- name: Install - Include Python2/3 import test + include: "{{role_path}}/tasks/python_2_3_test.yml" + static: yes + +- name: Install - Server installation + server_install: + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + domain: "{{ ipaserver_domain | default(omit)}}" + realm: "{{ ipaserver_realm | default(omit)}}" + hostname: "{{ ipaserver_hostname | default(ansible_fqdn) }}" + setup_dns: "{{ ipaserver_setup_dns }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + register: server_install + +## + +- name: Install - Cleanup root IPA cache + file: + path: "/root/.ipa_cache" + state: absent diff --git a/roles/ipaserver/tasks/install.yml b/roles/ipaserver/tasks/install.yml new file mode 100644 index 00000000..aa19f94a --- /dev/null +++ b/roles/ipaserver/tasks/install.yml @@ -0,0 +1,428 @@ +--- +# tasks file for ipaserver + +- name: Install - Install IPA server package + package: + name: "{{ item }}" + state: present + with_items: "{{ ipaserver_packages }}" + +- name: Install - Install packages for dns + package: + name: "{{ item }}" + state: present + with_items: "{{ ipaserver_packages_dns }}" + when: ipaserver_setup_dns | bool + +- name: Install - Install packages for adtrust + package: + name: "{{ item }}" + state: present + with_items: "{{ ipaserver_packages_adtrust }}" + when: ipaserver_setup_adtrust | bool + +- name: Install - Include Python2/3 import test + include: "{{role_path}}/tasks/python_2_3_test.yml" + static: yes + +- name: Install - Server installation test + ipaserver_test: + ### basic ### + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + master_password: "{{ ipaserver_master_password | default(omit) }}" + ip_addresses: "{{ ipaserver_ip_addresses | default([]) }}" + domain: "{{ ipaserver_domain | default(omit) }}" + realm: "{{ ipaserver_realm | default(omit) }}" + hostname: "{{ ipaserver_hostname | default(ansible_fqdn) }}" + ca_cert_files: "{{ ipaserver_ca_cert_files | default(omit) }}" + # no_host_dns: "{{ ipaserver_no_host_dns }}" + ### server ### + setup_adtrust: "{{ ipaserver_setup_adtrust }}" + setup_kra: "{{ ipaserver_setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + idstart: "{{ ipaserver_idstart | default(omit) }}" + idmax: "{{ ipaserver_idmax | default(omit) }}" + # no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + no_pkinit: "{{ ipaserver_no_pkinit }}" + # no_ui_redirect: "{{ ipaserver_no_ui_redirect }}" + dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" + ### ssl certificate ### + dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}" + http_cert_files: "{{ ipaserver_http_cert_files | default([]) }}" + pkinit_cert_files: "{{ ipaserver_pkinit_cert_files | default([]) }}" + # dirsrv_pin + # http_pin + # pkinit_pin + # dirsrv_name + # http_name + # pkinit_name + ### client ### + # mkhomedir + no_ntp: "{{ ipaserver_no_ntp }}" + # ssh_trust_dns + # no_ssh + # no_sshd + # no_dns_sshfp + ### certificate system ### + external_ca: "{{ ipaserver_external_ca }}" + external_ca_type: "{{ ipaserver_external_ca_type | default(omit) }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_subject_base | default(omit) }}" + ca_subject: "{{ ipaserver_ca_subject | default(omit) }}" + # ca_signing_algorithm + ### dns ### + allow_zone_overlap: "{{ ipaserver_allow_zone_overlap }}" + reverse_zones: "{{ ipaserver_reverse_zones | default([]) }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_reverse: "{{ ipaserver_auto_reverse }}" + zonemgr: "{{ ipaserver_zonemgr | default(omit) }}" + forwarders: "{{ ipaserver_forwarders | default([]) }}" + no_forwarders: "{{ ipaserver_no_forwarders }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + forward_policy: "{{ ipaserver_forward_policy | default(omit) }}" + no_dnssec_validation: "{{ ipaserver_no_dnssec_validation }}" + ### ad trust ### + enable_compat: "{{ ipaserver_enable_compat }}" + netbios_name: "{{ ipaserver_netbios_name | default(omit) }}" + rid_base: "{{ ipaserver_rid_base | default(omit) }}" + secondary_rid_base: "{{ ipaserver_secondary_rid_base | default(omit) }}" + + ### additional ### + allow_repair: "{{ ipaserver_allow_repair }}" + register: ipaserver_test + + +- block: + + - block: + - name: Install - Master password creation + no_log: yes + ipaserver_master_password: + dm_password: "{{ ipaserver_dm_password }}" + master_password: "{{ ipaserver_master_password | default(omit) }}" + register: ipaserver_master_password + + - name: Install - Use new master password + no_log: yes + set_fact: + ipaserver_master_password: "{{ ipaserver_master_password.value }}" + + when: ipaserver_master_password is undefined + + - name: Install - Server preparation + ipaserver_prepare: + ### basic ### + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + # master_password + #ip_addresses: "{{ ipaserver_ip_addresses | default([]) }}" + domain: "{{ ipaserver_domain | default(omit) }}" + realm: "{{ ipaserver_realm | default(omit) }}" + hostname: "{{ ipaserver_hostname | default(ansible_fqdn) }}" + ca_cert_files: "{{ ipaserver_ca_cert_files | default(omit) }}" + # no_host_dns: "{{ ipaserver_no_host_dns }}" + ### server ### + setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + setup_kra: "{{ ipaserver_test.setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + idstart: "{{ ipaserver_idstart | default(omit) }}" + idmax: "{{ ipaserver_idmax | default(omit) }}" + # no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + no_pkinit: "{{ ipaserver_no_pkinit }}" + # no_ui_redirect: "{{ ipaserver_no_ui_redirect }}" + dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" + ### ssl certificate ### + dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}" + http_cert_files: "{{ ipaserver_http_cert_files | default([]) }}" + pkinit_cert_files: "{{ ipaserver_pkinit_cert_files | default([]) }}" + # dirsrv_pin + # http_pin + # pkinit_pin + # dirsrv_name + # http_name + # pkinit_name + ### client ### + # mkhomedir + no_ntp: "{{ ipaserver_no_ntp }}" + # ssh_trust_dns + # no_ssh + # no_sshd + # no_dns_sshfp + ### certificate system ### + external_ca: "{{ ipaserver_external_ca }}" + external_ca_type: "{{ ipaserver_external_ca_type | default(omit) }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_test.subject_base | default(omit) }}" + ca_subject: "{{ ipaserver_test.ca_subject | default(omit) }}" + # ca_signing_algorithm + ### dns ### + allow_zone_overlap: "{{ ipaserver_allow_zone_overlap }}" + reverse_zones: "{{ ipaserver_reverse_zones | default([]) }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_reverse: "{{ ipaserver_auto_reverse }}" + zonemgr: "{{ ipaserver_zonemgr | default(omit) }}" + forwarders: "{{ ipaserver_test.forwarders | default([]) }}" + no_forwarders: "{{ ipaserver_no_forwarders }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + forward_policy: "{{ ipaserver_forward_policy | default(omit) }}" + no_dnssec_validation: "{{ ipaserver_no_dnssec_validation }}" + ### ad trust ### + enable_compat: "{{ ipaserver_enable_compat }}" + netbios_name: "{{ ipaserver_netbios_name | default(omit) }}" + rid_base: "{{ ipaserver_rid_base | default(omit) }}" + secondary_rid_base: "{{ ipaserver_secondary_rid_base | default(omit) }}" + + _hostname_overridden: "{{ ipaserver_test._hostname_overridden | default(omit) }}" + + when: ipaserver_foo is defined + + + + + - name: Install - Server preparation + ipaserver_prepare: + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + domain: "{{ ipaserver_test.domain }}" + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + ##ip_addresses: "{{ ipaserver_test.ip_addresses }}" + reverse_zones: "{{ ipaserver_test.reverse_zones }}" + setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + setup_kra: "{{ ipaserver_test.setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + no_host_dns: "{{ ipaserver_test.no_host_dns }}" + subject_base: "{{ ipaserver_test.subject_base }}" + ca_subject: "{{ ipaserver_test.ca_subject }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_reverse: "{{ ipaserver_auto_reverse }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + #no_pkinit: "{{ ipaserver_test.no_pkinit }}" + _hostname_overridden: "{{ ipaserver_test._hostname_overridden }}" + register: ipaserver_prepare + + - name: Install - Setup NTP + ipaserver_setup_ntp: + when: not ipaserver_no_ntp | bool and (ipaserver_external_cert_files is undefined or ipaserver_external_cert_files|length < 1) + + - name: Install - Setup DS + ipaserver_setup_ds: + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + #master_password: "{{ ipaserver_master_password }}" + domain: "{{ ipaserver_test.domain }}" + realm: "{{ ipaserver_test.realm | default(omit) }}" + hostname: "{{ ipaserver_test.hostname }}" + #ip_addresses: "{{ ipaserver_test.ip_addresses }}" + #reverse_zones: "{{ ipaserver_test.reverse_zones }}" + #setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + #setup_kra: "{{ ipaserver_test.setup_kra }}" + #setup_dns: "{{ ipaserver_setup_dns }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + #no_host_dns: "{{ ipaserver_test.no_host_dns }}" + dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" + dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_test.subject_base }}" + ca_subject: "{{ ipaserver_test.ca_subject }}" + #no_reverse: "{{ ipaserver_no_reverse }}" + #auto_forwarders: "{{ ipaserver_auto_forwarders }}" + no_pkinit: "{{ ipaserver_test.no_pkinit }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + idstart: "{{ ipaserver_test.idstart }}" + idmax: "{{ ipaserver_test.idmax }}" + + - name: Install - Setup KRB + ipaserver_setup_krb: + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + master_password: "{{ ipaserver_master_password }}" + domain: "{{ ipaserver_test.domain }}" + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + #ip_addresses: "{{ ipaserver_test.ip_addresses }}" + reverse_zones: "{{ ipaserver_test.reverse_zones }}" + setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + setup_kra: "{{ ipaserver_test.setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + no_host_dns: "{{ ipaserver_test.no_host_dns }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_test.subject_base }}" + ca_subject: "{{ ipaserver_test.ca_subject }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + no_pkinit: "{{ ipaserver_test.no_pkinit }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + idstart: "{{ ipaserver_test.idstart }}" + idmax: "{{ ipaserver_test.idmax }}" + _pkinit_pkcs12_info: "{{ ipaserver_test._pkinit_pkcs12_info }}" + + - name: Install - Setup CA + ipaserver_setup_ca: + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + master_password: "{{ ipaserver_master_password }}" + #ip_addresses: "{{ ipaserver_test.ip_addresses }}" + domain: "{{ ipaserver_test.domain }}" + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + no_host_dns: "{{ ipaserver_test.no_host_dns }}" + setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + setup_kra: "{{ ipaserver_test.setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + idstart: "{{ ipaserver_test.idstart }}" + idmax: "{{ ipaserver_test.idmax }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + no_pkinit: "{{ ipaserver_test.no_pkinit }}" + dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" + dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}" + _dirsrv_pkcs12_info: "{{ ipaserver_test._dirsrv_pkcs12_info }}" + external_ca: "{{ ipaserver_external_ca }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_test.subject_base }}" + _subject_base: "{{ ipaserver_test._subject_base }}" + ca_subject: "{{ ipaserver_test.ca_subject }}" + _ca_subject: "{{ ipaserver_test._ca_subject }}" + ca_signing_algorithm: "{{ ipaserver_ca_signing_algorithm | default(omit) }}" + + reverse_zones: "{{ ipaserver_test.reverse_zones }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + + - name: Install - Setup otpd + ipaserver_setup_otpd: + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + + - name: Install - Setup custodia + ipaserver_setup_custodia: + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + + - name: Install - Setup HTTP + ipaserver_setup_http: + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + master_password: "{{ ipaserver_master_password }}" + domain: "{{ ipaserver_test.domain }}" + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + #ip_addresses: "{{ ipaserver_test.ip_addresses }}" + reverse_zones: "{{ ipaserver_test.reverse_zones }}" + setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + setup_kra: "{{ ipaserver_test.setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + no_host_dns: "{{ ipaserver_test.no_host_dns }}" + dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_test.subject_base }}" + _subject_base: "{{ ipaserver_test._subject_base }}" + ca_subject: "{{ ipaserver_test.ca_subject }}" + _ca_subject: "{{ ipaserver_test._ca_subject }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + no_pkinit: "{{ ipaserver_test.no_pkinit }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + idstart: "{{ ipaserver_test.idstart }}" + idmax: "{{ ipaserver_test.idmax }}" + http_cert_files: "{{ ipaserver_http_cert_files | default([]) }}" + no_ui_redirect: "{{ ipaserver_no_ui_redirect }}" + + - name: Install - Setup KRA + ipaserver_setup_kra: + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + dm_password: "{{ ipaserver_dm_password }}" + setup_kra: "{{ ipaserver_test.setup_kra }}" + when: ipaserver_test.setup_kra | bool + + - name: Install - Setup DNS + ipaserver_setup_dns: + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + setup_dns: "{{ ipaserver_setup_dns }}" + forwarders: "{{ ipaserver_test.forwarders | default(omit) }}" + forward_policy: "{{ ipaserver_forward_policy | default(omit) }}" + zonemgr: "{{ ipaserver_zonemgr | default(omit) }}" + no_dnssec_validation: "{{ ipaserver_no_dnssec_validation }}" + when: ipaserver_setup_dns | bool + + - name: Install - Setup ADTRUST + ipaserver_setup_adtrust: + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + when: ipaserver_test.setup_adtrust + + - name: Install - Set DS password + ipaserver_set_ds_password: + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + domain: "{{ ipaserver_test.domain }}" + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + subject_base: "{{ ipaserver_test.subject_base }}" + ca_subject: "{{ ipaserver_test.ca_subject }}" + no_pkinit: "{{ ipaserver_test.no_pkinit }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + idstart: "{{ ipaserver_test.idstart }}" + idmax: "{{ ipaserver_test.idmax }}" + dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" + _dirsrv_pkcs12_info: "{{ ipaserver_test._dirsrv_pkcs12_info }}" + + #- name: Install - Setup client + # include_role: + # name: ipaclient + # private: yes + # defaults_from: "/roles/ipaclient/defaults/main.yml" + # tasks_from: "/roles/ipaclient/tasks/main.yml" + # vars_from: "/roles/ipaclient/vars/main.yml" + # vars: + # state: present + # on_master: yes + # domain: "{{ ipaserver_test.domain }}" + # realm: "{{ ipaserver_test.realm }}" + # server: "{{ ipaserver_test.hostname }}" + # hostname: "{{ ipaserver_test.hostname }}" + # #no_dns_sshfp: "{{ ipaserver_no_dns_sshfp }}" + # #ssh_trust_dns: "{{ ipaserver_ssh_trust_dns }}" + # #no_ssh: "{{ ipaserver_no_ssh }}" + # #no_sshd: "{{ ipaserver_no_sshd }}" + # mkhomedir: "{{ ipaserver_mkhomedir }}" + # #allow_repair: "{{ ipaserver_allow_repair }}" + + - name: Install - Setup client + command: > + /usr/sbin/ipa-client-install + --unattended + --on-master + --domain "{{ ipaserver_test.domain }}" + --realm "{{ ipaserver_test.realm }}" + --server "{{ ipaserver_test.hostname }}" + --hostname "{{ ipaserver_test.hostname }}" + {{ "--mkhomedir" if ipaserver_mkhomedir | bool else "" }} + + # {{ "--no-dns-sshfp" if ipaserver_no_dns_sshfp | bool else "" }} + # {{ "--ssh-trust-dns" if ipaserver_ssh_trust_dns | bool else "" }} + # {{ "--no-ssh" if ipaserver_no_ssh | bool else "" }} + # {{ "--no-sshd" if ipaserver_no_sshd | bool else "" }} + + - name: Install - Enable IPA + ipaserver_enable_ipa: + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + register: ipaserver_enable_ipa + + - name: Install - Cleanup root IPA cache + file: + path: "/root/.ipa_cache" + state: absent + when: ipaserver_enable_ipa.changed diff --git a/roles/ipaserver/tasks/install_cache.yml b/roles/ipaserver/tasks/install_cache.yml new file mode 100644 index 00000000..4e5eb6bb --- /dev/null +++ b/roles/ipaserver/tasks/install_cache.yml @@ -0,0 +1,566 @@ +--- +# tasks file for ipaserver + +- name: Install - Install IPA server package + package: + name: "{{ item }}" + state: present + with_items: "{{ ipaserver_packages }}" + +- name: Install - Install packages for dns + package: + name: "{{ item }}" + state: present + with_items: "{{ ipaserver_packages_dns }}" + when: ipaserver_setup_dns | bool + +- name: Install - Install packages for adtrust + package: + name: "{{ item }}" + state: present + with_items: "{{ ipaserver_packages_adtrust }}" + when: ipaserver_setup_adtrust | bool + +- name: Install - Include Python2/3 import test + include: "{{role_path}}/tasks/python_2_3_test.yml" + static: yes + +- name: Install - Server load cache + ipaserver_load_cache: + dm_password: "{{ ipaserver_dm_password }}" + register: ipaserver_cache + +- name: Install - Server apply cache + set_fact: + ### basic ### + ipaserver_master_password: "{{ ipaserver_cache.master_password | default(omit) }}" + ipaserver_password: "{{ ipaserver_cache.admin_password | default(omit) }}" + ipaserver_ip_addresses: "{{ ipaserver_cache.ip_addresses | default(omit) }}" + ipaserver_domain: "{{ ipaserver_cache.domain_name | default(omit) }}" + ipaserver_realm: "{{ ipaserver_cache.realm_name | default(omit) }}" + ipaserver_hostname: "{{ ipaserver_cache.host_name | default(omit) }}" + ipaserver_ca_cert_files: "{{ ipaserver_cache.ca_cert_files | default(omit) }}" + ipaserver_no_host_dns: "{{ ipaserver_cache.no_host_dns | default(omit) }}" + ### server ### + ipaserver_setup_adtrust: "{{ ipaserver_cache.setup_adtrust | default(omit) }}" + ipaserver_setup_kra: "{{ ipaserver_cache.setup_kra | default(omit) }}" + ipaserver_setup_dns: "{{ ipaserver_cache.setup_dns | default(omit) }}" + ipaserver_idstart: "{{ ipaserver_cache.idstart | default(omit) }}" + ipaserver_idmax: "{{ ipaserver_cache.idmax | default(omit) }}" + ipaserver_no_hbac_allow: "{{ ipaserver_cache.no_hbac_allow | default(omit) }}" + ipaserver_no_pkinit: "{{ ipaserver_cache.no_pkinit | default(omit) }}" + ipaserver_no_ui_redirect: "{{ ipaserver_cache.no_ui_redirect | default(omit) }}" + ipaserver_dirsrv_config_file: "{{ ipaserver_cache.dirsrv_config_file | default(omit) }}" + ### ssl certificate ### + ipaserver_dirsrv_cert_files: "{{ ipaserver_cache.dirsrv_cert_files | default(omit) }}" + ipaserver_http_cert_files: "{{ ipaserver_cache.http_cert_files | default(omit) }}" + ipaserver_pkinit_cert_files: "{{ ipaserver_cache.pkinit_cert_files | default(omit) }}" + ipaserver_dirsrv_pin: "{{ ipaserver_cache.dirsrv_pin | default(omit) }}" + ipaserver_http_pin: "{{ ipaserver_cache.http_pin | default(omit) }}" + ipaserver_pkinit_pin: "{{ ipaserver_cache.pkinit_pin | default(omit) }}" + ipaserver_dirsrv_name: "{{ ipaserver_cache.dirsrv_name | default(omit) }}" + ipaserver_http_name: "{{ ipaserver_cache.http_name | default(omit) }}" + ipaserver_pkinit_name: "{{ ipaserver_cache.pkinit_name | default(omit) }}" + ### client ### + ipaserver_mkhomedir: "{{ ipaserver_cache.mkhomedir | default(omit) }}" + ipaserver_no_ntp: "{{ ipaserver_cache.no_ntp | default(omit) }}" + ipaserver_ssh_trust_dns: "{{ ipaserver_cache.ssh_trust_dns | default(omit) }}" + ipaserver_no_ssh: "{{ ipaserver_cache.no_ssh | default(omit) }}" + ipaserver_no_sshd: "{{ ipaserver_cache.no_sshd | default(omit) }}" + ipaserver_no_dns_sshfp: "{{ ipaserver_cache.no_dns_sshfp | default(omit) }}" + ### certificate system ### + ipaserver_external_ca: "{{ ipaserver_cache.external_ca | default(omit) }}" + ipaserver_external_ca_type: "{{ ipaserver_cache.external_ca_type | default(omit) }}" + ipaserver_external_cert_files: "{{ ipaserver_cache.external_cert_files | default(omit) }}" + ipaserver_subject_base: "{{ ipaserver_cache.subject_base | default(omit) }}" + ipaserver_ca_subject: "{{ ipaserver_cache.ca_subject | default(omit) }}" + ipaserver_ca_signing_algorithm: "{{ ipaserver_cache.ca_signing_algorithm | default(omit) }}" + ### dns ### + ipaserver_allow_zone_overlap: "{{ ipaserver_cache.allow_zone_overlap | default(omit) }}" + ipaserver_reverse_zones: "{{ ipaserver_cache.reverse_zones | default(omit) }}" + ipaserver_no_reverse: "{{ ipaserver_cache.no_reverse | default(omit) }}" + ipaserver_auto_reverse: "{{ ipaserver_cache.auto_reverse | default(omit) }}" + ipaserver_zonemgr: "{{ ipaserver_cache.zonemgr | default(omit) }}" + ipaserver_forwarders: "{{ ipaserver_cache.forwarders | default(omit) }}" + ipaserver_no_forwarders: "{{ ipaserver_cache.no_forwarders | default(omit) }}" + ipaserver_auto_forwarders: "{{ ipaserver_cache.auto_forwarders | default(omit) }}" + ipaserver_forward_policy: "{{ ipaserver_cache.forward_policy | default(omit) }}" + ipaserver_no_dnssec_validation: "{{ ipaserver_cache.no_dnssec_validation | default(omit) }}" + ### ad trust ### + ipaserver_enable_compat: "{{ ipaserver_cache.enable_compat | default(omit) }}" + ipaserver_netbios_name: "{{ ipaserver_cache.netbios_name | default(omit) }}" + ipaserver_rid_base: "{{ ipaserver_cache.rid_base | default(omit) }}" + ipaserver_secondary_rid_base: "{{ ipaserver_cache.secondary_rid_base | default(omit) }}" + ### additional ### + ipaserver_allow_repair: "{{ ipaserver_cache.allow_repair | default(omit) }}" + ipaserver_domainlevel: "{{ ipaserver_cache.domainlevel | default(omit) }}" + ipaserver__subject_base: "{{ ipaserver_cache._subject_base | default(omit) }}" + ipaserver__ca_subject: "{{ ipaserver_cache._ca_subject | default(omit) }}" + ipaserver__hostname_overridden: "{{ ipaserver_cache._hostname_overridden | default(omit) }}" + ipaserver_setup_ca: "{{ ipaserver_cache.setup_ca | default(omit) }}" + ipaserver__installation_cleanup: "{{ ipaserver_cache._installation_cleanup | default(omit) }}" + ipaserver__dirsrv_pkcs12_file: "{{ ipaserver_cache._dirsrv_pkcs12_file | default(omit) }}" + ipaserver__dirsrv_pkcs12_info: "{{ ipaserver_cache._dirsrv_pkcs12_info | default(omit) }}" + ipaserver__dirsrv_ca_cert: "{{ ipaserver_cache._dirsrv_ca_cert | default(omit) }}" + ipaserver__http_pkcs12_file: "{{ ipaserver_cache._http_pkcs12_file | default(omit) }}" + ipaserver__http_pkcs12_info: "{{ ipaserver_cache._http_pkcs12_info | default(omit) }}" + ipaserver__http_ca_cert: "{{ ipaserver_cache._http_ca_cert | default(omit) }}" + ipaserver__pkinit_pkcs12_file: "{{ ipaserver_cache._pkinit_pkcs12_file | default(omit) }}" + ipaserver__pkinit_pkcs12_info: "{{ ipaserver_cache._pkinit_pkcs12_info | default(omit) }}" + ipaserver__pkinit_ca_cert: "{{ ipaserver_cache._pkinit_ca_cert | default(omit) }}" + when: ipaserver_cache.changed + +- name: Install - Server installation test + ipaserver_test: + ### basic ### + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + master_password: "{{ ipaserver_master_password | default(omit) }}" + ip_addresses: "{{ ipaserver_ip_addresses | default([]) }}" + domain: "{{ ipaserver_domain | default(omit) }}" + realm: "{{ ipaserver_realm | default(omit) }}" + hostname: "{{ ipaserver_hostname | default(ansible_fqdn) }}" + ca_cert_files: "{{ ipaserver_ca_cert_files | default(omit) }}" + # no_host_dns: "{{ ipaserver_no_host_dns }}" + ### server ### + setup_adtrust: "{{ ipaserver_setup_adtrust }}" + setup_kra: "{{ ipaserver_setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + idstart: "{{ ipaserver_idstart | default(omit) }}" + idmax: "{{ ipaserver_idmax | default(omit) }}" + # no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + no_pkinit: "{{ ipaserver_no_pkinit }}" + # no_ui_redirect: "{{ ipaserver_no_ui_redirect }}" + dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" + ### ssl certificate ### + dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}" + http_cert_files: "{{ ipaserver_http_cert_files | default([]) }}" + pkinit_cert_files: "{{ ipaserver_pkinit_cert_files | default([]) }}" + # dirsrv_pin + # http_pin + # pkinit_pin + # dirsrv_name + # http_name + # pkinit_name + ### client ### + # mkhomedir + no_ntp: "{{ ipaserver_no_ntp }}" + # ssh_trust_dns + # no_ssh + # no_sshd + # no_dns_sshfp + ### certificate system ### + external_ca: "{{ ipaserver_external_ca }}" + external_ca_type: "{{ ipaserver_external_ca_type | default(omit) }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_subject_base | default(omit) }}" + ca_subject: "{{ ipaserver_ca_subject | default(omit) }}" + # ca_signing_algorithm + ### dns ### + allow_zone_overlap: "{{ ipaserver_allow_zone_overlap }}" + reverse_zones: "{{ ipaserver_reverse_zones | default([]) }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_reverse: "{{ ipaserver_auto_reverse }}" + zonemgr: "{{ ipaserver_zonemgr | default(omit) }}" + forwarders: "{{ ipaserver_forwarders | default([]) }}" + no_forwarders: "{{ ipaserver_no_forwarders }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + forward_policy: "{{ ipaserver_forward_policy | default(omit) }}" + no_dnssec_validation: "{{ ipaserver_no_dnssec_validation }}" + ### ad trust ### + enable_compat: "{{ ipaserver_enable_compat }}" + netbios_name: "{{ ipaserver_netbios_name | default(omit) }}" + rid_base: "{{ ipaserver_rid_base | default(omit) }}" + secondary_rid_base: "{{ ipaserver_secondary_rid_base | default(omit) }}" + + ### additional ### + allow_repair: "{{ ipaserver_allow_repair }}" + register: ipaserver_test + +#- name: Install - Server apply test results +# set_fact: +# #ipaserver_setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" +# #ipaserver_setup_kra: "{{ ipaserver_test.setup_kra }}" +# #ipaserver_setup_ca: "{{ ipaserver_test.setup_ca }}" +# #ipaserver_reverse_zones: "{{ ipaserver_test.reverse_zones }}" +# #ipaserver_forwarders: "{{ ipaserver_test.forwarders }}" +# #ipaserver_subject_base: "{{ ipaserver_test.subject_base }}" +# #ipaserver_ca_subject: "{{ ipaserver_test.ca_subject }}" +# #ipaserver__subject_base: "{{ ipaserver_test._subject_base }}" +# #ipaserver__ca_subject: "{{ ipaserver_test._ca_subject }}" +# #ipaserver__hostname_overridden: "{{ ipaserver_test._hostname_overridden }}" +# #ipaserver__installation_cleanup: "{{ ipaserver_test._installation_cleanup }}" +# #ipaserver__dirsrv_pkcs12_file: "{{ ipaserver_test._dirsrv_pkcs12_file }}" +# #ipaserver__dirsrv_pkcs12_info: "{{ ipaserver_test._dirsrv_pkcs12_info }}" +# #ipaserver__dirsrv_ca_cert: "{{ ipaserver_test._dirsrv_ca_cert }}" +# #ipaserver__http_pkcs12_file: "{{ ipaserver_test._http_pkcs12_file }}" +# #ipaserver__http_pkcs12_info: "{{ ipaserver_test._http_pkcs12_info }}" +# #ipaserver__http_ca_cert: "{{ ipaserver_test._http_ca_cert }}" +# #ipaserver__pkinit_pkcs12_file: "{{ ipaserver_test._pkinit_pkcs12_file }}" +# #ipaserver__pkinit_pkcs12_info: "{{ ipaserver_test._pkinit_pkcs12_info }}" +# #ipaserver__pkinit_ca_cert: "{{ ipaserver_test._pkinit_ca_cert }}" +# when: ipaserver_test.changed + +- block: + + - block: + - name: Install - Master password creation + no_log: yes + ipaserver_master_password: + dm_password: "{{ ipaserver_dm_password }}" + master_password: "{{ ipaserver_master_password | default(omit) }}" + register: ipaserver_master_password + + - name: Install - Use new master password + no_log: yes + set_fact: + ipaserver_master_password: "{{ ipaserver_master_password.value }}" + + when: ipaserver_master_password is undefined + + - name: Install - Server preparation + ipaserver_prepare: + ### basic ### + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + # master_password + #ip_addresses: "{{ ipaserver_ip_addresses | default([]) }}" + domain: "{{ ipaserver_domain | default(omit) }}" + realm: "{{ ipaserver_realm | default(omit) }}" + hostname: "{{ ipaserver_hostname | default(ansible_fqdn) }}" + ca_cert_files: "{{ ipaserver_ca_cert_files | default(omit) }}" + # no_host_dns: "{{ ipaserver_no_host_dns }}" + ### server ### + setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + setup_kra: "{{ ipaserver_test.setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + idstart: "{{ ipaserver_idstart | default(omit) }}" + idmax: "{{ ipaserver_idmax | default(omit) }}" + # no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + no_pkinit: "{{ ipaserver_no_pkinit }}" + # no_ui_redirect: "{{ ipaserver_no_ui_redirect }}" + dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" + ### ssl certificate ### + dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}" + http_cert_files: "{{ ipaserver_http_cert_files | default([]) }}" + pkinit_cert_files: "{{ ipaserver_pkinit_cert_files | default([]) }}" + # dirsrv_pin + # http_pin + # pkinit_pin + # dirsrv_name + # http_name + # pkinit_name + ### client ### + # mkhomedir + no_ntp: "{{ ipaserver_no_ntp }}" + # ssh_trust_dns + # no_ssh + # no_sshd + # no_dns_sshfp + ### certificate system ### + external_ca: "{{ ipaserver_external_ca }}" + external_ca_type: "{{ ipaserver_external_ca_type | default(omit) }}" + external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" + subject_base: "{{ ipaserver_test.subject_base | default(omit) }}" + ca_subject: "{{ ipaserver_test.ca_subject | default(omit) }}" + # ca_signing_algorithm + ### dns ### + allow_zone_overlap: "{{ ipaserver_allow_zone_overlap }}" + reverse_zones: "{{ ipaserver_reverse_zones | default([]) }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_reverse: "{{ ipaserver_auto_reverse }}" + zonemgr: "{{ ipaserver_zonemgr | default(omit) }}" + forwarders: "{{ ipaserver_test.forwarders | default([]) }}" + no_forwarders: "{{ ipaserver_no_forwarders }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + forward_policy: "{{ ipaserver_forward_policy | default(omit) }}" + no_dnssec_validation: "{{ ipaserver_no_dnssec_validation }}" + ### ad trust ### + enable_compat: "{{ ipaserver_enable_compat }}" + netbios_name: "{{ ipaserver_netbios_name | default(omit) }}" + rid_base: "{{ ipaserver_rid_base | default(omit) }}" + secondary_rid_base: "{{ ipaserver_secondary_rid_base | default(omit) }}" + + _hostname_overridden: "{{ ipaserver_test._hostname_overridden | default(omit) }}" + + when: ipaserver_foo is defined + + + + + - name: Install - Server preparation + ipaserver_prepare: + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + domain: "{{ ipaserver_test.domain }}" + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + ##ip_addresses: "{{ ipaserver_test.ip_addresses }}" + reverse_zones: "{{ ipaserver_test.reverse_zones }}" + setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + setup_kra: "{{ ipaserver_test.setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + no_host_dns: "{{ ipaserver_test.no_host_dns }}" + subject_base: "{{ ipaserver_test.subject_base }}" + ca_subject: "{{ ipaserver_test.ca_subject }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_reverse: "{{ ipaserver_auto_reverse }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + #no_pkinit: "{{ ipaserver_test.no_pkinit }}" + _hostname_overridden: "{{ ipaserver_test._hostname_overridden }}" + register: ipaserver_prepare + + - name: Install - Setup NTP + ipaserver_setup_ntp: + when: not ipaserver_no_ntp | bool and (ipaserver_external_cert_files is undefined or ipaserver_external_cert_files|length < 1) + + - name: Install - Setup DS + ipaserver_setup_ds: + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + #master_password: "{{ ipaserver_master_password }}" + domain: "{{ ipaserver_test.domain }}" + realm: "{{ ipaserver_test.realm | default(omit) }}" + hostname: "{{ ipaserver_test.hostname }}" + #ip_addresses: "{{ ipaserver_test.ip_addresses }}" + #reverse_zones: "{{ ipaserver_test.reverse_zones }}" + #setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + #setup_kra: "{{ ipaserver_test.setup_kra }}" + #setup_dns: "{{ ipaserver_setup_dns }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + #no_host_dns: "{{ ipaserver_test.no_host_dns }}" + subject_base: "{{ ipaserver_test.subject_base }}" + ca_subject: "{{ ipaserver_test.ca_subject }}" + #no_reverse: "{{ ipaserver_no_reverse }}" + #auto_forwarders: "{{ ipaserver_auto_forwarders }}" + no_pkinit: "{{ ipaserver_test.no_pkinit }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + idstart: "{{ ipaserver_test.idstart }}" + idmax: "{{ ipaserver_test.idmax }}" + + - name: Install - Setup KRB + ipaserver_setup_krb: + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + master_password: "{{ ipaserver_master_password }}" + domain: "{{ ipaserver_test.domain }}" + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + #ip_addresses: "{{ ipaserver_test.ip_addresses }}" + reverse_zones: "{{ ipaserver_test.reverse_zones }}" + setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + setup_kra: "{{ ipaserver_test.setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + no_host_dns: "{{ ipaserver_test.no_host_dns }}" + subject_base: "{{ ipaserver_test.subject_base }}" + ca_subject: "{{ ipaserver_test.ca_subject }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + no_pkinit: "{{ ipaserver_test.no_pkinit }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + idstart: "{{ ipaserver_test.idstart }}" + idmax: "{{ ipaserver_test.idmax }}" + + - name: Install - Setup CA + ipaserver_setup_ca: + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + master_password: "{{ ipaserver_master_password }}" + #ip_addresses: "{{ ipaserver_test.ip_addresses }}" + domain: "{{ ipaserver_test.domain }}" + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + no_host_dns: "{{ ipaserver_test.no_host_dns }}" + setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + setup_kra: "{{ ipaserver_test.setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + idstart: "{{ ipaserver_test.idstart }}" + idmax: "{{ ipaserver_test.idmax }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + no_pkinit: "{{ ipaserver_test.no_pkinit }}" + dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" + _dirsrv_pkcs12_info: "{{ ipaserver_test._dirsrv_pkcs12_info }}" + external_ca: "{{ ipaserver_external_ca }}" + subject_base: "{{ ipaserver_test.subject_base }}" + _subject_base: "{{ ipaserver_test._subject_base }}" + ca_subject: "{{ ipaserver_test.ca_subject }}" + _ca_subject: "{{ ipaserver_test._ca_subject }}" + ca_signing_algorithm: "{{ ipaserver_ca_signing_algorithm | default(omit) }}" + + reverse_zones: "{{ ipaserver_test.reverse_zones }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + + - name: Install - Setup otpd + ipaserver_setup_otpd: + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + + - name: Install - Setup custodia + ipaserver_setup_custodia: + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + + - name: Install - Setup HTTP + ipaserver_setup_http: + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + master_password: "{{ ipaserver_master_password }}" + domain: "{{ ipaserver_test.domain }}" + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + #ip_addresses: "{{ ipaserver_test.ip_addresses }}" + reverse_zones: "{{ ipaserver_test.reverse_zones }}" + setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + setup_kra: "{{ ipaserver_test.setup_kra }}" + setup_dns: "{{ ipaserver_setup_dns }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + no_host_dns: "{{ ipaserver_test.no_host_dns }}" + subject_base: "{{ ipaserver_test.subject_base }}" + _subject_base: "{{ ipaserver_test._subject_base }}" + ca_subject: "{{ ipaserver_test.ca_subject }}" + _ca_subject: "{{ ipaserver_test._ca_subject }}" + no_reverse: "{{ ipaserver_no_reverse }}" + auto_forwarders: "{{ ipaserver_auto_forwarders }}" + no_pkinit: "{{ ipaserver_test.no_pkinit }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + idstart: "{{ ipaserver_test.idstart }}" + idmax: "{{ ipaserver_test.idmax }}" + http_cert_files: "{{ ipaserver_http_cert_files | default([]) }}" + no_ui_redirect: "{{ ipaserver_no_ui_redirect }}" + + - name: Install - Setup KRA + ipaserver_setup_kra: + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + dm_password: "{{ ipaserver_dm_password }}" + setup_kra: "{{ ipaserver_test.setup_kra }}" + when: ipaserver_test.setup_kra | bool + + - name: Install - Setup DNS + ipaserver_setup_dns: + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + setup_dns: "{{ ipaserver_setup_dns }}" + forwarders: "{{ ipaserver_test.forwarders | default(omit) }}" + forward_policy: "{{ ipaserver_forward_policy | default(omit) }}" + zonemgr: "{{ ipaserver_zonemgr | default(omit) }}" + no_dnssec_validation: "{{ ipaserver_no_dnssec_validation }}" + when: ipaserver_setup_dns | bool + + - name: Install - Setup ADTRUST + ipaserver_setup_adtrust: + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" + when: ipaserver_test.setup_adtrust + + - name: Install - Set DS password + ipaserver_set_ds_password: + dm_password: "{{ ipaserver_dm_password }}" + password: "{{ ipaserver_password }}" + domain: "{{ ipaserver_test.domain }}" + realm: "{{ ipaserver_test.realm }}" + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + subject_base: "{{ ipaserver_test.subject_base }}" + ca_subject: "{{ ipaserver_test.ca_subject }}" + no_pkinit: "{{ ipaserver_test.no_pkinit }}" + no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" + idstart: "{{ ipaserver_test.idstart }}" + idmax: "{{ ipaserver_test.idmax }}" + dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" + _dirsrv_pkcs12_info: "{{ ipaserver_test._dirsrv_pkcs12_info }}" + + #- name: Install - Setup client + # include_role: + # name: ipaclient + # private: yes + # defaults_from: "/roles/ipaclient/defaults/main.yml" + # tasks_from: "/roles/ipaclient/tasks/main.yml" + # vars_from: "/roles/ipaclient/vars/main.yml" + # vars: + # state: present + # on_master: yes + # domain: "{{ ipaserver_test.domain }}" + # realm: "{{ ipaserver_test.realm }}" + # server: "{{ ipaserver_test.hostname }}" + # hostname: "{{ ipaserver_test.hostname }}" + # #no_dns_sshfp: "{{ ipaserver_no_dns_sshfp }}" + # #ssh_trust_dns: "{{ ipaserver_ssh_trust_dns }}" + # #no_ssh: "{{ ipaserver_no_ssh }}" + # #no_sshd: "{{ ipaserver_no_sshd }}" + # mkhomedir: "{{ ipaserver_mkhomedir }}" + # #allow_repair: "{{ ipaserver_allow_repair }}" + + - name: Install - Setup client + command: > + /usr/sbin/ipa-client-install + --unattended + --on-master + --domain "{{ ipaserver_test.domain }}" + --realm "{{ ipaserver_test.realm }}" + --server "{{ ipaserver_test.hostname }}" + --hostname "{{ ipaserver_test.hostname }}" + {{ "--mkhomedir" if ipaserver_mkhomedir | bool else "" }} + + # {{ "--no-dns-sshfp" if ipaserver_no_dns_sshfp | bool else "" }} + # {{ "--ssh-trust-dns" if ipaserver_ssh_trust_dns | bool else "" }} + # {{ "--no-ssh" if ipaserver_no_ssh | bool else "" }} + # {{ "--no-sshd" if ipaserver_no_sshd | bool else "" }} + + - name: Install - Enable IPA + ipaserver_enable_ipa: + hostname: "{{ ipaserver_test.hostname }}" + setup_ca: "{{ ipaserver_test.setup_ca }}" + register: ipaserver_enable_ipa + + - name: Install - Cleanup root IPA cache + file: + path: "/root/.ipa_cache" + state: absent + when: ipaserver_enable_ipa.changed + + +#- name: Install - Server installation +# ipaserver_install: +# dm_password: "{{ ipaserver_dm_password }}" +# password: "{{ ipaserver_password }}" +# domain: "{{ ipaserver_domain | default(omit) }}" +# realm: "{{ ipaserver_realm | default(omit) }}" +# hostname: "{{ ipaserver_hostname | default(ansible_fqdn) }}" +# setup_dns: "{{ ipaserver_setup_dns }}" +# no_reverse: "{{ ipaserver_no_reverse }}" +# auto_forwarders: "{{ ipaserver_auto_forwarders }}" +# register: ipaserver_install + +#- name: Install - Server installation +# ipaserver_install: +# dm_password: "{{ ipaserver_dm_password }}" +# password: "{{ ipaserver_password }}" +# domain: "{{ ipaserver_test.domain }}" +# realm: "{{ ipaserver_test.realm }}" +# hostname: "{{ ipaserver_test.hostname }}" +# #ip_addresses: "{{ ipaserver_test.ip_addresses }}" +# reverse_zones: "{{ ipaserver_test.reverse_zones }}" +# setup_adtrust: "{{ ipaserver_test.setup_adtrust }}" +# setup_kra: "{{ ipaserver_test.setup_kra }}" +# setup_dns: "{{ ipaserver_setup_dns }}" +# setup_ca: "{{ ipaserver_test.setup_ca }}" +# no_host_dns: "{{ ipaserver_test.no_host_dns }}" +# subject_base: "{{ ipaserver_test.subject_base }}" +# ca_subject: "{{ ipaserver_test.ca_subject }}" +# no_reverse: "{{ ipaserver_no_reverse }}" +# auto_forwarders: "{{ ipaserver_auto_forwarders }}" +# register: ipaserver_install +# +#- name: Install - Cleanup root IPA cache +# file: +# path: "/root/.ipa_cache" +# state: absent +# when: ipaserver_install.changed diff --git a/roles/ipaserver/tasks/main.yml b/roles/ipaserver/tasks/main.yml new file mode 100644 index 00000000..e2790be2 --- /dev/null +++ b/roles/ipaserver/tasks/main.yml @@ -0,0 +1,18 @@ +--- +# tasks file for ipaserver + +- name: Import variables specific to distribution + include_vars: "{{ item }}" + with_first_found: + - "vars/{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml" + - "vars/{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml" + - "vars/{{ ansible_distribution }}.yml" + - "vars/default.yml" + +- name: Install IPA server + include: tasks/install.yml + when: state|default('present') == 'present' + +- name: Uninstall IPA server + include: tasks/uninstall.yml + when: state|default('present') == 'absent' diff --git a/roles/ipaserver/tasks/python_2_3_test.yml b/roles/ipaserver/tasks/python_2_3_test.yml new file mode 100644 index 00000000..64353ee6 --- /dev/null +++ b/roles/ipaserver/tasks/python_2_3_test.yml @@ -0,0 +1,19 @@ +- block: + - name: Verify Python3 import + script: py3test.py + register: py3test + failed_when: False + + - name: Set python interpreter to 3 + set_fact: + ansible_python_interpreter: "/usr/bin/python3" + when: py3test.rc == 0 + + - name: Fail for IPA 4.5.90 + fail: msg="You need to install python2 bindings for ipa server usage" + when: py3test.rc != 0 and "not usable with python3" in py3test.stdout + + - name: Set python interpreter to 2 + set_fact: + ansible_python_interpreter: "/usr/bin/python2" + when: py3test.failed or py3test.rc != 0 diff --git a/roles/ipaserver/tasks/uninstall.yml b/roles/ipaserver/tasks/uninstall.yml new file mode 100644 index 00000000..eda945d8 --- /dev/null +++ b/roles/ipaserver/tasks/uninstall.yml @@ -0,0 +1,24 @@ +--- +# tasks to uninstall IPA server + +#- name: Uninstall - Include Python2/3 import test +# include: "{{role_path}}/tasks/python_2_3_test.yml" +# static: yes + +- name: Uninstall - Uninstall IPA server + command: > + /usr/sbin/ipa-server-install + --uninstall + -U + {{ '--ignore-topology-disconnect' if ipaserver_ignore_topology_disconnect | bool else '' }} + {{ '--ignore-last-of-role' if ipaserver_ignore_last_of_role | bool else ''}} + register: uninstall + # 2 means that uninstall failed because IPA server was not configured + failed_when: uninstall.rc != 0 and uninstall.rc != 2 + changed_when: uninstall.rc == 0 + +#- name: Remove IPA server packages +# package: +# name: "{{ item }}" +# state: absent +# with_items: "{{ ipaserver_packages }}" diff --git a/roles/ipaserver/tasks/uninstall.yml.old b/roles/ipaserver/tasks/uninstall.yml.old new file mode 100644 index 00000000..d9c31a8b --- /dev/null +++ b/roles/ipaserver/tasks/uninstall.yml.old @@ -0,0 +1,19 @@ +--- +# tasks to uninstall IPA server + +- name: Uninstall - Include Python2/3 import test + include: "{{role_path}}/tasks/python_2_3_test.yml" + static: yes + +- name: Uninstall - Uninstall IPA server + command: /usr/sbin/ipa-server-install --uninstall -U {% if ipaserver_ignore_topology_disconnect | bool %}--ignore-topology-disconnect{% endif %} {% if ipaserver_ignore_last_of_role | bool %}--ignore-last-of-role{% endif %} + register: uninstall + # 2 means that uninstall failed because IPA server was not configured + failed_when: uninstall.rc != 0 and uninstall.rc != 2 + changed_when: uninstall.rc == 0 + +#- name: Remove IPA server packages +# package: +# name: "{{ item }}" +# state: absent +# with_items: "{{ ipaserver_packages }}" diff --git a/roles/ipaserver/vars/Fedora-25.yml b/roles/ipaserver/vars/Fedora-25.yml new file mode 100644 index 00000000..f390adc4 --- /dev/null +++ b/roles/ipaserver/vars/Fedora-25.yml @@ -0,0 +1,3 @@ +ipaserver_packages: [ "ipa-server", "libselinux-python" ] +ipaserver_packages_dns: [ "ipa-server-dns" ] +ipaserver_packages_adtrust: [ ] \ No newline at end of file diff --git a/roles/ipaserver/vars/Fedora-26.yml b/roles/ipaserver/vars/Fedora-26.yml new file mode 100644 index 00000000..f390adc4 --- /dev/null +++ b/roles/ipaserver/vars/Fedora-26.yml @@ -0,0 +1,3 @@ +ipaserver_packages: [ "ipa-server", "libselinux-python" ] +ipaserver_packages_dns: [ "ipa-server-dns" ] +ipaserver_packages_adtrust: [ ] \ No newline at end of file diff --git a/roles/ipaserver/vars/Fedora.yml b/roles/ipaserver/vars/Fedora.yml new file mode 100644 index 00000000..bddded76 --- /dev/null +++ b/roles/ipaserver/vars/Fedora.yml @@ -0,0 +1,3 @@ +ipaserver_packages: [ "ipa-server", "ipa-server-dns", "libselinux-python" ] +ipaserver_packages_dns: [ "ipa-server-dns" ] +ipaserver_packages_adtrust: [ "samba" ] \ No newline at end of file diff --git a/roles/ipaserver/vars/RedHat-7.3.yml b/roles/ipaserver/vars/RedHat-7.3.yml new file mode 100644 index 00000000..47f8f323 --- /dev/null +++ b/roles/ipaserver/vars/RedHat-7.3.yml @@ -0,0 +1,5 @@ +# defaults file for ipaserver +# vars/rhel.yml +ipaserver_packages: [ "ipa-server", "libselinux-python" ] +ipaserver_packages_dns: [ "ipa-server-dns" ] +ipaserver_packages_adtrust: [ ] \ No newline at end of file diff --git a/roles/ipaserver/vars/RedHat-7.yml b/roles/ipaserver/vars/RedHat-7.yml new file mode 100644 index 00000000..47f8f323 --- /dev/null +++ b/roles/ipaserver/vars/RedHat-7.yml @@ -0,0 +1,5 @@ +# defaults file for ipaserver +# vars/rhel.yml +ipaserver_packages: [ "ipa-server", "libselinux-python" ] +ipaserver_packages_dns: [ "ipa-server-dns" ] +ipaserver_packages_adtrust: [ ] \ No newline at end of file diff --git a/roles/ipaserver/vars/default.yml b/roles/ipaserver/vars/default.yml new file mode 100644 index 00000000..c6019122 --- /dev/null +++ b/roles/ipaserver/vars/default.yml @@ -0,0 +1,5 @@ +# defaults file for ipaserver +# vars/default.yml +ipaserver_packages: [ "ipa-server", "libselinux-python" ] +ipaserver_packages_dns: [ "ipa-server-dns" ] +ipaserver_packages_adtrust: [ "samba" ] diff --git a/uninstall-server.yml b/uninstall-server.yml new file mode 100644 index 00000000..11042857 --- /dev/null +++ b/uninstall-server.yml @@ -0,0 +1,8 @@ +--- +- name: Playbook to unconfigure IPA servers + hosts: ipaserver + become: true + + roles: + - role: ipaserver + state: absent -- GitLab