Blame roles/ipaserver/library/ipaserver_setup_ca.py

Packit Service ee01e6
#!/usr/bin/python
Packit Service 0a38ef
# -*- coding: utf-8 -*-
Packit Service 0a38ef
Packit Service 0a38ef
# Authors:
Packit Service 0a38ef
#   Thomas Woerner <twoerner@redhat.com>
Packit Service 0a38ef
#
Packit Service 0a38ef
# Based on ipa-client-install code
Packit Service 0a38ef
#
Packit Service 0a38ef
# Copyright (C) 2017  Red Hat
Packit Service 0a38ef
# see file 'COPYING' for use and warranty information
Packit Service 0a38ef
#
Packit Service 0a38ef
# This program is free software; you can redistribute it and/or modify
Packit Service 0a38ef
# it under the terms of the GNU General Public License as published by
Packit Service 0a38ef
# the Free Software Foundation, either version 3 of the License, or
Packit Service 0a38ef
# (at your option) any later version.
Packit Service 0a38ef
#
Packit Service 0a38ef
# This program is distributed in the hope that it will be useful,
Packit Service 0a38ef
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 0a38ef
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 0a38ef
# GNU General Public License for more details.
Packit Service 0a38ef
#
Packit Service 0a38ef
# You should have received a copy of the GNU General Public License
Packit Service 0a38ef
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit Service 0a38ef
Packit Service 0a38ef
from __future__ import print_function
Packit Service 0a38ef
Packit Service 0a38ef
ANSIBLE_METADATA = {
Packit Service 0a38ef
    'metadata_version': '1.0',
Packit Service 0a38ef
    'supported_by': 'community',
Packit Service 0a38ef
    'status': ['preview'],
Packit Service 0a38ef
}
Packit Service 0a38ef
Packit Service 0a38ef
DOCUMENTATION = '''
Packit Service 0a38ef
---
Packit Service 0a38ef
module: ipaserver_setup_ca
Packit Service 0a38ef
short description: Setup CA
Packit Service 0a38ef
description: Setup CA
Packit Service 0a38ef
options:
Packit Service 0a38ef
  dm_password:
Packit Service 0a38ef
    description: Directory Manager password
Packit Service 0a38ef
    required: no
Packit Service 0a38ef
  password:
Packit Service 0a38ef
    description: Admin user kerberos password
Packit Service 0a38ef
    required: no
Packit Service 0a38ef
  master_password:
Packit Service 0a38ef
    description: kerberos master password (normally autogenerated)
Packit Service 0a38ef
    required: no
Packit Service 0a38ef
  ip_addresses:
Packit Service 0a38ef
    description: List of Master Server IP Addresses
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  domain:
Packit Service 0a38ef
    description: Primary DNS domain of the IPA deployment
Packit Service 0a38ef
    required: no
Packit Service 0a38ef
  realm:
Packit Service 0a38ef
    description: Kerberos realm name of the IPA deployment
Packit Service 0a38ef
    required: no
Packit Service 0a38ef
  hostname:
Packit Service 0a38ef
    description: Fully qualified name of this host
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  no_host_dns:
Packit Service 0a38ef
    description: Do not use DNS for hostname lookup during installation
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  pki_config_override:
Packit Service 0a38ef
    description: Path to ini file with config overrides
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  setup_adtrust:
Packit Service 0a38ef
    description: Configure AD trust capability
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  setup_kra:
Packit Service 0a38ef
    description: Configure a dogtag KRA
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  setup_dns:
Packit Service 0a38ef
    description: Configure bind with our zone
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  setup_ca:
Packit Service 0a38ef
    description: Configure a dogtag CA
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  idstart:
Packit Service 0a38ef
    description: The starting value for the IDs range (default random)
Packit Service 0a38ef
    required: no
Packit Service 0a38ef
  idmax:
Packit Service 0a38ef
    description: The max value for the IDs range (default idstart+199999)
Packit Service 0a38ef
    required: no
Packit Service 0a38ef
  no_hbac_allow:
Packit Service 0a38ef
    description: Don't install allow_all HBAC rule
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  no_pkinit:
Packit Service 0a38ef
    description: Disable pkinit setup steps
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  dirsrv_config_file:
Packit Service 0a38ef
    description:
Packit Service 0a38ef
      The path to LDIF file that will be used to modify configuration of
Packit Service 0a38ef
      dse.ldif during installation of the directory server instance
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  dirsrv_cert_files:
Packit Service 0a38ef
    description:
Packit Service 0a38ef
      Files containing the Directory Server SSL certificate and private key
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  _dirsrv_pkcs12_info:
Packit Service 0a38ef
    description: The installer _dirsrv_pkcs12_info setting
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  external_ca:
Packit Service 0a38ef
    description: External ca setting
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  external_ca_type:
Packit Service 0a38ef
    description: Type of the external CA
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  external_ca_profile:
Packit Service 0a38ef
    description:
Packit Service 0a38ef
      Specify the certificate profile/template to use at the external CA
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  external_cert_files:
Packit Service 0a38ef
    description:
Packit Service 0a38ef
      File containing the IPA CA certificate and the external CA certificate
Packit Service 0a38ef
      chain
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  subject_base:
Packit Service 0a38ef
    description:
Packit Service 0a38ef
      The certificate subject base (default O=<realm-name>).
Packit Service 0a38ef
      RDNs are in LDAP order (most specific RDN first).
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  _subject_base:
Packit Service 0a38ef
    description: The installer _subject_base setting
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  ca_subject:
Packit Service 0a38ef
    description: The installer ca_subject setting
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  _ca_subject:
Packit Service 0a38ef
    description: The installer _ca_subject setting
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  ca_signing_algorithm:
Packit Service 0a38ef
    description: Signing algorithm of the IPA CA certificate
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  reverse_zones:
Packit Service 0a38ef
    description: The reverse DNS zones to use
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  no_reverse:
Packit Service 0a38ef
    description: Do not create new reverse DNS zone
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  auto_forwarders:
Packit Service 0a38ef
    description: Use DNS forwarders configured in /etc/resolv.conf
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  domainlevel:
Packit Service 0a38ef
    description: The domain level
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
  _http_ca_cert:
Packit Service 0a38ef
    description: The installer _http_ca_cert setting
Packit Service 0a38ef
    required: yes
Packit Service 0a38ef
author:
Packit Service 0a38ef
    - Thomas Woerner
Packit Service 0a38ef
'''
Packit Service 0a38ef
Packit Service 0a38ef
EXAMPLES = '''
Packit Service 0a38ef
'''
Packit Service 0a38ef
Packit Service 0a38ef
RETURN = '''
Packit Service 0a38ef
'''
Packit Service 0a38ef
Packit Service 0a38ef
import os
Packit Service 0a38ef
Packit Service 0a38ef
from ansible.module_utils.basic import AnsibleModule
Packit Service 0a38ef
from ansible.module_utils.ansible_ipa_server import (
Packit Service 0a38ef
    AnsibleModuleLog, setup_logging, options, sysrestore, paths,
Packit Service 0a38ef
    ansible_module_get_parsed_ip_addresses,
Packit Service 0a38ef
    api_Backend_ldap2, redirect_stdout, ca, installutils, ds_init_info,
Packit Service 0a38ef
    custodiainstance, write_cache, x509, decode_certificate
Packit Service 0a38ef
)
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def main():
Packit Service 0a38ef
    ansible_module = AnsibleModule(
Packit Service 0a38ef
        argument_spec=dict(
Packit Service 0a38ef
            # basic
Packit Service 0a38ef
            dm_password=dict(required=True, no_log=True),
Packit Service 0a38ef
            password=dict(required=True, no_log=True),
Packit Service 0a38ef
            master_password=dict(required=True, no_log=True),
Packit Service 0a38ef
            ip_addresses=dict(required=False, type='list', default=[]),
Packit Service 0a38ef
            domain=dict(required=True),
Packit Service 0a38ef
            realm=dict(required=True),
Packit Service 0a38ef
            hostname=dict(required=False),
Packit Service 0a38ef
            no_host_dns=dict(required=False, type='bool', default=False),
Packit Service 0a38ef
            pki_config_override=dict(required=False),
Packit Service 0a38ef
            # server
Packit Service 0a38ef
            setup_adtrust=dict(required=False, type='bool', default=False),
Packit Service 0a38ef
            setup_kra=dict(required=False, type='bool', default=False),
Packit Service 0a38ef
            setup_dns=dict(required=False, type='bool', default=False),
Packit Service 0a38ef
            setup_ca=dict(required=False, type='bool', default=False),
Packit Service 0a38ef
            idstart=dict(required=True, type='int'),
Packit Service 0a38ef
            idmax=dict(required=True, type='int'),
Packit Service 0a38ef
            no_hbac_allow=dict(required=False, type='bool', default=False),
Packit Service 0a38ef
            no_pkinit=dict(required=False, type='bool', default=False),
Packit Service 0a38ef
            dirsrv_config_file=dict(required=False),
Packit Service 0a38ef
            dirsrv_cert_files=dict(required=False, type='list'),
Packit Service 0a38ef
            _dirsrv_pkcs12_info=dict(required=False, type='list'),
Packit Service 0a38ef
            # certificate system
Packit Service 0a38ef
            external_ca=dict(required=False, type='bool', default=False),
Packit Service 0a38ef
            external_ca_type=dict(required=False),
Packit Service 0a38ef
            external_ca_profile=dict(required=False),
Packit Service 0a38ef
            external_cert_files=dict(required=False, type='list',
Packit Service 0a38ef
                                     default=None),
Packit Service 0a38ef
            subject_base=dict(required=False),
Packit Service 0a38ef
            _subject_base=dict(required=False),
Packit Service 0a38ef
            ca_subject=dict(required=False),
Packit Service 0a38ef
            _ca_subject=dict(required=False),
Packit Service 0a38ef
            ca_signing_algorithm=dict(required=False),
Packit Service 0a38ef
            # dns
Packit Service 0a38ef
            reverse_zones=dict(required=False, type='list', default=[]),
Packit Service 0a38ef
            no_reverse=dict(required=False, type='bool', default=False),
Packit Service 0a38ef
            auto_forwarders=dict(required=False, type='bool', default=False),
Packit Service 0a38ef
            # additional
Packit Service 0a38ef
            domainlevel=dict(required=False, type='int'),
Packit Service 0a38ef
            _http_ca_cert=dict(required=False),
Packit Service 0a38ef
        ),
Packit Service 0a38ef
    )
