From 9cb75cdea70aaf2b7f7adecf04046fba3cfe4a29 Mon Sep 17 00:00:00 2001
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
Date: Fri, 14 Aug 2020 11:10:30 -0300
Subject: [PATCH] Add FreeIPA version as Ansible facts for testing.

Some attributes are not present in all supported versions of FreeIPA,
and this might cause tests to fail due to unsupported versions.

This patch add the means to test if a test can be executed based on
the target host FreeIPA version.
---
 tests/env_freeipa_facts.yml                   |  18 +
 .../test_hostgroup_membermanager.yml          | 429 ++++-----
 tests/hostgroup/test_hostgroup_rename.yml     | 180 ++--
 .../test_service_without_skip_host_check.yml  | 816 ++++++++++--------
 4 files changed, 803 insertions(+), 640 deletions(-)
 create mode 100644 tests/env_freeipa_facts.yml

diff --git a/tests/env_freeipa_facts.yml b/tests/env_freeipa_facts.yml
new file mode 100644
index 00000000..7a664c1c
--- /dev/null
+++ b/tests/env_freeipa_facts.yml
@@ -0,0 +1,18 @@
+# This playbook should be included with `include_tasks` as the first task
+# of a test playbook that requires FreeIPA information.
+#
+# Available Facts:
+#
+# ipa_version: The installed FreeIPA version.
+# ipa_api_version: The installed FreeIPA API version.
+#
+---
+- name: Retrieving FreeIPA version.
+  shell:
+    cmd: 'ipa --version | sed -n "s/VERSION: \([^,]*\).*API_VERSION: \([^,]*\).*/\1\\n\2/p"'
+  register: ipa_cmd_version
+
+- name: Set FreeIPA facts.
+  set_fact:
+    ipa_version: "{{ ipa_cmd_version.stdout_lines[0] }}"
+    ipa_api_version: "{{ ipa_cmd_version.stdout_lines[1] }}"
diff --git a/tests/hostgroup/test_hostgroup_membermanager.yml b/tests/hostgroup/test_hostgroup_membermanager.yml
index c0f65460..2af8445d 100644
--- a/tests/hostgroup/test_hostgroup_membermanager.yml
+++ b/tests/hostgroup/test_hostgroup_membermanager.yml
@@ -5,215 +5,220 @@
   gather_facts: false
 
   tasks:
