diff --git a/README-service.md b/README-service.md new file mode 100644 index 0000000000000000000000000000000000000000..8125190b241ecc9c517b6b4e2ace2a7ab325a0e0 --- /dev/null +++ b/README-service.md @@ -0,0 +1,319 @@ +Service module +============== + +Description +----------- + +The service module allows to ensure presence and absence of services. + + +Features +-------- + +* Service management + + +Supported FreeIPA Versions +-------------------------- + +FreeIPA versions 4.4.0 and up are supported by the ipaservice module. + +Option `skip_host_check` requires FreeIPA version 4.7.0 or later. + + +Requirements +------------ + +**Controller** +* Ansible version: 2.8+ + +**Node** +* Supported FReeIPA version (see above) + + +Usage +===== + +Example inventory file + +```ini +[ipaserver] +ipaserver.test.local +``` + + +Example playbook to make sure service is present: + +```yaml +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service is present + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + certificate: + - MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAw + DzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDT + ALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpH + VkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJzM + LJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmjfMXp0nIT + oTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn0vQINt55YoEd1s + 4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpc + xj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1 + UdDgQWBBRV0j7JYukuH/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+Q + eNlRLXDlEDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs + 5y1Zp0WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqic + uPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkGwIt1OH + 2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyEiaio3693l6no + obyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj9uKQ5GTWRh59VnRBVC + /SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV7MVq + pac_type: PAD + auth_ind: otp + requires_pre_auth: false + ok_as_delegate: false + ok_to_auth_as_delegate: false + skip-host-check: true + force: true +``` + + +Example playbook to make sure service is absent: + +```yaml +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service is present + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + state: absent +``` + + +Example playbook to make sure service is disabled: + +```yaml +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service is present + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + state: disabled +``` + +Example playbook to add a service even if the host object does not exist, but only if it does have a DNS entry: + +```yaml +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service is present + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + skip_host_check: true + force: false +``` + +Example playbook to add a service if it does have a DNS entry, but host object exits: + +```yaml +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service is present + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + skip_host_check: false + force: true +``` + +Example playbook to ensure service has a certificate: + +```yaml +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service member certificate is present. + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + certificate: + - MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAw + DzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDT + ALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpH + VkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJzM + LJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmjfMXp0nIT + oTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn0vQINt55YoEd1s + 4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpc + xj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1 + UdDgQWBBRV0j7JYukuH/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+Q + eNlRLXDlEDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs + 5y1Zp0WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqic + uPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkGwIt1OH + 2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyEiaio3693l6no + obyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj9uKQ5GTWRh59VnRBVC + /SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV7MVq + action: member + state: present +``` + +Example playbook to add a principal to the service: + +```yaml +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Principal host/test.example.com present in service. + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + principal: host/principal.example.com + action: member +``` + +Example playbook to enable a host to manage service: + +```yaml +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure host can manage service, again. + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + host: host1.example.com + action: member +``` + +Example playbook to allow users, groups, hosts or hostgroups to create a keytab of this service: + +```yaml +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Allow users, groups, hosts or host groups to create a keytab of this service. + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + allow_create_keytab_user: + - user01 + - user02 + allow_create_keytab_group: + - group01 + - group02 + allow_create_keytab_host: + - host1.example.com + - host2.example.com + allow_create_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member +``` + +Example playbook to allow users, groups, hosts or hostgroups to retrieve a keytab of this service: + +```yaml +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Allow users, groups, hosts or host groups to retrieve a keytab of this service. + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + allow_retrieve_keytab_user: + - user01 + - user02 + allow_retrieve_keytab_group: + - group01 + - group02 + allow_retrieve_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_retrieve_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member +``` + + +Variables +--------- + +ipaservice + +Variable | Description | Required +-------- | ----------- | -------- +`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no +`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no +`name` \| `service` | The list of service name strings. | yes +`certificate` \| `usercertificate` | Base-64 encoded service certificate. | no +`pac_type` \| `ipakrbauthzdata` | Supported PAC type. It can be one of `MS-PAC`, `PAD`, or `NONE`. | no +`auth_ind` \| `krbprincipalauthind` | Defines a whitelist for Authentication Indicators. It can be any of `otp`, `radius`, `pkinit`, or `hardened`. | no +`requires_pre_auth` \| `ipakrbrequirespreauth` | Pre-authentication is required for the service. Default to true. (bool) | no +`ok_as_delegate` \| `ipakrbokasdelegate` | Client credentials may be delegated to the service. Default to false. (bool) | no +`ok_to_auth_as_delegate` \| `ipakrboktoauthasdelegate` | The service is allowed to authenticate on behalf of a client. Default to false. (bool) | no +`skip_host_check` | Force service to be created even when host object does not exist to manage it. Default to false. (bool)| no +`force` | Force principal name even if host not in DNS. Default to false. (bool) | no +`host` \| `managedby_host`| Hosts that can manage the service. | no +`allow_create_keytab_user` \| `ipaallowedtoperform_write_keys_user` | Users allowed to create a keytab of this host. | no +`allow_create_keytab_group` \| `ipaallowedtoperform_write_keys_group`| Groups allowed to create a keytab of this host. | no +`allow_create_keytab_host` \| `ipaallowedtoperform_write_keys_host`| Hosts allowed to create a keytab of this host. | no +`allow_create_keytab_hostgroup` \| `ipaallowedtoperform_write_keys_group`| Host groups allowed to create a keytab of this host. | no +`allow_retrieve_keytab_user` \| `ipaallowedtoperform_read_keys_user` | Users allowed to retrieve a keytab of this host. | no +`allow_retrieve_keytab_group` \| `ipaallowedtoperform_read_keys_group` | Groups allowed to retrieve a keytab of this host. | no +`allow_retrieve_keytab_host` \| `ipaallowedtoperform_read_keys_host` | Hosts allowed to retrieve a keytab from of host. | no +`allow_retrieve_keytab_hostgroup` \| `ipaallowedtoperform_read_keys_hostgroup` | Host groups allowed to retrieve a keytab of this host. | no +`action` | Work on service or member level. It can be on of `member` or `service` and defaults to `service`. | no +`state` | The state to ensure. It can be one of `present`, `absent`, or `disabled`, default: `present`. | no + + +Authors +======= + +Rafael Jeffman diff --git a/README.md b/README.md index eea8026675459e4a35e81213cee5e558d85a8506..f5d4c257b4f478afe4a3ee9b99b639f8bc2b73b0 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Features * Modules for host management * Modules for hostgroup management * Modules for pwpolicy management +* Modules for service management * Modules for sudocmd management * Modules for sudocmdgroup management * Modules for sudorule management @@ -413,6 +414,7 @@ Modules in plugin/modules * [ipahost](README-host.md) * [ipahostgroup](README-hostgroup.md) * [ipapwpolicy](README-pwpolicy.md) +* [ipaservice](README-service.md) * [ipasudocmd](README-sudocmd.md) * [ipasudocmdgroup](README-sudocmdgroup.md) * [ipasudorule](README-sudorule.md) diff --git a/playbooks/service/service-host-is-absent.yml b/playbooks/service/service-host-is-absent.yml new file mode 100644 index 0000000000000000000000000000000000000000..5963340f3447aa83c8569fb905381cc7d4b84e7c --- /dev/null +++ b/playbooks/service/service-host-is-absent.yml @@ -0,0 +1,14 @@ +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure management host is absent. + - ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com + host: "{{ groups.ipaserver[0] }}" + action: member + state: absent diff --git a/playbooks/service/service-host-is-present.yml b/playbooks/service/service-host-is-present.yml new file mode 100644 index 0000000000000000000000000000000000000000..2460051ebf793ab6e357cf24cd02499c1aaeb777 --- /dev/null +++ b/playbooks/service/service-host-is-present.yml @@ -0,0 +1,13 @@ +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure management host is present. + - ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com + host: "{{ groups.ipaserver[0] }}" + action: member diff --git a/playbooks/service/service-is-absent.yml b/playbooks/service/service-is-absent.yml new file mode 100644 index 0000000000000000000000000000000000000000..fe65771ef893048fcc888adb4f0ca226026acaac --- /dev/null +++ b/playbooks/service/service-is-absent.yml @@ -0,0 +1,12 @@ +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service is absent + - ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com + state: absent diff --git a/playbooks/service/service-is-disabled.yml b/playbooks/service/service-is-disabled.yml new file mode 100644 index 0000000000000000000000000000000000000000..2bf01fb156aa88ba0a3f9d8ded7ea084ccc06f9d --- /dev/null +++ b/playbooks/service/service-is-disabled.yml @@ -0,0 +1,12 @@ +--- +- name: Playbook to disable IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service is disabled + - ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com + state: disabled diff --git a/playbooks/service/service-is-present-with-all-attributes.yml b/playbooks/service/service-is-present-with-all-attributes.yml new file mode 100644 index 0000000000000000000000000000000000000000..f7e59ebca7ad8082befb552d5b3e06ba433dab78 --- /dev/null +++ b/playbooks/service/service-is-present-with-all-attributes.yml @@ -0,0 +1,23 @@ +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service is present + - ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com + certificate: + - MIICBjCCAW8CFHnm32VcXaUDGfEGdDL/erPSijUAMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwHhcNMjAwMTIzMDA1NjQ2WhcNMjEwMTIyMDA1NjQ2WjBCMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYrdVmsr7iT3f67DM5bb1osSEe5/c91UUMEIcFq5wrgBhzVfs8iIMDVC1yiUGTsDLJNJc4nb1tUxeR9K5fh25E6n/eWDBP75NStotjAXRU4Ahi3FNRhWFOKesds5xNqgDk5/dY8UekJv2yUblQuZzeF8b2XFrmHuCaYuFctzPfWwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACF+5RS8Ce0HRixGPu4Xd51i+Kzblg++lx8fDJ8GW5G16/Z1AsB72Hc7etJL2PksHlue/xCq6SA9fIfHc4TBNCiWjPSP1NhHJeYyoPiSkcYsqXuxWyoyRLbnAhBVvhoiqZbUt3u3tGB0uMMA0yJvj07mP7Nea2KdBYVH8X1pM0V+ + pac_type: + - MS-PAC + - PAD + auth_ind: otp + force: no + requires_pre_auth: yes + ok_as_delegate: no + ok_to_auth_as_delegate: no + action: service + state: present diff --git a/playbooks/service/service-is-present-with-host-force.yml b/playbooks/service/service-is-present-with-host-force.yml new file mode 100644 index 0000000000000000000000000000000000000000..2268ea8f402afc815df7fe978177ee3d93f6c3eb --- /dev/null +++ b/playbooks/service/service-is-present-with-host-force.yml @@ -0,0 +1,13 @@ +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service is present + - ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/ihavenodns.info + force: yes + # state: absent diff --git a/playbooks/service/service-is-present-without-host-object.yml b/playbooks/service/service-is-present-without-host-object.yml new file mode 100644 index 0000000000000000000000000000000000000000..ddf72b8e24ad6a57e564fe2c4321487c77c2955c --- /dev/null +++ b/playbooks/service/service-is-present-without-host-object.yml @@ -0,0 +1,12 @@ +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service is present + - ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.ansible.com + skip_host_check: yes diff --git a/playbooks/service/service-is-present.yml b/playbooks/service/service-is-present.yml new file mode 100644 index 0000000000000000000000000000000000000000..06e883431b13f6b3e275f7117387725eac68f703 --- /dev/null +++ b/playbooks/service/service-is-present.yml @@ -0,0 +1,11 @@ +--- +- name: Playbook to manage IPA service. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service is present + - ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com diff --git a/playbooks/service/service-member-allow_create_keytab-absent.yml b/playbooks/service/service-member-allow_create_keytab-absent.yml new file mode 100644 index 0000000000000000000000000000000000000000..d4a15ea4828753242d5527e52e2db4b7ebd5b15a --- /dev/null +++ b/playbooks/service/service-member-allow_create_keytab-absent.yml @@ -0,0 +1,24 @@ +--- +- name: Service member allow_create_keytab absent + hosts: ipaserver + become: true + + tasks: + - name: Service HTTP/www.example.com members allow_create_keytab absent for users, groups, hosts and hostgroups + ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com + allow_create_keytab_user: + - user01 + - user02 + allow_create_keytab_group: + - group01 + - group02 + allow_create_keytab_host: + - host01.example.com + - host02.example.com + allow_create_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + state: absent diff --git a/playbooks/service/service-member-allow_create_keytab-present.yml b/playbooks/service/service-member-allow_create_keytab-present.yml new file mode 100644 index 0000000000000000000000000000000000000000..b28b6dc23a89e061eaa267426543746c1938f2d4 --- /dev/null +++ b/playbooks/service/service-member-allow_create_keytab-present.yml @@ -0,0 +1,23 @@ +--- +- name: Service member allow_create_keytab present + hosts: ipaserver + become: true + + tasks: + - name: Service HTTP/www.example.com members allow_create_keytab present for users, groups, hosts and hostgroups + ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com + allow_create_keytab_user: + - user01 + - user02 + allow_create_keytab_group: + - group01 + - group02 + allow_create_keytab_host: + - host01.example.com + - host02.example.com + allow_create_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member diff --git a/playbooks/service/service-member-allow_retrieve_keytab-absent.yml b/playbooks/service/service-member-allow_retrieve_keytab-absent.yml new file mode 100644 index 0000000000000000000000000000000000000000..ceada70e5ee1b75e80f6fde05298fa28852902e2 --- /dev/null +++ b/playbooks/service/service-member-allow_retrieve_keytab-absent.yml @@ -0,0 +1,24 @@ +--- +- name: Service member allow_retrieve_keytab absent + hosts: ipaserver + become: true + + tasks: + - name: Service HTTP/www.example.com members allow_retrieve_keytab absent for users, groups, hosts and hostgroups + ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com + allow_retrieve_keytab_user: + - user01 + - user02 + allow_retrieve_keytab_group: + - group01 + - group02 + allow_retrieve_keytab_host: + - host01.example.com + - host02.example.com + allow_retrieve_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + state: absent diff --git a/playbooks/service/service-member-allow_retrieve_keytab-present.yml b/playbooks/service/service-member-allow_retrieve_keytab-present.yml new file mode 100644 index 0000000000000000000000000000000000000000..ac98904b32b2ec3e58ab2d9366d76e7177cad28e --- /dev/null +++ b/playbooks/service/service-member-allow_retrieve_keytab-present.yml @@ -0,0 +1,23 @@ +--- +- name: Service member allow_retrieve_keytab present + hosts: ipaserver + become: true + + tasks: + - name: Service HTTP/www.example.com members allow_retrieve_keytab present for users, groups, hosts and hostgroups + ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com + allow_retrieve_keytab_user: + - user01 + - user02 + allow_retrieve_keytab_group: + - group01 + - group02 + allow_retrieve_keytab_host: + - host01.example.com + - host02.example.com + allow_retrieve_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member diff --git a/playbooks/service/service-member-certificate-absent.yml b/playbooks/service/service-member-certificate-absent.yml new file mode 100644 index 0000000000000000000000000000000000000000..57b71e5eda70c4cc8fffcf3cd93b0c314620ab12 --- /dev/null +++ b/playbooks/service/service-member-certificate-absent.yml @@ -0,0 +1,16 @@ +--- +- name: Service certificate absent. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service certificate is absent + - ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com + + certificate: + - MIICBjCCAW8CFHnm32VcXaUDGfEGdDL/erPSijUAMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwHhcNMjAwMTIzMDA1NjQ2WhcNMjEwMTIyMDA1NjQ2WjBCMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYrdVmsr7iT3f67DM5bb1osSEe5/c91UUMEIcFq5wrgBhzVfs8iIMDVC1yiUGTsDLJNJc4nb1tUxeR9K5fh25E6n/eWDBP75NStotjAXRU4Ahi3FNRhWFOKesds5xNqgDk5/dY8UekJv2yUblQuZzeF8b2XFrmHuCaYuFctzPfWwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACF+5RS8Ce0HRixGPu4Xd51i+Kzblg++lx8fDJ8GW5G16/Z1AsB72Hc7etJL2PksHlue/xCq6SA9fIfHc4TBNCiWjPSP1NhHJeYyoPiSkcYsqXuxWyoyRLbnAhBVvhoiqZbUt3u3tGB0uMMA0yJvj07mP7Nea2KdBYVH8X1pM0V+ + action: member + state: absent diff --git a/playbooks/service/service-member-certificate-present.yml b/playbooks/service/service-member-certificate-present.yml new file mode 100644 index 0000000000000000000000000000000000000000..bfa01d055d1e5efd8b88422a7b9000469782cc7a --- /dev/null +++ b/playbooks/service/service-member-certificate-present.yml @@ -0,0 +1,15 @@ +--- +- name: Service certificate present. + hosts: ipaserver + become: true + gather_facts: false + + tasks: + # Ensure service certificate is present + - ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com + certificate: + - MIICBjCCAW8CFHnm32VcXaUDGfEGdDL/erPSijUAMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwHhcNMjAwMTIzMDA1NjQ2WhcNMjEwMTIyMDA1NjQ2WjBCMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYrdVmsr7iT3f67DM5bb1osSEe5/c91UUMEIcFq5wrgBhzVfs8iIMDVC1yiUGTsDLJNJc4nb1tUxeR9K5fh25E6n/eWDBP75NStotjAXRU4Ahi3FNRhWFOKesds5xNqgDk5/dY8UekJv2yUblQuZzeF8b2XFrmHuCaYuFctzPfWwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACF+5RS8Ce0HRixGPu4Xd51i+Kzblg++lx8fDJ8GW5G16/Z1AsB72Hc7etJL2PksHlue/xCq6SA9fIfHc4TBNCiWjPSP1NhHJeYyoPiSkcYsqXuxWyoyRLbnAhBVvhoiqZbUt3u3tGB0uMMA0yJvj07mP7Nea2KdBYVH8X1pM0V+ + action: member + state: present diff --git a/playbooks/service/service-member-principal-absent.yml b/playbooks/service/service-member-principal-absent.yml new file mode 100644 index 0000000000000000000000000000000000000000..6bfb168c4f8233384a1c8cdaea9f492c53b10c9c --- /dev/null +++ b/playbooks/service/service-member-principal-absent.yml @@ -0,0 +1,14 @@ +--- +- name: Service member principal absent + hosts: ipaserver + become: true + + tasks: + - name: Service HTTP/www.exmaple.com member principals host/test.exmaple.com absent + ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com + principal: + - host/test.exmaple.com + action: member + state: absent diff --git a/playbooks/service/service-member-principal-present.yml b/playbooks/service/service-member-principal-present.yml new file mode 100644 index 0000000000000000000000000000000000000000..aa94f32e896e568076a2ae017aaac8f224cde09d --- /dev/null +++ b/playbooks/service/service-member-principal-present.yml @@ -0,0 +1,13 @@ +--- +- name: Service member principal present + hosts: ipaserver + become: true + + tasks: + - name: Service HTTP/www.exmaple.com member principals host/test.exmaple.com present + ipaservice: + ipaadmin_password: MyPassword123 + name: HTTP/www.example.com + principal: + - host/test.exmaple.com + action: member diff --git a/plugins/modules/ipaservice.py b/plugins/modules/ipaservice.py new file mode 100644 index 0000000000000000000000000000000000000000..d3074ffe52a418061801acda04330a2795242afe --- /dev/null +++ b/plugins/modules/ipaservice.py @@ -0,0 +1,811 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Authors: +# Rafael Guterres Jeffman <rjeffman@redhat.com> +# +# Copyright (C) 2019 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: ipaservice +short description: Manage FreeIPA service +description: Manage FreeIPA service +options: + ipaadmin_principal: + description: The admin principal + default: admin + ipaadmin_password: + description: The admin password + required: false + name: + description: The service to manage + required: true + aliases: ["service"] + certificate: + description: Base-64 encoded service certificate. + required: false + type: list + aliases=['usercertificate'] + pac_type: + description: Supported PAC type. + required: false + choices: ["MS-PAC", "PAD", "NONE"] + type: list + aliases: ["pac_type", "ipakrbauthzdata"] + auth_ind: + description: Defines a whitelist for Authentication Indicators. + required: false + choices: ["otp", "radius", "pkinit", "hardened"] + aliases: ["krbprincipalauthind"] + skip_host_check: + description: Skip checking if host object exists. + required: False + type: bool + force: + description: Force principal name even if host is not in DNS. + required: False + type: bool + requires_pre_auth: + description: Pre-authentication is required for the service. + required: false + type: bool + default: False + aliases: ["ipakrbrequirespreauth"] + ok_as_delegate: + description: Client credentials may be delegated to the service. + required: false + type: bool + default: False + aliases: ["ipakrbokasdelegate"] + ok_to_auth_as_delegate: Allow service to authenticate on behalf of a client. + description: . + required: false + type: bool + default: False + aliases:["ipakrboktoauthasdelegate"] + principal: + description: + required: false + type: list + aliases: ["krbprincipalname"] + host: + description: Host that can manage the service. + required: false + type: list + aliases: ["managedby_host"] + allow_create_keytab_user: + descrption: Users allowed to create a keytab of this host. + required: false + type: list + aliases: ["ipaallowedtoperform_write_keys_user"] + allow_create_keytab_group: + descrption: Groups allowed to create a keytab of this host. + required: false + type: list + aliases: ["ipaallowedtoperform_write_keys_group"] + allow_create_keytab_host: + descrption: Hosts allowed to create a keytab of this host. + required: false + type: list + aliases: ["ipaallowedtoperform_write_keys_host"] + allow_create_keytab_hostgroup: + descrption: Host group allowed to create a keytab of this host. + required: false + type: list + aliases: ["ipaallowedtoperform_write_keys_hostgroup"] + allow_retrieve_keytab_user: + descrption: User allowed to retrieve a keytab of this host. + required: false + type: list + aliases: ["ipaallowedtoperform_read_keys_user"] + allow_retrieve_keytab_group: + descrption: Groups allowed to retrieve a keytab of this host. + required: false + type: list + aliases: ["ipaallowedtoperform_read_keys_group"] + allow_retrieve_keytab_host: + descrption: Hosts allowed to retrieve a keytab of this host. + required: false + type: list + aliases: ["ipaallowedtoperform_read_keys_host"] + allow_retrieve_keytab_hostgroup: + descrption: Host groups allowed to retrieve a keytab of this host. + required: false + type: list + aliases: ["ipaallowedtoperform_read_keys_hostgroup"] + action: + description: Work on service or member level + default: service + choices: ["member", "service"] + state: + description: State to ensure + default: present + choices: ["present", "absent", "enabled", "disabled"] +author: + - Rafael Jeffman +""" + +EXAMPLES = """ + # Ensure service is present + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + pac_type: + - MS-PAC + - PAD + auth_ind: otp + skip_host_check: true + force: false + requires_pre_auth: true + ok_as_delegate: false + ok_to_auth_as_delegate: false + + # Ensure service is absent + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + state: absent + + # Ensure service member certificate is present. + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + certificate: + - MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAw + DzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDT + ALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpH + VkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJzM + LJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmjfMXp0nIT + oTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn0vQINt55YoEd1s + 4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpc + xj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1 + UdDgQWBBRV0j7JYukuH/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+Q + eNlRLXDlEDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs + 5y1Zp0WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqic + uPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkGwIt1OH + 2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyEiaio3693l6no + obyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj9uKQ5GTWRh59VnRBVC + /SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV7MVq + action: member + state: present + + # Ensure principal host/test.example.com present in service. + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + principal: + - host/test.example.com + action: member + + # Ensure host can manage service. + - ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.example.com + host: + - host1.example.com + - host2.example.com + action: member +""" + +RETURN = """ +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_freeipa_module import temp_kinit, \ + temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \ + encode_certificate, gen_add_del_lists, module_params_get, to_text, \ + api_check_param + + +def find_service(module, name): + _args = { + "all": True, + } + + _result = api_command(module, "service_find", to_text(name), _args) + + if len(_result["result"]) > 1: + module.fail_json( + msg="There is more than one service '%s'" % (name)) + elif len(_result["result"]) == 1: + _res = _result["result"][0] + certs = _res.get("usercertificate") + if certs is not None: + _res["usercertificate"] = [encode_certificate(cert) for + cert in certs] + return _res + else: + return None + + +def gen_args(pac_type, auth_ind, skip_host_check, force, requires_pre_auth, + ok_as_delegate, ok_to_auth_as_delegate): + _args = {} + + if pac_type is not None: + _args['ipakrbauthzdata'] = pac_type + if auth_ind is not None: + _args['krbprincipalauthind'] = auth_ind + if skip_host_check is not None: + _args['skip_host_check'] = (skip_host_check) + if force is not None: + _args['force'] = (force) + if requires_pre_auth is not None: + _args['ipakrbrequirespreauth'] = (requires_pre_auth) + if ok_as_delegate is not None: + _args['ipakrbokasdelegate'] = (ok_as_delegate) + if ok_to_auth_as_delegate is not None: + _args['ipakrboktoauthasdelegate'] = (ok_to_auth_as_delegate) + + return _args + + +def check_parameters(module, state, action, names, parameters): + assert isinstance(parameters, dict) + + # invalid parameters for everything but state 'present', action 'service'. + invalid = ['pac_type', 'auth_ind', 'skip_host_check', + 'force', 'requires_pre_auth', 'ok_as_delegate', + 'ok_to_auth_as_delegate'] + + # invalid parameters when not handling service members. + invalid_not_member = \ + ['principal', 'certificate', 'host', 'allow_create_keytab_user', + 'allow_create_keytab_group', 'allow_create_keytab_host', + 'allow_create_keytab_hostgroup', 'allow_retrieve_keytab_user', + 'allow_retrieve_keytab_group', 'allow_retrieve_keytab_host', + 'allow_retrieve_keytab_hostgroup'] + + if state == 'present': + if len(names) != 1: + module.fail_json(msg="Only one service can be added at a time.") + + if action == 'service': + invalid = [] + + elif state == 'absent': + if len(names) < 1: + module.fail_json(msg="No name given.") + + if action == "service": + invalid.extend(invalid_not_member) + + elif state == 'disabled': + invalid.extend(invalid_not_member) + if action != "service": + module.fail_json( + msg="Invalid action '%s' for state '%s'" % (action, state)) + + else: + module.fail_json(msg="Invalid state '%s'" % (state)) + + for _invalid in invalid: + if parameters[_invalid] is not None: + module.fail_json( + msg="Argument '%s' can not be used with state '%s'" % + (_invalid, state)) + + +def init_ansible_module(): + ansible_module = AnsibleModule( + argument_spec=dict( + # general + ipaadmin_principal=dict(type="str", default="admin"), + ipaadmin_password=dict(type="str", required=False, no_log=True), + + name=dict(type="list", aliases=["service"], default=None, + required=True), + # service attributesstr + certificate=dict(type="list", aliases=['usercertificate'], + default=None, required=False), + principal=dict(type="list", aliases=["krbprincipalname"], + default=None), + pac_type=dict(type="list", aliases=["ipakrbauthzdata"], + choices=["MS-PAC", "PAD", "NONE"]), + auth_ind=dict(type="str", + aliases=["krbprincipalauthind"], + choices=["otp", "radius", "pkinit", "hardened"]), + skip_host_check=dict(type="bool"), + force=dict(type="bool"), + requires_pre_auth=dict( + type="bool", aliases=["ipakrbrequirespreauth"]), + ok_as_delegate=dict(type="bool", aliases=["ipakrbokasdelegate"]), + ok_to_auth_as_delegate=dict(type="bool", + aliases=["ipakrboktoauthasdelegate"]), + host=dict(type="list", aliases=["managedby_host"], required=False), + allow_create_keytab_user=dict( + type="list", required=False, + aliases=['ipaallowedtoperform_write_keys_user']), + allow_retrieve_keytab_user=dict( + type="list", required=False, + aliases=['ipaallowedtoperform_read_keys_user']), + allow_create_keytab_group=dict( + type="list", required=False, + aliases=['ipaallowedtoperform_write_keys_group']), + allow_retrieve_keytab_group=dict( + type="list", required=False, + aliases=['ipaallowedtoperform_read_keys_group']), + allow_create_keytab_host=dict( + type="list", required=False, + aliases=['ipaallowedtoperform_write_keys_host']), + allow_retrieve_keytab_host=dict( + type="list", required=False, + aliases=['ipaallowedtoperform_read_keys_host']), + allow_create_keytab_hostgroup=dict( + type="list", required=False, + aliases=['ipaallowedtoperform_write_keys_hostgroup']), + allow_retrieve_keytab_hostgroup=dict( + type="list", required=False, + aliases=['ipaallowedtoperform_read_keys_hostgroup']), + # action + action=dict(type="str", default="service", + choices=["member", "service"]), + # state + state=dict(type="str", default="present", + choices=["present", "absent", + "enabled", "disabled"]), + ), + supports_check_mode=True, + ) + + ansible_module._ansible_debug = True + + return ansible_module + + +def main(): + ansible_module = init_ansible_module() + + # Get parameters + + # general + ipaadmin_principal = module_params_get(ansible_module, + "ipaadmin_principal") + ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password") + names = module_params_get(ansible_module, "name") + + # service attributes + principal = module_params_get(ansible_module, "principal") + certificate = module_params_get(ansible_module, "certificate") + pac_type = module_params_get(ansible_module, "pac_type") + auth_ind = module_params_get(ansible_module, "auth_ind") + skip_host_check = module_params_get(ansible_module, "skip_host_check") + force = module_params_get(ansible_module, "force") + requires_pre_auth = module_params_get(ansible_module, "requires_pre_auth") + ok_as_delegate = module_params_get(ansible_module, "ok_as_delegate") + ok_to_auth_as_delegate = module_params_get(ansible_module, + "ok_to_auth_as_delegate") + + host = module_params_get(ansible_module, "host") + + allow_create_keytab_user = module_params_get( + ansible_module, "allow_create_keytab_user") + allow_create_keytab_group = module_params_get( + ansible_module, "allow_create_keytab_group") + allow_create_keytab_host = module_params_get( + ansible_module, "allow_create_keytab_host") + allow_create_keytab_hostgroup = module_params_get( + ansible_module, "allow_create_keytab_hostgroup") + + allow_retrieve_keytab_user = module_params_get( + ansible_module, "allow_retrieve_keytab_user") + allow_retrieve_keytab_group = module_params_get( + ansible_module, "allow_retrieve_keytab_group") + allow_retrieve_keytab_host = module_params_get( + ansible_module, "allow_create_keytab_host") + allow_retrieve_keytab_hostgroup = module_params_get( + ansible_module, "allow_retrieve_keytab_hostgroup") + + # action + action = module_params_get(ansible_module, "action") + # state + state = module_params_get(ansible_module, "state") + + # check parameters + check_parameters(ansible_module, state, action, names, vars()) + + # Init + + changed = False + exit_args = {} + ccache_dir = None + ccache_name = None + try: + if not valid_creds(ansible_module, ipaadmin_principal): + ccache_dir, ccache_name = temp_kinit(ipaadmin_principal, + ipaadmin_password) + api_connect() + + has_skip_host_check = api_check_param( + "service_add", "skip_host_check") + if skip_host_check and not has_skip_host_check: + ansible_module.fail_json( + msg="Skipping host check is not supported by your IPA version") + + commands = [] + + for name in names: + res_find = find_service(ansible_module, name) + + if state == "present": + if action == "service": + args = gen_args( + pac_type, auth_ind, skip_host_check, force, + requires_pre_auth, ok_as_delegate, + ok_to_auth_as_delegate) + if not has_skip_host_check and 'skip_host_check' in args: + del args['skip_host_check'] + + if res_find is None: + commands.append([name, 'service_add', args]) + + certificate_add = certificate or [] + certificate_del = [] + host_add = host or [] + host_del = [] + principal_add = principal or [] + principal_del = [] + allow_create_keytab_user_add = \ + allow_create_keytab_user or [] + allow_create_keytab_user_del = [] + allow_create_keytab_group_add = \ + allow_create_keytab_group or [] + allow_create_keytab_group_del = [] + allow_create_keytab_host_add = \ + allow_create_keytab_host or [] + allow_create_keytab_host_del = [] + allow_create_keytab_hostgroup_add = \ + allow_create_keytab_hostgroup or [] + allow_create_keytab_hostgroup_del = [] + allow_retrieve_keytab_user_add = \ + allow_retrieve_keytab_user or [] + allow_retrieve_keytab_user_del = [] + allow_retrieve_keytab_group_add = \ + allow_retrieve_keytab_group or [] + allow_retrieve_keytab_group_del = [] + allow_retrieve_keytab_host_add = \ + allow_retrieve_keytab_host or [] + allow_retrieve_keytab_host_del = [] + allow_retrieve_keytab_hostgroup_add = \ + allow_retrieve_keytab_hostgroup or [] + allow_retrieve_keytab_hostgroup_del = [] + + else: + for remove in ['skip_host_check', 'force']: + if remove in args: + del args[remove] + + if not compare_args_ipa(ansible_module, args, + res_find): + commands.append([name, "service_mod", args]) + + certificate_add, certificate_del = gen_add_del_lists( + certificate, res_find.get("usercertificate")) + + host_add, host_del = gen_add_del_lists( + host, res_find.get('managedby_host', [])) + + principal_add, principal_del = gen_add_del_lists( + principal, res_find.get("principal")) + + (allow_create_keytab_user_add, + allow_create_keytab_user_del) = \ + gen_add_del_lists( + allow_create_keytab_user, res_find.get( + 'ipaallowedtoperform_write_keys_user', + [])) + (allow_retrieve_keytab_user_add, + allow_retrieve_keytab_user_del) = \ + gen_add_del_lists( + allow_retrieve_keytab_user, res_find.get( + 'ipaallowedtoperform_read_keys_user', + [])) + (allow_create_keytab_group_add, + allow_create_keytab_group_del) = \ + gen_add_del_lists( + allow_create_keytab_group, res_find.get( + 'ipaallowedtoperform_write_keys_group', + [])) + (allow_retrieve_keytab_group_add, + allow_retrieve_keytab_group_del) = \ + gen_add_del_lists( + allow_retrieve_keytab_group, + res_find.get( + 'ipaallowedtoperform_read_keys_group', + [])) + (allow_create_keytab_host_add, + allow_create_keytab_host_del) = \ + gen_add_del_lists( + allow_create_keytab_host, + res_find.get( + 'ipaallowedtoperform_write_keys_host', + [])) + (allow_retrieve_keytab_host_add, + allow_retrieve_keytab_host_del) = \ + gen_add_del_lists( + allow_retrieve_keytab_host, + res_find.get( + 'ipaallowedtoperform_read_keys_host', + [])) + (allow_create_keytab_hostgroup_add, + allow_create_keytab_hostgroup_del) = \ + gen_add_del_lists( + allow_create_keytab_hostgroup, + res_find.get( + 'ipaallowedtoperform_write_keys_hostgroup', + [])) + (allow_retrieve_keytab_hostgroup_add, + allow_retrieve_keytab_hostgroup_del) = \ + gen_add_del_lists( + allow_retrieve_keytab_hostgroup, + res_find.get( + 'ipaallowedtoperform_read_keys_hostgroup', + [])) + + elif action == "member": + if res_find is None: + ansible_module.fail_json(msg="No service '%s'" % name) + + existing = res_find.get('usercertificate', []) + if certificate is None: + certificate_add = [] + else: + certificate_add = [c for c in certificate + if c not in existing] + certificate_del = [] + host_add = host or [] + host_del = [] + principal_add = principal or [] + principal_del = [] + + allow_create_keytab_user_add = \ + allow_create_keytab_user or [] + allow_create_keytab_user_del = [] + allow_create_keytab_group_add = \ + allow_create_keytab_group or [] + allow_create_keytab_group_del = [] + allow_create_keytab_host_add = \ + allow_create_keytab_host or [] + allow_create_keytab_host_del = [] + allow_create_keytab_hostgroup_add = \ + allow_create_keytab_hostgroup or [] + allow_create_keytab_hostgroup_del = [] + allow_retrieve_keytab_user_add = \ + allow_retrieve_keytab_user or [] + allow_retrieve_keytab_user_del = [] + allow_retrieve_keytab_group_add = \ + allow_retrieve_keytab_group or [] + allow_retrieve_keytab_group_del = [] + allow_retrieve_keytab_host_add = \ + allow_retrieve_keytab_host or [] + allow_retrieve_keytab_host_del = [] + allow_retrieve_keytab_hostgroup_add = \ + allow_retrieve_keytab_hostgroup or [] + allow_retrieve_keytab_hostgroup_del = [] + + # Add principals + for _principal in principal_add: + commands.append([name, "service_add_principal", + { + "krbprincipalname": + _principal, + }]) + + # Remove principals + for _principal in principal_del: + commands.append([name, "service_remove_principal", + { + "krbprincipalname": + _principal, + }]) + + for _certificate in certificate_add: + commands.append([name, "service_add_cert", + { + "usercertificate": + _certificate, + }]) + # Remove certificates + for _certificate in certificate_del: + commands.append([name, "service_remove_cert", + { + "usercertificate": + _certificate, + }]) + + # Add hosts. + if host is not None and len(host) > 0 and len(host_add) > 0: + commands.append([name, "service_add_host", + {"host": host_add}]) + # Remove hosts + if host is not None and len(host) > 0 and len(host_del) > 0: + commands.append([name, "service_remove_host", + {"host": host_del}]) + + # Allow create keytab + if len(allow_create_keytab_user_add) > 0 or \ + len(allow_create_keytab_group_add) > 0 or \ + len(allow_create_keytab_host_add) > 0 or \ + len(allow_create_keytab_hostgroup_add) > 0: + commands.append( + [name, "service_allow_create_keytab", + {'user': allow_create_keytab_user_add, + 'group': allow_create_keytab_group_add, + 'host': allow_create_keytab_host_add, + 'hostgroup': allow_create_keytab_hostgroup_add + }]) + + # Disallow create keytab + if len(allow_create_keytab_user_del) > 0 or \ + len(allow_create_keytab_group_del) > 0 or \ + len(allow_create_keytab_host_del) > 0 or \ + len(allow_create_keytab_hostgroup_del) > 0: + commands.append( + [name, "service_disallow_create_keytab", + {'user': allow_create_keytab_user_del, + 'group': allow_create_keytab_group_del, + 'host': allow_create_keytab_host_del, + 'hostgroup': allow_create_keytab_hostgroup_del + }]) + + # Allow retrieve keytab + if len(allow_retrieve_keytab_user_add) > 0 or \ + len(allow_retrieve_keytab_group_add) > 0 or \ + len(allow_retrieve_keytab_hostgroup_add) > 0 or \ + len(allow_retrieve_keytab_hostgroup_add) > 0: + commands.append( + [name, "service_allow_retrieve_keytab", + {'user': allow_retrieve_keytab_user_add, + 'group': allow_retrieve_keytab_group_add, + 'host': allow_retrieve_keytab_host_add, + 'hostgroup': allow_retrieve_keytab_hostgroup_add + }]) + + # Disllow retrieve keytab + if len(allow_retrieve_keytab_user_del) > 0 or \ + len(allow_retrieve_keytab_group_del) > 0 or \ + len(allow_retrieve_keytab_host_del) > 0 or \ + len(allow_retrieve_keytab_hostgroup_del) > 0: + commands.append( + [name, "service_disallow_retrieve_keytab", + {'user': allow_retrieve_keytab_user_del, + 'group': allow_retrieve_keytab_group_del, + 'host': allow_retrieve_keytab_host_del, + 'hostgroup': allow_retrieve_keytab_hostgroup_del + }]) + + elif state == "absent": + if action == "service": + if res_find is not None: + commands.append([name, 'service_del', {}]) + + elif action == "member": + if res_find is None: + ansible_module.fail_json(msg="No service '%s'" % name) + + # Remove principals + if principal is not None: + for _principal in principal: + commands.append([name, "service_remove_principal", + { + "krbprincipalname": + _principal, + }]) + # Remove certificates + if certificate is not None: + existing = res_find.get('usercertificate', []) + for _certificate in certificate: + if _certificate in existing: + commands.append([name, "service_remove_cert", + { + "usercertificate": + _certificate, + }]) + + # Add hosts + if host is not None: + commands.append( + [name, "service_remove_host", {"host": host}]) + + # Allow create keytab + if allow_create_keytab_user is not None or \ + allow_create_keytab_group is not None or \ + allow_create_keytab_host is not None or \ + allow_create_keytab_hostgroup is not None: + commands.append( + [name, "service_disallow_create_keytab", + {'user': allow_create_keytab_user, + 'group': allow_create_keytab_group, + 'host': allow_create_keytab_host, + 'hostgroup': allow_create_keytab_hostgroup + }]) + + # Allow retriev keytab + if allow_retrieve_keytab_user is not None or \ + allow_retrieve_keytab_group is not None or \ + allow_retrieve_keytab_host is not None or \ + allow_retrieve_keytab_hostgroup is not None: + commands.append( + [name, "service_disallow_retrieve_keytab", + {'user': allow_retrieve_keytab_user, + 'group': allow_retrieve_keytab_group, + 'host': allow_retrieve_keytab_host, + 'hostgroup': allow_retrieve_keytab_hostgroup + }]) + + elif state == "disabled": + if action == "service": + if res_find is not None and \ + len(res_find.get('usercertificate', [])) > 0: + commands.append([name, 'service_disable', {}]) + else: + ansible_module.fail_json( + msg="Invalid action '%s' for state '%s'" % + (action, state)) + else: + ansible_module.fail_json(msg="Unkown state '%s'" % state) + + # Execute commands + errors = [] + for name, command, args in commands: + try: + result = api_command(ansible_module, command, name, args) + + if "completed" in result: + if result["completed"] > 0: + changed = True + else: + changed = True + except Exception as ex: + ansible_module.fail_json(msg="%s: %s: %s" % (command, name, + str(ex))) + # Get all errors + # All "already a member" and "not a member" failures in the + # result are ignored. All others are reported. + if "failed" in result and len(result["failed"]) > 0: + for item in result["failed"]: + failed_item = result["failed"][item] + for member_type in failed_item: + for member, failure in failed_item[member_type]: + if "already a member" in failure \ + or "not a member" in failure: + continue + errors.append("%s: %s %s: %s" % ( + command, member_type, member, failure)) + if len(errors) > 0: + ansible_module.fail_json(msg=", ".join(errors)) + + except Exception as ex: + ansible_module.fail_json(msg=str(ex)) + + finally: + temp_kdestroy(ccache_dir, ccache_name) + + # Done + ansible_module.exit_json(changed=changed, **exit_args) + + +if __name__ == "__main__": + main() diff --git a/tests/service/certificate/cert1.der b/tests/service/certificate/cert1.der new file mode 100644 index 0000000000000000000000000000000000000000..b1b90efde6d33ab44ca7b62941eee06fdbc05da9 Binary files /dev/null and b/tests/service/certificate/cert1.der differ diff --git a/tests/service/certificate/cert1.pem b/tests/service/certificate/cert1.pem new file mode 100644 index 0000000000000000000000000000000000000000..ab3704bba5957ba125762cfb3b5b11b1067b20a8 --- /dev/null +++ b/tests/service/certificate/cert1.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQEL +BQAwDzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQx +MDhaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC+XVVGFYpHVkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk ++OfEkzLUAhWBOwEraELJzMLJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa +8KvgRVRyGLoVvGbLJvmjfMXp0nIToTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0am +nvsgparYXhypHaRLnikn0vQINt55YoEd1s4KrvEcD2VdZkIMPbLRu2zFvMprF3cj +QQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpcxj9aGUVt5bsq1D+Tzj3GsidS +X0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1UdDgQWBBRV0j7JYuku +H/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+QeNlRLXDlEDAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs5y1Zp0 +WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqic +uPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkG +wIt1OH2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyE +iaio3693l6noobyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj +9uKQ5GTWRh59VnRBVC/SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV +7MVq +-----END CERTIFICATE----- diff --git a/tests/service/certificate/cert2.der b/tests/service/certificate/cert2.der new file mode 100644 index 0000000000000000000000000000000000000000..e176c2ba50270b331c457e784dea5f5f6a09e53a Binary files /dev/null and b/tests/service/certificate/cert2.der differ diff --git a/tests/service/certificate/cert2.pem b/tests/service/certificate/cert2.pem new file mode 100644 index 0000000000000000000000000000000000000000..e8ea2e434b79dd142b7531c03ab105ddd2d5d5fd --- /dev/null +++ b/tests/service/certificate/cert2.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIURhps6LEteMDCdBrlVkWe4cgSh0YwDQYJKoZIhvcNAQEL +BQAwDzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQyNDBaFw0zMDAyMDExNDQy +NDBaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC4W56H0VraEKGlCxSTS2PqnaD11shMjruexmholmTEtYPePPnQHpwiiZlg +K7CPBIOdCn4hHH+hXQDg/TJRMjrde1VzD0pFRBUq6H25sy8oOlfD0bDXkncWn82S +OJu2UJHeL7htQLRxW14VIAO2YO9zaXdophy6/csTAkFq1ls/vTBp73pnnYp8D7Tg +zBB6bb95OZBSHeCzPIH2FSCJ/W0j6bHw4i7uHu/jWx0o0LR152fSFFwk0Wrmp8HH +b2083OlnSBgTM+BZDg9rB7jpLCsIGHWXbjG36jmRaZu5z4vq2FNomJ8PXkX7mwUf +aft6z+px7UlhrwUxEVWIXOoUBYcJAgMBAAGjUzBRMB0GA1UdDgQWBBTttCQn5UaQ +i+N5WRnA7ZTQlkVfRTAfBgNVHSMEGDAWgBTttCQn5UaQi+N5WRnA7ZTQlkVfRTAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBW3vRR5wEDztuLVrcQ +Dojn1XB24OOqn4C6OJyz3FUxd4MQA8J2vKN4P2QXhY0oYsauFKhR5xfOaDUcK2Tu +kAtFz1mxqm1ygUVQHbrs8lBeIi4hoMc76ODJ/V9GNY7N/y/5xtD7XlyTVT2tb6tc +6tmv8e4497PTPspuHp9YbbvzdSI12JENDW4hKCOpR/Uv7mRcCT+c2iMJdUL3f3YO +FsGBbxVdTPmuhL4My8qR/CtCNpN0gBsaxUKFAP+/1AvFbFDChFVDEEdD8PLznH5x +8HLmA9/K5x/cXbgqESUqK13P53f1XYOfggKb1f7yqBAZRnTY82+k9Kn9qWOcnyxS +uUtZ +-----END CERTIFICATE----- diff --git a/tests/service/certificate/private1.key b/tests/service/certificate/private1.key new file mode 100644 index 0000000000000000000000000000000000000000..372908d226ff4d711846f4a4097d8059437b0388 --- /dev/null +++ b/tests/service/certificate/private1.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC+XVVGFYpHVkcD +fVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJ +zMLJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmj +fMXp0nIToTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn +0vQINt55YoEd1s4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQW +AnAsu7OJEkNF+E4Mkmpcxj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63 +g5cZyE+nAgMBAAECggEBALJIsw5aKhE5inSIN0xZT3FTWxcjHF26jE+X86G0H3KZ +roLqnjOagOKTwjeErXt66IWKFh3b5vKCSNq6PEs8OCeRHv71bay5zK1WWLH87sKJ +EAUSPuK5O6donI9aC36VL8tTwSOOOS9WJ0KoHqsn/tLHlONXOvo063iYEg8xFhuP +etrOf2gDjwGbeWis7VeHG7wL5p2/WdsyjTDbQPhmUlBO93rtkBlm9FaqYKwrp8qe +4c5gf6ZAKgY2EZaQuEvq3Lonk7TRCtPDVCPLYQxZGOmn2UeUS+HMnDSqrlQesBKD +hNNCCJVaQZHsghmwXa8t9yRBIxoOqVObdEQYJ8wuxMECgYEA676x3m7T2PwJXS+q +Km3snv60lCozxKbzaNJ1xlAmpW08MijYCkDS/kWSIwN5GO+b5B6use8iALrV9SyP +eC/6bFuMJ+zRfGhn1cw4Ibz79EroTxmJio7J7SiD/yxvjNVznKx5xgQeB9tdgjaf +yHSxInWoQzcDGKUe2h2KFJxUzJECgYEAzrh6zI8Ugne5iBUbLcpJUehlMd4+RM0l +1y8ZOBS1tjzimWycjZaPtMB0q4FOc1ou2zcSxwoGIv5khvUsjKhTfOc6lK+cHPhE +fAppYUxhHw2UDpX/0hKDuDu++O+86ANp7AOvM+KcNAiEoovxUyurVjBsT/PPlrTA +r5w7xuyi1LcCgYAZ7ZdSh431R4MgJKXqlLx5oDnsMdgPwOz0knExpo8ZkrIUMjnQ +puCN5sjz4OXowDG9HULJfyuWOPZfSM9ewKgiUs9PdNR1gmYpNZTW4Ro0/CggywY9 +nwbGdrZN0m1SaAeXK8EY7kr/Qjk+oRNh0LPKvnYLLnnAtCh4hNcy/R62gQKBgBaD +3UweYVt8csaxlc489BNpvmvaCuovdemkBZkoGEqLAxs2yy5Ysbo8I/jyEntZ3TSf +IPpwyw5Qqt5QIdQIGV/HR4geQGCfYcYo1CV2zjU1o2SbTcuxnIsaZshyRB75EDZW +iGScT+sS6m9R0qz+WqD+kS18HqYJddsqpxAZgfqtAoGBAJx7E8HxFpaNfz/QQPAQ +mvON6ub5u4AfhH4DgiPErMxNsdzVICL+mnQy0wdmi1oEpq9KH4/8aSxdPhadyl/8 +l+0CkCkBZvEP7+NmctR8Zot60wS0DnOwuURCxm/zYJ26DXjB0XitDDumFJ56Wd6p +uLl9eKMBE/jBsCSWQTuwrtnT +-----END PRIVATE KEY----- diff --git a/tests/service/certificate/private2.key b/tests/service/certificate/private2.key new file mode 100644 index 0000000000000000000000000000000000000000..58909dbf5990ff703c7d70395edb0899ce90fb3d --- /dev/null +++ b/tests/service/certificate/private2.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC4W56H0VraEKGl +CxSTS2PqnaD11shMjruexmholmTEtYPePPnQHpwiiZlgK7CPBIOdCn4hHH+hXQDg +/TJRMjrde1VzD0pFRBUq6H25sy8oOlfD0bDXkncWn82SOJu2UJHeL7htQLRxW14V +IAO2YO9zaXdophy6/csTAkFq1ls/vTBp73pnnYp8D7TgzBB6bb95OZBSHeCzPIH2 +FSCJ/W0j6bHw4i7uHu/jWx0o0LR152fSFFwk0Wrmp8HHb2083OlnSBgTM+BZDg9r +B7jpLCsIGHWXbjG36jmRaZu5z4vq2FNomJ8PXkX7mwUfaft6z+px7UlhrwUxEVWI +XOoUBYcJAgMBAAECggEAPTBrlbiu5uHORPFAiwLizuQyoGYBZSearkA8Nzpzh7aX +ZhPm9mSyfeQdvAXEPDPLWzw4UNUcp3ou6H4hTUHWt9xPqDjS9dp7DBrOX+xRIpD6 +wEvA3kwGqsOvf3C6ffCP+abtF5X6TgV9XJWbpdTWpP/EWj+IGahS1qRRAhzTfHvF +YGMTFwlgbz4eOs+FXBnVNGsdsdMLpOyqHMdDAA4BhyspWHyHgCRjEjROuJCKSDUR +MD1pNdaEYzoj5QeE1IKzXAzTaxG/YKd36BxV5Cp9DOBuZZLgNEd2EisXxV7UwZL4 +leGgxAc+KQs6QoPoz+mrKbdDnxe6V+uaa9KHoqnj4QKBgQD1qh+MEIF+Vuf/keFJ +vDgS7oFeg1UGzMtWypiNfVYu9cBLp32tgY48+ey3OCvhRSJAVROH1rc5ZfkESSQ2 +rSeV/T3plr5bBkLc7chuDM8An745p8VSOM+Ak1zE2qb+Qo+IsxNRA9KyeUvupuB8 +HJ7fxdZ7JpgueD/mKyCn1WaGIwKBgQDAHTS6J7LKm52d2norERK6ZyBNVhKaKNDW +ssRqSh906oFU63Qijsp4dbm1iRXGME6Zoe1quN/K80iATdv/VzjzxS1Of8mqA7gr +/2juZbpEluSxjkqPAZp1p4Kx9WURdzv2ModkYwM3zSTGR5l22Whd9QdNQvVl1mf0 ++RfgE6ty4wKBgA+GtwO1L1n6yCLg52ovmSOpK0f76O3LF7beixG2MDI7mfGuHkVP +ANxdt1ZFGJDeO7HxLpDRQzc/eKOKs904yF20aatPuawrEyK/bIF4EcUqU211awUt +TgAEUEKoxxEex8+N8dSW90QMYn4s0ddGP8xIxqt13vxg4Tj81M2GsTodAoGAOa8L +S/Hrj0ZWdzVIhXHk669XVaFIiJ1Ex5J5w2hqNZLMLpFcF5xEUxMWJdn5fb63ew3R +2b+VAr01wcCfE/Y+lYNY7T8VcEUZoaxY92v4F+wu0tlkrbfPhxA6//As3qesi2n0 +mUHZj4G7TwXkoHj7C2stPBek02UjZbz9XDzLt/0CgYAiawpqmHJK4LhRm+P6J1+X +nzLPzQ6t15ivh4jPrWZPgOG3hKV+If+PTv7lLy51y2X4Ttuyumy09J+kYiy3qIHR +nmbAEkc9lesrxk1eytxmYY+fGTBpaLAc+vNXWCtUc1ttKcfrPhZdncmSh5Z0aFN3 +D+EddEZHzfzoGlfbNVkfmQ== +-----END PRIVATE KEY----- diff --git a/tests/service/certificate/test_service_certificate.yml b/tests/service/certificate/test_service_certificate.yml new file mode 100644 index 0000000000000000000000000000000000000000..89c46f10e69aecf419e354cd68bc995c54604d4e --- /dev/null +++ b/tests/service/certificate/test_service_certificate.yml @@ -0,0 +1,225 @@ +# +# Generate self-signed certificates using openssl: +# +# openssl req -x509 -newkey rsa:2048 -days 3650 -nodes -keyout private1.key -out cert1.pem -subj '/CN=test' +# openssl req -x509 -newkey rsa:2048 -days 3650 -nodes -keyout private2.key -out cert2.pem -subj '/CN=test' +# +# Convert the certificate do DER for easier handling through CLI +# +# openssl x509 -outform der -in cert1.pem -out cert1.der +# openssl x509 -outform der -in cert2.pem -out cert2.der +# +# Use base64: +# +# base64 cert1.der -w5000 +# base64 cert2.der -w5000 +# +# Certificates: +# cert1: +# - MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpHVkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJzMLJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmjfMXp0nIToTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn0vQINt55YoEd1s4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpcxj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1UdDgQWBBRV0j7JYukuH/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+QeNlRLXDlEDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs5y1Zp0WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqicuPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkGwIt1OH2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyEiaio3693l6noobyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj9uKQ5GTWRh59VnRBVC/SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV7MVq +# cert2: +# - MIIC/zCCAeegAwIBAgIURhps6LEteMDCdBrlVkWe4cgSh0YwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQyNDBaFw0zMDAyMDExNDQyNDBaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4W56H0VraEKGlCxSTS2PqnaD11shMjruexmholmTEtYPePPnQHpwiiZlgK7CPBIOdCn4hHH+hXQDg/TJRMjrde1VzD0pFRBUq6H25sy8oOlfD0bDXkncWn82SOJu2UJHeL7htQLRxW14VIAO2YO9zaXdophy6/csTAkFq1ls/vTBp73pnnYp8D7TgzBB6bb95OZBSHeCzPIH2FSCJ/W0j6bHw4i7uHu/jWx0o0LR152fSFFwk0Wrmp8HHb2083OlnSBgTM+BZDg9rB7jpLCsIGHWXbjG36jmRaZu5z4vq2FNomJ8PXkX7mwUfaft6z+px7UlhrwUxEVWIXOoUBYcJAgMBAAGjUzBRMB0GA1UdDgQWBBTttCQn5UaQi+N5WRnA7ZTQlkVfRTAfBgNVHSMEGDAWgBTttCQn5UaQi+N5WRnA7ZTQlkVfRTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBW3vRR5wEDztuLVrcQDojn1XB24OOqn4C6OJyz3FUxd4MQA8J2vKN4P2QXhY0oYsauFKhR5xfOaDUcK2TukAtFz1mxqm1ygUVQHbrs8lBeIi4hoMc76ODJ/V9GNY7N/y/5xtD7XlyTVT2tb6tc6tmv8e4497PTPspuHp9YbbvzdSI12JENDW4hKCOpR/Uv7mRcCT+c2iMJdUL3f3YOFsGBbxVdTPmuhL4My8qR/CtCNpN0gBsaxUKFAP+/1AvFbFDChFVDEEdD8PLznH5x8HLmA9/K5x/cXbgqESUqK13P53f1XYOfggKb1f7yqBAZRnTY82+k9Kn9qWOcnyxSuUtZ + +--- +- name: Test service certificates + hosts: ipaserver + become: true + + tasks: + # setup + - name: Get Domain from server name + set_fact: + ipaserver_domain: "{{ groups.ipaserver[0].split('.')[1:] | join ('.') }}" + when: ipaserver_domain is not defined + + - name: Get IPv4 address prefix from server node + set_fact: + ipv4_prefix: "{{ ansible_default_ipv4.address.split('.')[:-1] | + join('.') }}" + + - name: Set test host FQDN + set_fact: + test_subdomain: testcert + test_host: "{{ 'testcert.' + ipaserver_domain }}" + + - name: Host test absent + ipahost: + ipaadmin_password: SomeADMINpassword + name: "{{ test_host }}" + update_dns: yes + state: absent + + - name: Host test present + ipahost: + ipaadmin_password: SomeADMINpassword + name: "{{ test_host }}" + ip_address: "{{ ipv4_prefix + '.201' }}" + update_dns: yes + + - name: Ensure testing group group01 is present. + ipagroup: + ipaadmin_password: SomeADMINpassword + name: group01 + + - name: Ensure testing group group02 is present. + ipagroup: + ipaadmin_password: SomeADMINpassword + name: group02 + + - name: Ensure services are absent. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + state: absent + + # tests + - name: Ensure service is present + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + certificate: + - MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpHVkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJzMLJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmjfMXp0nIToTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn0vQINt55YoEd1s4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpcxj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1UdDgQWBBRV0j7JYukuH/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+QeNlRLXDlEDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs5y1Zp0WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqicuPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkGwIt1OH2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyEiaio3693l6noobyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj9uKQ5GTWRh59VnRBVC/SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV7MVq + pac_type: + - MS-PAC + - PAD + auth_ind: otp + force: no + requires_pre_auth: yes + ok_as_delegate: no + ok_to_auth_as_delegate: no + register: result + failed_when: not result.changed + + - name: Ensure service is present, again + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + certificate: + - MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpHVkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJzMLJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmjfMXp0nIToTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn0vQINt55YoEd1s4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpcxj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1UdDgQWBBRV0j7JYukuH/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+QeNlRLXDlEDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs5y1Zp0WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqicuPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkGwIt1OH2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyEiaio3693l6noobyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj9uKQ5GTWRh59VnRBVC/SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV7MVq + pac_type: + - MS_PAC + - PAD + auth_ind: otp + force: no + requires_pre_auth: yes + ok_as_delegate: no + ok_to_auth_as_delegate: no + register: result + failed_when: result.changed + + - name: Ensure service is disabled + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + state: disabled + register: result + failed_when: not result.changed + + - name: Ensure service member certificate is present. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + certificate: + - MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpHVkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJzMLJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmjfMXp0nIToTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn0vQINt55YoEd1s4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpcxj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1UdDgQWBBRV0j7JYukuH/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+QeNlRLXDlEDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs5y1Zp0WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqicuPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkGwIt1OH2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyEiaio3693l6noobyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj9uKQ5GTWRh59VnRBVC/SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV7MVq + action: member + state: present + register: result + failed_when: not result.changed + + - name: Ensure service member certificate is present, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + certificate: + - MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpHVkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJzMLJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmjfMXp0nIToTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn0vQINt55YoEd1s4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpcxj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1UdDgQWBBRV0j7JYukuH/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+QeNlRLXDlEDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs5y1Zp0WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqicuPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkGwIt1OH2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyEiaio3693l6noobyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj9uKQ5GTWRh59VnRBVC/SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV7MVq + action: member + state: present + register: result + failed_when: result.changed + + - name: Ensure service multiple member certificates are present, with duplicate. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + certificate: + - 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 + action: member + state: present + register: result + failed_when: not result.changed + + - name: Ensure service member certificate is absent. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + certificate: + - MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpHVkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJzMLJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmjfMXp0nIToTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn0vQINt55YoEd1s4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpcxj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1UdDgQWBBRV0j7JYukuH/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+QeNlRLXDlEDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs5y1Zp0WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqicuPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkGwIt1OH2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyEiaio3693l6noobyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj9uKQ5GTWRh59VnRBVC/SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV7MVq + action: member + state: absent + register: result + failed_when: not result.changed + + - name: Ensure service member certificate is absent, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + certificate: + - MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpHVkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJzMLJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmjfMXp0nIToTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn0vQINt55YoEd1s4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpcxj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1UdDgQWBBRV0j7JYukuH/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+QeNlRLXDlEDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs5y1Zp0WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqicuPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkGwIt1OH2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyEiaio3693l6noobyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj9uKQ5GTWRh59VnRBVC/SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV7MVq + action: member + state: absent + register: result + failed_when: result.changed + + - name: Ensure service member certificates are absent. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + certificate: + - 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 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: Ensure service multiple member certificates is present. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + certificate: + - MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpHVkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJzMLJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmjfMXp0nIToTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn0vQINt55YoEd1s4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpcxj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1UdDgQWBBRV0j7JYukuH/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+QeNlRLXDlEDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs5y1Zp0WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqicuPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkGwIt1OH2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyEiaio3693l6noobyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj9uKQ5GTWRh59VnRBVC/SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV7MVq + action: member + state: present + register: result + failed_when: not result.changed + + - name: Ensure service is disabled + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + state: disabled + register: result + failed_when: not result.changed + + - name: Ensure service is disabled, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + state: disabled + register: result + failed_when: result.changed + + # cleanup + - name: Ensure services are absent. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ test_host }}" + state: absent + + - name: Ensure host is absent + ipahost: + ipaadmin_password: SomeADMINpassword + name: "{{ test_host }}" + update_dns: yes + state: absent diff --git a/tests/service/test_service.yml b/tests/service/test_service.yml new file mode 100644 index 0000000000000000000000000000000000000000..10d1285a372402de92a0660914fc7ac29bad0fed --- /dev/null +++ b/tests/service/test_service.yml @@ -0,0 +1,536 @@ +# This test uses skip_host_check, so it will fail if not using +# FreeIPA version 4.7.0 or later. +# +# To test against earlier versions, use test_without_skip_host_check.yml. +# +# This test define 6 hosts: +# - www.ansible.com: a host with a DNS setup (external), not present in IPA +# - no.idontexist.info: a host without DNS and not present in IPA. +# - svc.ihavenodns.inf: a host without DNS, but present in IPA. +# - svc_fqdn: a host with DNS and present in IPA. +# - host1_fqdn and host2_fqdn: used for member actions only. +# +--- +- name: Test service + hosts: ipaserver + become: yes + + tasks: + # setup + - name: Get Domain from server name + set_fact: + ipaserver_domain: "{{ groups.ipaserver[0].split('.')[1:] | join ('.') }}" + when: ipaserver_domain is not defined + + - name: Set host1, host2 and svc hosts fqdn + set_fact: + host1_fqdn: "{{ 'host1.' + ipaserver_domain }}" + host2_fqdn: "{{ 'host2.' + ipaserver_domain }}" + svc_fqdn: "{{ 'svc.' + ipaserver_domain }}" + + - name: Host absent + ipahost: + ipaadmin_password: SomeADMINpassword + name: + - www.ansible.com + - no.idontexist.info + - svc.ihavenodns.info + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + - "{{ svc_fqdn }}" + update_dns: no + state: absent + + - name: Get IPv4 address prefix from server node + set_fact: + ipv4_prefix: "{{ ansible_default_ipv4.address.split('.')[:-1] | + join('.') }}" + + - name: Add hosts for tests. + ipahost: + ipaadmin_password: SomeADMINpassword + hosts: + - name: "{{ host1_fqdn }}" + force: yes + - name: "{{ host2_fqdn }}" + force: yes + - name: "{{ svc_fqdn }}" + ip_address: "{{ ipv4_prefix + '.201' }}" + - name: svc.ihavenodns.info + force: yes + + - name: Ensure testing user user01 is present. + ipauser: + ipaadmin_password: SomeADMINpassword + name: user01 + first: user01 + last: last + + - name: Ensure testing user user02 is present. + ipauser: + ipaadmin_password: SomeADMINpassword + name: user02 + first: user02 + last: last + + - name: Ensure testing group group01 is present. + ipagroup: + ipaadmin_password: SomeADMINpassword + name: group01 + + - name: Ensure testing group group02 is present. + ipagroup: + ipaadmin_password: SomeADMINpassword + name: group02 + + - name: Ensure testing hostgroup hostgroup01 is present. + ipahostgroup: + ipaadmin_password: SomeADMINpassword + name: hostgroup01 + + - name: Ensure testing hostgroup hostgroup02 is present. + ipahostgroup: + ipaadmin_password: SomeADMINpassword + name: hostgroup02 + + - name: Ensure services are absent. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: + - "HTTP/{{ svc_fqdn }}" + - HTTP/www.ansible.com + - HTTP/svc.ihavenodns.info + - HTTP/no.idontexist.info + state: absent + + # tests + - name: Ensure service is present + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + pac_type: + - MS-PAC + - PAD + auth_ind: otp + skip_host_check: no + force: no + requires_pre_auth: yes + ok_as_delegate: no + ok_to_auth_as_delegate: no + register: result + failed_when: not result.changed + + - name: Ensure service is present, again + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + pac_type: + - MS_PAC + - PAD + auth_ind: otp + skip_host_check: no + force: no + requires_pre_auth: yes + ok_as_delegate: no + ok_to_auth_as_delegate: no + register: result + failed_when: result.changed + + - name: Modify service. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + pac_type: NONE + ok_as_delegate: yes + ok_to_auth_as_delegate: yes + register: result + failed_when: not result.changed + + - name: Modify service, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + pac_type: NONE + ok_as_delegate: yes + ok_to_auth_as_delegate: yes + register: result + failed_when: result.changed + + - name: Ensure service is present, without host object. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.ansible.com + skip_host_check: yes + register: result + failed_when: not result.changed + + - name: Ensure service is present, without host object, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/www.ansible.com + skip_host_check: yes + register: result + failed_when: result.changed + + - name: Ensure service is present, with host not in DNS. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/svc.ihavenodns.info + skip_host_check: no + force: yes + register: result + failed_when: not result.changed + + - name: Ensure service is present, with host not in DNS, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/svc.ihavenodns.info + skip_host_check: no + force: yes + register: result + failed_when: result.changed + + - name: Ensure service is present, whithout host object and with host not in DNS. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/no.idontexist.info + skip_host_check: yes + force: yes + register: result + failed_when: not result.changed + + - name: Ensure service is present, whithout host object and with host not in DNS, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/no.idontexist.info + skip_host_check: yes + force: yes + register: result + failed_when: result.changed + + - name: Principal host/test.example.com present in service. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + principal: + - host/test.example.com + action: member + register: result + failed_when: not result.changed + + - name: Principal host/test.example.com present in service, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + principal: + - host/test.example.com + action: member + register: result + failed_when: result.changed + + - name: Principal host/test.example.com absent in service. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + principal: + - host/test.example.com + action: member + state: absent + register: result + failed_when: not result.changed + + - name: Principal host/test.example.com absent in service, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + principal: + - host/test.example.com + action: member + state: absent + register: result + failed_when: result.changed + + - name: Ensure host can manage service. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + action: member + register: result + failed_when: not result.changed + + - name: Ensure host can manage service, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + host: "{{ host1_fqdn }}" + action: member + register: result + failed_when: result.changed + + - name: Ensure host cannot manage service. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + action: member + state: absent + register: result + failed_when: not result.changed + + - name: Ensure host cannot manage service, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + action: member + state: absent + register: result + failed_when: result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for users, groups, hosts and hostgroups. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_create_keytab_user: + - user01 + - user02 + allow_create_keytab_group: + - group01 + - group02 + allow_create_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_create_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + register: result + failed_when: not result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for users, groups, hosts and hostgroups, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_create_keytab_user: + - user01 + - user02 + allow_create_keytab_group: + - group01 + - group02 + allow_create_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_create_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + register: result + failed_when: result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for users, groups, hosts and hostgroups. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_create_keytab_user: + - user01 + - user02 + allow_create_keytab_group: + - group01 + - group02 + allow_create_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_create_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for users, groups, hosts and hostgroups, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_create_keytab_user: + - user01 + - user02 + allow_create_keytab_group: + - group01 + - group02 + allow_create_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_create_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + state: absent + register: result + failed_when: result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for users, groups, hosts and hostgroups + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_retrieve_keytab_user: + - user01 + - user02 + allow_retrieve_keytab_group: + - group01 + - group02 + allow_retrieve_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_retrieve_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + register: result + failed_when: not result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for users, groups, hosts and hostgroups, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_retrieve_keytab_user: + - user01 + - user02 + allow_retrieve_keytab_group: + - group01 + - group02 + allow_retrieve_keytab_host: + - "{{ host1_fqdn }}" + - host02.exampl "{{ groups.ipaserver[0] }}"e.com + allow_retrieve_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + register: result + failed_when: result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for users, groups, hosts and hostgroups. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_retrieve_keytab_user: + - user01 + - user02 + allow_retrieve_keytab_group: + - group01 + - group02 + allow_retrieve_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_retrieve_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for users, groups, hosts and hostgroups, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_retrieve_keytab_user: + - user01 + - user02 + allow_retrieve_keytab_group: + - group01 + - group02 + allow_retrieve_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_retrieve_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + state: absent + register: result + failed_when: result.changed + + # + - name: Ensure service is absent + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + state: absent + register: result + failed_when: not result.changed + + - name: Ensure service is absent, again + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + state: absent + register: result + failed_when: result.changed + + # cleanup + + - name: Ensure services are absent. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: + - "HTTP/{{ svc_fqdn }}" + - HTTP/www.ansible.com + - HTTP/svc.ihavenodns.info + - HTTP/no.idontexist.local + state: absent + + - name: Ensure host "{{ svc_fqdn }}" is absent + ipahost: + ipaadmin_password: SomeADMINpassword + name: "{{ svc_fqdn }}" + update_dns: yes + state: absent + + - name: Ensure host is absent + ipahost: + ipaadmin_password: SomeADMINpassword + name: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + - www.ansible.com + - svc.ihavenodns.info + update_dns: no + state: absent + + - name: Ensure testing users are absent. + ipauser: + ipaadmin_password: SomeADMINpassword + name: + - user01 + - user02 + state: absent + + - name: Ensure testing groups are absent. + ipagroup: + ipaadmin_password: SomeADMINpassword + name: + - group01 + - group02 + state: absent + + - name: Ensure testing hostgroup hostgroup01 is absent. + ipagroup: + ipaadmin_password: SomeADMINpassword + name: + - hostgroup01 + state: absent + + - name: Ensure testing hostgroup hostgroup02 is absent. + ipagroup: + ipaadmin_password: SomeADMINpassword + name: + - hostgroup02 + state: absent diff --git a/tests/service/test_service_without_skip_host_check.yml b/tests/service/test_service_without_skip_host_check.yml new file mode 100644 index 0000000000000000000000000000000000000000..147da0c97d0bd21f1fa4f7def9585a16254cb69a --- /dev/null +++ b/tests/service/test_service_without_skip_host_check.yml @@ -0,0 +1,476 @@ +--- +- name: Test service without using option skip_host_check + hosts: ipaserver + become: yes + + tasks: + # setup + - name: Get Domain from server name + set_fact: + ipaserver_domain: "{{ groups.ipaserver[0].split('.')[1:] | join ('.') }}" + when: ipaserver_domain is not defined + + - name: Set host1, host2 and svc hosts fqdn + set_fact: + host1_fqdn: "{{ 'host1.' + ipaserver_domain }}" + host2_fqdn: "{{ 'host2.' + ipaserver_domain }}" + svc_fqdn: "{{ 'svc.' + ipaserver_domain }}" + + - name: Host absent + ipahost: + ipaadmin_password: SomeADMINpassword + name: + - svc.ihavenodns.info + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + - "{{ svc_fqdn }}" + update_dns: yes + state: absent + + - name: Get IPv4 address prefix from server node + set_fact: + ipv4_prefix: "{{ ansible_default_ipv4.address.split('.')[:-1] | + join('.') }}" + + - name: Add hosts for tests. + ipahost: + ipaadmin_password: SomeADMINpassword + hosts: + - name: "{{ host1_fqdn }}" + ip_address: "{{ ipv4_prefix + '.201' }}" + update_dns: yes + - name: "{{ host2_fqdn }}" + ip_address: "{{ ipv4_prefix + '.202' }}" + update_dns: yes + - name: "{{ svc_fqdn }}" + ip_address: "{{ ipv4_prefix + '.203' }}" + update_dns: yes + - name: svc.ihavenodns.info + update_dns: no + force: yes + + - name: Ensure testing user user01 is present. + ipauser: + ipaadmin_password: SomeADMINpassword + name: user01 + first: user01 + last: last + + - name: Ensure testing user user02 is present. + ipauser: + ipaadmin_password: SomeADMINpassword + name: user02 + first: user02 + last: last + + - name: Ensure testing group group01 is present. + ipagroup: + ipaadmin_password: SomeADMINpassword + name: group01 + + - name: Ensure testing group group02 is present. + ipagroup: + ipaadmin_password: SomeADMINpassword + name: group02 + + - name: Ensure testing hostgroup hostgroup01 is present. + ipahostgroup: + ipaadmin_password: SomeADMINpassword + name: hostgroup01 + + - name: Ensure testing hostgroup hostgroup02 is present. + ipahostgroup: + ipaadmin_password: SomeADMINpassword + name: hostgroup02 + + - name: Ensure services are absent. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: + - "HTTP/{{ svc_fqdn }}" + - HTTP/svc.ihavenodns.info + state: absent + + # tests + - name: Ensure service is present + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + pac_type: + - MS-PAC + - PAD + auth_ind: otp + force: no + requires_pre_auth: yes + ok_as_delegate: no + ok_to_auth_as_delegate: no + register: result + failed_when: not result.changed + + - name: Ensure service is present, again + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + pac_type: + - MS_PAC + - PAD + auth_ind: otp + force: no + requires_pre_auth: yes + ok_as_delegate: no + ok_to_auth_as_delegate: no + register: result + failed_when: result.changed + + - name: Modify service. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + pac_type: NONE + ok_as_delegate: yes + ok_to_auth_as_delegate: yes + register: result + failed_when: not result.changed + + - name: Modify service, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + pac_type: NONE + ok_as_delegate: yes + ok_to_auth_as_delegate: yes + register: result + failed_when: result.changed + + - name: Ensure service is present, with host not in DNS. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/svc.ihavenodns.info + force: yes + register: result + failed_when: not result.changed + + - name: Ensure service is present, with host not in DNS, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: HTTP/svc.ihavenodns.info + force: yes + register: result + failed_when: result.changed + + - name: Principal host/test.example.com present in service. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + principal: + - host/test.example.com + action: member + register: result + failed_when: not result.changed + + - name: Principal host/test.exabple.com present in service, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + principal: + - host/test.example.com + action: member + register: result + failed_when: result.changed + + - name: Principal host/test.example.com absent in service. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + principal: + - host/test.example.com + action: member + state: absent + register: result + failed_when: not result.changed + + - name: Principal host/test.example.com absent in service, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + principal: + - host/test.example.com + action: member + state: absent + register: result + failed_when: result.changed + + - name: Ensure host can manage service. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + action: member + register: result + failed_when: not result.changed + + - name: Ensure host can manage service, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + host: "{{ host1_fqdn }}" + action: member + register: result + failed_when: result.changed + + - name: Ensure host cannot manage service. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + action: member + state: absent + register: result + failed_when: not result.changed + + - name: Ensure host cannot manage service, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + action: member + state: absent + register: result + failed_when: result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for users, groups, hosts and hostgroups. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_create_keytab_user: + - user01 + - user02 + allow_create_keytab_group: + - group01 + - group02 + allow_create_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_create_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + register: result + failed_when: not result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab present for users, groups, hosts and hostgroups, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_create_keytab_user: + - user01 + - user02 + allow_create_keytab_group: + - group01 + - group02 + allow_create_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_create_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + register: result + failed_when: result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for users, groups, hosts and hostgroups. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_create_keytab_user: + - user01 + - user02 + allow_create_keytab_group: + - group01 + - group02 + allow_create_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_create_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_create_keytab absent for users, groups, hosts and hostgroups, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_create_keytab_user: + - user01 + - user02 + allow_create_keytab_group: + - group01 + - group02 + allow_create_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_create_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + state: absent + register: result + failed_when: result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for users, groups, hosts and hostgroups + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_retrieve_keytab_user: + - user01 + - user02 + allow_retrieve_keytab_group: + - group01 + - group02 + allow_retrieve_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_retrieve_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + register: result + failed_when: not result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab present for users, groups, hosts and hostgroups, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_retrieve_keytab_user: + - user01 + - user02 + allow_retrieve_keytab_group: + - group01 + - group02 + allow_retrieve_keytab_host: + - "{{ host1_fqdn }}" + - host02.exampl "{{ groups.ipaserver[0] }}"e.com + allow_retrieve_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + register: result + failed_when: result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for users, groups, hosts and hostgroups. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_retrieve_keytab_user: + - user01 + - user02 + allow_retrieve_keytab_group: + - group01 + - group02 + allow_retrieve_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_retrieve_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + state: absent + register: result + failed_when: not result.changed + + - name: Service "HTTP/{{ svc_fqdn }}" members allow_retrieve_keytab absent for users, groups, hosts and hostgroups, again. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + allow_retrieve_keytab_user: + - user01 + - user02 + allow_retrieve_keytab_group: + - group01 + - group02 + allow_retrieve_keytab_host: + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + allow_retrieve_keytab_hostgroup: + - hostgroup01 + - hostgroup02 + action: member + state: absent + register: result + failed_when: result.changed + + # + - name: Ensure service is absent + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + state: absent + register: result + failed_when: not result.changed + + - name: Ensure service is absent, again + ipaservice: + ipaadmin_password: SomeADMINpassword + name: "HTTP/{{ svc_fqdn }}" + state: absent + register: result + failed_when: result.changed + + # cleanup + + - name: Ensure services are absent. + ipaservice: + ipaadmin_password: SomeADMINpassword + name: + - "HTTP/{{ svc_fqdn }}" + - HTTP/svc.ihavenodns.info + state: absent + + - name: Ensure host is absent + ipahost: + ipaadmin_password: SomeADMINpassword + name: + - "{{ svc_fqdn }}" + - "{{ host1_fqdn }}" + - "{{ host2_fqdn }}" + - svc.ihavenodns.info + state: absent + + - name: Ensure testing users are absent. + ipauser: + ipaadmin_password: SomeADMINpassword + name: + - user01 + - user02 + state: absent + + - name: Ensure testing groups are absent. + ipagroup: + ipaadmin_password: SomeADMINpassword + name: + - group01 + - group02 + state: absent + + - name: Ensure testing hostgroup hostgroup01 is absent. + ipagroup: + ipaadmin_password: SomeADMINpassword + name: + - hostgroup01 + state: absent + + - name: Ensure testing hostgroup hostgroup02 is absent. + ipagroup: + ipaadmin_password: SomeADMINpassword + name: + - hostgroup02 + state: absent