Packit Service 0a38ef
Packit Service 0a38ef
    ansible_module._ansible_debug = True
Packit Service 0a38ef
    setup_logging()
Packit Service 0a38ef
    ansible_log = AnsibleModuleLog(ansible_module)
Packit Service 0a38ef
Packit Service 0a38ef
    # set values ############################################################
Packit Service 0a38ef
Packit Service 0a38ef
    # basic
Packit Service 0a38ef
    options.dm_password = ansible_module.params.get('dm_password')
Packit Service 0a38ef
    options.admin_password = ansible_module.params.get('password')
Packit Service 0a38ef
    options.master_password = ansible_module.params.get('master_password')
Packit Service 0a38ef
    options.ip_addresses = ansible_module_get_parsed_ip_addresses(
Packit Service 0a38ef
        ansible_module)
Packit Service 0a38ef
    options.domain_name = ansible_module.params.get('domain')
Packit Service 0a38ef
    options.realm_name = ansible_module.params.get('realm')
Packit Service 0a38ef
    options.host_name = ansible_module.params.get('hostname')
Packit Service 0a38ef
    options.no_host_dns = ansible_module.params.get('no_host_dns')
Packit Service 0a38ef
    options.pki_config_override = ansible_module.params.get(
Packit Service 0a38ef
        'pki_config_override')
