ipahostgroup: Fix idempotence issues due to capitalization

ipahostgroup parameters 'host', 'hostgroup', 'membermanager_user' and
'membermanager_group' must be compared in a case insensitive manner
and stored as lower case strings.

This patch fixes the comparison and storage of this parameters, and
change the handling of members to use the same structure as in newer
modules.

Two new tests files were added:

    tests/hostgroup/test_hostgroup_case_insensitive.yml
    tests/hostgroup/test_hostgroup_membermanager_case_insensitive.yml
This commit is contained in:
Rafael Guterres Jeffman
2023-12-28 18:08:52 -03:00
parent 4321478cf0
commit 22401d18d6
3 changed files with 427 additions and 135 deletions

View File

@@ -0,0 +1,144 @@
---
- name: Test hostgroup members case insensitive
hosts: ipaserver
become: true
gather_facts: false
module_defaults:
ipagroup:
ipaadmin_password: SomeADMINpassword
ipaapi_context: "{{ ipa_context | default(omit) }}"
ipauser:
ipaadmin_password: SomeADMINpassword
ipaapi_context: "{{ ipa_context | default(omit) }}"
ipahost:
ipaadmin_password: SomeADMINpassword
ipaapi_context: "{{ ipa_context | default(omit) }}"
ipahostgroup:
ipaadmin_password: SomeADMINpassword
ipaapi_context: "{{ ipa_context | default(omit) }}"
vars:
# Hostnames are supposed to have first letter
# capitalized for this test.
test_hosts:
- Host1
- Host2
test_hostgroups:
- testhostgroup1
# TestHostgrop2 is meant to use CamelCase here.
- TestHostGroup2
tasks:
- name: Test in all supported versions of IPA
block:
# setup environment
- name: Ensure domain name is set
ansible.builtin.set_fact:
ipa_domain: "test.local"
when: ipa_domain is not defined
- name: Ensure hostgroup testhostgroup1 and testhostgroup2 are absent
ipahostgroup:
name: "{{ test_hostgroups }}"
state: absent
- name: Ensure test hosts are present
ipahost:
name: "{{ item }}.{{ ipa_domain }}"
force: true
loop: "{{ test_hosts }}"
- name: Ensure hostgroup testhostgroup2 is present
ipahostgroup:
name: testhostgroup2
# tests
- name: Hostgroup should not be renamed only due to case
ipahostgroup:
name: testhostgroup2
rename: testhostgroup2
state: renamed
register: result
failed_when: result.changed or result.failed
- name: Test hostgroup presence with single host and action hostgroup
vars:
test_cases:
- { id: 1, value: "{{ test_hosts[0] | lower }}", expected: true }
- { id: 2, value: "{{ test_hosts[0] | upper }}", expected: false }
- { id: 3, value: "{{ test_hosts[0] }}", expected: false }
block:
- name: "Ensure hostgroup testhostgroup with host 'host1'"
ipahostgroup:
name: testhostgroup1
host: "{{ item.value }}"
register: output
failed_when: output.changed != item.expected or output.failed
loop: "{{ test_cases }}"
loop_control:
label: "Test id: {{ item.id }}"
- name: Test hostgroup presence with multiple hosts and action hostgroup
vars:
test_cases:
- { id: 1, value: "{{ test_hosts | lower }}", expected: true }
- { id: 2, value: "{{ test_hosts | upper }}", expected: false }
- { id: 3, value: "{{ test_hosts }}", expected: false }
- { id: 4, value: "{{ test_hosts[1] }}", expected: true }
- { id: 5, value: "{{ test_hosts[1] | lower }}", expected: false }
- { id: 6, value: "{{ test_hosts[1] | upper }}", expected: false }
- { id: 7, value: "{{ test_hosts[0] }}", expected: true }
- { id: 8, value: "{{ test_hosts[0] | lower }}", expected: false }
- { id: 9, value: "{{ test_hosts[0] | upper }}", expected: false }
block:
- name: "Ensure hostgroup testhostgroup with host 'host1'"
ipahostgroup:
name: testhostgroup1
host: "{{ item.value }}"
register: output
failed_when: output.changed != item.expected or output.failed
loop: "{{ test_cases }}"
loop_control:
label: "Test id: {{ item.id }}"
- name: Test hostgroup with multiple hosts and action member
vars:
test_cases:
- { id: 1, value: "{{ test_hosts | lower }}", state: "absent", expected: true }
- { id: 2, value: "{{ test_hosts | upper }}", state: "absent", expected: false }
- { id: 3, value: "{{ test_hosts }}", state: "present", expected: true }
- { id: 4, value: "{{ test_hosts[1] }}", state: "absent", expected: true }
- { id: 5, value: "{{ test_hosts[1] | lower }}", state: "absent", expected: false }
- { id: 6, value: "{{ test_hosts[1] | upper }}", state: "absent", expected: false }
- { id: 7, value: "{{ test_hosts[0] | lower }}", state: "present", expected: false }
- { id: 8, value: "{{ test_hosts[0] }}", state: "present", expected: false }
- { id: 9, value: "{{ test_hosts[0] | upper }}", state: "present", expected: false }
- { id: 10, value: "{{ test_hosts | upper }}", state: "present", expected: true }
- { id: 11, value: "{{ test_hosts[1] }}", state: "present", expected: false }
- { id: 12, value: "{{ test_hosts[0] | lower }}", state: "present", expected: false }
- { id: 13, value: "{{ test_hosts[0] }}", state: "absent", expected: true }
- { id: 14, value: "{{ test_hosts[0] | lower }}", state: "absent", expected: false }
- { id: 15, value: "{{ test_hosts[0] | upper }}", state: "absent", expected: false }
block:
- name: "Ensure hostgroup testhostgroup with host 'host1'"
ipahostgroup:
name: testhostgroup1
host: "{{ item.value }}"
action: member
state: "{{ item.state }}"
register: output
failed_when: output.changed != item.expected or output.failed
loop: "{{ test_cases }}"
loop_control:
label: "Test id: {{ item.id }}"
always:
# cleanup
- name: Ensure hostgroup testhostgroup is absent
ipahostgroup:
name: "{{ test_hostgroups }}"
state: absent
- name: Ensure test hosts are absent
ipahost:
name: "{{ test_hosts | product([ipa_domain]) | map('join') | list }}"
state: absent

