ipaserver: Add support for external signed CA

This adds support for the --external-ca option to ipaserver. Lots of
additional tests and checks from ServerInstallInterface.__init__ have
been added to ipaserver_test. Also duplicate tests cna checks have been
removed.

Installer settings in ansible_ipa_server module_util are now also set
to the defaults that are used in Installable, ServerInstallInterface,
ServerMasterInstall, ADTrustInstallInterface and Uninstall.

The /root/ipa.csr file generated on the node in ca.install_step_0 will
be copied to the controller as "{{ inventory_hostname }}-ipa.csr".

The new task file copy_external_cert.yml has been added to copy the
generated certificate defined in ipaserver_external_cert_files to the node
to continue with ca.install_step_1.

The tasks/install.yml file has been adapted to make sure that the steps
that will be done in step two will be skipped after step one has been
done.
This commit is contained in:
Thomas Woerner
2019-06-26 18:34:20 +02:00
parent 5f580b5152
commit 45d8008033
8 changed files with 620 additions and 298 deletions

View File

@@ -42,11 +42,11 @@ Requirements
Limitations Limitations
----------- -----------
External CA External signed CA
External CA support is not supported or working. The currently needed two step process is an issue for the processing in the role. The configuration of the server is partly done already and needs to be continued after the CSR has been handled. This is for example breaking the deployment of a server with replicas or clients in one playbook. External signed CA is now supported. But the currently needed two step process is an issue for the processing in a simple playbook.
Work is planned to have a new method to handle CSR for external CAs in a separate step before starting the server installation. Work is planned to have a new method to handle CSR for external signed CAs in a separate step before starting the server installation.
Usage Usage
@@ -106,6 +106,56 @@ Example playbook to setup the IPA server using admin and dirman passwords from i
- role: ipaserver - role: ipaserver
state: present state: present
Example playbook to setup the IPA primary with external signed CA using the previous inventory file:
Server installation step 1: Generate CSR, copy to controller as `<ipaserver hostname>-ipa.csr`
```yaml
---
- name: Playbook to configure IPA server step1
hosts: ipaserver
become: true
vars:
ipaserver_external_ca: yes
roles:
- role: ipaserver
state: present
post_tasks:
- name: Copy CSR /root/ipa.csr from node to "{{ groups.ipaserver[0] + '-ipa.csr' }}"
fetch:
src: /root/ipa.csr
dest: "{{ groups.ipaserver[0] + '-ipa.csr' }}"
flat: yes
```
Sign with CA: This is up to you
Server installatin step 2: Copy `<ipaserver hostname>-chain.crt` to the IPA server and continue with installation of the primary.
```yaml
- name: Playbook to configure IPA server step3
hosts: ipaserver
become: true
vars:
ipaserver_external_cert_files: "/root/chain.crt"
pre_tasks:
- name: Copy "{{ groups.ipaserver[0] + '-chain.crt' }}" to /root/chain.crt on node
copy:
src: "{{ groups.ipaserver[0] + '-chain.crt' }}"
dest: "/root/chain.crt"
force: yes
roles:
- role: ipaserver
state: present
```
The files can also be copied automatically: Set `ipaserver_copy_csr_to_controller` to true in the server installation step 1 and set `ipaserver_external_cert_files_from_controller` to point to the `chain.crt` file in the server installatin step 2.
Playbooks Playbooks
========= =========
@@ -192,13 +242,13 @@ Certificate system Variables
Variable | Description | Required Variable | Description | Required
-------- | ----------- | -------- -------- | ----------- | --------
~~`ipaserver_external_ca`~~ | ~~Generate a CSR for the IPA CA certificate to be signed by an external CA. (bool, default: false)~~ | ~~no~~ `ipaserver_external_ca` | Generate a CSR for the IPA CA certificate to be signed by an external CA. (bool, default: false) | no
~~`ipaserver_external_ca_type`~~ | ~~Type of the external CA. (choice: generic,ms-cs)~~ | ~~no~~ `ipaserver_external_ca_type` | Type of the external CA. (choice: generic,ms-cs) | no
~~`ipaserver_external_ca_profile`~~ | ~~Specify the certificate profile/template to use at the external CA. (string)~~ | ~~no~~ `ipaserver_external_ca_profile` | Specify the certificate profile/template to use at the external CA. (string) | no
~~`ipaserver_external_cert_files`~~ | ~~Files containing the IPA CA certificates and the external CA certificate chains (list of string)~~ | ~~no~~ `ipaserver_external_cert_files` | Files containing the IPA CA certificates and the external CA certificate chains (list of string) | no
`ipaserver_subject_base` | The certificate subject base (default O=<realm-name>). RDNs are in LDAP order (most specific RDN first). (string) | no `ipaserver_subject_base` | The certificate subject base (default O=<realm-name>). RDNs are in LDAP order (most specific RDN first). (string) | no
`ipaserver_ca_subject` | The CA certificate subject DN (default CN=Certificate Authority,O=<realm-name>). RDNs are in LDAP order (most specific RDN first). (string) | no `ipaserver_ca_subject` | The CA certificate subject DN (default CN=Certificate Authority,O=<realm-name>). RDNs are in LDAP order (most specific RDN first). (string) | no
~~`ipaserver_ca_signing_algorithm`~~ | ~~Signing algorithm of the IPA CA certificate. (choice: SHA1withRSA,SHA256withRSA,SHA512withRSA)~~ | ~~no~~ `ipaserver_ca_signing_algorithm` | Signing algorithm of the IPA CA certificate. (choice: SHA1withRSA,SHA256withRSA,SHA512withRSA) | no
DNS Variables DNS Variables
------------- -------------
@@ -233,7 +283,8 @@ Variable | Description | Required
-------- | ----------- | -------- -------- | ----------- | --------
`ipaserver_install_packages` | The bool value defines if the needed packages are installed on the node. (bool, default: true) | no `ipaserver_install_packages` | The bool value defines if the needed packages are installed on the node. (bool, default: true) | no
`ipaserver_setup_firewalld` | The value defines if the needed services will automatically be openen in the firewall managed by firewalld. (bool, default: true) | no `ipaserver_setup_firewalld` | The value defines if the needed services will automatically be openen in the firewall managed by firewalld. (bool, default: true) | no
`ipaserver_external_cert_files_from_controller` | Files containing the IPA CA certificates and the external CA certificate chains on the controller that will be copied to the ipaserver host to `/root` folder. (list of string) | no
`ipaserver_copy_csr_to_controller` | Copy the generated CSR from the ipaserver to the controller as `"{{ inventory_hostname }}-ipa.csr"`. (bool) | no
Authors Authors
======= =======