Packit Service 0a38ef
    # server
Packit Service 0a38ef
    options.setup_adtrust = ansible_module.params.get('setup_adtrust')
Packit Service 0a38ef
    options.setup_kra = ansible_module.params.get('setup_kra')
Packit Service 0a38ef
    options.setup_dns = ansible_module.params.get('setup_dns')
Packit Service 0a38ef
    options.setup_ca = ansible_module.params.get('setup_ca')
Packit Service 0a38ef
    options.idstart = ansible_module.params.get('idstart')
Packit Service 0a38ef
    options.idmax = ansible_module.params.get('idmax')
Packit Service 0a38ef
    options.no_hbac_allow = ansible_module.params.get('no_hbac_allow')
Packit Service 0a38ef
    options.no_pkinit = ansible_module.params.get('no_pkinit')
Packit Service 0a38ef
    options.dirsrv_config_file = ansible_module.params.get(
Packit Service 0a38ef
        'dirsrv_config_file')
Packit Service 0a38ef
    options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files')
Packit Service 0a38ef
    options._dirsrv_pkcs12_info = ansible_module.params.get(
Packit Service 0a38ef
        '_dirsrv_pkcs12_info')
Packit Service 0a38ef
    # certificate system
Packit Service 0a38ef
    options.external_ca = ansible_module.params.get('external_ca')