View File

@@ -0,0 +1,179 @@
---
- name: Test hostgroup membermanagers
hosts: ipaserver
become: true
gather_facts: false
module_defaults:
ipagroup:
ipaadmin_password: SomeADMINpassword
ipaapi_context: "{{ ipa_context | default(omit) }}"
ipauser:
ipaadmin_password: SomeADMINpassword
ipaapi_context: "{{ ipa_context | default(omit) }}"
ipahostgroup:
ipaadmin_password: SomeADMINpassword
ipaapi_context: "{{ ipa_context | default(omit) }}"
tasks:
- name: Include tasks ../env_freeipa_facts.yml
ansible.builtin.include_tasks: ../env_freeipa_facts.yml
- name: Tests requiring IPA version 4.8.4+
when: ipa_version is version('4.8.4', '>=')
block:
# setup environment
- name: Ensure host-group testhostgroup is absent
ipahostgroup:
name: testhostgroup
state: absent
- name: Ensure user manageruser1 and manageruser2 are present
ipauser:
users:
- name: manageruser1
first: manageruser1
last: Last1
- name: manageruser2
first: manageruser2
last: Last2
- name: Ensure managergroup1 and managergroup2 are present
ipagroup:
groups:
- name: managergroup1
- name: managergroup2
# tests
- name: Ensure host-group testhostgroup is present
ipahostgroup:
name: testhostgroup
- name: Test membermanager_user parameter presence
vars:
test_cases:
- { id: 1, value: "{{ 'ManagerUser1' | lower }}", expected: true }
- { id: 2, value: "{{ 'ManagerUser1' | upper }}", expected: false }
- { id: 3, value: 'ManagerUser1', expected: false }
block:
- name: "Ensure membermanager_user 'manageruser1' is present for testhostgroup"
ipahostgroup:
name: testhostgroup
membermanager_user: "{{ item.value }}"
action: member
register: output
failed_when: output.changed != item.expected or output.failed
loop: "{{ test_cases }}"
loop_control:
label: "{{ item.value }}"
- name: Test membermanager_group parameter presence
vars:
test_cases:
- { id: 1, value: "{{ 'ManagerGroup1' | upper }}", expected: true }
- { id: 2, value: "{{ 'ManagerGroup1' | lower }}", expected: false }
- { id: 3, value: 'ManagerGroup1', expected: false }
block:
- name: "Ensure membermanager_group 'managergroup1' is present for testhostgroup"
ipahostgroup:
name: testhostgroup
membermanager_group: "{{ item.value }}"
action: member
register: output
failed_when: output.changed != item.expected or output.failed
loop: "{{ test_cases }}"
loop_control:
label: "{{ item.value }}"
- name: Test membermanager_group and membermanager_user parameters presence
vars:
test_cases:
- { id: 1, user: 'ManagerUser2', group: 'ManagerGroup2', expected: true }
- { id: 2, user: "{{ 'ManagerUser2' | upper }}", group: "{{ 'ManagerGroup2' | upper }}", expected: false }
- { id: 3, user: "{{ 'ManagerUser2' | lower }}", group: "{{ 'ManagerGroup2' | lower }}", expected: false }
block:
- name: "Ensure membermanager_group 'managergroup2' and membermanager_user 'manageruser2' are present for testhostgroup"
ipahostgroup:
name: testhostgroup
membermanager_group: "{{ item.group }}"
membermanager_user: "{{ item.user }}"
action: member
register: output
failed_when: output.changed != item.expected or output.failed
loop: "{{ test_cases }}"
loop_control:
label: "Test id: {{ item.id }}"
- name: Test membermanager_group parameter absence
vars:
test_cases:
- { id: 1, value: 'ManagerGroup1', expected: true }
- { id: 2, value: "{{ 'ManagerGroup1' | lower }}", expected: false }
- { id: 3, value: "{{ 'ManagerGroup1' | upper }}", expected: false }
block:
- name: "Ensure membermanager_group 'managergroup1' is absent for testhostgroup"
ipahostgroup:
name: testhostgroup
membermanager_group: "{{ item.value }}"
action: member
state: absent
register: output
failed_when: output.changed != item.expected or output.failed
loop: "{{ test_cases }}"
loop_control:
label: "{{ item.value }}"
- name: Test membermanager_user parameter absence
vars:
test_cases:
- { id: 1, value: 'ManagerUser1', expected: true }
- { id: 2, value: "{{ 'ManagerUser1' | lower }}", expected: false }
- { id: 3, value: "{{ 'ManagerUser1' | upper }}", expected: false }
block:
- name: "Ensure membermanager_user 'manageruser1' is absent for testhostgroup"
ipahostgroup:
name: testhostgroup
membermanager_user: "{{ item.value }}"
action: member
state: absent
register: output
failed_when: output.changed != item.expected or output.failed
loop: "{{ test_cases }}"
loop_control:
label: "{{ item.value }}"
- name: Test membermanager_group and membermanager_user parameters absence
vars:
test_cases:
- { id: 1, user: "{{ 'ManagerUser2' | lower }}", group: "{{ 'ManagerGroup2' | lower }}", expected: true }
- { id: 2, user: 'ManagerUser2', group: 'ManagerGroup2', expected: false }
- { id: 3, user: "{{ 'ManagerUser2' | upper }}", group: "{{ 'ManagerGroup2' | upper }}", expected: false }
block:
- name: "Ensure membermanager_user 'manageruser2' and membermanager_group 'managergroup2' are absent for testhostgroup"
ipahostgroup:
name: testhostgroup
membermanager_group: "{{ item.group }}"
membermanager_user: "{{ item.user }}"
action: member
state: absent
register: output
failed_when: output.changed != item.expected or output.failed
loop: "{{ test_cases }}"
loop_control:
label: "Test id: {{ item.id }}"
always:
# cleanup
- name: Ensure host-group testhostgroup is absent
ipahostgroup:
name: testhostgroup
state: absent
- name: Ensure user manangeruser1 and manageruser2 is absent
ipauser:
name: manageruser1,manageruser2
state: absent
- name: Ensure group managergroup1 and managergroup2 are absent
ipagroup:
name: managergroup1,managergroup2
state: absent