[RFE] Allow multiple groups creation.

Adding an option `groups` to create multiple groups in one operation.
Adding tests (present/absent/external/nonposix) with server and
client context.
Simple example of `groups` option:
```
tasks:
- name: Ensure 2 groups are present
  ipagroup:
    ipaadmin_password: SomeADMINpassword
    groups:
    - name: group1
    - name: group2
```

Signed-off-by: Denis Karpelevich <dkarpele@redhat.com>
This commit is contained in:
Denis Karpelevich
2023-03-30 21:07:52 +02:00
parent 24e05d1df4
commit a649a8dfe1
18 changed files with 1095 additions and 53 deletions

View File

@@ -0,0 +1,13 @@
---
- name: Create groups.json
hosts: localhost
tasks:
- name: Check if groups.json exists
ansible.builtin.stat:
path: groups.json
register: register_stat_groups
- name: Create groups.json
ansible.builtin.command: /bin/bash groups.sh 500
when: not register_stat_groups.stat.exists

25
tests/group/groups.sh Normal file
View File

@@ -0,0 +1,25 @@
#!/bin/bash
NUM=${1-1000}
FILE="groups.json"
echo "{" > "$FILE"
echo " \"group_list\": [" >> "$FILE"
for i in $(seq 1 "$NUM"); do
{
echo " {"
echo " \"name\": \"group$i\","
echo " \"description\": \"group description $i\""
} >> "$FILE"
if [ "$i" -lt "$NUM" ]; then
echo " }," >> "$FILE"
else
echo " }" >> "$FILE"
fi
done
echo " ]" >> "$FILE"
echo "}" >> "$FILE"

View File

@@ -37,3 +37,27 @@
when: groups['ipaclients'] is not defined or not groups['ipaclients']
vars:
ipa_context: client
- name: Test groups using client context, in client host.
ansible.builtin.import_playbook: test_groups.yml
when: groups['ipaclients']
vars:
ipa_test_host: ipaclients
- name: Test groups using client context, in server host.
ansible.builtin.import_playbook: test_groups.yml
when: groups['ipaclients'] is not defined or not groups['ipaclients']
vars:
ipa_context: client
- name: Test groups with mixed types using client context, in client host.
ansible.builtin.import_playbook: test_groups_external_nonposix.yml
when: groups['ipaclients']
vars:
ipa_test_host: ipaclients
- name: Test groups with mixed types using client context, in server host.
ansible.builtin.import_playbook: test_groups_external_nonposix.yml
when: groups['ipaclients'] is not defined or not groups['ipaclients']
vars:
ipa_context: client

143
tests/group/test_groups.yml Normal file
View File

@@ -0,0 +1,143 @@
---
- name: Test groups
hosts: "{{ ipa_test_host | default('ipaserver') }}"
gather_facts: true
tasks:
# setup
- name: Include tasks ../env_freeipa_facts.yml
ansible.builtin.include_tasks: ../env_freeipa_facts.yml
# GET FQDN_AT_DOMAIN
- name: Get fqdn_at_domain
ansible.builtin.set_fact:
fqdn_at_domain: "{{ ansible_facts['fqdn'] + '@' + ipaserver_realm }}"
# CLEANUP TEST ITEMS
- name: Remove test groups
ipagroup:
ipaadmin_password: SomeADMINpassword
name: group1,group2,group3,group4,group5,group6,group7,group8,group9,group10
state: absent
- name: Remove test users
ipauser:
ipaadmin_password: SomeADMINpassword
name: user1,user2,user3
state: absent
# CREATE TEST ITEMS
- name: Users user1..3 present
ipauser:
ipaadmin_password: SomeADMINpassword
users:
- name: user1
first: user1
last: Last
- name: user2
first: user2
last: Last
- name: user3
first: user3
last: Last
# TESTS
- name: Groups group1..10 present
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: group1
- name: group2
user:
- user1
- user2
- user3
- name: group3
group:
- group1
- group2
- name: group4
- name: group5
- name: group6
- name: group7
- name: group8
- name: group9
- name: group10
register: result
failed_when: not result.changed or result.failed
- name: Groups group1..10 present again
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: group1
- name: group2
- name: group3
- name: group4
- name: group5
- name: group6
- name: group7
- name: group8
- name: group9
- name: group10
register: result
failed_when: result.changed or result.failed
# failed_when: not result.failed has been added as this test needs to
# fail because two groups with the same name should be added in the same
# task.
- name: Duplicate names in groups failure test
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: group1
- name: group2
- name: group3
- name: group3
register: result
failed_when: result.changed or not result.failed or "is used more than once" not in result.msg
- name: Groups/name and name group11 present
ipagroup:
ipaadmin_password: SomeADMINpassword
name: group11
groups:
- name: group11
register: result
failed_when: result.changed or not result.failed or "parameters are mutually exclusive" not in result.msg
- name: Groups/name and name are absent
ipagroup:
ipaadmin_password: SomeADMINpassword
register: result
failed_when: result.changed or not result.failed or "one of the following is required" not in result.msg
- name: Name is absent
ipagroup:
ipaadmin_password: SomeADMINpassword
name:
register: result
failed_when: result.changed or not result.failed or "At least one name or groups is required" not in result.msg
- name: Only one group can be added at a time using name.
ipagroup:
ipaadmin_password: SomeADMINpassword
name: group11,group12
register: result
failed_when: result.changed or not result.failed or "Only one group can be added at a time using 'name'." not in result.msg
- name: Remove test groups
ipagroup:
ipaadmin_password: SomeADMINpassword
name: group1,group2,group3,group4,group5,group6,group7,group8,group9,group10
state: absent
- name: Remove test users
ipauser:
ipaadmin_password: SomeADMINpassword
name: user1,user2,user3
state: absent