-  - name: Ensure host-group testhostgroup is absent
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name:
-      - testhostgroup
-      state: absent
-
-  - name: Ensure user manangeruser1 and manageruser2 is absent
-    ipauser:
-      ipaadmin_password: SomeADMINpassword
-      name: manageruser1,manageruser2,unknown_user
-      state: absent
-
-  - name: Ensure group managergroup1 and managergroup2 are absent
-    ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      name: managergroup1,managergroup2
-      state: absent
-
-  - name: Ensure host-group testhostgroup is present
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name:
-      - testhostgroup
-
-  - name: Ensure user manageruser1 and manageruser2 are present
-    ipauser:
-      ipaadmin_password: SomeADMINpassword
-      users:
-      - name: manageruser1
-        first: manageruser1
-        last: Last1
-      - name: manageruser2
-        first: manageruser2
-        last: Last2
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure managergroup1 is present
-    ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      name: managergroup1
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure managergroup2 is present
-    ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      name: managergroup2
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure membermanager user1 is present for testhostgroup
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_user: manageruser1
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure membermanager user1 is present for testhostgroup again
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_user: manageruser1
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure membermanager group1 is present for testhostgroup
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_group: managergroup1
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure membermanager group1 is present for testhostgroup again
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_group: managergroup1
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure membermanager user2 and group2 members are present for testhostgroup
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_user: manageruser2
-      membermanager_group: managergroup2
-      action: member
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure membermanager user2 and group2 members are present for testhostgroup again
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_user: manageruser2
-      membermanager_group: managergroup2
-      action: member
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure membermanager user and group members are present for testhostgroup again
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_user: manageruser1,manageruser2
-      membermanager_group: managergroup1,managergroup2
-      action: member
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure membermanager user1 and group1 members are absent for testhostgroup
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_user: manageruser1
-      membermanager_group: managergroup1
-      action: member
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure membermanager user1 and group1 members are absent for testhostgroup again
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_user: manageruser1
-      membermanager_group: managergroup1
-      action: member
-      state: absent
-    register: result
-    failed_when: result.changed
-
-
-  - name: Ensure membermanager user1 and group1 members are present for testhostgroup
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_user: manageruser1
-      membermanager_group: managergroup1
-      action: member
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure membermanager user1 and group1 members are present for testhostgroup again
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_user: manageruser1
-      membermanager_group: managergroup1
-      action: member
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure membermanager user and group members are absent for testhostgroup
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_user: manageruser1,manageruser2
-      membermanager_group: managergroup1,managergroup2
-      action: member
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure membermanager user and group members are absent for testhostgroup again
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_user: manageruser1,manageruser2
-      membermanager_group: managergroup1,managergroup2
-      action: member
-      state: absent
-    register: result
-    failed_when: result.changed
-
-  - name: Ensure user manangeruser1 and manageruser2 is absent
-    ipauser:
-      ipaadmin_password: SomeADMINpassword
-      name: manageruser1,manageruser2
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure group managergroup1 and managergroup2 are absent
-    ipagroup:
-      ipaadmin_password: SomeADMINpassword
-      name: managergroup1,managergroup2
-      state: absent
-    register: result
-    failed_when: not result.changed
-
-  - name: Ensure unknown membermanager_user member failure
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: testhostgroup
-      membermanager_user: unknown_user
-      action: member
-    register: result
-    failed_when: result.changed or "no such entry" not in result.msg
-
-  - name: Ensure host-group testhostgroup is absent
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name:
-      - testhostgroup
-      state: absent
-    register: result
-    failed_when: not result.changed
+  - include_tasks: ../env_freeipa_facts.yml
+
+  - name: Tests requiring IPA version 4.8.4+
+    block:
+      - name: Ensure host-group testhostgroup is absent
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name:
+          - testhostgroup
+          state: absent
+
+      - name: Ensure user manangeruser1 and manageruser2 is absent
+        ipauser:
+          ipaadmin_password: SomeADMINpassword
+          name: manageruser1,manageruser2,unknown_user
+          state: absent
+
+      - name: Ensure group managergroup1 and managergroup2 are absent
+        ipagroup:
+          ipaadmin_password: SomeADMINpassword
+          name: managergroup1,managergroup2
+          state: absent
+
+      - name: Ensure host-group testhostgroup is present
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name:
+          - testhostgroup
+
+      - name: Ensure user manageruser1 and manageruser2 are present
+        ipauser:
+          ipaadmin_password: SomeADMINpassword
+          users:
+          - name: manageruser1
+            first: manageruser1
+            last: Last1
+          - name: manageruser2
+            first: manageruser2
+            last: Last2
+        register: result
+        failed_when: not result.changed
+
+      - name: Ensure managergroup1 is present
+        ipagroup:
+          ipaadmin_password: SomeADMINpassword
+          name: managergroup1
+        register: result
+        failed_when: not result.changed
+
+      - name: Ensure managergroup2 is present
+        ipagroup:
+          ipaadmin_password: SomeADMINpassword
+          name: managergroup2
+        register: result
+        failed_when: not result.changed
+
+      - name: Ensure membermanager user1 is present for testhostgroup
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_user: manageruser1
+        register: result
+        failed_when: not result.changed
+
+      - name: Ensure membermanager user1 is present for testhostgroup again
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_user: manageruser1
+        register: result
+        failed_when: result.changed
+
+      - name: Ensure membermanager group1 is present for testhostgroup
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_group: managergroup1
+        register: result
+        failed_when: not result.changed
+
+      - name: Ensure membermanager group1 is present for testhostgroup again
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_group: managergroup1
+        register: result
+        failed_when: result.changed
+
+      - name: Ensure membermanager user2 and group2 members are present for testhostgroup
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_user: manageruser2
+          membermanager_group: managergroup2
+          action: member
+        register: result
+        failed_when: not result.changed
+
+      - name: Ensure membermanager user2 and group2 members are present for testhostgroup again
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_user: manageruser2
+          membermanager_group: managergroup2
+          action: member
+        register: result
+        failed_when: result.changed
+
+      - name: Ensure membermanager user and group members are present for testhostgroup again
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_user: manageruser1,manageruser2
+          membermanager_group: managergroup1,managergroup2
+          action: member
+        register: result
+        failed_when: result.changed
+
+      - name: Ensure membermanager user1 and group1 members are absent for testhostgroup
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_user: manageruser1
+          membermanager_group: managergroup1
+          action: member
+          state: absent
+        register: result
+        failed_when: not result.changed
+
+      - name: Ensure membermanager user1 and group1 members are absent for testhostgroup again
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_user: manageruser1
+          membermanager_group: managergroup1
+          action: member
+          state: absent
+        register: result
+        failed_when: result.changed
+
+
+      - name: Ensure membermanager user1 and group1 members are present for testhostgroup
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_user: manageruser1
+          membermanager_group: managergroup1
+          action: member
+        register: result
+        failed_when: not result.changed
+
+      - name: Ensure membermanager user1 and group1 members are present for testhostgroup again
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_user: manageruser1
+          membermanager_group: managergroup1
+          action: member
+        register: result
+        failed_when: result.changed
+
+      - name: Ensure membermanager user and group members are absent for testhostgroup
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_user: manageruser1,manageruser2
+          membermanager_group: managergroup1,managergroup2
+          action: member
+          state: absent
+        register: result
+        failed_when: not result.changed
+
+      - name: Ensure membermanager user and group members are absent for testhostgroup again
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_user: manageruser1,manageruser2
+          membermanager_group: managergroup1,managergroup2
+          action: member
+          state: absent
+        register: result
+        failed_when: result.changed
+
+      - name: Ensure user manangeruser1 and manageruser2 is absent
+        ipauser:
+          ipaadmin_password: SomeADMINpassword
+          name: manageruser1,manageruser2
+          state: absent
+        register: result
+        failed_when: not result.changed
+
+      - name: Ensure group managergroup1 and managergroup2 are absent
+        ipagroup:
+          ipaadmin_password: SomeADMINpassword
+          name: managergroup1,managergroup2
+          state: absent
+        register: result
+        failed_when: not result.changed
+
+      - name: Ensure unknown membermanager_user member failure
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: testhostgroup
+          membermanager_user: unknown_user
+          action: member
+        register: result
+        failed_when: result.changed or "no such entry" not in result.msg
+
+      - name: Ensure host-group testhostgroup is absent
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name:
+          - testhostgroup
+          state: absent
+        register: result
+        failed_when: not result.changed
+    when: ipa_version is version('4.8.4', '>=')
diff --git a/tests/hostgroup/test_hostgroup_rename.yml b/tests/hostgroup/test_hostgroup_rename.yml
index 8d13338f..98007175 100644
--- a/tests/hostgroup/test_hostgroup_rename.yml
+++ b/tests/hostgroup/test_hostgroup_rename.yml
@@ -5,101 +5,107 @@
   gather_facts: false
 
   tasks:
