mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-03-26 21:33:05 +00:00
[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:
105
README-group.md
105
README-group.md
@@ -8,6 +8,9 @@ The group module allows to ensure presence and absence of groups and members of
|
|||||||
|
|
||||||
The group module is as compatible as possible to the Ansible upstream `ipa_group` module, but additionally offers to add users to a group and also to remove users from a group.
|
The group module is as compatible as possible to the Ansible upstream `ipa_group` module, but additionally offers to add users to a group and also to remove users from a group.
|
||||||
|
|
||||||
|
## Note
|
||||||
|
Ensuring presence (adding) of several groups with mixed types (`external`, `nonposix` and `posix`) requires a fix in FreeIPA. The module implements a workaround to automatically use `client` context if the fix is not present in the target node FreeIPA and if more than one group is provided to the task using the `groups` parameter. If `ipaapi_context` is forced to be `server`, the module will fail in this case.
|
||||||
|
|
||||||
|
|
||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
@@ -71,6 +74,62 @@ Example playbook to add groups:
|
|||||||
name: appops
|
name: appops
|
||||||
```
|
```
|
||||||
|
|
||||||
|
These three `ipagroup` module calls can be combined into one with the `groups` variable:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Playbook to handle groups
|
||||||
|
hosts: ipaserver
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Ensure groups ops, sysops and appops are present
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
groups:
|
||||||
|
- name: ops
|
||||||
|
gidnumber: 1234
|
||||||
|
- name: sysops
|
||||||
|
user:
|
||||||
|
- pinky
|
||||||
|
- name: appops
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also alternatively use a json file containing the groups, here `groups_present.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"groups": [
|
||||||
|
{
|
||||||
|
"name": "group1",
|
||||||
|
"description": "description group1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "group2",
|
||||||
|
"description": "description group2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And ensure the presence of the groups with this example playbook:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Tests
|
||||||
|
hosts: ipaserver
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Include groups_present.json
|
||||||
|
include_vars:
|
||||||
|
file: groups_present.json
|
||||||
|
|
||||||
|
- name: Groups present
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
groups: "{{ groups }}"
|
||||||
|
```
|
||||||
|
|
||||||
Example playbook to add users to a group:
|
Example playbook to add users to a group:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -112,11 +171,11 @@ Example playbook to add group members to a group:
|
|||||||
Example playbook to add members from a trusted realm to an external group:
|
Example playbook to add members from a trusted realm to an external group:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
--
|
---
|
||||||
- name: Playbook to handle groups.
|
- name: Playbook to handle groups.
|
||||||
hosts: ipaserver
|
hosts: ipaserver
|
||||||
became: true
|
|
||||||
|
tasks:
|
||||||
- name: Create an external group and add members from a trust to it.
|
- name: Create an external group and add members from a trust to it.
|
||||||
ipagroup:
|
ipagroup:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
@@ -127,6 +186,24 @@ Example playbook to add members from a trusted realm to an external group:
|
|||||||
- WINIPA\\Developers
|
- WINIPA\\Developers
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Example playbook to add nonposix and external groups:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Playbook to add nonposix and external groups
|
||||||
|
hosts: ipaserver
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Add nonposix group sysops and external group appops
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
groups:
|
||||||
|
- name: sysops
|
||||||
|
nonposix: true
|
||||||
|
- name: appops
|
||||||
|
external: true
|
||||||
|
```
|
||||||
|
|
||||||
Example playbook to remove groups:
|
Example playbook to remove groups:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -136,13 +213,29 @@ Example playbook to remove groups:
|
|||||||
become: true
|
become: true
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
# Remove goups sysops, appops and ops
|
# Remove groups sysops, appops and ops
|
||||||
- ipagroup:
|
- ipagroup:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: sysops,appops,ops
|
name: sysops,appops,ops
|
||||||
state: absent
|
state: absent
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Example playbook to ensure groups are absent:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Playbook to handle groups
|
||||||
|
hosts: ipaserver
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Ensure groups ops and sysops are absent
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
groups:
|
||||||
|
- name: ops
|
||||||
|
- name: sysops
|
||||||
|
state: absent
|
||||||
|
```
|
||||||
|
|
||||||
Variables
|
Variables
|
||||||
=========
|
=========
|
||||||
@@ -152,8 +245,10 @@ Variable | Description | Required
|
|||||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
`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
|
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||||
`ipaapi_context` | The context in which the module will execute. Executing in a server context is preferred. If not provided context will be determined by the execution environment. Valid values are `server` and `client`. | no
|
`ipaapi_context` | The context in which the module will execute. Executing in a server context is preferred. If not provided context will be determined by the execution environment. Valid values are `server` and `client`. | no
|
||||||
`ipaapi_ldap_cache` | Use LDAP cache for IPA connection. The bool setting defaults to yes. (bool) | no
|
`ipaapi_ldap_cache` | Use LDAP cache for IPA connection. The bool setting defaults to <br/>. (bool) | no
|
||||||
`name` \| `cn` | The list of group name strings. | no
|
`name` \| `cn` | The list of group name strings. | no
|
||||||
|
`groups` | The list of group dicts. Each `groups` dict entry can contain group variables.<br>There is one required option in the `groups` dict:| no
|
||||||
|
| `name` - The group name string of the entry. | yes
|
||||||
`description` | The group description string. | no
|
`description` | The group description string. | no
|
||||||
`gid` \| `gidnumber` | The GID integer. | no
|
`gid` \| `gidnumber` | The GID integer. | no
|
||||||
`posix` | Create a non-POSIX group or change a non-POSIX to a posix group. `nonposix`, `posix` and `external` are mutually exclusive. (bool) | no
|
`posix` | Create a non-POSIX group or change a non-POSIX to a posix group. `nonposix`, `posix` and `external` are mutually exclusive. (bool) | no
|
||||||
|
|||||||
32
playbooks/group/add-groups.yml
Normal file
32
playbooks/group/add-groups.yml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to handle multiple groups
|
||||||
|
hosts: ipaserver
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Create multiple groups ops, sysops
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
groups:
|
||||||
|
- name: ops
|
||||||
|
gidnumber: 1234
|
||||||
|
- name: sysops
|
||||||
|
|
||||||
|
- name: Add user and group members to groups sysops and appops
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
groups:
|
||||||
|
- name: sysops
|
||||||
|
user:
|
||||||
|
- user1
|
||||||
|
- name: appops
|
||||||
|
group:
|
||||||
|
- group2
|
||||||
|
|
||||||
|
- name: Create multiple non-POSIX and external groups
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
groups:
|
||||||
|
- name: nongroup
|
||||||
|
nonposix: true
|
||||||
|
- name: extgroup
|
||||||
|
external: true
|
||||||
@@ -41,8 +41,88 @@ options:
|
|||||||
description: The group name
|
description: The group name
|
||||||
type: list
|
type: list
|
||||||
elements: str
|
elements: str
|
||||||
required: true
|
required: false
|
||||||
aliases: ["cn"]
|
aliases: ["cn"]
|
||||||
|
groups:
|
||||||
|
description: The list of group dicts (internally gid).
|
||||||
|
type: list
|
||||||
|
elements: dict
|
||||||
|
suboptions:
|
||||||
|
name:
|
||||||
|
description: The group (internally gid).
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
aliases: ["cn"]
|
||||||
|
description:
|
||||||
|
description: The group description
|
||||||
|
type: str
|
||||||
|
required: false
|
||||||
|
gid:
|
||||||
|
description: The GID
|
||||||
|
type: int
|
||||||
|
required: false
|
||||||
|
aliases: ["gidnumber"]
|
||||||
|
nonposix:
|
||||||
|
description: Create as a non-POSIX group
|
||||||
|
required: false
|
||||||
|
type: bool
|
||||||
|
external:
|
||||||
|
description: Allow adding external non-IPA members from trusted domains
|
||||||
|
required: false
|
||||||
|
type: bool
|
||||||
|
posix:
|
||||||
|
description:
|
||||||
|
Create a non-POSIX group or change a non-POSIX to a posix group.
|
||||||
|
required: false
|
||||||
|
type: bool
|
||||||
|
nomembers:
|
||||||
|
description: Suppress processing of membership attributes
|
||||||
|
required: false
|
||||||
|
type: bool
|
||||||
|
user:
|
||||||
|
description: List of user names assigned to this group.
|
||||||
|
required: false
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
group:
|
||||||
|
description: List of group names assigned to this group.
|
||||||
|
required: false
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
service:
|
||||||
|
description:
|
||||||
|
- List of service names assigned to this group.
|
||||||
|
- Only usable with IPA versions 4.7 and up.
|
||||||
|
required: false
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
membermanager_user:
|
||||||
|
description:
|
||||||
|
- List of member manager users assigned to this group.
|
||||||
|
- Only usable with IPA versions 4.8.4 and up.
|
||||||
|
required: false
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
membermanager_group:
|
||||||
|
description:
|
||||||
|
- List of member manager groups assigned to this group.
|
||||||
|
- Only usable with IPA versions 4.8.4 and up.
|
||||||
|
required: false
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
externalmember:
|
||||||
|
description:
|
||||||
|
- List of members of a trusted domain in DOM\\name or name@domain form.
|
||||||
|
required: false
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
aliases: ["ipaexternalmember", "external_member"]
|
||||||
|
idoverrideuser:
|
||||||
|
description:
|
||||||
|
- User ID overrides to add
|
||||||
|
required: false
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
description:
|
description:
|
||||||
description: The group description
|
description: The group description
|
||||||
type: str
|
type: str
|
||||||
@@ -144,6 +224,14 @@ EXAMPLES = """
|
|||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: appops
|
name: appops
|
||||||
|
|
||||||
|
# Create multiple groups ops, sysops
|
||||||
|
- ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
groups:
|
||||||
|
- name: ops
|
||||||
|
gidnumber: 1234
|
||||||
|
- name: sysops
|
||||||
|
|
||||||
# Add user member pinky to group sysops
|
# Add user member pinky to group sysops
|
||||||
- ipagroup:
|
- ipagroup:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
@@ -160,7 +248,7 @@ EXAMPLES = """
|
|||||||
user:
|
user:
|
||||||
- brain
|
- brain
|
||||||
|
|
||||||
# Add group members sysops and appops to group sysops
|
# Add group members sysops and appops to group ops
|
||||||
- ipagroup:
|
- ipagroup:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: ops
|
name: ops
|
||||||
@@ -168,6 +256,17 @@ EXAMPLES = """
|
|||||||
- sysops
|
- sysops
|
||||||
- appops
|
- appops
|
||||||
|
|
||||||
|
# Add user and group members to groups sysops and appops
|
||||||
|
- ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
groups:
|
||||||
|
- name: sysops
|
||||||
|
user:
|
||||||
|
- user1
|
||||||
|
- name: appops
|
||||||
|
group:
|
||||||
|
- group2
|
||||||
|
|
||||||
# Create a non-POSIX group
|
# Create a non-POSIX group
|
||||||
- ipagroup:
|
- ipagroup:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
@@ -189,7 +288,16 @@ EXAMPLES = """
|
|||||||
- WINIPA\\Web Users
|
- WINIPA\\Web Users
|
||||||
- WINIPA\\Developers
|
- WINIPA\\Developers
|
||||||
|
|
||||||
# Remove goups sysops, appops, ops and nongroup
|
# Create multiple non-POSIX and external groups
|
||||||
|
- ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
groups:
|
||||||
|
- name: nongroup
|
||||||
|
nonposix: true
|
||||||
|
- name: extgroup
|
||||||
|
external: true
|
||||||
|
|
||||||
|
# Remove groups sysops, appops, ops and nongroup
|
||||||
- ipagroup:
|
- ipagroup:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: sysops,appops,ops, nongroup
|
name: sysops,appops,ops, nongroup
|
||||||
@@ -203,6 +311,9 @@ from ansible.module_utils._text import to_text
|
|||||||
from ansible.module_utils.ansible_freeipa_module import \
|
from ansible.module_utils.ansible_freeipa_module import \
|
||||||
IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, \
|
IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, \
|
||||||
gen_add_list, gen_intersection_list, api_check_param
|
gen_add_list, gen_intersection_list, api_check_param
|
||||||
|
from ansible.module_utils import six
|
||||||
|
if six.PY3:
|
||||||
|
unicode = str
|
||||||
|
|
||||||
|
|
||||||
def find_group(module, name):
|
def find_group(module, name):
|
||||||
@@ -257,6 +368,22 @@ def gen_member_args(user, group, service, externalmember, idoverrideuser):
|
|||||||
return _args
|
return _args
|
||||||
|
|
||||||
|
|
||||||
|
def check_parameters(module, state, action):
|
||||||
|
invalid = []
|
||||||
|
if state == "present":
|
||||||
|
if action == "member":
|
||||||
|
invalid = ["description", "gid", "posix", "nonposix", "external",
|
||||||
|
"nomembers"]
|
||||||
|
|
||||||
|
else:
|
||||||
|
invalid = ["description", "gid", "posix", "nonposix", "external",
|
||||||
|
"nomembers"]
|
||||||
|
if action == "group":
|
||||||
|
invalid.extend(["user", "group", "service", "externalmember"])
|
||||||
|
|
||||||
|
module.params_fail_used_invalid(invalid, state, action)
|
||||||
|
|
||||||
|
|
||||||
def is_external_group(res_find):
|
def is_external_group(res_find):
|
||||||
"""Verify if the result group is an external group."""
|
"""Verify if the result group is an external group."""
|
||||||
return res_find and 'ipaexternalgroup' in res_find['objectclass']
|
return res_find and 'ipaexternalgroup' in res_find['objectclass']
|
||||||
@@ -285,45 +412,63 @@ def check_objectclass_args(module, res_find, posix, external):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
group_spec = dict(
|
||||||
|
# present
|
||||||
|
description=dict(type="str", default=None),
|
||||||
|
gid=dict(type="int", aliases=["gidnumber"], default=None),
|
||||||
|
nonposix=dict(required=False, type='bool', default=None),
|
||||||
|
external=dict(required=False, type='bool', default=None),
|
||||||
|
posix=dict(required=False, type='bool', default=None),
|
||||||
|
nomembers=dict(required=False, type='bool', default=None),
|
||||||
|
user=dict(required=False, type='list', elements="str",
|
||||||
|
default=None),
|
||||||
|
group=dict(required=False, type='list', elements="str",
|
||||||
|
default=None),
|
||||||
|
service=dict(required=False, type='list', elements="str",
|
||||||
|
default=None),
|
||||||
|
idoverrideuser=dict(required=False, type='list', elements="str",
|
||||||
|
default=None),
|
||||||
|
membermanager_user=dict(required=False, type='list',
|
||||||
|
elements="str", default=None),
|
||||||
|
membermanager_group=dict(required=False, type='list',
|
||||||
|
elements="str", default=None),
|
||||||
|
externalmember=dict(required=False, type='list', elements="str",
|
||||||
|
default=None,
|
||||||
|
aliases=[
|
||||||
|
"ipaexternalmember",
|
||||||
|
"external_member"
|
||||||
|
])
|
||||||
|
)
|
||||||
ansible_module = IPAAnsibleModule(
|
ansible_module = IPAAnsibleModule(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
# general
|
# general
|
||||||
name=dict(type="list", elements="str", aliases=["cn"],
|
name=dict(type="list", elements="str", aliases=["cn"],
|
||||||
required=True),
|
default=None, required=False),
|
||||||
# present
|
groups=dict(type="list",
|
||||||
description=dict(type="str", default=None),
|
default=None,
|
||||||
gid=dict(type="int", aliases=["gidnumber"], default=None),
|
options=dict(
|
||||||
nonposix=dict(required=False, type='bool', default=None),
|
# Here name is a simple string
|
||||||
external=dict(required=False, type='bool', default=None),
|
name=dict(type="str", required=True,
|
||||||
posix=dict(required=False, type='bool', default=None),
|
aliases=["cn"]),
|
||||||
nomembers=dict(required=False, type='bool', default=None),
|
# Add group specific parameters
|
||||||
user=dict(required=False, type='list', elements="str",
|
**group_spec
|
||||||
default=None),
|
),
|
||||||
group=dict(required=False, type='list', elements="str",
|
elements='dict',
|
||||||
default=None),
|
required=False),
|
||||||
service=dict(required=False, type='list', elements="str",
|
# general
|
||||||
default=None),
|
|
||||||
idoverrideuser=dict(required=False, type='list', elements="str",
|
|
||||||
default=None),
|
|
||||||
membermanager_user=dict(required=False, type='list',
|
|
||||||
elements="str", default=None),
|
|
||||||
membermanager_group=dict(required=False, type='list',
|
|
||||||
elements="str", default=None),
|
|
||||||
externalmember=dict(required=False, type='list', elements="str",
|
|
||||||
default=None,
|
|
||||||
aliases=[
|
|
||||||
"ipaexternalmember",
|
|
||||||
"external_member"
|
|
||||||
]),
|
|
||||||
action=dict(type="str", default="group",
|
action=dict(type="str", default="group",
|
||||||
choices=["member", "group"]),
|
choices=["member", "group"]),
|
||||||
# state
|
|
||||||
state=dict(type="str", default="present",
|
state=dict(type="str", default="present",
|
||||||
choices=["present", "absent"]),
|
choices=["present", "absent"]),
|
||||||
|
|
||||||
|
# Add group specific parameters for simple use case
|
||||||
|
**group_spec
|
||||||
),
|
),
|
||||||
# It does not make sense to set posix, nonposix or external at the
|
# It does not make sense to set posix, nonposix or external at the
|
||||||
# same time
|
# same time
|
||||||
mutually_exclusive=[['posix', 'nonposix', 'external']],
|
mutually_exclusive=[['posix', 'nonposix', 'external'],
|
||||||
|
["name", "groups"]],
|
||||||
|
required_one_of=[["name", "groups"]],
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -333,6 +478,7 @@ def main():
|
|||||||
|
|
||||||
# general
|
# general
|
||||||
names = ansible_module.params_get("name")
|
names = ansible_module.params_get("name")
|
||||||
|
groups = ansible_module.params_get("groups")
|
||||||
|
|
||||||
# present
|
# present
|
||||||
description = ansible_module.params_get("description")
|
description = ansible_module.params_get("description")
|
||||||
@@ -354,31 +500,26 @@ def main():
|
|||||||
state = ansible_module.params_get("state")
|
state = ansible_module.params_get("state")
|
||||||
|
|
||||||
# Check parameters
|
# Check parameters
|
||||||
invalid = []
|
|
||||||
|
if (names is None or len(names) < 1) and \
|
||||||
|
(groups is None or len(groups) < 1):
|
||||||
|
ansible_module.fail_json(msg="At least one name or groups is required")
|
||||||
|
|
||||||
if state == "present":
|
if state == "present":
|
||||||
if len(names) != 1:
|
if names is not None and len(names) != 1:
|
||||||
ansible_module.fail_json(
|
ansible_module.fail_json(
|
||||||
msg="Only one group can be added at a time.")
|
msg="Only one group can be added at a time using 'name'.")
|
||||||
if action == "member":
|
|
||||||
invalid = ["description", "gid", "posix", "nonposix", "external",
|
|
||||||
"nomembers"]
|
|
||||||
|
|
||||||
if state == "absent":
|
check_parameters(ansible_module, state, action)
|
||||||
if len(names) < 1:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="No name given.")
|
|
||||||
invalid = ["description", "gid", "posix", "nonposix", "external",
|
|
||||||
"nomembers"]
|
|
||||||
if action == "group":
|
|
||||||
invalid.extend(["user", "group", "service", "externalmember"])
|
|
||||||
|
|
||||||
ansible_module.params_fail_used_invalid(invalid, state, action)
|
|
||||||
|
|
||||||
if external is False:
|
if external is False:
|
||||||
ansible_module.fail_json(
|
ansible_module.fail_json(
|
||||||
msg="group can not be non-external")
|
msg="group can not be non-external")
|
||||||
|
|
||||||
|
# Use groups if names is None
|
||||||
|
if groups is not None:
|
||||||
|
names = groups
|
||||||
|
|
||||||
# Init
|
# Init
|
||||||
|
|
||||||
changed = False
|
changed = False
|
||||||
@@ -415,8 +556,57 @@ def main():
|
|||||||
"supported by your IPA version")
|
"supported by your IPA version")
|
||||||
|
|
||||||
commands = []
|
commands = []
|
||||||
|
group_set = set()
|
||||||
|
|
||||||
|
for group_name in names:
|
||||||
|
if isinstance(group_name, dict):
|
||||||
|
name = group_name.get("name")
|
||||||
|
if name in group_set:
|
||||||
|
ansible_module.fail_json(
|
||||||
|
msg="group '%s' is used more than once" % name)
|
||||||
|
group_set.add(name)
|
||||||
|
# present
|
||||||
|
description = group_name.get("description")
|
||||||
|
gid = group_name.get("gid")
|
||||||
|
nonposix = group_name.get("nonposix")
|
||||||
|
external = group_name.get("external")
|
||||||
|
idoverrideuser = group_name.get("idoverrideuser")
|
||||||
|
posix = group_name.get("posix")
|
||||||
|
# Check mutually exclusive condition for multiple groups
|
||||||
|
# creation. It's not possible to check it with
|
||||||
|
# `mutually_exclusive` argument in `IPAAnsibleModule` class
|
||||||
|
# because it accepts only (list[str] or list[list[str]]). Here
|
||||||
|
# we need to loop over all groups and fail on mutually
|
||||||
|
# exclusive ones.
|
||||||
|
if all((posix, nonposix)) or\
|
||||||
|
all((posix, external)) or\
|
||||||
|
all((nonposix, external)):
|
||||||
|
ansible_module.fail_json(
|
||||||
|
msg="parameters are mutually exclusive for group "
|
||||||
|
"`{0}`: posix|nonposix|external".format(name))
|
||||||
|
# Duplicating the condition for multiple group creation
|
||||||
|
if external is False:
|
||||||
|
ansible_module.fail_json(
|
||||||
|
msg="group can not be non-external")
|
||||||
|
# If nonposix is used, set posix as not nonposix
|
||||||
|
if nonposix is not None:
|
||||||
|
posix = not nonposix
|
||||||
|
user = group_name.get("user")
|
||||||
|
group = group_name.get("group")
|
||||||
|
service = group_name.get("service")
|
||||||
|
membermanager_user = group_name.get("membermanager_user")
|
||||||
|
membermanager_group = group_name.get("membermanager_group")
|
||||||
|
externalmember = group_name.get("externalmember")
|
||||||
|
nomembers = group_name.get("nomembers")
|
||||||
|
|
||||||
|
check_parameters(ansible_module, state, action)
|
||||||
|
|
||||||
|
elif isinstance(group_name, (str, unicode)):
|
||||||
|
name = group_name
|
||||||
|
else:
|
||||||
|
ansible_module.fail_json(msg="Group '%s' is not valid" %
|
||||||
|
repr(group_name))
|
||||||
|
|
||||||
for name in names:
|
|
||||||
# Make sure group exists
|
# Make sure group exists
|
||||||
res_find = find_group(ansible_module, name)
|
res_find = find_group(ansible_module, name)
|
||||||
|
|
||||||
|
|||||||
13
tests/group/create_groups_json.yml
Normal file
13
tests/group/create_groups_json.yml
Normal 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
25
tests/group/groups.sh
Normal 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"
|
||||||
@@ -37,3 +37,27 @@
|
|||||||
when: groups['ipaclients'] is not defined or not groups['ipaclients']
|
when: groups['ipaclients'] is not defined or not groups['ipaclients']
|
||||||
vars:
|
vars:
|
||||||
ipa_context: client
|
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
143
tests/group/test_groups.yml
Normal 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
|
||||||
35
tests/group/test_groups_absent.yml
Normal file
35
tests/group/test_groups_absent.yml
Normal 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
|
||||||
395
tests/group/test_groups_external_nonposix.yml
Normal file
395
tests/group/test_groups_external_nonposix.yml
Normal 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
|
||||||
40
tests/group/test_groups_present.yml
Normal file
40
tests/group/test_groups_present.yml
Normal 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
|
||||||
47
tests/group/test_groups_present_slice.yml
Normal file
47
tests/group/test_groups_present_slice.yml
Normal 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
|
||||||
@@ -39,6 +39,7 @@ tests/pytests/conftest.py pylint:ansible-format-automatic-specification
|
|||||||
tests/sanity/sanity.sh shebang!skip
|
tests/sanity/sanity.sh shebang!skip
|
||||||
tests/user/users.sh shebang!skip
|
tests/user/users.sh shebang!skip
|
||||||
tests/user/users_absent.sh shebang!skip
|
tests/user/users_absent.sh shebang!skip
|
||||||
|
tests/group/groups.sh shebang!skip
|
||||||
tests/utils.py pylint:ansible-format-automatic-specification
|
tests/utils.py pylint:ansible-format-automatic-specification
|
||||||
utils/ansible-doc-test shebang!skip
|
utils/ansible-doc-test shebang!skip
|
||||||
utils/build-galaxy-release.sh shebang!skip
|
utils/build-galaxy-release.sh shebang!skip
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ tests/pytests/conftest.py pylint:ansible-format-automatic-specification
|
|||||||
tests/sanity/sanity.sh shebang!skip
|
tests/sanity/sanity.sh shebang!skip
|
||||||
tests/user/users.sh shebang!skip
|
tests/user/users.sh shebang!skip
|
||||||
tests/user/users_absent.sh shebang!skip
|
tests/user/users_absent.sh shebang!skip
|
||||||
|
tests/group/groups.sh shebang!skip
|
||||||
tests/utils.py pylint:ansible-format-automatic-specification
|
tests/utils.py pylint:ansible-format-automatic-specification
|
||||||
utils/ansible-doc-test shebang!skip
|
utils/ansible-doc-test shebang!skip
|
||||||
utils/build-galaxy-release.sh shebang!skip
|
utils/build-galaxy-release.sh shebang!skip
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ tests/pytests/conftest.py pylint:ansible-format-automatic-specification
|
|||||||
tests/sanity/sanity.sh shebang!skip
|
tests/sanity/sanity.sh shebang!skip
|
||||||
tests/user/users.sh shebang!skip
|
tests/user/users.sh shebang!skip
|
||||||
tests/user/users_absent.sh shebang!skip
|
tests/user/users_absent.sh shebang!skip
|
||||||
|
tests/group/groups.sh shebang!skip
|
||||||
tests/utils.py pylint:ansible-format-automatic-specification
|
tests/utils.py pylint:ansible-format-automatic-specification
|
||||||
utils/ansible-doc-test shebang!skip
|
utils/ansible-doc-test shebang!skip
|
||||||
utils/build-galaxy-release.sh shebang!skip
|
utils/build-galaxy-release.sh shebang!skip
|
||||||
|
|||||||
Reference in New Issue
Block a user