View File

@@ -0,0 +1,35 @@
---
- name: Include create_groups_json.yml
ansible.builtin.import_playbook: create_groups_json.yml
- name: Test groups absent
hosts: ipaserver
gather_facts: false
tasks:
- name: Include groups.json
ansible.builtin.include_vars:
file: groups.json # noqa 505
- name: Initialize groups_names
ansible.builtin.set_fact:
groups_names: []
- name: Create dict with group names
ansible.builtin.set_fact:
groups_names: "{{ groups_names | default([]) + [{'name': item.name}] }}"
loop: "{{ group_list }}"
- name: Groups absent len:{{ group_list | length }}
ipagroup:
ipaadmin_password: SomeADMINpassword
groups: "{{ groups_names }}"
state: absent
- name: Remove groups.json
hosts: localhost
tasks:
- name: Remove groups.json
ansible.builtin.file:
state: absent
path: groups.json

View File

@@ -0,0 +1,395 @@
---
- name: Test multiple external and nonposix groups
hosts: "{{ ipa_test_host | default('ipaserver') }}"
gather_facts: true
tasks:
# setup
- name: Include tasks ../env_freeipa_facts.yml
ansible.builtin.include_tasks: ../env_freeipa_facts.yml
# GET FQDN_AT_DOMAIN
- name: Get fqdn_at_domain
ansible.builtin.set_fact:
fqdn_at_domain: "{{ ansible_facts['fqdn'] + '@' + ipaserver_realm }}"
# CLEANUP TEST ITEMS
- name: Remove testing groups.
ipagroup:
ipaadmin_password: SomeADMINpassword
name:
- extgroup
- nonposixgroup
- posixgroup
- fail_group
- group_1
- posix_group_1
- nonposix_group_1
- external_group_1
- external_group_2
state: absent
- name: Ensure test users testuser1, testuser2 and testuser3 are absent
ipauser:
ipaadmin_password: SomeADMINpassword
name: testuser1,testuser2,testuser3
state: absent
# CREATE TEST ITEMS
- name: Ensure test users testuser1..testuser3 are present
ipauser:
ipaadmin_password: SomeADMINpassword
users:
- name: testuser1
first: testuser1
last: Last
- name: testuser2
first: testuser2
last: Last
- name: testuser3
first: testuser3
last: Last
register: result
failed_when: not result.changed or result.failed
- name: Add nonposix group.
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: extgroup
nonposix: true
register: result
failed_when: result.failed or not result.changed
- name: Add nonposix group, again.
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: extgroup
nonposix: true
register: result
failed_when: result.failed or result.changed
- name: Set group to be external
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: extgroup
external: true
register: result
failed_when: result.failed or not result.changed
- name: Set group to be external, again.
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: extgroup
external: true
register: result
failed_when: result.failed or result.changed
- name: Set external group to be non-external.
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: extgroup
external: false
register: result
failed_when: not result.failed or "group can not be non-external" not in result.msg
- name: Set external group to be posix.
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: extgroup
posix: true
register: result
failed_when: not result.failed or "Cannot change `external` group" not in result.msg
- name: Add nonposix group.
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: posixgroup
nonposix: true
register: result
failed_when: result.failed or not result.changed
- name: Set group to be posix
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: posixgroup
posix: true
register: result
failed_when: result.failed or not result.changed
- name: Set group to be posix, again.
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: posixgroup
posix: true
register: result
failed_when: result.failed or result.changed
- name: Set posix group to be external.
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: posixgroup
external: true
register: result
failed_when: not result.failed or "Cannot change `posix` group" not in result.msg
- name: Set posix group to be non-posix.
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: posixgroup
posix: false
register: result
failed_when: not result.failed or "Cannot change `posix` group" not in result.msg
- name: Set posix group to be non-posix.
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: posixgroup
nonposix: true
register: result
failed_when: not result.failed or "Cannot change `posix` group" not in result.msg
- name: Add nonposix group.
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: nonposixgroup
posix: false
register: result
failed_when: result.failed or not result.changed
- name: Add nonposix group, again.
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: nonposixgroup
nonposix: true
register: result
failed_when: result.failed or result.changed
# NONPOSIX MEMBER TEST
- name: Ensure users testuser1, testuser2 and testuser3 are present in group nonposixgroup
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: nonposixgroup
nonposix: true
user:
- testuser1
- testuser2
- testuser3
register: result
failed_when: not result.changed or result.failed
- name: Ensure users testuser1, testuser2 and testuser3 are present in group nonposixgroup again
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: nonposixgroup
nonposix: true
user:
- testuser1
- testuser2
- testuser3
register: result
failed_when: result.changed or result.failed
# POSIX MEMBER TEST
- name: Ensure users testuser1, testuser2 and testuser3 are present in group posixgroup
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: posixgroup
posix: true
user:
- testuser1
- testuser2
- testuser3
register: result
failed_when: not result.changed or result.failed
- name: Ensure users testuser1, testuser2 and testuser3 are present in group posixgroup again
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: posixgroup
posix: true
user:
- testuser1
- testuser2
- testuser3
register: result
failed_when: result.changed or result.failed
# EXTERNAL MEMBER TEST (REQUIRES AD)
- name: Execute group tests if trust test environment is supported
when: trust_test_is_supported | default(false)
block:
- name: Ensure users testuser1, testuser2 and testuser3 are present in group externalgroup
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: externalgroup
external: true
user:
- testuser1
- testuser2
- testuser3
register: result
failed_when: not result.changed or result.failed
- name: Ensure users testuser1, testuser2 and testuser3 are present in group externalgroup again
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: externalgroup
external: true
user:
- testuser1
- testuser2
- testuser3
register: result
failed_when: result.changed or result.failed
# CONVERT NONPOSIX TO POSIX GROUP WITH USERS
- name: Ensure nonposix group nonposixgroup as posix
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: nonposixgroup
posix: true
register: result
failed_when: not result.changed or result.failed
- name: Ensure nonposix group nonposixgroup as posix, again
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: nonposixgroup
posix: true
register: result
failed_when: result.changed or result.failed
- name: Ensure nonposix group nonposixgroup (now posix) has users still
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: nonposixgroup
posix: true
user:
- testuser1
- testuser2
- testuser3
register: result
failed_when: result.changed or result.failed
# FAIL ON COMBINATIONS OF NONPOSIX, POSIX AND EXTERNAL
- name: Fail to ensure group as nonposix and posix
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: firstgroup
nonposix: true
posix: false
- name: fail_group
nonposix: true
posix: true
register: result
failed_when: not result.failed or "parameters are mutually exclusive for group `fail_group`" not in result.msg
- name: Fail to ensure group as nonposix and external
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: firstgroup
nonposix: true
posix: false
- name: fail_group
nonposix: true
external: true
register: result
failed_when: not result.failed or "parameters are mutually exclusive for group `fail_group`" not in result.msg
- name: Fail to ensure group as posix and external
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: firstgroup
nonposix: true
posix: false
- name: fail_group
posix: true
external: true
register: result
failed_when: not result.failed or "parameters are mutually exclusive for group `fail_group`" not in result.msg
# GROUPS WITH MIXED TYPES
- name: Adding posix, nonposix and external groups in one batch
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: posix_group_1
posix: true
- name: nonposix_group_1
nonposix: true
- name: external_group_1
external: true
register: result
failed_when: not result.changed or result.failed
- name: Adding non-external and external groups in one batch
ipagroup:
ipaadmin_password: SomeADMINpassword
groups:
- name: non_external_group_2
- name: external_group_2
external: true
register: result
failed_when: not result.changed or result.failed
# CLEANUP
- name: Remove testing groups.
ipagroup:
ipaadmin_password: SomeADMINpassword
name:
- extgroup
- nonposixgroup
- posixgroup
- fail_group
- group_1
- posix_group_1
- nonposix_group_1
- external_group_1
- external_group_2
- non_external_group_2
state: absent
- name: Ensure test users testuser1, testuser2 and testuser3 are absent
ipauser:
ipaadmin_password: SomeADMINpassword
name: testuser1,testuser2,testuser3
state: absent