-  - name: Ensure testing host-group are absent
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name:
-      - databases
-      - datalake
-      - inexistenthostgroup
-      state: absent
+  - include_tasks: ../env_freeipa_facts.yml
 
-  - name: Ensure host-group databases is present
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: databases
-      state: present
-    register: result
-    failed_when: not result.changed
+  - name: Tests requiring IPA version 4.8.7+
+    block:
+      - name: Ensure testing host-group are absent
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name:
+          - databases
+          - datalake
+          - inexistenthostgroup
+          state: absent
 
-  - name: Rename host-group from `databases` to `datalake`
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: databases
-      rename: datalake
-      state: renamed
-    register: result
-    failed_when: not result.changed
+      - name: Ensure host-group databases is present
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: databases
+          state: present
+        register: result
+        failed_when: not result.changed
 
-  - name: Ensure host-group database was already absent
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: database
-      state: absent
-    register: result
-    failed_when: result.changed
+      - name: Rename host-group from `databases` to `datalake`
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: databases
+          rename: datalake
+          state: renamed
+        register: result
+        failed_when: not result.changed
 
-  - name: Rename host-group from `databases` to `datalake`, again
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: databases
-      rename: datalake
-      state: renamed
-    register: result
-    failed_when: result.changed or result.failed
+      - name: Ensure host-group database was already absent
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: database
+          state: absent
+        register: result
+        failed_when: result.changed
 