Packit Service 0a38ef
    options.external_ca_type = ansible_module.params.get('external_ca_type')
Packit Service 0a38ef
    options.external_ca_profile = ansible_module.params.get(
Packit Service 0a38ef
        'external_ca_profile')
Packit Service 0a38ef
    options.external_cert_files = ansible_module.params.get(
Packit Service 0a38ef
        'external_cert_files')
Packit Service 0a38ef
    options.subject_base = ansible_module.params.get('subject_base')
Packit Service 0a38ef
    options._subject_base = ansible_module.params.get('_subject_base')
Packit Service 0a38ef
    options.ca_subject = ansible_module.params.get('ca_subject')
Packit Service 0a38ef
    options._ca_subject = ansible_module.params.get('_ca_subject')
Packit Service 0a38ef
    options.ca_signing_algorithm = ansible_module.params.get(
Packit Service 0a38ef
        'ca_signing_algorithm')
Packit Service 0a38ef
    # dns
Packit Service 0a38ef
    options.reverse_zones = ansible_module.params.get('reverse_zones')
Packit Service 0a38ef
    options.no_reverse = ansible_module.params.get('no_reverse')
Packit Service 0a38ef
    options.auto_forwarders = ansible_module.params.get('auto_forwarders')
Packit Service 0a38ef
    # additional
Packit Service 0a38ef
    options.domainlevel = ansible_module.params.get('domainlevel')
Packit Service 0a38ef
    options._http_ca_cert = ansible_module.params.get('_http_ca_cert')
Packit Service 0a38ef
    if options._http_ca_cert:
Packit Service 0a38ef
        options._http_ca_cert = decode_certificate(options._http_ca_cert)
Packit Service 0a38ef
Packit Service 0a38ef
    # init #################################################################
Packit Service 0a38ef
Packit Service 0a38ef
    options.promote = False  # first master, no promotion
Packit Service 0a38ef
Packit Service 0a38ef
    # Repeat from ca.install_check
Packit Service 0a38ef
    # ca.external_cert_file and ca.external_ca_file need to be set
Packit Service 0a38ef
    if options.external_cert_files:
Packit Service 0a38ef
        ca.external_cert_file, ca.external_ca_file = \
Packit Service 0a38ef
            installutils.load_external_cert(
Packit Service 0a38ef
                options.external_cert_files, options._ca_subject)
Packit Service 0a38ef
Packit Service 0a38ef
    fstore = sysrestore.FileStore(paths.SYSRESTORE)
Packit Service 0a38ef
Packit Service 0a38ef
    api_Backend_ldap2(options.host_name, options.setup_ca, connect=True)
Packit Service 0a38ef
Packit Service 0a38ef
    ds = ds_init_info(ansible_log, fstore,
Packit Service 0a38ef
                      options.domainlevel, options.dirsrv_config_file,
Packit Service 0a38ef
                      options.realm_name, options.host_name,
Packit Service 0a38ef
                      options.domain_name, options.dm_password,
Packit Service 0a38ef
                      options.idstart, options.idmax,
Packit Service 0a38ef
                      options.subject_base, options.ca_subject,
Packit Service 0a38ef
                      options.no_hbac_allow, options._dirsrv_pkcs12_info,
Packit Service 0a38ef
                      options.no_pkinit)