View File

@@ -0,0 +1,40 @@
---
- name: Include create_groups_json.yml
ansible.builtin.import_playbook: create_groups_json.yml
- name: Test groups present
hosts: ipaserver
gather_facts: false
tasks:
- name: Include groups.json
ansible.builtin.include_vars:
file: groups.json # noqa 505
- name: Groups present len:{{ group_list | length }}
ipagroup:
ipaadmin_password: SomeADMINpassword
groups: "{{ group_list }}"
- name: Initialize groups_names
ansible.builtin.set_fact:
groups_names: []
- name: Create dict with group names
ansible.builtin.set_fact:
groups_names: "{{ groups_names | default([]) + [{'name': item.name}] }}"
loop: "{{ group_list }}"
- name: Remove groups
ipagroup:
ipaadmin_password: SomeADMINpassword
groups: "{{ groups_names }}"
state: absent
- name: Remove groups.json
hosts: localhost
tasks:
- name: Remove groups.json
ansible.builtin.file:
state: absent
path: groups.json

View File

@@ -0,0 +1,47 @@
---
- name: Include create_groups_json.yml
ansible.builtin.import_playbook: create_groups_json.yml
- name: Test groups present slice
hosts: ipaserver
gather_facts: false
vars:
slice_size: 500
tasks:
- name: Include groups.json
ansible.builtin.include_vars:
file: groups.json # noqa 505
- name: Size of groups slice.
ansible.builtin.debug:
msg: "{{ group_list | length }}"
- name: Groups present
ipagroup:
ipaadmin_password: SomeADMINpassword
groups: "{{ group_list[item : item + slice_size] }}"
loop: "{{ range(0, group_list | length, slice_size) | list }}"
- name: Initialize groups_names
ansible.builtin.set_fact:
groups_names: []
- name: Create dict with group names
ansible.builtin.set_fact:
groups_names: "{{ groups_names | default([]) + [{'name': item.name}] }}"
loop: "{{ group_list }}"
- name: Remove groups
ipagroup:
ipaadmin_password: SomeADMINpassword
groups: "{{ groups_names }}"
state: absent
- name: Remove groups.json
hosts: localhost
tasks:
- name: Remove groups.json
ansible.builtin.file:
state: absent
path: groups.json