-  - name: Rename host-group with same name.
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: datalake
-      rename: datalake
-      state: renamed
-    register: result
-    failed_when: result.changed
+      - name: Rename host-group from `databases` to `datalake`, again
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: databases
+          rename: datalake
+          state: renamed
+        register: result
+        failed_when: result.changed or result.failed
 
-  - name: Ensure testing hostgroups do not exist.
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: inexistenthostgroup,alsoinexistent
-      state: absent
+      - name: Rename host-group with same name.
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: datalake
+          rename: datalake
+          state: renamed
+        register: result
+        failed_when: result.changed
 
-  - name: Rename inexistent host-group to an existing one.
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: inexistenthostgroup
-      rename: datalake
-      state: renamed
-    register: result
-    failed_when: result.changed or result.failed
+      - name: Ensure testing hostgroups do not exist.
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: inexistenthostgroup,alsoinexistent
+          state: absent
 
-  - name: Rename inexistent host-group to a non-existing one.
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: inexistenthostgroup
-      rename: alsoinexistent
-      state: renamed
-    register: result
-    failed_when: not result.failed or "Attribute `rename` can not be used, unless hostgroup exists." not in result.msg
+      - name: Rename inexistent host-group to an existing one.
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: inexistenthostgroup
+          rename: datalake
+          state: renamed
+        register: result
+        failed_when: result.changed or result.failed
 
-  - name: Ensure host-group databases is present
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: databases
-      state: present
+      - name: Rename inexistent host-group to a non-existing one.
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: inexistenthostgroup
+          rename: alsoinexistent
+          state: renamed
+        register: result
+        failed_when: not result.failed or "Attribute `rename` can not be used, unless hostgroup exists." not in result.msg
 
-  - name: Rename host-group to an existing one.
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name: databases
-      rename: datalake
-      state: renamed
-    register: result
-    failed_when: not result.failed or "This entry already exists" not in result.msg
+      - name: Ensure host-group databases is present
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: databases
+          state: present
 
-  - name: Ensure host-group databases and datalake are absent
-    ipahostgroup:
-      ipaadmin_password: SomeADMINpassword
-      name:
-      - databases
-      - datalake
-      state: absent
+      - name: Rename host-group to an existing one.
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name: databases
+          rename: datalake
+          state: renamed
+        register: result
+        failed_when: not result.failed or "This entry already exists" not in result.msg
+
+      - name: Ensure host-group databases and datalake are absent
+        ipahostgroup:
+          ipaadmin_password: SomeADMINpassword
+          name:
+          - databases
+          - datalake
+          state: absent
+
+    when: ipa_version is version('4.8.7', '>=')
diff --git a/tests/service/test_service_without_skip_host_check.yml b/tests/service/test_service_without_skip_host_check.yml
index 0f89cc72..2b627256 100644
--- a/tests/service/test_service_without_skip_host_check.yml
+++ b/tests/service/test_service_without_skip_host_check.yml
@@ -4,344 +4,478 @@
   become: yes
 
   tasks:
-  # setup
-  - name: Setup test environment
-    include_tasks: env_setup.yml
-
-  # 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 }}"
-      - "{{ host2_fqdn }}"
-      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: Cleanup test environment
-    include_tasks: env_cleanup.yml
+  - include_tasks: ../env_freeipa_facts.yml
+
+  - name: Tests requiring IPA version 4.7.0+
+    block:
+      # setup
+      - name: Get Domain from server name
+        set_fact:
+          ipaserver_domain: "{{ ansible_fqdn.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 }}"
+          - "{{ host2_fqdn }}"
+          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
+    when: ipa_version is version('4.7.0', '>=')
-- 
GitLab