Packit Service 0a38ef
Packit Service 0a38ef
    # setup CA ##############################################################
Packit Service 0a38ef
Packit Service 0a38ef
    if hasattr(custodiainstance, "get_custodia_instance"):
Packit Service 0a38ef
        if hasattr(custodiainstance.CustodiaModes, "FIRST_MASTER"):
Packit Service 0a38ef
            mode = custodiainstance.CustodiaModes.FIRST_MASTER
Packit Service 0a38ef
        else:
Packit Service 0a38ef
            mode = custodiainstance.CustodiaModes.MASTER_PEER
Packit Service 0a38ef
        custodia = custodiainstance.get_custodia_instance(options, mode)
Packit Service 0a38ef
        custodia.set_output(ansible_log)
Packit Service 0a38ef
        with redirect_stdout(ansible_log):
Packit Service 0a38ef
            custodia.create_instance()
Packit Service 0a38ef
Packit Service 0a38ef
    if options.setup_ca:
Packit Service 0a38ef
        if not options.external_cert_files and options.external_ca:
Packit Service 0a38ef
            # stage 1 of external CA installation
Packit Service 0a38ef
            cache_vars = {n: options.__dict__[n] for o, n in options.knobs()
Packit Service 0a38ef
                          if n in options.__dict__}
Packit Service 0a38ef
            write_cache(cache_vars)
Packit Service 0a38ef
Packit Service 0a38ef
        try:
Packit Service 0a38ef
            with redirect_stdout(ansible_log):
Packit Service 0a38ef
                if hasattr(custodiainstance, "get_custodia_instance"):
Packit Service 0a38ef
                    ca.install_step_0(False, None, options, custodia=custodia)
Packit Service 0a38ef
                else:
Packit Service 0a38ef
                    ca.install_step_0(False, None, options)
Packit Service 0a38ef
        except SystemExit:
Packit Service 0a38ef
            ansible_module.exit_json(changed=True,
Packit Service 0a38ef
                                     csr_generated=True)
Packit Service 0a38ef
    else:
Packit Service 0a38ef
        # Put the CA cert where other instances expect it
Packit Service 0a38ef
        x509.write_certificate(options._http_ca_cert, paths.IPA_CA_CRT)
Packit Service 0a38ef
        os.chmod(paths.IPA_CA_CRT, 0o444)
Packit Service 0a38ef
Packit Service 0a38ef
        if not options.no_pkinit:
Packit Service 0a38ef
            x509.write_certificate(options._http_ca_cert,
Packit Service 0a38ef
                                   paths.KDC_CA_BUNDLE_PEM)
Packit Service 0a38ef
        else:
Packit Service 0a38ef
            with open(paths.KDC_CA_BUNDLE_PEM, 'w'):
Packit Service 0a38ef
                pass
Packit Service 0a38ef
        os.chmod(paths.KDC_CA_BUNDLE_PEM, 0o444)
Packit Service 0a38ef
Packit Service 0a38ef
        x509.write_certificate(options._http_ca_cert, paths.CA_BUNDLE_PEM)
Packit Service 0a38ef
        os.chmod(paths.CA_BUNDLE_PEM, 0o444)
Packit Service 0a38ef
Packit Service 0a38ef
    with redirect_stdout(ansible_log):
Packit Service 0a38ef
        # we now need to enable ssl on the ds
Packit Service 0a38ef
        ds.enable_ssl()
Packit Service 0a38ef
Packit Service 0a38ef
    if options.setup_ca:
Packit Service 0a38ef
        with redirect_stdout(ansible_log):
Packit Service 0a38ef
            if hasattr(custodiainstance, "get_custodia_instance"):
Packit Service 0a38ef
                ca.install_step_1(False, None, options, custodia=custodia)
Packit Service 0a38ef
            else:
Packit Service 0a38ef
                ca.install_step_1(False, None, options)
Packit Service 0a38ef
Packit Service 0a38ef
    ansible_module.exit_json(changed=True,
Packit Service 0a38ef
                             csr_generated=False)
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
if __name__ == '__main__':
Packit Service 0a38ef
    main()