View File

@@ -39,6 +39,7 @@ tests/pytests/conftest.py pylint:ansible-format-automatic-specification
tests/sanity/sanity.sh shebang!skip
tests/user/users.sh shebang!skip
tests/user/users_absent.sh shebang!skip
tests/group/groups.sh shebang!skip
tests/utils.py pylint:ansible-format-automatic-specification
utils/ansible-doc-test shebang!skip
utils/build-galaxy-release.sh shebang!skip

View File

@@ -21,6 +21,7 @@ tests/pytests/conftest.py pylint:ansible-format-automatic-specification
tests/sanity/sanity.sh shebang!skip
tests/user/users.sh shebang!skip
tests/user/users_absent.sh shebang!skip
tests/group/groups.sh shebang!skip
tests/utils.py pylint:ansible-format-automatic-specification
utils/ansible-doc-test shebang!skip
utils/build-galaxy-release.sh shebang!skip

View File

@@ -21,6 +21,7 @@ tests/pytests/conftest.py pylint:ansible-format-automatic-specification
tests/sanity/sanity.sh shebang!skip
tests/user/users.sh shebang!skip
tests/user/users_absent.sh shebang!skip
tests/group/groups.sh shebang!skip
tests/utils.py pylint:ansible-format-automatic-specification
utils/ansible-doc-test shebang!skip
utils/build-galaxy-release.sh shebang!skip