View File

@@ -36,7 +36,7 @@ ipaserver_install_packages: yes
ipaserver_setup_firewalld: yes ipaserver_setup_firewalld: yes
### additional ### ### additional ###
ipaserver_allow_missing: [ ] ipaserver_copy_csr_to_controller: no
### uninstall ### ### uninstall ###
ipaserver_ignore_topology_disconnect: no ipaserver_ignore_topology_disconnect: no

View File

@@ -97,7 +97,9 @@ def main():
### ssl certificate ### ### ssl certificate ###
### client ### ### client ###
### certificate system ### ### certificate system ###
external_ca=dict(required=False), external_ca=dict(required=False, type='bool'),
external_ca_type=dict(required=False),
external_ca_profile=dict(required=False),
external_cert_files=dict(required=False, type='list', default=[]), 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),
@@ -152,6 +154,9 @@ def main():
#options.no_ntp = ansible_module.params.get('no_ntp') #options.no_ntp = ansible_module.params.get('no_ntp')
### certificate system ### ### certificate system ###
options.external_ca = ansible_module.params.get('external_ca') options.external_ca = ansible_module.params.get('external_ca')
options.external_ca_type = ansible_module.params.get('external_ca_type')
options.external_ca_profile = ansible_module.params.get(
'external_ca_profile')
options.external_cert_files = ansible_module.params.get( options.external_cert_files = ansible_module.params.get(
'external_cert_files') 'external_cert_files')
options.subject_base = ansible_module.params.get('subject_base') options.subject_base = ansible_module.params.get('subject_base')

View File

@@ -106,7 +106,9 @@ def main():
_dirsrv_pkcs12_info=dict(required=False), _dirsrv_pkcs12_info=dict(required=False),
### certificate system ### ### certificate system ###
external_ca=dict(required=False, type='bool', default=False), external_ca=dict(required=False, type='bool', default=False),
external_cert_files=dict(required=False, type='list', default=[]), external_ca_type=dict(required=False),
external_ca_profile=dict(required=False),
external_cert_files=dict(required=False, type='list', default=None),
subject_base=dict(required=False), subject_base=dict(required=False),
_subject_base=dict(required=False), _subject_base=dict(required=False),
ca_subject=dict(required=False), ca_subject=dict(required=False),
@@ -154,6 +156,9 @@ def main():
'_dirsrv_pkcs12_info') '_dirsrv_pkcs12_info')
### certificate system ### ### certificate system ###
options.external_ca = ansible_module.params.get('external_ca') options.external_ca = ansible_module.params.get('external_ca')
options.external_ca_type = ansible_module.params.get('external_ca_type')
options.external_ca_profile = ansible_module.params.get(
'external_ca_profile')
options.external_cert_files = ansible_module.params.get( options.external_cert_files = ansible_module.params.get(
'external_cert_files') 'external_cert_files')
options.subject_base = ansible_module.params.get('subject_base') options.subject_base = ansible_module.params.get('subject_base')
@@ -175,6 +180,13 @@ def main():
options.promote = False # first master, no promotion options.promote = False # first master, no promotion
# Repeat from ca.install_check
# ca.external_cert_file and ca.external_ca_file need to be set
if options.external_cert_files:
ca.external_cert_file, ca.external_ca_file = \
installutils.load_external_cert(
options.external_cert_files, options._ca_subject)
fstore = sysrestore.FileStore(paths.SYSRESTORE) fstore = sysrestore.FileStore(paths.SYSRESTORE)
api_Backend_ldap2(options.host_name, options.setup_ca, connect=True) api_Backend_ldap2(options.host_name, options.setup_ca, connect=True)
@@ -190,53 +202,61 @@ def main():
# setup CA ############################################################## # setup CA ##############################################################
with redirect_stdout(ansible_log): if hasattr(custodiainstance, "get_custodia_instance"):
if hasattr(custodiainstance, "get_custodia_instance"): if hasattr(custodiainstance.CustodiaModes, "FIRST_MASTER"):
if hasattr(custodiainstance.CustodiaModes, "FIRST_MASTER"): mode = custodiainstance.CustodiaModes.FIRST_MASTER
mode = custodiainstance.CustodiaModes.FIRST_MASTER else:
else: mode = custodiainstance.CustodiaModes.MASTER_PEER
mode = custodiainstance.CustodiaModes.MASTER_PEER custodia = custodiainstance.get_custodia_instance(options, mode)
custodia = custodiainstance.get_custodia_instance(options, mode) custodia.set_output(ansible_log)
with redirect_stdout(ansible_log):
custodia.create_instance() custodia.create_instance()
if options.setup_ca: if options.setup_ca:
if not options.external_cert_files and options.external_ca: if not options.external_cert_files and options.external_ca:
# stage 1 of external CA installation # stage 1 of external CA installation
cache_vars = {n: options.__dict__[n] for o, n in options.knobs() cache_vars = {n: options.__dict__[n] for o, n in options.knobs()
if n in options.__dict__} if n in options.__dict__}
write_cache(cache_vars) write_cache(cache_vars)
if hasattr(custodiainstance, "get_custodia_instance"): try:
ca.install_step_0(False, None, options, custodia=custodia) with redirect_stdout(ansible_log):
else: if hasattr(custodiainstance, "get_custodia_instance"):
ca.install_step_0(False, None, options) ca.install_step_0(False, None, options, custodia=custodia)
else:
ca.install_step_0(False, None, options)
except SystemExit:
ansible_module.exit_json(changed=True,
csr_generated=True)
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: else:
# Put the CA cert where other instances expect it with open(paths.KDC_CA_BUNDLE_PEM, 'w'):
x509.write_certificate(options._http_ca_cert, paths.IPA_CA_CRT) pass
os.chmod(paths.IPA_CA_CRT, 0o444) os.chmod(paths.KDC_CA_BUNDLE_PEM, 0o444)
if not options.no_pkinit: x509.write_certificate(options._http_ca_cert, paths.CA_BUNDLE_PEM)
x509.write_certificate(options._http_ca_cert, os.chmod(paths.CA_BUNDLE_PEM, 0o444)
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 # we now need to enable ssl on the ds
ds.enable_ssl() ds.enable_ssl()
if options.setup_ca: if options.setup_ca:
with redirect_stdout(ansible_log): with redirect_stdout(ansible_log):
if hasattr(custodiainstance, "get_custodia_instance"): if hasattr(custodiainstance, "get_custodia_instance"):
ca.install_step_1(False, None, options, custodia=custodia) ca.install_step_1(False, None, options, custodia=custodia)
else: else:
ca.install_step_1(False, None, options) ca.install_step_1(False, None, options)
ansible_module.exit_json(changed=True) ansible_module.exit_json(changed=True,
csr_generated=False)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@@ -77,15 +77,15 @@ def main():
# no_ui_redirect # no_ui_redirect
dirsrv_config_file=dict(required=False), dirsrv_config_file=dict(required=False),
### ssl certificate ### ### ssl certificate ###
dirsrv_cert_files=dict(required=False, type='list', default=[]), dirsrv_cert_files=dict(required=False, type='list', default=None),
http_cert_files=dict(required=False, type='list', default=[]), http_cert_files=dict(required=False, type='list', defaullt=None),
pkinit_cert_files=dict(required=False, type='list', default=[]), pkinit_cert_files=dict(required=False, type='list', default=None),
# dirsrv_pin dirsrv_pin=dict(required=False),
# http_pin http_pin=dict(required=False),
# pkinit_pin pkinit_pin=dict(required=False),
# dirsrv_name dirsrv_cert_name=dict(required=False),
# http_name http_cert_name=dict(required=False),
# pkinit_name pkinit_cert_name=dict(required=False),
### client ### ### client ###
# mkhomedir # mkhomedir
no_ntp=dict(required=False, type='bool', default=False), no_ntp=dict(required=False, type='bool', default=False),
@@ -96,7 +96,8 @@ def main():
### certificate system ### ### certificate system ###
external_ca=dict(required=False, type='bool', default=False), external_ca=dict(required=False, type='bool', default=False),
external_ca_type=dict(required=False), external_ca_type=dict(required=False),
external_cert_files=dict(required=False, type='list', default=[]), external_ca_profile=dict(required=False),
external_cert_files=dict(required=False, type='list', default=None),
subject_base=dict(required=False), subject_base=dict(required=False),
ca_subject=dict(required=False), ca_subject=dict(required=False),
# ca_signing_algorithm # ca_signing_algorithm
@@ -155,12 +156,12 @@ def main():
options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files') options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files')
options.http_cert_files = ansible_module.params.get('http_cert_files') options.http_cert_files = ansible_module.params.get('http_cert_files')
options.pkinit_cert_files = ansible_module.params.get('pkinit_cert_files') options.pkinit_cert_files = ansible_module.params.get('pkinit_cert_files')
# dirsrv_pin options.dirsrv_pin = ansible_module.params.get('dirsrv_pin'),
# http_pin options.http_pin = ansible_module.params.get('http_pin'),
# pkinit_pin options.pkinit_pin = ansible_module.params.get('pkinit_pin'),
# dirsrv_name options.dirsrv_cert_name = ansible_module.params.get('dirsrv_cert_name'),
# http_name options.http_cert_name = ansible_module.params.get('http_cert_name'),
# pkinit_name options.pkinit_cert_name = ansible_module.params.get('pkinit_cert_name'),
### client ### ### client ###
# mkhomedir # mkhomedir
options.no_ntp = ansible_module.params.get('no_ntp') options.no_ntp = ansible_module.params.get('no_ntp')
@@ -171,6 +172,8 @@ def main():
### certificate system ### ### certificate system ###
options.external_ca = ansible_module.params.get('external_ca') options.external_ca = ansible_module.params.get('external_ca')
options.external_ca_type = ansible_module.params.get('external_ca_type') options.external_ca_type = ansible_module.params.get('external_ca_type')
options.external_ca_profile = ansible_module.params.get(
'external_ca_profile')
options.external_cert_files = ansible_module.params.get( options.external_cert_files = ansible_module.params.get(
'external_cert_files') 'external_cert_files')
options.subject_base = ansible_module.params.get('subject_base') options.subject_base = ansible_module.params.get('subject_base')
@@ -226,25 +229,6 @@ def main():
ansible_module.fail_json( ansible_module.fail_json(
msg="pki_config_override: %s" % str(e)) msg="pki_config_override: %s" % str(e))
# 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 ######################################################## # default values ########################################################
# idstart and idmax # idstart and idmax
@@ -253,50 +237,190 @@ def main():
if options.idmax is None or options.idmax == 0: if options.idmax is None or options.idmax == 0:
options.idmax = options.idstart + 199999 options.idmax = options.idstart + 199999
# validation ############################################################ #class ServerInstallInterface(ServerCertificateInstallInterface,
# client.ClientInstallInterface,
# ca.CAInstallInterface,
# kra.KRAInstallInterface,
# dns.DNSInstallInterface,
# adtrust.ADTrustInstallInterface,
# conncheck.ConnCheckInterface,
# ServerUninstallInterface):
# domain_level # ServerInstallInterface.__init__ #######################################
if options.domain_level < MIN_DOMAIN_LEVEL: try:
ansible_module.fail_json( self = options
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 any of the key file options are selected, all are required.
if options.dirsrv_config_file is not None: cert_file_req = (self.dirsrv_cert_files, self.http_cert_files)
if not os.path.exists(options.dirsrv_config_file): cert_file_opt = (self.pkinit_cert_files,)
ansible_module.fail_json( if not self.no_pkinit:
msg="File %s does not exist." % options.dirsrv_config_file) cert_file_req += cert_file_opt
if self.no_pkinit and self.pkinit_cert_files:
raise RuntimeError(
"--no-pkinit and --pkinit-cert-file cannot be specified "
"together"
)
if any(cert_file_req + cert_file_opt) and not all(cert_file_req):
raise RuntimeError(
"--dirsrv-cert-file, --http-cert-file, and --pkinit-cert-file "
"or --no-pkinit are required if any key file options are used."
)
# domain_name if not self.interactive:
if (options.setup_dns and not options.allow_zone_overlap and \ if self.dirsrv_cert_files and self.dirsrv_pin is None:
options.domain_name is not None): raise RuntimeError(
try: "You must specify --dirsrv-pin with --dirsrv-cert-file")
check_zone_overlap(options.domain_name, False) if self.http_cert_files and self.http_pin is None:
except ValueError as e: raise RuntimeError(
ansible_module.fail_json(msg=str(e)) "You must specify --http-pin with --http-cert-file")
if self.pkinit_cert_files and self.pkinit_pin is None:
raise RuntimeError(
"You must specify --pkinit-pin with --pkinit-cert-file")
# dm_password if not self.setup_dns:
with redirect_stdout(ansible_log): if self.forwarders:
validate_dm_password(options.dm_password) raise RuntimeError(
"You cannot specify a --forwarder option without the "
"--setup-dns option")
if self.auto_forwarders:
raise RuntimeError(
"You cannot specify a --auto-forwarders option without "
"the --setup-dns option")
if self.no_forwarders:
raise RuntimeError(
"You cannot specify a --no-forwarders option without the "
"--setup-dns option")
if self.forward_policy:
raise RuntimeError(
"You cannot specify a --forward-policy option without the "
"--setup-dns option")
if self.reverse_zones:
raise RuntimeError(
"You cannot specify a --reverse-zone option without the "
"--setup-dns option")
if self.auto_reverse:
raise RuntimeError(
"You cannot specify a --auto-reverse option without the "
"--setup-dns option")
if self.no_reverse:
raise RuntimeError(
"You cannot specify a --no-reverse option without the "
"--setup-dns option")
if self.no_dnssec_validation:
raise RuntimeError(
"You cannot specify a --no-dnssec-validation option "
"without the --setup-dns option")
elif self.forwarders and self.no_forwarders:
raise RuntimeError(
"You cannot specify a --forwarder option together with "
"--no-forwarders")
elif self.auto_forwarders and self.no_forwarders:
raise RuntimeError(
"You cannot specify a --auto-forwarders option together with "
"--no-forwarders")
elif self.reverse_zones and self.no_reverse:
raise RuntimeError(
"You cannot specify a --reverse-zone option together with "
"--no-reverse")
elif self.auto_reverse and self.no_reverse:
raise RuntimeError(
"You cannot specify a --auto-reverse option together with "
"--no-reverse")
# admin_password if not self.setup_adtrust:
with redirect_stdout(ansible_log): if self.add_agents:
validate_admin_password(options.admin_password) raise RuntimeError(
"You cannot specify an --add-agents option without the "
"--setup-adtrust option")
# pkinit is not supported on DL0, don't allow related options if self.enable_compat:
raise RuntimeError(
"You cannot specify an --enable-compat option without the "
"--setup-adtrust option")
# replica install: if not self.replica_file is None: if self.netbios_name:
if (not options._replica_install and \ raise RuntimeError(
not options.domain_level > DOMAIN_LEVEL_0) or \ "You cannot specify a --netbios-name option without the "
(options._replica_install and self.replica_file is not None): "--setup-adtrust option")
if (options.no_pkinit or options.pkinit_cert_files is not None or
options.pkinit_pin is not None): if self.no_msdcs:
ansible_module.fail_json( raise RuntimeError(
msg="pkinit on domain level 0 is not supported. Please " "You cannot specify a --no-msdcs option without the "
"don't use any pkinit-related options.") "--setup-adtrust option")
options.no_pkinit = True
if not hasattr(self, 'replica_install'):
if self.external_cert_files and self.dirsrv_cert_files:
raise RuntimeError(
"Service certificate file options cannot be used with the "
"external CA options.")
if self.external_ca_type and not self.external_ca:
raise RuntimeError(
"You cannot specify --external-ca-type without "
"--external-ca")
if self.external_ca_profile and not self.external_ca:
raise RuntimeError(
"You cannot specify --external-ca-profile without "
"--external-ca")
if self.uninstalling:
if (self.realm_name or self.admin_password or
self.master_password):
raise RuntimeError(
"In uninstall mode, -a, -r and -P options are not "
"allowed")
elif not self.interactive:
if (not self.realm_name or not self.dm_password or
not self.admin_password):
raise RuntimeError(
"In unattended mode you need to provide at least -r, "
"-p and -a options")
if self.setup_dns:
if (not self.forwarders and
not self.no_forwarders and
not self.auto_forwarders):
raise RuntimeError(
"You must specify at least one of --forwarder, "
"--auto-forwarders, or --no-forwarders options")
any_ignore_option_true = any(
[self.ignore_topology_disconnect, self.ignore_last_of_role])
if any_ignore_option_true and not self.uninstalling:
raise RuntimeError(
"'--ignore-topology-disconnect/--ignore-last-of-role' "
"options can be used only during uninstallation")
if self.idmax < self.idstart:
raise RuntimeError(
"idmax (%s) cannot be smaller than idstart (%s)" %
(self.idmax, self.idstart))
else:
# replica installers
if self.servers and not self.domain_name:
raise RuntimeError(
"The --server option cannot be used without providing "
"domain via the --domain option")
if self.setup_dns:
if (not self.forwarders and
not self.no_forwarders and
not self.auto_forwarders):
raise RuntimeError(
"You must specify at least one of --forwarder, "
"--auto-forwarders, or --no-forwarders options")
except RuntimeError as e:
ansible_module.fail_json(msg=e)
# #######################################################################
# If any of the key file options are selected, all are required. # 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_req = (options.dirsrv_cert_files, options.http_cert_files)
@@ -351,7 +475,7 @@ def main():
ansible_module.fail_json( ansible_module.fail_json(
msg="You cannot specify auto-reverse together with no-reverse") msg="You cannot specify auto-reverse together with no-reverse")
if not options._replica_install: if not hasattr(self, 'replica_install'):
if options.external_cert_files and options.dirsrv_cert_files: if options.external_cert_files and options.dirsrv_cert_files:
ansible_module.fail_json( ansible_module.fail_json(
msg="Service certificate file options cannot be used with the " msg="Service certificate file options cannot be used with the "
@@ -403,34 +527,63 @@ def main():
ansible_module.fail_json( ansible_module.fail_json(
msg="idmax (%s) cannot be smaller than idstart (%s)" % msg="idmax (%s) cannot be smaller than idstart (%s)" %
(options.idmax, options.idstart)) (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: # validation #############################################################
if not os.path.isfile(options.replica_file):
ansible_module.fail_json( if options.dm_password is None:
msg="Replica file %s does not exist" % options.replica_file) ansible_module.fail_json(msg="Directory Manager password required")
if options.admin_password is None:
ansible_module.fail_json(msg="IPA admin password required")
# 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 and \
options.domain_name is not None):
try:
check_zone_overlap(options.domain_name, False)
except ValueError as e:
ansible_module.fail_json(str(e))
# 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 options.replica_file is None:
if (not options._replica_install and \
not options.domain_level > DOMAIN_LEVEL_0) or \
(options._replica_install and options.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(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 options.setup_dns:
if len(options.forwarders) < 1 and not options.no_forwarders and \ if len(options.forwarders) < 1 and not options.no_forwarders and \
@@ -439,11 +592,12 @@ def main():
msg="You must specify at least one of forwarders, " msg="You must specify at least one of forwarders, "
"auto-forwarders or no-forwarders") "auto-forwarders or no-forwarders")
if NUM_VERSION >= 40200 and options.master_password: if NUM_VERSION >= 40200 and options.master_password and \
ansible_module.warn("Specifying master-password is deprecated") not options.external_cert_files:
ansible_module.warn("Specifying kerberos master-password is deprecated")
options._installation_cleanup = True options._installation_cleanup = True
if not options.external_ca and len(options.external_cert_files) < 1 and \ if not options.external_ca and not options.external_cert_files and \
is_ipa_configured(): is_ipa_configured():
options._installation_cleanup = False options._installation_cleanup = False
ansible_module.log( ansible_module.log(
@@ -495,10 +649,11 @@ def main():
ansible_module.fail_json(msg=error) ansible_module.fail_json(msg=error)
# external cert file paths are absolute # external cert file paths are absolute
for path in options.external_cert_files: if options.external_cert_files:
if not os.path.isabs(path): for path in options.external_cert_files:
ansible_module.fail_json( if not os.path.isabs(path):
msg="External cert file '%s' must use an absolute path" % path) ansible_module.fail_json(
msg="External cert file '%s' must use an absolute path" % path)
options.setup_ca = True options.setup_ca = True
# We only set up the CA if the PKCS#12 options are not given. # We only set up the CA if the PKCS#12 options are not given.
@@ -517,6 +672,18 @@ def main():
ansible_module.fail_json(msg= ansible_module.fail_json(msg=
"--setup-kra cannot be used with CA-less installation") "--setup-kra cannot be used with CA-less installation")
# 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))
# ca_subject # ca_subject
if options.ca_subject: if options.ca_subject:
ca.subject_validator(ca.VALID_SUBJECT_ATTRS, options.ca_subject) ca.subject_validator(ca.VALID_SUBJECT_ATTRS, options.ca_subject)
@@ -697,6 +864,10 @@ def main():
_pkinit_pkcs12_file=pkinit_pkcs12_file, _pkinit_pkcs12_file=pkinit_pkcs12_file,
_pkinit_pkcs12_info=pkinit_pkcs12_info, _pkinit_pkcs12_info=pkinit_pkcs12_info,
_pkinit_ca_cert=pkinit_ca_cert, _pkinit_ca_cert=pkinit_ca_cert,
### certificate system ###
external_ca=options.external_ca,
external_ca_type=options.external_ca_type,
external_ca_profile=options.external_ca_profile,
### ad trust ### ### ad trust ###
rid_base=options.rid_base, rid_base=options.rid_base,
secondary_rid_base=options.secondary_rid_base, secondary_rid_base=options.secondary_rid_base,

View File

@@ -100,7 +100,7 @@ if NUM_VERSION >= 40500:
update_hosts_file) update_hosts_file)
from ipaserver.install.server.install import ( from ipaserver.install.server.install import (
check_dirsrv, validate_admin_password, validate_dm_password, check_dirsrv, validate_admin_password, validate_dm_password,
write_cache) read_cache, write_cache)
try: try:
from ipaserver.install.dogtaginstance import PKIIniLoader from ipaserver.install.dogtaginstance import PKIIniLoader
except ImportError: except ImportError:
@@ -218,6 +218,39 @@ options.add_sids = True
options.add_agents = False options.add_agents = False
# Installable
options.uninstalling = False
# ServerInstallInterface
options.description = "Server"
options.kinit_attempts = 1
options.fixed_primary = True
options.permit = False
options.enable_dns_updates = False
options.no_krb5_offline_passwords = False
options.preserve_sssd = False
options.no_sssd = False
# ServerMasterInstall
options.force_join = False
options.servers = None
options.no_wait_for_dns = True
options.host_password = None
options.keytab = None
options.setup_ca = True
# always run sidgen task and do not allow adding agents on first master
options.add_sids = True
options.add_agents = False
# ADTrustInstallInterface
# no_msdcs is deprecated
options.no_msdcs = False
# Uninstall
options.ignore_topology_disconnect = False
options.ignore_last_of_role = False
def api_Backend_ldap2(host_name, setup_ca, connect=False): def api_Backend_ldap2(host_name, setup_ca, connect=False):
# we are sure we have the configuration file ready. # we are sure we have the configuration file ready.
cfg = dict(context='installer', confdir=paths.ETC_IPA, in_server=True, cfg = dict(context='installer', confdir=paths.ETC_IPA, in_server=True,

View File

@@ -0,0 +1,12 @@
- name: Install - Initialize ipaserver_external_cert_files
set_fact:
ipaserver_external_cert_files: []
when: ipaserver_external_cert_files is undefined
- name: Install - Copy "{{ item }}" "{{ inventory_hostname }}':/root/'{{ item }}"
copy:
src: "{{ item }}"
dest: "/root/{{ item }}"
force: yes
- name: Install - Extend ipaserver_external_cert_files with "/root/{{ item }}"
set_fact:
ipaserver_external_cert_files: "{{ ipaserver_external_cert_files }} + [ '/root/{{ item }}' ]"

View File

@@ -24,6 +24,12 @@
#- name: Install - Include Python2/3 import test #- name: Install - Include Python2/3 import test
# import_tasks: "{{ role_path }}/tasks/python_2_3_test.yml" # import_tasks: "{{ role_path }}/tasks/python_2_3_test.yml"
- include_tasks: "{{ role_path }}/tasks/copy_external_cert.yml"
with_items: "{{ ipaserver_external_cert_files_from_controller }}"
when: ipaserver_external_cert_files_from_controller is defined and
ipaserver_external_cert_files_from_controller|length > 0 and
not ipaserver_external_cert_files is defined
- name: Install - Server installation test - name: Install - Server installation test
ipaserver_test: ipaserver_test:
### basic ### ### basic ###
@@ -47,9 +53,9 @@
# no_ui_redirect: "{{ ipaserver_no_ui_redirect }}" # no_ui_redirect: "{{ ipaserver_no_ui_redirect }}"
dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}"
### ssl certificate ### ### ssl certificate ###
dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}" dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default(omit) }}"
http_cert_files: "{{ ipaserver_http_cert_files | default([]) }}" http_cert_files: "{{ ipaserver_http_cert_files | default(omit) }}"
pkinit_cert_files: "{{ ipaserver_pkinit_cert_files | default([]) }}" pkinit_cert_files: "{{ ipaserver_pkinit_cert_files | default(omit) }}"
# dirsrv_pin # dirsrv_pin
# http_pin # http_pin
# pkinit_pin # pkinit_pin
@@ -66,7 +72,8 @@
### certificate system ### ### certificate system ###
external_ca: "{{ ipaserver_external_ca }}" external_ca: "{{ ipaserver_external_ca }}"
external_ca_type: "{{ ipaserver_external_ca_type | default(omit) }}" external_ca_type: "{{ ipaserver_external_ca_type | default(omit) }}"
external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" external_ca_profile: "{{ ipaserver_external_ca_profile | default(omit) }}"
external_cert_files: "{{ ipaserver_external_cert_files | default(omit) }}"
subject_base: "{{ ipaserver_subject_base | default(omit) }}" subject_base: "{{ ipaserver_subject_base | default(omit) }}"
ca_subject: "{{ ipaserver_ca_subject | default(omit) }}" ca_subject: "{{ ipaserver_ca_subject | default(omit) }}"
# ca_signing_algorithm # ca_signing_algorithm
@@ -128,8 +135,12 @@
setup_kra: "{{ ipaserver_setup_kra }}" setup_kra: "{{ ipaserver_setup_kra }}"
setup_dns: "{{ ipaserver_setup_dns }}" setup_dns: "{{ ipaserver_setup_dns }}"
### certificate system ### ### certificate system ###
# external_ca external_ca: "{{ ipaserver_external_ca }}"
# external_cert_files external_ca_type: "{{ ipaserver_external_ca_type | default(omit) }}"
external_ca_profile:
"{{ ipaserver_external_ca_profile | default(omit) }}"
external_cert_files:
"{{ ipaserver_external_cert_files | default(omit) }}"
subject_base: "{{ ipaserver_subject_base | default(omit) }}" subject_base: "{{ ipaserver_subject_base | default(omit) }}"
ca_subject: "{{ ipaserver_ca_subject | default(omit) }}" ca_subject: "{{ ipaserver_ca_subject | default(omit) }}"
### dns ### ### dns ###
@@ -174,8 +185,9 @@
setup_ca: "{{ result_ipaserver_test.setup_ca }}" setup_ca: "{{ result_ipaserver_test.setup_ca }}"
# no_host_dns: "{{ result_ipaserver_test.no_host_dns }}" # no_host_dns: "{{ result_ipaserver_test.no_host_dns }}"
dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}" dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}"
dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}" dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default(omit) }}"
external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" external_cert_files:
"{{ ipaserver_external_cert_files | default(omit) }}"
subject_base: "{{ result_ipaserver_prepare.subject_base }}" subject_base: "{{ result_ipaserver_prepare.subject_base }}"
ca_subject: "{{ result_ipaserver_prepare.ca_subject }}" ca_subject: "{{ result_ipaserver_prepare.ca_subject }}"
# no_reverse: "{{ ipaserver_no_reverse }}" # no_reverse: "{{ ipaserver_no_reverse }}"
@@ -200,7 +212,8 @@
setup_dns: "{{ ipaserver_setup_dns }}" setup_dns: "{{ ipaserver_setup_dns }}"
setup_ca: "{{ result_ipaserver_test.setup_ca }}" setup_ca: "{{ result_ipaserver_test.setup_ca }}"
no_host_dns: "{{ result_ipaserver_test.no_host_dns }}" no_host_dns: "{{ result_ipaserver_test.no_host_dns }}"
external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" external_cert_files:
"{{ ipaserver_external_cert_files | default(omit) }}"
subject_base: "{{ result_ipaserver_prepare.subject_base }}" subject_base: "{{ result_ipaserver_prepare.subject_base }}"
ca_subject: "{{ result_ipaserver_prepare.ca_subject }}" ca_subject: "{{ result_ipaserver_prepare.ca_subject }}"
no_reverse: "{{ ipaserver_no_reverse }}" no_reverse: "{{ ipaserver_no_reverse }}"
@@ -241,7 +254,11 @@
dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}" dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}"
_dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info }}" _dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info }}"
external_ca: "{{ ipaserver_external_ca }}" external_ca: "{{ ipaserver_external_ca }}"
external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}" external_ca_type: "{{ ipaserver_external_ca_type | default(omit) }}"
external_ca_profile:
"{{ ipaserver_external_ca_profile | default(omit) }}"
external_cert_files:
"{{ ipaserver_external_cert_files | default(omit) }}"
subject_base: "{{ result_ipaserver_prepare.subject_base }}" subject_base: "{{ result_ipaserver_prepare.subject_base }}"
_subject_base: "{{ result_ipaserver_prepare._subject_base }}" _subject_base: "{{ result_ipaserver_prepare._subject_base }}"
ca_subject: "{{ result_ipaserver_prepare.ca_subject }}" ca_subject: "{{ result_ipaserver_prepare.ca_subject }}"
@@ -251,150 +268,163 @@
reverse_zones: "{{ result_ipaserver_prepare.reverse_zones }}" reverse_zones: "{{ result_ipaserver_prepare.reverse_zones }}"
no_reverse: "{{ ipaserver_no_reverse }}" no_reverse: "{{ ipaserver_no_reverse }}"
auto_forwarders: "{{ ipaserver_auto_forwarders }}" auto_forwarders: "{{ ipaserver_auto_forwarders }}"
register: result_ipaserver_setup_ca
- name: Install - Setup otpd - name: Copy /root/ipa.csr to "{{ inventory_hostname }}-ipa.csr"
ipaserver_setup_otpd: fetch:
realm: "{{ result_ipaserver_test.realm }}" src: /root/ipa.csr
hostname: "{{ result_ipaserver_test.hostname }}" dest: "{{ inventory_hostname }}-ipa.csr"
setup_ca: "{{ result_ipaserver_test.setup_ca }}" flat: yes
when: result_ipaserver_setup_ca.csr_generated | bool and
ipaserver_copy_csr_to_controller | bool
- name: Install - Setup HTTP - block:
ipaserver_setup_http: - name: Install - Setup otpd
dm_password: "{{ ipadm_password }}" ipaserver_setup_otpd:
password: "{{ ipaadmin_password }}" realm: "{{ result_ipaserver_test.realm }}"
master_password: "{{ ipaserver_master_password }}" hostname: "{{ result_ipaserver_test.hostname }}"
domain: "{{ result_ipaserver_test.domain }}" setup_ca: "{{ result_ipaserver_test.setup_ca }}"
realm: "{{ result_ipaserver_test.realm }}"
hostname: "{{ result_ipaserver_test.hostname }}"
# ip_addresses: "{{ result_ipaserver_prepare.ip_addresses }}"
reverse_zones: "{{ result_ipaserver_prepare.reverse_zones }}"
setup_adtrust: "{{ result_ipaserver_test.setup_adtrust }}"
setup_kra: "{{ result_ipaserver_test.setup_kra }}"
setup_dns: "{{ ipaserver_setup_dns }}"
setup_ca: "{{ result_ipaserver_test.setup_ca }}"
no_host_dns: "{{ result_ipaserver_test.no_host_dns }}"
dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}"
external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}"
subject_base: "{{ result_ipaserver_prepare.subject_base }}"
_subject_base: "{{ result_ipaserver_prepare._subject_base }}"
ca_subject: "{{ result_ipaserver_prepare.ca_subject }}"
_ca_subject: "{{ result_ipaserver_prepare._ca_subject }}"
no_reverse: "{{ ipaserver_no_reverse }}"
auto_forwarders: "{{ ipaserver_auto_forwarders }}"
no_pkinit: "{{ result_ipaserver_test.no_pkinit }}"
no_hbac_allow: "{{ ipaserver_no_hbac_allow }}"
idstart: "{{ result_ipaserver_test.idstart }}"
idmax: "{{ result_ipaserver_test.idmax }}"
http_cert_files: "{{ ipaserver_http_cert_files | default([]) }}"
no_ui_redirect: "{{ ipaserver_no_ui_redirect }}"
- name: Install - Setup KRA - name: Install - Setup HTTP
ipaserver_setup_kra: ipaserver_setup_http:
hostname: "{{ result_ipaserver_test.hostname }}" dm_password: "{{ ipadm_password }}"
setup_ca: "{{ result_ipaserver_test.setup_ca }}" password: "{{ ipaadmin_password }}"
dm_password: "{{ ipadm_password }}" master_password: "{{ ipaserver_master_password }}"
setup_kra: "{{ result_ipaserver_test.setup_kra }}" domain: "{{ result_ipaserver_test.domain }}"
realm: "{{ result_ipaserver_test.realm }}" realm: "{{ result_ipaserver_test.realm }}"
pki_config_override: "{{ ipaserver_pki_config_override | hostname: "{{ result_ipaserver_test.hostname }}"
default(omit) }}" # ip_addresses: "{{ result_ipaserver_prepare.ip_addresses }}"
when: result_ipaserver_test.setup_kra | bool reverse_zones: "{{ result_ipaserver_prepare.reverse_zones }}"
setup_adtrust: "{{ result_ipaserver_test.setup_adtrust }}"
setup_kra: "{{ result_ipaserver_test.setup_kra }}"
setup_dns: "{{ ipaserver_setup_dns }}"
setup_ca: "{{ result_ipaserver_test.setup_ca }}"
no_host_dns: "{{ result_ipaserver_test.no_host_dns }}"
dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}"
external_cert_files:
"{{ ipaserver_external_cert_files | default(omit) }}"
subject_base: "{{ result_ipaserver_prepare.subject_base }}"
_subject_base: "{{ result_ipaserver_prepare._subject_base }}"
ca_subject: "{{ result_ipaserver_prepare.ca_subject }}"
_ca_subject: "{{ result_ipaserver_prepare._ca_subject }}"
no_reverse: "{{ ipaserver_no_reverse }}"
auto_forwarders: "{{ ipaserver_auto_forwarders }}"
no_pkinit: "{{ result_ipaserver_test.no_pkinit }}"
no_hbac_allow: "{{ ipaserver_no_hbac_allow }}"
idstart: "{{ result_ipaserver_test.idstart }}"
idmax: "{{ result_ipaserver_test.idmax }}"
http_cert_files: "{{ ipaserver_http_cert_files | default([]) }}"
no_ui_redirect: "{{ ipaserver_no_ui_redirect }}"
- name: Install - Setup DNS - name: Install - Setup KRA
ipaserver_setup_dns: ipaserver_setup_kra:
hostname: "{{ result_ipaserver_test.hostname }}" hostname: "{{ result_ipaserver_test.hostname }}"
setup_ca: "{{ result_ipaserver_test.setup_ca }}" setup_ca: "{{ result_ipaserver_test.setup_ca }}"
setup_dns: "{{ ipaserver_setup_dns }}" dm_password: "{{ ipadm_password }}"
forwarders: "{{ result_ipaserver_prepare.forwarders }}" setup_kra: "{{ result_ipaserver_test.setup_kra }}"
forward_policy: "{{ result_ipaserver_prepare.forward_policy }}" realm: "{{ result_ipaserver_test.realm }}"
zonemgr: "{{ ipaserver_zonemgr | default(omit) }}" pki_config_override: "{{ ipaserver_pki_config_override |
no_dnssec_validation: "{{ result_ipaserver_prepare.no_dnssec_validation }}" default(omit) }}"
### additional ### when: result_ipaserver_test.setup_kra | bool
dns_ip_addresses: "{{ result_ipaserver_prepare.dns_ip_addresses }}"
dns_reverse_zones: "{{ result_ipaserver_prepare.dns_reverse_zones }}"
when: ipaserver_setup_dns | bool
- name: Install - Setup ADTRUST - name: Install - Setup DNS
ipaserver_setup_adtrust: ipaserver_setup_dns:
hostname: "{{ result_ipaserver_test.hostname }}" hostname: "{{ result_ipaserver_test.hostname }}"
setup_ca: "{{ result_ipaserver_test.setup_ca }}" setup_ca: "{{ result_ipaserver_test.setup_ca }}"
setup_adtrust: "{{ result_ipaserver_test.setup_adtrust }}" setup_dns: "{{ ipaserver_setup_dns }}"
### ad trust ### forwarders: "{{ result_ipaserver_prepare.forwarders }}"
enable_compat: "{{ ipaserver_enable_compat }}" forward_policy: "{{ result_ipaserver_prepare.forward_policy }}"
rid_base: "{{ result_ipaserver_test.rid_base }}" zonemgr: "{{ ipaserver_zonemgr | default(omit) }}"
secondary_rid_base: "{{ result_ipaserver_test.secondary_rid_base }}" no_dnssec_validation: "{{ result_ipaserver_prepare.no_dnssec_validation }}"
### additional ### ### additional ###
adtrust_netbios_name: "{{ result_ipaserver_prepare.adtrust_netbios_name }}" dns_ip_addresses: "{{ result_ipaserver_prepare.dns_ip_addresses }}"
adtrust_reset_netbios_name: dns_reverse_zones: "{{ result_ipaserver_prepare.dns_reverse_zones }}"
"{{ result_ipaserver_prepare.adtrust_reset_netbios_name }}" when: ipaserver_setup_dns | bool
when: result_ipaserver_test.setup_adtrust
- name: Install - Set DS password - name: Install - Setup ADTRUST
ipaserver_set_ds_password: ipaserver_setup_adtrust:
dm_password: "{{ ipadm_password }}" hostname: "{{ result_ipaserver_test.hostname }}"
password: "{{ ipaadmin_password }}" setup_ca: "{{ result_ipaserver_test.setup_ca }}"
domain: "{{ result_ipaserver_test.domain }}" setup_adtrust: "{{ result_ipaserver_test.setup_adtrust }}"
realm: "{{ result_ipaserver_test.realm }}" ### ad trust ###
hostname: "{{ result_ipaserver_test.hostname }}" enable_compat: "{{ ipaserver_enable_compat }}"
setup_ca: "{{ result_ipaserver_test.setup_ca }}" rid_base: "{{ result_ipaserver_test.rid_base }}"
subject_base: "{{ result_ipaserver_prepare.subject_base }}" secondary_rid_base: "{{ result_ipaserver_test.secondary_rid_base }}"
ca_subject: "{{ result_ipaserver_prepare.ca_subject }}" ### additional ###
no_pkinit: "{{ result_ipaserver_test.no_pkinit }}" adtrust_netbios_name: "{{ result_ipaserver_prepare.adtrust_netbios_name }}"
no_hbac_allow: "{{ ipaserver_no_hbac_allow }}" adtrust_reset_netbios_name:
idstart: "{{ result_ipaserver_test.idstart }}" "{{ result_ipaserver_prepare.adtrust_reset_netbios_name }}"
idmax: "{{ result_ipaserver_test.idmax }}" when: result_ipaserver_test.setup_adtrust
dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}"
_dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info }}"
- name: Install - Setup client - name: Install - Set DS password
include_role: ipaserver_set_ds_password:
name: ipaclient dm_password: "{{ ipadm_password }}"
vars: password: "{{ ipaadmin_password }}"
state: present domain: "{{ result_ipaserver_test.domain }}"
ipaclient_on_master: yes realm: "{{ result_ipaserver_test.realm }}"
ipaclient_domain: "{{ result_ipaserver_test.domain }}" hostname: "{{ result_ipaserver_test.hostname }}"
ipaclient_realm: "{{ result_ipaserver_test.realm }}" setup_ca: "{{ result_ipaserver_test.setup_ca }}"
ipaclient_servers: ["{{ result_ipaserver_test.hostname }}"] subject_base: "{{ result_ipaserver_prepare.subject_base }}"
ipaclient_hostname: "{{ result_ipaserver_test.hostname }}" ca_subject: "{{ result_ipaserver_prepare.ca_subject }}"
ipaclient_no_ntp: no_pkinit: "{{ result_ipaserver_test.no_pkinit }}"
"{{ 'true' if result_ipaserver_test.ipa_python_version >= 40690 no_hbac_allow: "{{ ipaserver_no_hbac_allow }}"
else 'false' }}" idstart: "{{ result_ipaserver_test.idstart }}"
ipaclient_install_packages: "{{ ipaserver_install_packages }}" idmax: "{{ result_ipaserver_test.idmax }}"
dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}"
_dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info }}"
- name: Install - Enable IPA - name: Install - Setup client
ipaserver_enable_ipa: include_role:
hostname: "{{ result_ipaserver_test.hostname }}" name: ipaclient
setup_dns: "{{ ipaserver_setup_dns }}" vars:
setup_ca: "{{ result_ipaserver_test.setup_ca }}" state: present
register: result_ipaserver_enable_ipa ipaclient_on_master: yes
ipaclient_domain: "{{ result_ipaserver_test.domain }}"
ipaclient_realm: "{{ result_ipaserver_test.realm }}"
ipaclient_servers: ["{{ result_ipaserver_test.hostname }}"]
ipaclient_hostname: "{{ result_ipaserver_test.hostname }}"
ipaclient_no_ntp:
"{{ 'true' if result_ipaserver_test.ipa_python_version >= 40690
else 'false' }}"
ipaclient_install_packages: "{{ ipaserver_install_packages }}"
- name: Install - Cleanup root IPA cache - name: Install - Enable IPA
file: ipaserver_enable_ipa:
path: "/root/.ipa_cache" hostname: "{{ result_ipaserver_test.hostname }}"
state: absent setup_dns: "{{ ipaserver_setup_dns }}"
when: result_ipaserver_enable_ipa.changed setup_ca: "{{ result_ipaserver_test.setup_ca }}"
register: result_ipaserver_enable_ipa
- name: Install - Configure firewalld - name: Install - Cleanup root IPA cache
command: > file:
firewall-cmd path: "/root/.ipa_cache"
--permanent state: absent
--add-service=freeipa-ldap when: result_ipaserver_enable_ipa.changed
--add-service=freeipa-ldaps
{{ "--add-service=freeipa-trust" if ipaserver_setup_adtrust | bool
else "" }}
{{ "--add-service=dns" if ipaserver_setup_dns | bool else "" }}
{{ "--add-service=ntp" if not ipaclient_no_ntp | bool else "" }}
when: ipaserver_setup_firewalld | bool
- name: Install - Configure firewalld runtime - name: Install - Configure firewalld
command: > command: >
firewall-cmd firewall-cmd
--add-service=freeipa-ldap --permanent
--add-service=freeipa-ldaps --add-service=freeipa-ldap
{{ "--add-service=freeipa-trust" if ipaserver_setup_adtrust | bool --add-service=freeipa-ldaps
else "" }} {{ "--add-service=freeipa-trust" if ipaserver_setup_adtrust | bool
{{ "--add-service=dns" if ipaserver_setup_dns | bool else "" }} else "" }}
{{ "--add-service=ntp" if not ipaclient_no_ntp | bool else "" }} {{ "--add-service=dns" if ipaserver_setup_dns | bool else "" }}
when: ipaserver_setup_firewalld | bool {{ "--add-service=ntp" if not ipaclient_no_ntp | bool else "" }}
when: ipaserver_setup_firewalld | bool
- name: Install - Configure firewalld runtime
command: >
firewall-cmd
--add-service=freeipa-ldap
--add-service=freeipa-ldaps
{{ "--add-service=freeipa-trust" if ipaserver_setup_adtrust | bool
else "" }}
{{ "--add-service=dns" if ipaserver_setup_dns | bool else "" }}
{{ "--add-service=ntp" if not ipaclient_no_ntp | bool else "" }}
when: ipaserver_setup_firewalld | bool
when: not result_ipaserver_setup_ca.csr_generated | bool
when: not ansible_check_mode and not when: not ansible_check_mode and not
(not result_ipaserver_test.changed and (not result_ipaserver_test.changed and