mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-03-30 15:23:06 +00:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3a6919416 | ||
|
|
e9c6e93608 | ||
|
|
f40f4d4c9a | ||
|
|
7b7d9c9957 | ||
|
|
c0c3394d8d | ||
|
|
11205102af | ||
|
|
22401d18d6 | ||
|
|
9b5a54c4fa | ||
|
|
9920a76777 | ||
|
|
249eab6047 | ||
|
|
29f046b8e2 | ||
|
|
2317c20556 | ||
|
|
0d1f8b53b8 | ||
|
|
0a468d32e8 | ||
|
|
03c65bd761 | ||
|
|
b87b346a0a | ||
|
|
e92db5c5cd | ||
|
|
1028f61b6c | ||
|
|
1fde1764af | ||
|
|
4321478cf0 | ||
|
|
900c76e810 | ||
|
|
1ecdbd3a49 | ||
|
|
47a1d50c84 | ||
|
|
3fe41a5260 | ||
|
|
3a304e8bd7 | ||
|
|
86e089fd42 | ||
|
|
3eb86b2c2d | ||
|
|
3bd68ac0fa | ||
|
|
0f2c37612e | ||
|
|
4e831b0cb8 | ||
|
|
34973c04c6 | ||
|
|
bc694b722c | ||
|
|
92d579be41 | ||
|
|
e55a41ca0c | ||
|
|
0f7ebd22fd | ||
|
|
f4c9e28715 | ||
|
|
81e6cbe6b7 | ||
|
|
9ecbe2315e | ||
|
|
102d6c5a6d | ||
|
|
66bbc50c4d | ||
|
|
a38106afae | ||
|
|
47940b48c6 | ||
|
|
8114120814 | ||
|
|
505cb356c1 | ||
|
|
d2e0cad90b | ||
|
|
9c735939a2 | ||
|
|
22214dafff | ||
|
|
2c9ee7d842 | ||
|
|
de3c6c0ace | ||
|
|
ff084fbd96 | ||
|
|
ca5496918a | ||
|
|
48c0fd0a28 | ||
|
|
f2a1d50b82 | ||
|
|
b22bf4dfb9 | ||
|
|
f012da22ce |
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
python-version: "3.x"
|
||||
- name: Run ansible-lint
|
||||
run: |
|
||||
pip install "ansible-core>=2.16,<2.17" 'ansible-lint>=6.21'
|
||||
pip install "ansible-core>=2.16,<2.17" 'ansible-lint>=6.22'
|
||||
utils/build-galaxy-release.sh -ki
|
||||
cd .galaxy-build
|
||||
ansible-lint --profile production --exclude tests/integration/ --exclude tests/unit/ --parseable --nocolor
|
||||
|
||||
@@ -133,6 +133,22 @@ Example playbook to enable a zone:
|
||||
state: enabled
|
||||
```
|
||||
|
||||
Example playbook to allow per-zone privilege delegation:
|
||||
|
||||
``` yaml
|
||||
---
|
||||
- name: Playbook to enable per-zone privilege delegation
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Enable privilege delegation.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: testzone.local
|
||||
permission: true
|
||||
```
|
||||
|
||||
|
||||
Example playbook to remove a zone:
|
||||
```yaml
|
||||
@@ -223,6 +239,7 @@ Variable | Description | Required
|
||||
`ttl`| Time to live for records at zone apex | no
|
||||
`default_ttl`| Time to live for records without explicit TTL definition | no
|
||||
`nsec3param_rec`| NSEC3PARAM record for zone in format: hash_algorithm flags iterations salt | no
|
||||
`permission` \| `managedby` | Set per-zone access delegation permission. | no
|
||||
`skip_overlap_check`| Force DNS zone creation even if it will overlap with an existing zone | no
|
||||
`skip_nameserver_check` | Force DNS zone creation even if nameserver is not resolvable | no
|
||||
|
||||
@@ -238,4 +255,6 @@ Variable | Description | Returned When
|
||||
Authors
|
||||
=======
|
||||
|
||||
Sergio Oliveira Campos
|
||||
- Sergio Oliveira Campos
|
||||
- Thomas Woerner
|
||||
- Rafael Jeffman
|
||||
|
||||
@@ -130,6 +130,45 @@ And ensure the presence of the groups with this example playbook:
|
||||
groups: "{{ groups }}"
|
||||
```
|
||||
|
||||
Example playbook to rename a group:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to rename a single group
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Rename group appops to webops
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: appops
|
||||
rename: webops
|
||||
state: renamed
|
||||
```
|
||||
|
||||
Several groups can also be renamed with a single task, as in the example playbook:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to rename multiple groups
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name Rename group1 to newgroup1 and group2 to newgroup2
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
groups:
|
||||
- name: group1
|
||||
rename: newgroup1
|
||||
- name: group2
|
||||
rename: newgroup2
|
||||
state: renamed
|
||||
```
|
||||
|
||||
Example playbook to add users to a group:
|
||||
|
||||
```yaml
|
||||
@@ -262,11 +301,13 @@ Variable | Description | Required
|
||||
`membermanager_group` | List of member manager groups assigned to this group. Only usable with IPA versions 4.8.4 and up. | no
|
||||
`externalmember` \| `ipaexternalmember` \| `external_member`| List of members of a trusted domain in DOM\\name or name@domain form. | no
|
||||
`idoverrideuser` | List of user ID overrides to manage. Only usable with IPA versions 4.8.7 and up.| no
|
||||
`rename` \| `new_name` | Rename the user object to the new name string. Only usable with `state: renamed`. | no
|
||||
`action` | Work on group or member level. It can be on of `member` or `group` and defaults to `group`. | no
|
||||
`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | yes
|
||||
`state` | The state to ensure. It can be one of `present`, `absent` or `renamed`, default: `present`. | yes
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
- Thomas Woerner
|
||||
- Rafael Jeffman
|
||||
|
||||
@@ -93,6 +93,26 @@ Example playbook to make sure sudocmds are not present in Sudo Rule:
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Example playbook to ensure a Group of RunAs User is present in sudo rule:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage sudorule member
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure sudorule 'runasuser' has 'ipasuers' group as runas users.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: testrule1
|
||||
runasuser_group: ipausers
|
||||
action: member
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure Sudo Rule is absent:
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -279,7 +279,6 @@ Example playbook to disable a user:
|
||||
|
||||
This can also be done as an alternative with the `users` variable containing only names.
|
||||
|
||||
|
||||
Example playbook to enable users:
|
||||
|
||||
```yaml
|
||||
@@ -298,6 +297,22 @@ Example playbook to enable users:
|
||||
|
||||
This can also be done as an alternative with the `users` variable containing only names.
|
||||
|
||||
Example playbook to rename users:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Rename user pinky to reddy
|
||||
- ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: pinky
|
||||
rename: reddy
|
||||
state: enabled
|
||||
```
|
||||
|
||||
Example playbook to unlock users:
|
||||
|
||||
@@ -401,7 +416,7 @@ Variable | Description | Required
|
||||
`update_password` | Set password for a user in present state only on creation or always. It can be one of `always` or `on_create` and defaults to `always`. | no
|
||||
`preserve` | Delete a user, keeping the entry available for future use. (bool) | no
|
||||
`action` | Work on user or member level. It can be on of `member` or `user` and defaults to `user`. | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, `enabled`, `disabled`, `unlocked` or `undeleted`, default: `present`. Only `names` or `users` with only `name` set are allowed if state is not `present`. | yes
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, `enabled`, `disabled`, `renamed`, `unlocked` or `undeleted`, default: `present`. Only `names` or `users` with only `name` set are allowed if state is not `present`. | yes
|
||||
|
||||
|
||||
|
||||
@@ -458,10 +473,10 @@ Variable | Description | Required
|
||||
`smb_profile_path:` \| `ipantprofilepath` | SMB profile path, in UNC format. Requires FreeIPA version 4.8.0+. | no
|
||||
`smb_home_dir` \| `ipanthomedirectory` | SMB Home Directory, in UNC format. Requires FreeIPA version 4.8.0+. | no
|
||||
`smb_home_drive` \| `ipanthomedirectorydrive` | SMB Home Directory Drive, a single upercase letter (A-Z) followed by a colon (:), for example "U:". Requires FreeIPA version 4.8.0+. | no
|
||||
`rename` \| `new_name` | Rename the user object to the new name string. Only usable with `state: renamed`. | no
|
||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
=============
|
||||
|
||||
@@ -477,5 +492,5 @@ Variable | Description | Returned When
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
Rafael Jeffman
|
||||
- Thomas Woerner
|
||||
- Rafael Jeffman
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
---
|
||||
- name: Certificate manage example
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Playbook to manage sudorule member
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure sudorule 'runasuser' do not have 'ipasuers' group as runas users.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: testrule1
|
||||
runasuser_group: ipausers
|
||||
action: member
|
||||
state: absent
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Playbook to manage sudorule member
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure sudorule 'runasuser' has 'ipasuers' group as runas users.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: testrule1
|
||||
runasuser_group: ipausers
|
||||
action: member
|
||||
@@ -30,7 +30,8 @@ __all__ = ["gssapi", "netaddr", "api", "ipalib_errors", "Env",
|
||||
"kinit_password", "kinit_keytab", "run", "DN", "VERSION",
|
||||
"paths", "tasks", "get_credentials_if_valid", "Encoding",
|
||||
"DNSName", "getargspec", "certificate_loader",
|
||||
"write_certificate_list", "boolean", "template_str"]
|
||||
"write_certificate_list", "boolean", "template_str",
|
||||
"urlparse"]
|
||||
|
||||
import os
|
||||
# ansible-freeipa requires locale to be C, IPA requires utf-8.
|
||||
@@ -147,6 +148,11 @@ try:
|
||||
except ImportError:
|
||||
_dcerpc_bindings_installed = False # pylint: disable=invalid-name
|
||||
|
||||
try:
|
||||
from urllib.parse import urlparse
|
||||
except ImportError:
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlparse
|
||||
|
||||
except ImportError as _err:
|
||||
ANSIBLE_FREEIPA_MODULE_IMPORT_ERROR = str(_err)
|
||||
|
||||
@@ -464,12 +470,11 @@ def _afm_convert(value):
|
||||
return value
|
||||
|
||||
|
||||
def module_params_get(module, name, allow_empty_string=False):
|
||||
def module_params_get(module, name, allow_empty_list_item=False):
|
||||
value = _afm_convert(module.params.get(name))
|
||||
|
||||
# Fail on empty strings in the list or if allow_empty_string is True
|
||||
# if there is another entry in the list together with the empty
|
||||
# string.
|
||||
# Fail on empty strings in the list or if allow_empty_list_item is True
|
||||
# if there is another entry in the list together with the empty string.
|
||||
# Due to an issue in Ansible it is possible to use the empty string
|
||||
# "" for lists with choices, even if the empty list is not part of
|
||||
# the choices.
|
||||
@@ -477,7 +482,7 @@ def module_params_get(module, name, allow_empty_string=False):
|
||||
if isinstance(value, list):
|
||||
for val in value:
|
||||
if isinstance(val, (str, unicode)) and not val:
|
||||
if not allow_empty_string:
|
||||
if not allow_empty_list_item:
|
||||
module.fail_json(
|
||||
msg="Parameter '%s' contains an empty string" %
|
||||
name)
|
||||
@@ -489,8 +494,8 @@ def module_params_get(module, name, allow_empty_string=False):
|
||||
return value
|
||||
|
||||
|
||||
def module_params_get_lowercase(module, name, allow_empty_string=False):
|
||||
value = module_params_get(module, name, allow_empty_string)
|
||||
def module_params_get_lowercase(module, name, allow_empty_list_item=False):
|
||||
value = module_params_get(module, name, allow_empty_list_item)
|
||||
if isinstance(value, list):
|
||||
value = [v.lower() for v in value]
|
||||
if isinstance(value, (str, unicode)):
|
||||
@@ -498,6 +503,48 @@ def module_params_get_lowercase(module, name, allow_empty_string=False):
|
||||
return value
|
||||
|
||||
|
||||
def module_params_get_with_type_cast(
|
||||
module, name, datatype, allow_empty=False
|
||||
):
|
||||
"""
|
||||
Retrieve value set for module parameter as a specific data type.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
module: AnsibleModule
|
||||
The module from where to get the parameter value from.
|
||||
name: string
|
||||
The name of the parameter to retrieve.
|
||||
datatype: type
|
||||
The type to convert the value to, if value is not empty.
|
||||
allow_empty: bool
|
||||
Allow an empty string for non list parameters or a list
|
||||
containing (only) an empty string item. This is used for
|
||||
resetting parameters to the default value.
|
||||
|
||||
"""
|
||||
value = module_params_get(module, name, allow_empty)
|
||||
if not allow_empty and value == "":
|
||||
module.fail_json(
|
||||
msg="Argument '%s' must not be an empty string" % (name,)
|
||||
)
|
||||
if value is not None and value != "":
|
||||
try:
|
||||
if datatype is bool:
|
||||
# We let Ansible handle bool values
|
||||
value = boolean(value)
|
||||
else:
|
||||
value = datatype(value)
|
||||
except ValueError:
|
||||
module.fail_json(
|
||||
msg="Invalid value '%s' for argument '%s'" % (value, name)
|
||||
)
|
||||
except TypeError as terr:
|
||||
# If Ansible fails to parse a boolean, it will raise TypeError
|
||||
module.fail_json(msg="Param '%s': %s" % (name, str(terr)))
|
||||
return value
|
||||
|
||||
|
||||
def api_get_domain():
|
||||
return api.env.domain
|
||||
|
||||
@@ -1045,7 +1092,7 @@ class IPAAnsibleModule(AnsibleModule):
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
def params_get(self, name, allow_empty_string=False):
|
||||
def params_get(self, name, allow_empty_list_item=False):
|
||||
"""
|
||||
Retrieve value set for module parameter.
|
||||
|
||||
@@ -1053,13 +1100,13 @@ class IPAAnsibleModule(AnsibleModule):
|
||||
----------
|
||||
name: string
|
||||
The name of the parameter to retrieve.
|
||||
allow_empty_string: bool
|
||||
allow_empty_list_item: bool
|
||||
The parameter allowes to have empty strings in a list
|
||||
|
||||
"""
|
||||
return module_params_get(self, name, allow_empty_string)
|
||||
return module_params_get(self, name, allow_empty_list_item)
|
||||
|
||||
def params_get_lowercase(self, name, allow_empty_string=False):
|
||||
def params_get_lowercase(self, name, allow_empty_list_item=False):
|
||||
"""
|
||||
Retrieve value set for module parameter as lowercase, if not None.
|
||||
|
||||
@@ -1067,11 +1114,34 @@ class IPAAnsibleModule(AnsibleModule):
|
||||
----------
|
||||
name: string
|
||||
The name of the parameter to retrieve.
|
||||
allow_empty_string: bool
|
||||
allow_empty_list_item: bool
|
||||
The parameter allowes to have empty strings in a list
|
||||
|
||||
"""
|
||||
return module_params_get_lowercase(self, name, allow_empty_string)
|
||||
return module_params_get_lowercase(self, name, allow_empty_list_item)
|
||||
|
||||
def params_get_with_type_cast(
|
||||
self, name, datatype, allow_empty=True
|
||||
):
|
||||
"""
|
||||
Retrieve value set for module parameter as a specific data type.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
name: string
|
||||
The name of the parameter to retrieve.
|
||||
datatype: type
|
||||
The type to convert the value to, if not empty.
|
||||
datatype: type
|
||||
The type to convert the value to, if value is not empty.
|
||||
allow_empty: bool
|
||||
Allow an empty string for non list parameters or a list
|
||||
containing (only) an empty string item. This is used for
|
||||
resetting parameters to the default value.
|
||||
|
||||
"""
|
||||
return module_params_get_with_type_cast(
|
||||
self, name, datatype, allow_empty)
|
||||
|
||||
def params_fail_used_invalid(self, invalid_params, state, action=None):
|
||||
"""
|
||||
|
||||
@@ -470,13 +470,13 @@ def main():
|
||||
"netbios_name": "netbios_name",
|
||||
"add_sids": "add_sids",
|
||||
}
|
||||
allow_empty_string = ["pac_type", "user_auth_type", "configstring"]
|
||||
reverse_field_map = {v: k for k, v in field_map.items()}
|
||||
allow_empty_list_item = ["pac_type", "user_auth_type", "configstring"]
|
||||
|
||||
params = {}
|
||||
for x in field_map:
|
||||
val = ansible_module.params_get(
|
||||
x, allow_empty_string=x in allow_empty_string)
|
||||
x, allow_empty_list_item=x in allow_empty_list_item)
|
||||
|
||||
if val is not None:
|
||||
params[field_map.get(x, x)] = val
|
||||
|
||||
@@ -180,10 +180,10 @@ def main():
|
||||
names = ansible_module.params_get("name")
|
||||
|
||||
# present
|
||||
permission = ansible_module.params_get("permission")
|
||||
attribute = ansible_module.params_get("attribute")
|
||||
permission = ansible_module.params_get_lowercase("permission")
|
||||
attribute = ansible_module.params_get_lowercase("attribute")
|
||||
membergroup = ansible_module.params_get("membergroup")
|
||||
group = ansible_module.params_get("group")
|
||||
group = ansible_module.params_get_lowercase("group")
|
||||
action = ansible_module.params_get("action")
|
||||
# state
|
||||
state = ansible_module.params_get("state")
|
||||
@@ -233,6 +233,7 @@ def main():
|
||||
|
||||
commands = []
|
||||
for name in names:
|
||||
args = {}
|
||||
# Make sure delegation exists
|
||||
res_find = find_delegation(ansible_module, name)
|
||||
|
||||
@@ -244,14 +245,7 @@ def main():
|
||||
|
||||
if action == "delegation":
|
||||
# Found the delegation
|
||||
if res_find is not None:
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
if not compare_args_ipa(ansible_module, args,
|
||||
res_find):
|
||||
commands.append([name, "delegation_mod", args])
|
||||
else:
|
||||
if res_find is None:
|
||||
commands.append([name, "delegation_add", args])
|
||||
|
||||
elif action == "member":
|
||||
@@ -265,9 +259,7 @@ def main():
|
||||
# New attribute list (add given ones to find result)
|
||||
# Make list with unique entries
|
||||
attrs = list(set(list(res_find["attrs"]) + attribute))
|
||||
if len(attrs) > len(res_find["attrs"]):
|
||||
commands.append([name, "delegation_mod",
|
||||
{"attrs": attrs}])
|
||||
args["attrs"] = attrs
|
||||
|
||||
elif state == "absent":
|
||||
if action == "delegation":
|
||||
@@ -288,15 +280,18 @@ def main():
|
||||
if len(attrs) < 1:
|
||||
ansible_module.fail_json(
|
||||
msg="At minimum one attribute is needed.")
|
||||
|
||||
# Entries New number of attributes is smaller
|
||||
if len(attrs) < len(res_find["attrs"]):
|
||||
commands.append([name, "delegation_mod",
|
||||
{"attrs": attrs}])
|
||||
args["attrs"] = attrs
|
||||
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Manage members
|
||||
if (
|
||||
args and res_find and
|
||||
not compare_args_ipa(ansible_module, args, res_find)
|
||||
):
|
||||
commands.append([name, "delegation_mod", args])
|
||||
|
||||
# Execute commands
|
||||
|
||||
changed = ansible_module.execute_ipa_commands(commands)
|
||||
|
||||
@@ -142,6 +142,11 @@ options:
|
||||
salt.
|
||||
required: false
|
||||
type: str
|
||||
permission:
|
||||
description: Set per-zone access delegation permission.
|
||||
required: false
|
||||
type: bool
|
||||
aliases: ["managedby"]
|
||||
skip_overlap_check:
|
||||
description: |
|
||||
Force DNS zone creation even if it will overlap with an existing zone
|
||||
@@ -154,6 +159,7 @@ options:
|
||||
author:
|
||||
- Sergio Oliveira Campos (@seocam)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
- Rafael Jeffman (@rjeffman)
|
||||
""" # noqa: E501
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -253,6 +259,9 @@ class DNSZoneModule(IPAAnsibleModule):
|
||||
"idnsallowdynupdate": "dynamic_update",
|
||||
"idnssecinlinesigning": "dnssec",
|
||||
"idnsupdatepolicy": "update_policy",
|
||||
# FreeIPA uses 'managedby' for dnszone and dnsforwardzone
|
||||
# to manage 'permissions'.
|
||||
"managedby": "permission",
|
||||
# Mapping by method
|
||||
"idnsforwarders": self.get_ipa_idnsforwarders,
|
||||
"idnsallowtransfer": self.get_ipa_idnsallowtransfer,
|
||||
@@ -434,7 +443,7 @@ class DNSZoneModule(IPAAnsibleModule):
|
||||
is_zone_active = False
|
||||
else:
|
||||
zone = response["result"]
|
||||
# FreeIPA 4.9.10+ and 4.10 use proper mapping for boolean vaalues.
|
||||
# FreeIPA 4.9.10+ and 4.10 use proper mapping for boolean values.
|
||||
# See: https://github.com/freeipa/freeipa/pull/6294
|
||||
is_zone_active = (
|
||||
str(zone.get("idnszoneactive")[0]).upper() == "TRUE"
|
||||
@@ -462,18 +471,24 @@ class DNSZoneModule(IPAAnsibleModule):
|
||||
self.fail_json(
|
||||
msg="Either `name` or `name_from_ip` must be provided."
|
||||
)
|
||||
# check invalid parameters
|
||||
invalid = []
|
||||
if self.ipa_params.state != "present":
|
||||
invalid = ["name_from_ip"]
|
||||
|
||||
self.params_fail_used_invalid(invalid, self.ipa_params.state)
|
||||
invalid .extend(["name_from_ip"])
|
||||
if self.ipa_params.state == "absent":
|
||||
invalid.extend(["permission"])
|
||||
self.params_fail_used_invalid(invalid, self.ipa_params.state)
|
||||
|
||||
def define_ipa_commands(self):
|
||||
for zone_name in self.get_zone_names():
|
||||
# Look for existing zone in IPA
|
||||
zone, is_zone_active = self.get_zone(zone_name)
|
||||
args = self.ipa_params.get_ipa_command_args(zone=zone)
|
||||
|
||||
if self.ipa_params.state in ["present", "enabled", "disabled"]:
|
||||
args = self.ipa_params.get_ipa_command_args(zone=zone)
|
||||
# We'll handle "managedby" after dnszone add/mod.
|
||||
args.pop("managedby", None)
|
||||
|
||||
if not zone:
|
||||
# Since the zone doesn't exist we just create it
|
||||
# with given args
|
||||
@@ -487,6 +502,16 @@ class DNSZoneModule(IPAAnsibleModule):
|
||||
if not compare_args_ipa(self, args, zone):
|
||||
self.commands.append((zone_name, "dnszone_mod", args))
|
||||
|
||||
# Permissions must be set on existing zones.
|
||||
if self.ipa_params.permission is not None:
|
||||
is_managed = zone.get("managedby")
|
||||
if self.ipa_params.permission and not is_managed:
|
||||
self.commands.append(
|
||||
(zone_name, "dnszone_add_permission", {}))
|
||||
if not self.ipa_params.permission and is_managed:
|
||||
self.commands.append(
|
||||
(zone_name, "dnszone_remove_permission", {}))
|
||||
|
||||
if self.ipa_params.state == "enabled" and not is_zone_active:
|
||||
self.commands.append((zone_name, "dnszone_enable", {}))
|
||||
|
||||
@@ -555,6 +580,8 @@ def get_argument_spec():
|
||||
ttl=dict(type="int", required=False, default=None),
|
||||
default_ttl=dict(type="int", required=False, default=None),
|
||||
nsec3param_rec=dict(type="str", required=False, default=None),
|
||||
permission=dict(type="bool", required=False, default=None,
|
||||
aliases=["managedby"]),
|
||||
skip_nameserver_check=dict(type="bool", required=False, default=None),
|
||||
skip_overlap_check=dict(type="bool", required=False, default=None),
|
||||
)
|
||||
|
||||
@@ -123,6 +123,11 @@ options:
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
rename:
|
||||
description: Rename the group object
|
||||
required: false
|
||||
type: str
|
||||
aliases: ["new_name"]
|
||||
description:
|
||||
description: The group description
|
||||
type: str
|
||||
@@ -198,11 +203,16 @@ options:
|
||||
type: str
|
||||
default: group
|
||||
choices: ["member", "group"]
|
||||
rename:
|
||||
description: Rename the group object
|
||||
required: false
|
||||
type: str
|
||||
aliases: ["new_name"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
choices: ["present", "absent", "renamed"]
|
||||
author:
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
@@ -267,6 +277,13 @@ EXAMPLES = """
|
||||
group:
|
||||
- group2
|
||||
|
||||
# Rename a group
|
||||
- ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: oldname
|
||||
rename: newestname
|
||||
state: renamed
|
||||
|
||||
# Create a non-POSIX group
|
||||
- ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
@@ -380,18 +397,20 @@ def gen_member_args(user, group, service, externalmember, idoverrideuser):
|
||||
|
||||
|
||||
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 = ["description", "gid", "posix", "nonposix", "external",
|
||||
"nomembers"]
|
||||
if action == "group":
|
||||
if state == "present":
|
||||
invalid = []
|
||||
elif state == "absent":
|
||||
invalid.extend(["user", "group", "service", "externalmember"])
|
||||
|
||||
if state == "renamed":
|
||||
if action == "member":
|
||||
module.fail_json(
|
||||
msg="Action member can not be used with state: renamed.")
|
||||
invalid.extend(["user", "group", "service", "externalmember"])
|
||||
else:
|
||||
invalid.append("rename")
|
||||
module.params_fail_used_invalid(invalid, state, action)
|
||||
|
||||
|
||||
@@ -448,7 +467,9 @@ def main():
|
||||
aliases=[
|
||||
"ipaexternalmember",
|
||||
"external_member"
|
||||
])
|
||||
]),
|
||||
rename=dict(type="str", required=False, default=None,
|
||||
aliases=["new_name"]),
|
||||
)
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
@@ -470,7 +491,7 @@ def main():
|
||||
action=dict(type="str", default="group",
|
||||
choices=["member", "group"]),
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
choices=["present", "absent", "renamed"]),
|
||||
|
||||
# Add group specific parameters for simple use case
|
||||
**group_spec
|
||||
@@ -499,15 +520,19 @@ def main():
|
||||
idoverrideuser = ansible_module.params_get("idoverrideuser")
|
||||
posix = ansible_module.params_get("posix")
|
||||
nomembers = ansible_module.params_get("nomembers")
|
||||
user = ansible_module.params_get("user")
|
||||
group = ansible_module.params_get("group")
|
||||
user = ansible_module.params_get_lowercase("user")
|
||||
group = ansible_module.params_get_lowercase("group")
|
||||
# Services are not case sensitive
|
||||
service = ansible_module.params_get_lowercase("service")
|
||||
membermanager_user = ansible_module.params_get("membermanager_user")
|
||||
membermanager_group = ansible_module.params_get("membermanager_group")
|
||||
membermanager_user = (
|
||||
ansible_module.params_get_lowercase("membermanager_user"))
|
||||
membermanager_group = (
|
||||
ansible_module.params_get_lowercase("membermanager_group"))
|
||||
externalmember = ansible_module.params_get("externalmember")
|
||||
# rename
|
||||
rename = ansible_module.params_get("rename")
|
||||
# state and action
|
||||
action = ansible_module.params_get("action")
|
||||
# state
|
||||
state = ansible_module.params_get("state")
|
||||
|
||||
# Check parameters
|
||||
@@ -516,10 +541,11 @@ def main():
|
||||
(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 in ["present", "renamed"]:
|
||||
if names is not None and len(names) != 1:
|
||||
what = "renamed" if state == "renamed" else "added"
|
||||
ansible_module.fail_json(
|
||||
msg="Only one group can be added at a time using 'name'.")
|
||||
msg="Only one group can be %s at a time using 'name'." % what)
|
||||
|
||||
check_parameters(ansible_module, state, action)
|
||||
|
||||
@@ -633,6 +659,7 @@ def main():
|
||||
membermanager_group = group_name.get("membermanager_group")
|
||||
externalmember = group_name.get("externalmember")
|
||||
nomembers = group_name.get("nomembers")
|
||||
rename = group_name.get("rename")
|
||||
|
||||
check_parameters(ansible_module, state, action)
|
||||
|
||||
@@ -794,6 +821,11 @@ def main():
|
||||
membermanager_group,
|
||||
res_find.get("membermanager_group")
|
||||
)
|
||||
elif state == "renamed":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No group '%s'" % name)
|
||||
elif rename != name:
|
||||
commands.append([name, 'group_mod', {"rename": rename}])
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
|
||||
@@ -188,13 +188,12 @@ def find_hbacrule(module, name):
|
||||
elif len(_result["result"]) == 1:
|
||||
res = _result["result"][0]
|
||||
# hbacsvcgroup names are converted to lower case while creation with
|
||||
# hbacsvcgroup_add.
|
||||
# The hbacsvcgroup for sudo is builtin with the name "Sudo" though.
|
||||
# This breaks the lower case comparison. Therefore all
|
||||
# memberservice_hbacsvcgroup items are converted to lower case if
|
||||
# "Sudo" is in the list.
|
||||
# hbacsvcgroup_add, but builtin names may have mixed case as "Sudo",
|
||||
# breaking the lower case comparison. Therefore all
|
||||
# memberservice_hbacsvcgroup items are converted to lower case.
|
||||
# (See: https://pagure.io/freeipa/issue/9464).
|
||||
_member = "memberservice_hbacsvcgroup"
|
||||
if _member in res and "Sudo" in res[_member]:
|
||||
if _member in res:
|
||||
res[_member] = [item.lower() for item in res[_member]]
|
||||
return res
|
||||
|
||||
@@ -400,7 +399,8 @@ def main():
|
||||
|
||||
if hbacsvc is not None:
|
||||
hbacsvc_add, hbacsvc_del = gen_add_del_lists(
|
||||
hbacsvc, res_find.get("memberservice_hbacsvc"))
|
||||
hbacsvc, res_find.get("memberservice_hbacsvc"),
|
||||
)
|
||||
|
||||
if hbacsvcgroup is not None:
|
||||
hbacsvcgroup_add, hbacsvcgroup_del = gen_add_del_lists(
|
||||
|
||||
@@ -876,10 +876,11 @@ def main():
|
||||
allow_retrieve_keytab_hostgroup = ansible_module.params_get(
|
||||
"allow_retrieve_keytab_hostgroup")
|
||||
mac_address = ansible_module.params_get("mac_address")
|
||||
sshpubkey = ansible_module.params_get("sshpubkey",
|
||||
allow_empty_string=True)
|
||||
sshpubkey = ansible_module.params_get(
|
||||
"sshpubkey", allow_empty_list_item=True)
|
||||
userclass = ansible_module.params_get("userclass")
|
||||
auth_ind = ansible_module.params_get("auth_ind", allow_empty_string=True)
|
||||
auth_ind = ansible_module.params_get(
|
||||
"auth_ind", allow_empty_list_item=True)
|
||||
requires_pre_auth = ansible_module.params_get("requires_pre_auth")
|
||||
ok_as_delegate = ansible_module.params_get("ok_as_delegate")
|
||||
ok_to_auth_as_delegate = ansible_module.params_get(
|
||||
|
||||
@@ -181,16 +181,6 @@ def gen_args(description, nomembers, rename):
|
||||
return _args
|
||||
|
||||
|
||||
def gen_member_args(host, hostgroup):
|
||||
_args = {}
|
||||
if host is not None:
|
||||
_args["member_host"] = host
|
||||
if hostgroup is not None:
|
||||
_args["member_hostgroup"] = hostgroup
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
@@ -224,16 +214,20 @@ def main():
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
names = ansible_module.params_get("name")
|
||||
names = ansible_module.params_get_lowercase("name")
|
||||
|
||||
# present
|
||||
description = ansible_module.params_get("description")
|
||||
nomembers = ansible_module.params_get("nomembers")
|
||||
host = ansible_module.params_get("host")
|
||||
hostgroup = ansible_module.params_get("hostgroup")
|
||||
membermanager_user = ansible_module.params_get("membermanager_user")
|
||||
membermanager_group = ansible_module.params_get("membermanager_group")
|
||||
rename = ansible_module.params_get("rename")
|
||||
hostgroup = ansible_module.params_get_lowercase("hostgroup")
|
||||
membermanager_user = ansible_module.params_get_lowercase(
|
||||
"membermanager_user"
|
||||
)
|
||||
membermanager_group = ansible_module.params_get_lowercase(
|
||||
"membermanager_group"
|
||||
)
|
||||
rename = ansible_module.params_get_lowercase("rename")
|
||||
action = ansible_module.params_get("action")
|
||||
# state
|
||||
state = ansible_module.params_get("state")
|
||||
@@ -306,6 +300,12 @@ def main():
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
# clean add/del lists
|
||||
host_add, host_del = [], []
|
||||
hostgroup_add, hostgroup_del = [], []
|
||||
membermanager_user_add, membermanager_user_del = [], []
|
||||
membermanager_group_add, membermanager_group_del = [], []
|
||||
|
||||
# Make sure hostgroup exists
|
||||
res_find = find_hostgroup(ansible_module, name)
|
||||
|
||||
@@ -328,63 +328,26 @@ def main():
|
||||
# Set res_find to empty dict for next step
|
||||
res_find = {}
|
||||
|
||||
member_args = gen_member_args(host, hostgroup)
|
||||
if not compare_args_ipa(ansible_module, member_args,
|
||||
res_find):
|
||||
# Generate addition and removal lists
|
||||
host_add, host_del = gen_add_del_lists(
|
||||
host, res_find.get("member_host"))
|
||||
# Generate addition and removal lists
|
||||
host_add, host_del = gen_add_del_lists(
|
||||
host, res_find.get("member_host")
|
||||
)
|
||||
|
||||
hostgroup_add, hostgroup_del = gen_add_del_lists(
|
||||
hostgroup, res_find.get("member_hostgroup"))
|
||||
|
||||
# Add members
|
||||
if len(host_add) > 0 or len(hostgroup_add) > 0:
|
||||
commands.append([name, "hostgroup_add_member",
|
||||
{
|
||||
"host": host_add,
|
||||
"hostgroup": hostgroup_add,
|
||||
}])
|
||||
# Remove members
|
||||
if len(host_del) > 0 or len(hostgroup_del) > 0:
|
||||
commands.append([name, "hostgroup_remove_member",
|
||||
{
|
||||
"host": host_del,
|
||||
"hostgroup": hostgroup_del,
|
||||
}])
|
||||
|
||||
membermanager_user_add, membermanager_user_del = \
|
||||
gen_add_del_lists(
|
||||
membermanager_user,
|
||||
res_find.get("membermanager_user")
|
||||
)
|
||||
|
||||
membermanager_group_add, membermanager_group_del = \
|
||||
gen_add_del_lists(
|
||||
membermanager_group,
|
||||
res_find.get("membermanager_group")
|
||||
)
|
||||
hostgroup_add, hostgroup_del = gen_add_del_lists(
|
||||
hostgroup, res_find.get("member_hostgroup")
|
||||
)
|
||||
|
||||
if has_add_membermanager:
|
||||
# Add membermanager users and groups
|
||||
if len(membermanager_user_add) > 0 or \
|
||||
len(membermanager_group_add) > 0:
|
||||
commands.append(
|
||||
[name, "hostgroup_add_member_manager",
|
||||
{
|
||||
"user": membermanager_user_add,
|
||||
"group": membermanager_group_add,
|
||||
}]
|
||||
membermanager_user_add, membermanager_user_del = \
|
||||
gen_add_del_lists(
|
||||
membermanager_user,
|
||||
res_find.get("membermanager_user")
|
||||
)
|
||||
# Remove member manager
|
||||
if len(membermanager_user_del) > 0 or \
|
||||
len(membermanager_group_del) > 0:
|
||||
commands.append(
|
||||
[name, "hostgroup_remove_member_manager",
|
||||
{
|
||||
"user": membermanager_user_del,
|
||||
"group": membermanager_group_del,
|
||||
}]
|
||||
|
||||
membermanager_group_add, membermanager_group_del = \
|
||||
gen_add_del_lists(
|
||||
membermanager_group,
|
||||
res_find.get("membermanager_group")
|
||||
)
|
||||
|
||||
elif action == "member":
|
||||
@@ -394,45 +357,25 @@ def main():
|
||||
|
||||
# Reduce add lists for member_host and member_hostgroup,
|
||||
# to new entries only that are not in res_find.
|
||||
if host is not None and "member_host" in res_find:
|
||||
host = gen_add_list(host, res_find["member_host"])
|
||||
if hostgroup is not None \
|
||||
and "member_hostgroup" in res_find:
|
||||
hostgroup = gen_add_list(
|
||||
hostgroup, res_find["member_hostgroup"])
|
||||
|
||||
# Ensure members are present
|
||||
commands.append([name, "hostgroup_add_member",
|
||||
{
|
||||
"host": host,
|
||||
"hostgroup": hostgroup,
|
||||
}])
|
||||
host_add = gen_add_list(
|
||||
host, res_find.get("member_host")
|
||||
)
|
||||
hostgroup_add = gen_add_list(
|
||||
hostgroup, res_find.get("member_hostgroup")
|
||||
)
|
||||
|
||||
if has_add_membermanager:
|
||||
# Reduce add list for membermanager_user and
|
||||
# membermanager_group to new entries only that are
|
||||
# not in res_find.
|
||||
if membermanager_user is not None \
|
||||
and "membermanager_user" in res_find:
|
||||
membermanager_user = gen_add_list(
|
||||
membermanager_user,
|
||||
res_find["membermanager_user"])
|
||||
if membermanager_group is not None \
|
||||
and "membermanager_group" in res_find:
|
||||
membermanager_group = gen_add_list(
|
||||
membermanager_group,
|
||||
res_find["membermanager_group"])
|
||||
|
||||
# Add membermanager users and groups
|
||||
if membermanager_user is not None or \
|
||||
membermanager_group is not None:
|
||||
commands.append(
|
||||
[name, "hostgroup_add_member_manager",
|
||||
{
|
||||
"user": membermanager_user,
|
||||
"group": membermanager_group,
|
||||
}]
|
||||
)
|
||||
membermanager_user_add = gen_add_list(
|
||||
membermanager_user,
|
||||
res_find.get("membermanager_user")
|
||||
)
|
||||
membermanager_group_add = gen_add_list(
|
||||
membermanager_group,
|
||||
res_find.get("membermanager_group")
|
||||
)
|
||||
|
||||
elif state == "renamed":
|
||||
if res_find is not None:
|
||||
@@ -463,46 +406,72 @@ def main():
|
||||
# Reduce del lists of member_host and member_hostgroup,
|
||||
# to the entries only that are in res_find.
|
||||
if host is not None:
|
||||
host = gen_intersection_list(
|
||||
host, res_find.get("member_host"))
|
||||
host_del = gen_intersection_list(
|
||||
host, res_find.get("member_host")
|
||||
)
|
||||
if hostgroup is not None:
|
||||
hostgroup = gen_intersection_list(
|
||||
hostgroup, res_find.get("member_hostgroup"))
|
||||
|
||||
# Ensure members are absent
|
||||
commands.append([name, "hostgroup_remove_member",
|
||||
{
|
||||
"host": host,
|
||||
"hostgroup": hostgroup,
|
||||
}])
|
||||
hostgroup_del = gen_intersection_list(
|
||||
hostgroup, res_find.get("member_hostgroup")
|
||||
)
|
||||
|
||||
if has_add_membermanager:
|
||||
# Reduce del lists of membermanager_user and
|
||||
# membermanager_group to the entries only that are
|
||||
# in res_find.
|
||||
if membermanager_user is not None:
|
||||
membermanager_user = gen_intersection_list(
|
||||
membermanager_user,
|
||||
res_find.get("membermanager_user"))
|
||||
if membermanager_group is not None:
|
||||
membermanager_group = gen_intersection_list(
|
||||
membermanager_group,
|
||||
res_find.get("membermanager_group"))
|
||||
|
||||
# Remove membermanager users and groups
|
||||
if membermanager_user is not None or \
|
||||
membermanager_group is not None:
|
||||
commands.append(
|
||||
[name, "hostgroup_remove_member_manager",
|
||||
{
|
||||
"user": membermanager_user,
|
||||
"group": membermanager_group,
|
||||
}]
|
||||
)
|
||||
# Get lists of membermanager users that exist
|
||||
# in IPA and should be removed.
|
||||
membermanager_user_del = gen_intersection_list(
|
||||
membermanager_user,
|
||||
res_find.get("membermanager_user")
|
||||
)
|
||||
membermanager_group_del = gen_intersection_list(
|
||||
membermanager_group,
|
||||
res_find.get("membermanager_group")
|
||||
)
|
||||
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Manage members
|
||||
|
||||
# Add members
|
||||
if host_add or hostgroup_add:
|
||||
commands.append([
|
||||
name, "hostgroup_add_member",
|
||||
{
|
||||
"host": host_add,
|
||||
"hostgroup": hostgroup_add,
|
||||
}
|
||||
])
|
||||
|
||||
# Remove members
|
||||
if host_del or hostgroup_del:
|
||||
commands.append([
|
||||
name, "hostgroup_remove_member",
|
||||
{
|
||||
"host": host_del,
|
||||
"hostgroup": hostgroup_del,
|
||||
}
|
||||
])
|
||||
|
||||
# Manage membermanager users and groups
|
||||
if has_add_membermanager:
|
||||
# Add membermanager users and groups
|
||||
if membermanager_user_add or membermanager_group_add:
|
||||
commands.append([
|
||||
name, "hostgroup_add_member_manager",
|
||||
{
|
||||
"user": membermanager_user_add,
|
||||
"group": membermanager_group_add,
|
||||
}
|
||||
])
|
||||
# Remove membermanager users and groups
|
||||
if membermanager_user_del or membermanager_group_del:
|
||||
commands.append([
|
||||
name, "hostgroup_remove_member_manager",
|
||||
{
|
||||
"user": membermanager_user_del,
|
||||
"group": membermanager_group_del,
|
||||
}
|
||||
])
|
||||
|
||||
# Execute commands
|
||||
|
||||
changed = ansible_module.execute_ipa_commands(
|
||||
|
||||
@@ -243,7 +243,7 @@ def main():
|
||||
# present
|
||||
description = ansible_module.params_get("description")
|
||||
name = ansible_module.params_get("name")
|
||||
gid = ansible_module.params_get("gid")
|
||||
gid = ansible_module.params_get_with_type_cast("gid", int)
|
||||
|
||||
# runtime flags
|
||||
fallback_to_ldap = ansible_module.params_get("fallback_to_ldap")
|
||||
@@ -271,19 +271,6 @@ def main():
|
||||
|
||||
ansible_module.params_fail_used_invalid(invalid, state)
|
||||
|
||||
# Ensure parameter values are valid and have proper type.
|
||||
def int_or_empty_param(value, param):
|
||||
if value is not None and value != "":
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
ansible_module.fail_json(
|
||||
msg="Invalid value '%s' for argument '%s'" % (value, param)
|
||||
)
|
||||
return value
|
||||
|
||||
gid = int_or_empty_param(gid, "gid")
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
|
||||
@@ -439,9 +439,9 @@ def main():
|
||||
# present
|
||||
description = ansible_module.params_get("description")
|
||||
name = ansible_module.params_get("name")
|
||||
uid = ansible_module.params_get("uid")
|
||||
uid = ansible_module.params_get_with_type_cast("uid", int)
|
||||
gecos = ansible_module.params_get("gecos")
|
||||
gidnumber = ansible_module.params_get("gidnumber")
|
||||
gidnumber = ansible_module.params_get_with_type_cast("gidnumber", int)
|
||||
homedir = ansible_module.params_get("homedir")
|
||||
shell = ansible_module.params_get("shell")
|
||||
sshpubkey = ansible_module.params_get("sshpubkey")
|
||||
@@ -479,20 +479,6 @@ def main():
|
||||
|
||||
ansible_module.params_fail_used_invalid(invalid, state, action)
|
||||
|
||||
# Ensure parameter values are valid and have proper type.
|
||||
def int_or_empty_param(value, param):
|
||||
if value is not None and value != "":
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
ansible_module.fail_json(
|
||||
msg="Invalid value '%s' for argument '%s'" % (value, param)
|
||||
)
|
||||
return value
|
||||
|
||||
uid = int_or_empty_param(uid, "uid")
|
||||
gidnumber = int_or_empty_param(gidnumber, "gidnumber")
|
||||
|
||||
if certificate is not None:
|
||||
certificate = [cert.strip() for cert in certificate]
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ RETURN = """
|
||||
|
||||
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, compare_args_ipa, template_str
|
||||
IPAAnsibleModule, compare_args_ipa, template_str, urlparse
|
||||
from ansible.module_utils import six
|
||||
from copy import deepcopy
|
||||
import string
|
||||
@@ -274,7 +274,14 @@ def find_idp(module, name):
|
||||
# An exception is raised if idp name is not found.
|
||||
return None
|
||||
|
||||
return _result["result"]
|
||||
res = _result["result"]
|
||||
|
||||
# Decode binary string secret
|
||||
if "ipaidpclientsecret" in res and len(res["ipaidpclientsecret"]) > 0:
|
||||
res["ipaidpclientsecret"][0] = \
|
||||
res["ipaidpclientsecret"][0].decode("ascii")
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def gen_args(auth_uri, dev_auth_uri, token_uri, userinfo_uri, keys_uri,
|
||||
@@ -333,6 +340,16 @@ def convert_provider_to_endpoints(module, _args, provider):
|
||||
_args.update(points)
|
||||
|
||||
|
||||
def validate_uri(module, uri):
|
||||
try:
|
||||
parsed = urlparse(uri, 'https')
|
||||
except Exception:
|
||||
module.fail_json(msg="Invalid URI '%s': not an https scheme" % uri)
|
||||
|
||||
if not parsed.netloc:
|
||||
module.fail_json(msg="Invalid URI '%s': missing netloc" % uri)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
@@ -426,19 +443,6 @@ def main():
|
||||
if provider not in idp_providers:
|
||||
ansible_module.fail_json(
|
||||
msg="Provider '%s' is unknown" % provider)
|
||||
else:
|
||||
if not auth_uri:
|
||||
ansible_module.fail_json(
|
||||
msg="Parameter '%s' is missing" % "auth_uri")
|
||||
if not dev_auth_uri:
|
||||
ansible_module.fail_json(
|
||||
msg="Parameter '%s' is missing" % "dev_auth_uri")
|
||||
if not token_uri:
|
||||
ansible_module.fail_json(
|
||||
msg="Parameter '%s' is missing" % "token_uri")
|
||||
if not userinfo_uri:
|
||||
ansible_module.fail_json(
|
||||
msg="Parameter '%s' is missing" % "userinfo_uri")
|
||||
invalid = ["rename", "delete_continue"]
|
||||
else:
|
||||
# state renamed and absent
|
||||
@@ -459,6 +463,19 @@ def main():
|
||||
|
||||
ansible_module.params_fail_used_invalid(invalid, state)
|
||||
|
||||
# Empty client_id test
|
||||
if client_id is not None and client_id == "":
|
||||
ansible_module.fail_json(msg="'client_id' is required")
|
||||
|
||||
# Normalize base_url
|
||||
if base_url is not None and base_url.startswith('https://'):
|
||||
base_url = base_url[len('https://'):]
|
||||
|
||||
# Validate uris
|
||||
for uri in [auth_uri, dev_auth_uri, token_uri, userinfo_uri, keys_uri]:
|
||||
if uri is not None and uri != "":
|
||||
validate_uri(ansible_module, uri)
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
@@ -507,6 +524,19 @@ def main():
|
||||
res_find):
|
||||
commands.append([name, "idp_mod", args])
|
||||
else:
|
||||
if "ipaidpauthendpoint" not in args:
|
||||
ansible_module.fail_json(
|
||||
msg="Parameter '%s' is missing" % "auth_uri")
|
||||
if "ipaidpdevauthendpoint" not in args:
|
||||
ansible_module.fail_json(
|
||||
msg="Parameter '%s' is missing" % "dev_auth_uri")
|
||||
if "ipaidptokenendpoint" not in args:
|
||||
ansible_module.fail_json(
|
||||
msg="Parameter '%s' is missing" % "token_uri")
|
||||
if "ipaidpuserinfoendpoint" not in args:
|
||||
ansible_module.fail_json(
|
||||
msg="Parameter '%s' is missing" % "userinfo_uri")
|
||||
|
||||
commands.append([name, "idp_add", args])
|
||||
|
||||
elif state == "absent":
|
||||
|
||||
@@ -153,7 +153,7 @@ RETURN = """
|
||||
"""
|
||||
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, compare_args_ipa, boolean
|
||||
IPAAnsibleModule, compare_args_ipa
|
||||
|
||||
|
||||
def find_pwpolicy(module, name):
|
||||
@@ -294,20 +294,34 @@ def main():
|
||||
names = ansible_module.params_get("name")
|
||||
|
||||
# present
|
||||
maxlife = ansible_module.params_get("maxlife")
|
||||
minlife = ansible_module.params_get("minlife")
|
||||
history = ansible_module.params_get("history")
|
||||
minclasses = ansible_module.params_get("minclasses")
|
||||
minlength = ansible_module.params_get("minlength")
|
||||
priority = ansible_module.params_get("priority")
|
||||
maxfail = ansible_module.params_get("maxfail")
|
||||
failinterval = ansible_module.params_get("failinterval")
|
||||
lockouttime = ansible_module.params_get("lockouttime")
|
||||
maxrepeat = ansible_module.params_get("maxrepeat")
|
||||
maxsequence = ansible_module.params_get("maxsequence")
|
||||
dictcheck = ansible_module.params_get("dictcheck")
|
||||
usercheck = ansible_module.params_get("usercheck")
|
||||
gracelimit = ansible_module.params_get("gracelimit")
|
||||
maxlife = ansible_module.params_get_with_type_cast(
|
||||
"maxlife", int, allow_empty=True)
|
||||
minlife = ansible_module.params_get_with_type_cast(
|
||||
"minlife", int, allow_empty=True)
|
||||
history = ansible_module.params_get_with_type_cast(
|
||||
"history", int, allow_empty=True)
|
||||
minclasses = ansible_module.params_get_with_type_cast(
|
||||
"minclasses", int, allow_empty=True)
|
||||
minlength = ansible_module.params_get_with_type_cast(
|
||||
"minlength", int, allow_empty=True)
|
||||
priority = ansible_module.params_get_with_type_cast(
|
||||
"priority", int, allow_empty=True)
|
||||
maxfail = ansible_module.params_get_with_type_cast(
|
||||
"maxfail", int, allow_empty=True)
|
||||
failinterval = ansible_module.params_get_with_type_cast(
|
||||
"failinterval", int, allow_empty=True)
|
||||
lockouttime = ansible_module.params_get_with_type_cast(
|
||||
"lockouttime", int, allow_empty=True)
|
||||
maxrepeat = ansible_module.params_get_with_type_cast(
|
||||
"maxrepeat", int, allow_empty=True)
|
||||
maxsequence = ansible_module.params_get_with_type_cast(
|
||||
"maxsequence", int, allow_empty=True)
|
||||
dictcheck = ansible_module.params_get_with_type_cast(
|
||||
"dictcheck", bool, allow_empty=True)
|
||||
usercheck = ansible_module.params_get_with_type_cast(
|
||||
"usercheck", bool, allow_empty=True)
|
||||
gracelimit = ansible_module.params_get_with_type_cast(
|
||||
"gracelimit", int, allow_empty=True)
|
||||
|
||||
# state
|
||||
state = ansible_module.params_get("state")
|
||||
@@ -336,41 +350,6 @@ def main():
|
||||
|
||||
ansible_module.params_fail_used_invalid(invalid, state)
|
||||
|
||||
# Ensure parameter values are valid and have proper type.
|
||||
def int_or_empty_param(value, param):
|
||||
if value is not None and value != "":
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
ansible_module.fail_json(
|
||||
msg="Invalid value '%s' for argument '%s'" % (value, param)
|
||||
)
|
||||
return value
|
||||
|
||||
maxlife = int_or_empty_param(maxlife, "maxlife")
|
||||
minlife = int_or_empty_param(minlife, "minlife")
|
||||
history = int_or_empty_param(history, "history")
|
||||
minclasses = int_or_empty_param(minclasses, "minclasses")
|
||||
minlength = int_or_empty_param(minlength, "minlength")
|
||||
priority = int_or_empty_param(priority, "priority")
|
||||
maxfail = int_or_empty_param(maxfail, "maxfail")
|
||||
failinterval = int_or_empty_param(failinterval, "failinterval")
|
||||
lockouttime = int_or_empty_param(lockouttime, "lockouttime")
|
||||
maxrepeat = int_or_empty_param(maxrepeat, "maxrepeat")
|
||||
maxsequence = int_or_empty_param(maxsequence, "maxsequence")
|
||||
gracelimit = int_or_empty_param(gracelimit, "gracelimit")
|
||||
|
||||
def bool_or_empty_param(value, param): # pylint: disable=R1710
|
||||
if value is None or value == "":
|
||||
return value
|
||||
try:
|
||||
return boolean(value)
|
||||
except TypeError as terr:
|
||||
ansible_module.fail_json(msg="Param '%s': %s" % (param, str(terr)))
|
||||
|
||||
dictcheck = bool_or_empty_param(dictcheck, "dictcheck")
|
||||
usercheck = bool_or_empty_param(usercheck, "usercheck")
|
||||
|
||||
# Ensure gracelimit has proper limit.
|
||||
if gracelimit:
|
||||
if gracelimit < -1:
|
||||
|
||||
@@ -607,8 +607,10 @@ def main():
|
||||
# white space also.
|
||||
if certificate is not None:
|
||||
certificate = [cert.strip() for cert in certificate]
|
||||
pac_type = ansible_module.params_get("pac_type", allow_empty_string=True)
|
||||
auth_ind = ansible_module.params_get("auth_ind", allow_empty_string=True)
|
||||
pac_type = ansible_module.params_get(
|
||||
"pac_type", allow_empty_list_item=True)
|
||||
auth_ind = ansible_module.params_get(
|
||||
"auth_ind", allow_empty_list_item=True)
|
||||
skip_host_check = ansible_module.params_get("skip_host_check")
|
||||
force = ansible_module.params_get("force")
|
||||
requires_pre_auth = ansible_module.params_get("requires_pre_auth")
|
||||
|
||||
@@ -138,6 +138,11 @@ options:
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
runasuser_group:
|
||||
description: List of groups for Sudo to execute as.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
runasgroup:
|
||||
description: List of groups for Sudo to execute as.
|
||||
required: false
|
||||
@@ -214,6 +219,12 @@ EXAMPLES = """
|
||||
hostmask:
|
||||
- 192.168.122.1/24
|
||||
- 192.168.120.1/24
|
||||
|
||||
# Ensure sudorule 'runasuser' has 'ipasuers' group as runas users.
|
||||
- ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: testrule1
|
||||
runasuser_group: ipausers
|
||||
action: member
|
||||
|
||||
# Ensure Sudo Rule tesrule1 is absent
|
||||
@@ -315,6 +326,8 @@ def main():
|
||||
default=None),
|
||||
runasgroup=dict(required=False, type="list", elements="str",
|
||||
default=None),
|
||||
runasuser_group=dict(required=False, type="list", elements="str",
|
||||
default=None),
|
||||
order=dict(type="int", required=False, aliases=['sudoorder']),
|
||||
sudooption=dict(required=False, type='list', elements="str",
|
||||
default=None, aliases=["options"]),
|
||||
@@ -362,6 +375,7 @@ def main():
|
||||
sudooption = ansible_module.params_get("sudooption")
|
||||
order = ansible_module.params_get("order")
|
||||
runasuser = ansible_module.params_get_lowercase("runasuser")
|
||||
runasuser_group = ansible_module.params_get_lowercase("runasuser_group")
|
||||
runasgroup = ansible_module.params_get_lowercase("runasgroup")
|
||||
action = ansible_module.params_get("action")
|
||||
|
||||
@@ -406,7 +420,8 @@ def main():
|
||||
invalid.extend(["host", "hostgroup", "hostmask", "user", "group",
|
||||
"runasuser", "runasgroup", "allow_sudocmd",
|
||||
"allow_sudocmdgroup", "deny_sudocmd",
|
||||
"deny_sudocmdgroup", "sudooption"])
|
||||
"deny_sudocmdgroup", "sudooption",
|
||||
"runasuser_group"])
|
||||
|
||||
elif state in ["enabled", "disabled"]:
|
||||
if len(names) < 1:
|
||||
@@ -420,7 +435,7 @@ def main():
|
||||
"nomembers", "nomembers", "host", "hostgroup", "hostmask",
|
||||
"user", "group", "allow_sudocmd", "allow_sudocmdgroup",
|
||||
"deny_sudocmd", "deny_sudocmdgroup", "runasuser",
|
||||
"runasgroup", "order", "sudooption"]
|
||||
"runasgroup", "order", "sudooption", "runasuser_group"]
|
||||
else:
|
||||
ansible_module.fail_json(msg="Invalid state '%s'" % state)
|
||||
|
||||
@@ -453,6 +468,7 @@ def main():
|
||||
deny_cmdgroup_add, deny_cmdgroup_del = [], []
|
||||
sudooption_add, sudooption_del = [], []
|
||||
runasuser_add, runasuser_del = [], []
|
||||
runasuser_group_add, runasuser_group_del = [], []
|
||||
runasgroup_add, runasgroup_del = [], []
|
||||
|
||||
for name in names:
|
||||
@@ -552,6 +568,12 @@ def main():
|
||||
+ res_find.get('ipasudorunasextuser', [])
|
||||
)
|
||||
)
|
||||
runasuser_group_add, runasuser_group_del = (
|
||||
gen_add_del_lists(
|
||||
runasuser_group,
|
||||
res_find.get('ipasudorunas_group', [])
|
||||
)
|
||||
)
|
||||
|
||||
# runasgroup attribute can be used with both IPA and
|
||||
# non-IPA (external) groups. IPA will handle the correct
|
||||
@@ -623,6 +645,11 @@ def main():
|
||||
(list(res_find.get('ipasudorunas_user', []))
|
||||
+ list(res_find.get('ipasudorunasextuser', [])))
|
||||
)
|
||||
if runasuser_group is not None:
|
||||
runasuser_group_add = gen_add_list(
|
||||
runasuser_group,
|
||||
res_find.get('ipasudorunas_group', [])
|
||||
)
|
||||
# runasgroup attribute can be used with both IPA and
|
||||
# non-IPA (external) groups, so we need to compare
|
||||
# the provided list against both users and external
|
||||
@@ -703,6 +730,11 @@ def main():
|
||||
+ list(res_find.get('ipasudorunasextuser', []))
|
||||
)
|
||||
)
|
||||
if runasuser_group is not None:
|
||||
runasuser_group_del = gen_intersection_list(
|
||||
runasuser_group,
|
||||
res_find.get('ipasudorunas_group', [])
|
||||
)
|
||||
# runasgroup attribute can be used with both IPA and
|
||||
# non-IPA (external) groups, so we need to compare
|
||||
# the provided list against both groups and external
|
||||
@@ -812,13 +844,19 @@ def main():
|
||||
}
|
||||
])
|
||||
# Manage RunAS users
|
||||
if runasuser_add:
|
||||
if runasuser_add or runasuser_group_add:
|
||||
# Can't use empty lists with command "sudorule_add_runasuser".
|
||||
_args = {}
|
||||
if runasuser_add:
|
||||
_args["user"] = runasuser_add
|
||||
if runasuser_group_add:
|
||||
_args["group"] = runasuser_group_add
|
||||
commands.append([name, "sudorule_add_runasuser", _args])
|
||||
if runasuser_del or runasuser_group_del:
|
||||
commands.append([
|
||||
name, "sudorule_add_runasuser", {"user": runasuser_add}
|
||||
])
|
||||
if runasuser_del:
|
||||
commands.append([
|
||||
name, "sudorule_remove_runasuser", {"user": runasuser_del}
|
||||
name,
|
||||
"sudorule_remove_runasuser",
|
||||
{"user": runasuser_del, "group": runasuser_group_del}
|
||||
])
|
||||
|
||||
# Manage RunAS Groups
|
||||
|
||||
@@ -319,6 +319,11 @@ options:
|
||||
description: Suppress processing of membership attributes
|
||||
required: false
|
||||
type: bool
|
||||
rename:
|
||||
description: Rename the user object
|
||||
required: false
|
||||
type: str
|
||||
aliases: ["new_name"]
|
||||
required: false
|
||||
first:
|
||||
description: The first name. Required if user does not exist.
|
||||
@@ -586,6 +591,11 @@ options:
|
||||
description: Suppress processing of membership attributes
|
||||
required: false
|
||||
type: bool
|
||||
rename:
|
||||
description: Rename the user object
|
||||
required: false
|
||||
type: str
|
||||
aliases: ["new_name"]
|
||||
preserve:
|
||||
description: Delete a user, keeping the entry available for future use
|
||||
required: false
|
||||
@@ -607,7 +617,8 @@ options:
|
||||
default: present
|
||||
choices: ["present", "absent",
|
||||
"enabled", "disabled",
|
||||
"unlocked", "undeleted"]
|
||||
"unlocked", "undeleted",
|
||||
"renamed"]
|
||||
author:
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
@@ -694,6 +705,13 @@ EXAMPLES = """
|
||||
smb_profile_path: \\\\server\\profiles\\some_profile
|
||||
smb_home_dir: \\\\users\\home\\smbuser
|
||||
smb_home_drive: "U:"
|
||||
|
||||
# Rename an existing user
|
||||
- ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: someuser
|
||||
rename: anotheruser
|
||||
state: renamed
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
@@ -857,7 +875,7 @@ def check_parameters( # pylint: disable=unused-argument
|
||||
employeenumber, employeetype, preferredlanguage, certificate,
|
||||
certmapdata, noprivate, nomembers, preserve, update_password,
|
||||
smb_logon_script, smb_profile_path, smb_home_dir, smb_home_drive,
|
||||
idp, ipa_user_id,
|
||||
idp, ipa_user_id, rename
|
||||
):
|
||||
if state == "present" and action == "user":
|
||||
invalid = ["preserve"]
|
||||
@@ -885,6 +903,19 @@ def check_parameters( # pylint: disable=unused-argument
|
||||
module.fail_json(
|
||||
msg="Preserve is only possible for state=absent")
|
||||
|
||||
if state != "renamed":
|
||||
invalid.append("rename")
|
||||
else:
|
||||
invalid.extend([
|
||||
"preserve", "principal", "manager", "certificate", "certmapdata",
|
||||
])
|
||||
if not rename:
|
||||
module.fail_json(
|
||||
msg="A value for attribute 'rename' must be provided.")
|
||||
if action == "member":
|
||||
module.fail_json(
|
||||
msg="Action member can not be used with state: renamed.")
|
||||
|
||||
module.params_fail_used_invalid(invalid, state, action)
|
||||
|
||||
if certmapdata is not None:
|
||||
@@ -1097,6 +1128,8 @@ def main():
|
||||
idp=dict(type="str", default=None, aliases=['ipaidpconfiglink']),
|
||||
idp_user_id=dict(type="str", default=None,
|
||||
aliases=['ipaidpconfiglink']),
|
||||
rename=dict(type="str", required=False, default=None,
|
||||
aliases=["new_name"]),
|
||||
)
|
||||
|
||||
ansible_module = IPAAnsibleModule(
|
||||
@@ -1128,7 +1161,7 @@ def main():
|
||||
choices=["member", "user"]),
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent", "enabled", "disabled",
|
||||
"unlocked", "undeleted"]),
|
||||
"unlocked", "undeleted", "renamed"]),
|
||||
|
||||
# Add user specific parameters for simple use case
|
||||
**user_spec
|
||||
@@ -1185,9 +1218,9 @@ def main():
|
||||
manager = ansible_module.params_get("manager")
|
||||
carlicense = ansible_module.params_get("carlicense")
|
||||
sshpubkey = ansible_module.params_get("sshpubkey",
|
||||
allow_empty_string=True)
|
||||
allow_empty_list_item=True)
|
||||
userauthtype = ansible_module.params_get("userauthtype",
|
||||
allow_empty_string=True)
|
||||
allow_empty_list_item=True)
|
||||
userclass = ansible_module.params_get("userclass")
|
||||
radius = ansible_module.params_get("radius")
|
||||
radiususer = ansible_module.params_get("radiususer")
|
||||
@@ -1209,6 +1242,8 @@ def main():
|
||||
preserve = ansible_module.params_get("preserve")
|
||||
# mod
|
||||
update_password = ansible_module.params_get("update_password")
|
||||
# rename
|
||||
rename = ansible_module.params_get("rename")
|
||||
# general
|
||||
action = ansible_module.params_get("action")
|
||||
state = ansible_module.params_get("state")
|
||||
@@ -1219,27 +1254,30 @@ def main():
|
||||
(users is None or len(users) < 1):
|
||||
ansible_module.fail_json(msg="One of name and users is required")
|
||||
|
||||
if state == "present":
|
||||
if state in ["present", "renamed"]:
|
||||
if names is not None and len(names) != 1:
|
||||
act = "renamed" if state == "renamed" else "added"
|
||||
ansible_module.fail_json(
|
||||
msg="Only one user can be added at a time using name.")
|
||||
|
||||
check_parameters(
|
||||
ansible_module, state, action,
|
||||
first, last, fullname, displayname, initials, homedir, gecos, shell,
|
||||
email,
|
||||
principal, principalexpiration, passwordexpiration, password, random,
|
||||
uid, gid, street, city, phone, mobile, pager, fax, orgunit, title,
|
||||
manager, carlicense, sshpubkey, userauthtype, userclass, radius,
|
||||
radiususer, departmentnumber, employeenumber, employeetype,
|
||||
preferredlanguage, certificate, certmapdata, noprivate, nomembers,
|
||||
preserve, update_password, smb_logon_script, smb_profile_path,
|
||||
smb_home_dir, smb_home_drive, idp, idp_user_id)
|
||||
certmapdata = convert_certmapdata(certmapdata)
|
||||
msg="Only one user can be %s at a time using name." % (act))
|
||||
|
||||
# Use users if names is None
|
||||
if users is not None:
|
||||
names = users
|
||||
else:
|
||||
check_parameters(
|
||||
ansible_module, state, action,
|
||||
first, last, fullname, displayname, initials, homedir, gecos,
|
||||
shell, email,
|
||||
principal, principalexpiration, passwordexpiration, password,
|
||||
random,
|
||||
uid, gid, street, city, phone, mobile, pager, fax, orgunit, title,
|
||||
manager, carlicense, sshpubkey, userauthtype, userclass, radius,
|
||||
radiususer, departmentnumber, employeenumber, employeetype,
|
||||
preferredlanguage, certificate, certmapdata, noprivate, nomembers,
|
||||
preserve, update_password, smb_logon_script, smb_profile_path,
|
||||
smb_home_dir, smb_home_drive, idp, idp_user_id, rename,
|
||||
)
|
||||
certmapdata = convert_certmapdata(certmapdata)
|
||||
|
||||
# Init
|
||||
|
||||
@@ -1330,6 +1368,7 @@ def main():
|
||||
smb_home_drive = user.get("smb_home_drive")
|
||||
idp = user.get("idp")
|
||||
idp_user_id = user.get("idp_user_id")
|
||||
rename = user.get("rename")
|
||||
certificate = user.get("certificate")
|
||||
certmapdata = user.get("certmapdata")
|
||||
noprivate = user.get("noprivate")
|
||||
@@ -1346,7 +1385,8 @@ def main():
|
||||
employeetype, preferredlanguage, certificate,
|
||||
certmapdata, noprivate, nomembers, preserve,
|
||||
update_password, smb_logon_script, smb_profile_path,
|
||||
smb_home_dir, smb_home_drive, idp, idp_user_id)
|
||||
smb_home_dir, smb_home_drive, idp, idp_user_id, rename,
|
||||
)
|
||||
certmapdata = convert_certmapdata(certmapdata)
|
||||
|
||||
# Check API specific parameters
|
||||
@@ -1449,6 +1489,10 @@ def main():
|
||||
del args["userpassword"]
|
||||
if "random" in args:
|
||||
del args["random"]
|
||||
# if using "random:false" password should not be
|
||||
# generated.
|
||||
if not args.get("random", True):
|
||||
del args["random"]
|
||||
if "noprivate" in args:
|
||||
del args["noprivate"]
|
||||
|
||||
@@ -1733,6 +1777,12 @@ def main():
|
||||
else:
|
||||
raise ValueError("No user '%s'" % name)
|
||||
|
||||
elif state == "renamed":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No user '%s'" % name)
|
||||
else:
|
||||
if rename != name:
|
||||
commands.append([name, 'user_mod', {"rename": rename}])
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
|
||||
@@ -7,4 +7,4 @@ pylint==2.17.2
|
||||
wrapt==1.14.1
|
||||
pydocstyle==6.3.0
|
||||
yamllint==1.32.0
|
||||
ansible-lint
|
||||
ansible-lint >= 6.22
|
||||
|
||||
@@ -201,6 +201,7 @@ Variable | Description | Required
|
||||
`ipasssd_preserve_sssd` | The bool value defines if the old SSSD configuration will be preserved if it is not possible to merge it with a new one. `ipasssd_preserve_sssd` defaults to `no`. | no
|
||||
`ipaclient_request_cert` | The bool value defines if the certificate for the machine wil be requested. The certificate will be stored in /etc/ipa/nssdb under the nickname "Local IPA host". . `ipaclient_request_cert` defaults to `no`. The option is deprecated and will be removed in a future release. | no
|
||||
`ipaclient_keytab` | The string value contains the path on the node of a backup host keytab from a previous enrollment. | no
|
||||
`ipaclient_automount_location` | Automount location | no
|
||||
|
||||
|
||||
Server Variables
|
||||
|
||||
@@ -68,7 +68,8 @@ RETURN = '''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging, check_imports, options, configure_automount
|
||||
setup_logging, check_imports, options, configure_automount, sysrestore,
|
||||
paths, getargspec
|
||||
)
|
||||
|
||||
|
||||
@@ -94,10 +95,23 @@ def main():
|
||||
options.automount_location = module.params.get('automount_location')
|
||||
options.location = options.automount_location
|
||||
|
||||
changed = False
|
||||
if options.automount_location:
|
||||
configure_automount(options)
|
||||
changed = True
|
||||
argspec = getargspec(configure_automount)
|
||||
if len(argspec.args) > 1:
|
||||
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||
statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE)
|
||||
|
||||
module.exit_json(changed=True)
|
||||
configure_automount(options, statestore)
|
||||
|
||||
# Reload the state as automount install may have modified it
|
||||
fstore._load()
|
||||
statestore._load()
|
||||
else:
|
||||
configure_automount(options)
|
||||
|
||||
module.exit_json(changed=changed)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -152,6 +152,10 @@ options:
|
||||
The dist of nss_ldap or nss-pam-ldapd files if sssd is disabled
|
||||
required: yes
|
||||
type: dict
|
||||
selinux_works:
|
||||
description: True if selinux status check passed
|
||||
required: false
|
||||
type: bool
|
||||
krb_name:
|
||||
description: The krb5 config file name
|
||||
type: str
|
||||
@@ -189,7 +193,7 @@ from ansible.module_utils.ansible_ipa_client import (
|
||||
CalledProcessError, tasks, client_dns, services,
|
||||
update_ssh_keys, save_state, configure_ldap_conf, configure_nslcd_conf,
|
||||
configure_openldap_conf, hardcode_ldap_server, getargspec, NUM_VERSION,
|
||||
serialization
|
||||
serialization, configure_selinux_for_client
|
||||
)
|
||||
|
||||
|
||||
@@ -224,6 +228,7 @@ def main():
|
||||
no_dns_sshfp=dict(required=False, type='bool', default=False),
|
||||
nosssd_files=dict(required=True, type='dict'),
|
||||
krb_name=dict(required=True, type='str'),
|
||||
selinux_works=dict(required=False, type='bool', default=False),
|
||||
),
|
||||
supports_check_mode=False,
|
||||
)
|
||||
@@ -274,6 +279,7 @@ def main():
|
||||
options.sssd = not options.no_sssd
|
||||
options.no_ac = False
|
||||
nosssd_files = module.params.get('nosssd_files')
|
||||
selinux_works = module.params.get('selinux_works')
|
||||
krb_name = module.params.get('krb_name')
|
||||
os.environ['KRB5_CONFIG'] = krb_name
|
||||
|
||||
@@ -474,6 +480,9 @@ def main():
|
||||
logger.info("%s enabled", "SSSD" if options.sssd else "LDAP")
|
||||
|
||||
if options.sssd:
|
||||
if selinux_works and configure_selinux_for_client is not None:
|
||||
configure_selinux_for_client(statestore)
|
||||
|
||||
sssd = services.service('sssd', api)
|
||||
try:
|
||||
sssd.restart()
|
||||
|
||||
@@ -226,6 +226,10 @@ nosssd_files:
|
||||
returned: always
|
||||
type: list
|
||||
elements: str
|
||||
selinux_works:
|
||||
description: True if the selinux status check passed.
|
||||
returned: always
|
||||
type: bool
|
||||
'''
|
||||
|
||||
import os
|
||||
@@ -495,6 +499,8 @@ def main():
|
||||
# not installer.no_krb5_offline_passwords
|
||||
installer.sssd = not installer.no_sssd
|
||||
|
||||
selinux_works = False
|
||||
|
||||
try:
|
||||
|
||||
# client
|
||||
@@ -529,7 +535,7 @@ def main():
|
||||
"You must be root to run ipa-client-install.",
|
||||
rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
tasks.check_selinux_status()
|
||||
selinux_works = tasks.check_selinux_status()
|
||||
|
||||
# if is_ipa_client_installed(fstore, on_master=options.on_master):
|
||||
# logger.error("IPA client is already configured on this system.")
|
||||
@@ -971,7 +977,8 @@ def main():
|
||||
ntp_pool=options.ntp_pool,
|
||||
client_already_configured=client_already_configured,
|
||||
ipa_python_version=IPA_PYTHON_VERSION,
|
||||
nosssd_files=nosssd_files)
|
||||
nosssd_files=nosssd_files,
|
||||
selinux_works=selinux_works)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -46,7 +46,8 @@ __all__ = ["gssapi", "version", "ipadiscovery", "api", "errors", "x509",
|
||||
"configure_nslcd_conf", "configure_ssh_config",
|
||||
"configure_sshd_config", "configure_automount",
|
||||
"configure_firefox", "sync_time", "check_ldap_conf",
|
||||
"sssd_enable_ifp", "getargspec", "paths", "options",
|
||||
"sssd_enable_ifp", "configure_selinux_for_client",
|
||||
"getargspec", "paths", "options",
|
||||
"IPA_PYTHON_VERSION", "NUM_VERSION", "certdb", "get_ca_cert",
|
||||
"ipalib", "logger", "ipautil", "installer"]
|
||||
|
||||
@@ -302,6 +303,11 @@ try:
|
||||
except ImportError:
|
||||
sssd_enable_ifp = None
|
||||
|
||||
try:
|
||||
from ipaclient.install.client import configure_selinux_for_client
|
||||
except ImportError:
|
||||
configure_selinux_for_client = None
|
||||
|
||||
logger = logging.getLogger("ipa-client-install")
|
||||
root_logger = logger
|
||||
|
||||
|
||||
@@ -166,18 +166,19 @@
|
||||
register: result_ipaclient_get_otp
|
||||
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
||||
|
||||
- name: Install - Report error for OTP generation
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ result_ipaclient_get_otp.msg }}"
|
||||
when: result_ipaclient_get_otp is failed
|
||||
failed_when: yes
|
||||
|
||||
- name: Install - Store the previously obtained OTP
|
||||
no_log: yes
|
||||
ansible.builtin.set_fact:
|
||||
ipaadmin_orig_password: "{{ ipaadmin_password | default(omit) }}"
|
||||
ipaadmin_password: "{{ result_ipaclient_get_otp.host.randompassword
|
||||
if result_ipaclient_get_otp.host is defined }}"
|
||||
rescue:
|
||||
- name: Install - Report error for OTP generation
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ result_ipaclient_get_otp.msg }}"
|
||||
when: result_ipaclient_get_otp is failed
|
||||
failed_when: yes
|
||||
|
||||
always:
|
||||
- name: Install - Remove keytab temporary file
|
||||
ansible.builtin.file:
|
||||
@@ -383,6 +384,7 @@
|
||||
| default(ipasssd_no_krb5_offline_passwords) }}"
|
||||
no_dns_sshfp: "{{ ipaclient_no_dns_sshfp }}"
|
||||
nosssd_files: "{{ result_ipaclient_test.nosssd_files }}"
|
||||
selinux_works: "{{ result_ipaclient_test.selinux_works }}"
|
||||
krb_name: "{{ result_ipaclient_temp_krb5.krb_name }}"
|
||||
|
||||
- name: Install - Configure SSH and SSHD
|
||||
@@ -397,7 +399,7 @@
|
||||
ipaclient_setup_automount:
|
||||
servers: "{{ result_ipaclient_test.servers }}"
|
||||
sssd: "{{ result_ipaclient_test.sssd }}"
|
||||
automount_location: "{{ ipaautomount_location | default(omit) }}"
|
||||
automount_location: "{{ ipaclient_automount_location | default(omit) }}"
|
||||
|
||||
- name: Install - Configure firefox
|
||||
ipaclient_setup_firefox:
|
||||
|
||||
@@ -57,6 +57,11 @@
|
||||
ipareplica_servers: "{{ groups['ipaservers'] | list }}"
|
||||
when: groups.ipaservers is defined and ipareplica_servers is not defined
|
||||
|
||||
- name: Install - Set ipareplica_servers from cluster inventory
|
||||
ansible.builtin.set_fact:
|
||||
ipareplica_servers: "{{ groups['ipaserver'] | list }}"
|
||||
when: ipareplica_servers is not defined and groups.ipaserver is defined
|
||||
|
||||
- name: Install - Set default principal if no keytab is given
|
||||
ansible.builtin.set_fact:
|
||||
ipaadmin_principal: admin
|
||||
|
||||
@@ -131,7 +131,8 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
check_imports,
|
||||
MAX_DOMAIN_LEVEL, AnsibleModuleLog, options, sysrestore, paths,
|
||||
api_Backend_ldap2, ds_init_info, redirect_stdout, setup_logging
|
||||
api_Backend_ldap2, ds_init_info, redirect_stdout, setup_logging,
|
||||
krbinstance, service
|
||||
)
|
||||
|
||||
|
||||
@@ -221,6 +222,16 @@ def main():
|
||||
with redirect_stdout(ansible_log):
|
||||
ds.change_admin_password(options.admin_password)
|
||||
|
||||
# Force KDC to refresh the cached value of ipaKrbAuthzData by restarting.
|
||||
# ipaKrbAuthzData has to be set with "MS-PAC" to trigger PAC generation,
|
||||
# which is required to handle S4U2Proxy with the Bronze-Bit fix.
|
||||
# Not doing so would cause API malfunction for around a minute, which is
|
||||
# long enough to cause the hereafter client installation to fail.
|
||||
krb = krbinstance.KrbInstance(fstore)
|
||||
krb.set_output(ansible_log)
|
||||
service.print_msg("Restarting the KDC")
|
||||
krb.restart()
|
||||
|
||||
# done ##########################################################
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
@@ -21,7 +21,7 @@ parameters:
|
||||
jobs:
|
||||
- job: Test_Group${{ parameters.group_number }}
|
||||
displayName: Run playbook tests ${{ parameters.scenario }} (${{ parameters.group_number }}/${{ parameters.number_of_groups }})
|
||||
timeoutInMinutes: 240
|
||||
timeoutInMinutes: 360
|
||||
variables:
|
||||
- template: variables.yaml
|
||||
- template: variables_${{ parameters.scenario }}.yaml
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
#
|
||||
---
|
||||
variables:
|
||||
empty: true
|
||||
# empty: true
|
||||
# ipa_enabled_modules: >-
|
||||
# ipa_enabled_tests: >-
|
||||
# ipa_disabled_modules: >-
|
||||
ipa_disabled_modules: >-
|
||||
config
|
||||
# ipa_disabled_tests: >-
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
check_mode: yes
|
||||
register: sid_disabled
|
||||
|
||||
- name: Ensure netbios_name can't be changed without SID enabled. # noqa 503
|
||||
- name: Ensure netbios_name can't be changed without SID enabled. # noqa no-handler
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
@@ -39,7 +39,7 @@
|
||||
failed_when: not result.failed and "SID generation must be enabled" in result.msg
|
||||
when: sid_disabled.changed
|
||||
|
||||
- name: Ensure SIDs can't be changed without SID enabled. # noqa 503
|
||||
- name: Ensure SIDs can't be changed without SID enabled. # noqa no-handler
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
|
||||
227
tests/delegation/test_delegation_member_case_insensitive.yml
Normal file
227
tests/delegation/test_delegation_member_case_insensitive.yml
Normal file
@@ -0,0 +1,227 @@
|
||||
---
|
||||
- name: Test delegation
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Test different cases for string case.
|
||||
block:
|
||||
# CLEANUP TEST ITEMS
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" is absent
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
state: absent
|
||||
|
||||
# CREATE TEST ITEMS
|
||||
|
||||
- name: Ensure test group managers is present
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: managers
|
||||
|
||||
- name: Ensure test group employees is present
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: employees
|
||||
|
||||
# TESTS
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" is present, group/membergroup mixed case
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
permission: read
|
||||
attribute:
|
||||
- businesscategory
|
||||
group: Managers
|
||||
membergroup: Employees
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" is present, group lowercase
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
permission: read
|
||||
attribute:
|
||||
- businesscategory
|
||||
group: "{{ 'Managers' | lower }}"
|
||||
membergroup: Employees
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" is present, group uppercase
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
permission: read
|
||||
attribute:
|
||||
- businesscategory
|
||||
group: "{{ 'Managers' | upper }}"
|
||||
membergroup: Employees
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" is present, permission upercase
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
permission: "{{ 'read' | upper }}"
|
||||
attribute:
|
||||
- businesscategory
|
||||
group: managers
|
||||
membergroup: Employees
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" is present, permission mixed case
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
permission: Read
|
||||
attribute:
|
||||
- businesscategory
|
||||
group: managers
|
||||
membergroup: Employees
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" is present, attribute upercase
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
permission: read
|
||||
attribute:
|
||||
- "{{ 'businesscategory' | upper }}"
|
||||
group: managers
|
||||
membergroup: Employees
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" is present, attribute mixed case
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
permission: read
|
||||
attribute:
|
||||
- BusinessCategory
|
||||
group: managers
|
||||
membergroup: Employees
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
# membergroup does not use case insensitive comparison
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" is present, membergroup lowercase
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
permission: read
|
||||
attribute:
|
||||
- businesscategory
|
||||
group: managers
|
||||
membergroup: "{{ 'Employees' | lower }}"
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" is present, membergroup uppercase
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
permission: read
|
||||
attribute:
|
||||
- businesscategory
|
||||
group: managers
|
||||
membergroup: "{{ 'Employees' | upper }}"
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" is present, group/membergroup mixed case
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
permission: read
|
||||
attribute:
|
||||
- businesscategory
|
||||
group: Managers
|
||||
membergroup: Employees
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
# tests for action: member
|
||||
- name: Ensure delegation "basic manager attributes" is present, with group and attribute in mixed case
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
permission: read
|
||||
attribute:
|
||||
- BusinessCategory
|
||||
group: Managers
|
||||
membergroup: Employees
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" is present, attribute mixed case
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
permission: read
|
||||
attribute:
|
||||
- BusinessCategory
|
||||
group: managers
|
||||
membergroup: employees
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" member is present, attribute upercase
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
attribute:
|
||||
- "{{ 'BusinessCategory' | upper }}"
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" member is present, attribute lowercase
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
attribute:
|
||||
- "{{ 'BusinessCategory' | lower }}"
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
always:
|
||||
# CLEANUP TEST ITEMS
|
||||
|
||||
- name: Ensure delegation "basic manager attributes" is absent
|
||||
ipadelegation:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "basic manager attributes"
|
||||
state: absent
|
||||
|
||||
- name: Ensure test groups are absent
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: managers,employees
|
||||
state: absent
|
||||
@@ -1549,7 +1549,7 @@
|
||||
- name: Cleanup test environment.
|
||||
ansible.builtin.include_tasks: env_cleanup.yml
|
||||
|
||||
- name: Remove certificate files. # noqa: deprecated-command-syntax
|
||||
- name: Remove certificate files.
|
||||
ansible.builtin.shell: rm -f "private{{ item }}.key" "cert{{ item }}.pem" "cert{{ item }}.der" "cert{{ item }}.b64"
|
||||
with_items: [1]
|
||||
become: no
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: true
|
||||
gather_facts: true
|
||||
module_defaults:
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
|
||||
tasks:
|
||||
|
||||
@@ -13,8 +17,6 @@
|
||||
# Tests
|
||||
- name: Check if zone is present, when it shouldn't be.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
state: present
|
||||
check_mode: yes
|
||||
@@ -23,8 +25,6 @@
|
||||
|
||||
- name: Check if zone is present again, when it shouldn't be.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
state: present
|
||||
check_mode: yes
|
||||
@@ -33,8 +33,6 @@
|
||||
|
||||
- name: Ensure zone is present.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
state: present
|
||||
register: result
|
||||
@@ -42,8 +40,6 @@
|
||||
|
||||
- name: Check if zone is present, when it should be.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
state: present
|
||||
check_mode: yes
|
||||
@@ -52,8 +48,6 @@
|
||||
|
||||
- name: Ensure zone is present, again.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
state: present
|
||||
register: result
|
||||
@@ -61,8 +55,6 @@
|
||||
|
||||
- name: Ensure zone is disabled.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
state: disabled
|
||||
register: result
|
||||
@@ -70,8 +62,6 @@
|
||||
|
||||
- name: Ensure zone is disabled, again.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
state: disabled
|
||||
register: result
|
||||
@@ -79,8 +69,6 @@
|
||||
|
||||
- name: Ensure zone is enabled.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
state: enabled
|
||||
register: result
|
||||
@@ -88,8 +76,6 @@
|
||||
|
||||
- name: Ensure zone is enabled, again.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
state: enabled
|
||||
register: result
|
||||
@@ -97,8 +83,6 @@
|
||||
|
||||
- name: Ensure forward_policy is none.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
forward_policy: none
|
||||
register: result
|
||||
@@ -106,8 +90,6 @@
|
||||
|
||||
- name: Ensure forward_policy is none, again.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
forward_policy: none
|
||||
register: result
|
||||
@@ -115,8 +97,6 @@
|
||||
|
||||
- name: Ensure forward_policy is first.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
forward_policy: first
|
||||
register: result
|
||||
@@ -124,8 +104,6 @@
|
||||
|
||||
- name: Ensure forward_policy is first, again.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
forward_policy: first
|
||||
register: result
|
||||
@@ -133,8 +111,6 @@
|
||||
|
||||
- name: Ensure first forwarder is set.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
forwarders:
|
||||
- ip_address: 8.8.8.8
|
||||
@@ -144,8 +120,6 @@
|
||||
|
||||
- name: Ensure first and second forwarder are set.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
forwarders:
|
||||
- ip_address: 8.8.8.8
|
||||
@@ -156,8 +130,6 @@
|
||||
|
||||
- name: Ensure first and second forwarder are set, again.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
forwarders:
|
||||
- ip_address: 8.8.8.8
|
||||
@@ -168,8 +140,6 @@
|
||||
|
||||
- name: Ensure only second forwarder is set.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
forwarders:
|
||||
- ip_address: 2001:4860:4860::8888
|
||||
@@ -178,16 +148,12 @@
|
||||
|
||||
- name: Nothing changes.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure no forwarders are set.
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testzone.local
|
||||
forwarders: []
|
||||
register: result
|
||||
@@ -195,56 +161,70 @@
|
||||
|
||||
- name: Create zones test1
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test1.testzone.local
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Create zones test1, again
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test1.testzone.local
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Create zones test2
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test2.testzone.local
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Create zones test2, again
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test2.testzone.local
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Create zones test3
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test3.testzone.local
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Create zones test3, again
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test3.testzone.local
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure zone test1.testzone.local has management permissioon
|
||||
ipadnszone:
|
||||
name: test1.testzone.local
|
||||
permission: true
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure zone test1.testzone.local has management permissioon
|
||||
ipadnszone:
|
||||
name: test1.testzone.local
|
||||
permission: true
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure zone test1.testzone.local don't have management permissioon
|
||||
ipadnszone:
|
||||
name: test1.testzone.local
|
||||
permission: false
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure zone test1.testzone.local don't have management permissioon
|
||||
ipadnszone:
|
||||
name: test1.testzone.local
|
||||
permission: false
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure multiple zones are absent
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name:
|
||||
- test1.testzone.local
|
||||
- test2.testzone.local
|
||||
@@ -255,8 +235,6 @@
|
||||
|
||||
- name: Ensure multiple zones are absent, again
|
||||
ipadnszone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name:
|
||||
- test1.testzone.local
|
||||
- test2.testzone.local
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: true
|
||||
gather_facts: true
|
||||
module_defaults:
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
|
||||
tasks:
|
||||
# setup
|
||||
@@ -19,24 +26,18 @@
|
||||
|
||||
- name: Ensure users user1, user2 and user3 are absent
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: user1,user2,user3
|
||||
state: absent
|
||||
|
||||
- name: Ensure group group3, group2 and group1 are absent
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group3,group2,group1
|
||||
name: groupren,group3,group2,group1
|
||||
state: absent
|
||||
|
||||
# CREATE TEST ITEMS
|
||||
|
||||
- name: Ensure users user1..user3 are present
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
users:
|
||||
- name: user1
|
||||
first: user1
|
||||
@@ -54,56 +55,74 @@
|
||||
|
||||
- name: Ensure group1 is present
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure group1 is present again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Rename group1 to groupren
|
||||
ipagroup:
|
||||
name: group1
|
||||
rename: groupren
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Rename group1 to groupren
|
||||
ipagroup:
|
||||
name: group1
|
||||
rename: groupren
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: not result.failed or "No group 'group1'" not in result.msg
|
||||
|
||||
- name: Rename group groupren to groupren
|
||||
ipagroup:
|
||||
name: groupren
|
||||
rename: groupren
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Rename group groupren back to group1
|
||||
ipagroup:
|
||||
name: groupren
|
||||
rename: group1
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure group2 is present
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group2
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure group2 is present again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group2
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure group3 is present
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group3
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure group3 is present again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group3
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure groups group2 and group3 are present in group group1
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
group:
|
||||
- group2
|
||||
@@ -114,8 +133,6 @@
|
||||
|
||||
- name: Ensure groups group2 and group3 are present in group group1 again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
group:
|
||||
- group2
|
||||
@@ -126,8 +143,6 @@
|
||||
|
||||
- name: Ensure group3 ia present in group group1
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
group:
|
||||
- group3
|
||||
@@ -143,8 +158,6 @@
|
||||
|
||||
- name: Ensure service "{{ 'HTTP/' + fqdn_at_domain }}" is present in group group1
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
@@ -154,8 +167,6 @@
|
||||
|
||||
- name: Ensure service "{{ 'HTTP/' + fqdn_at_domain }}" is present in group group1, again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
@@ -165,8 +176,6 @@
|
||||
|
||||
- name: Ensure service "{{ 'ldap/' + fqdn_at_domain }}" is present in group group1
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'ldap/' + fqdn_at_domain }}"
|
||||
@@ -176,8 +185,6 @@
|
||||
|
||||
- name: Ensure service "{{ 'ldap/' + fqdn_at_domain }}" is present in group group1, again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'ldap/' + fqdn_at_domain }}"
|
||||
@@ -187,8 +194,6 @@
|
||||
|
||||
- name: Ensure service "{{ 'HTTP/' + fqdn_at_domain }}" is absent in group group1
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
@@ -199,8 +204,6 @@
|
||||
|
||||
- name: Ensure service "{{ 'HTTP/' + fqdn_at_domain }}" is absent in group group1, again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
@@ -211,8 +214,6 @@
|
||||
|
||||
- name: Ensure service "{{ 'ldap/' + fqdn_at_domain }}" is absent in group group1
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'ldap/' + fqdn_at_domain }}"
|
||||
@@ -223,8 +224,6 @@
|
||||
|
||||
- name: Ensure service "{{ 'ldap/' + fqdn_at_domain }}" is absent in group group1, again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'ldap/' + fqdn_at_domain }}"
|
||||
@@ -235,8 +234,6 @@
|
||||
|
||||
- name: Ensure services are present in group group1
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
@@ -247,8 +244,6 @@
|
||||
|
||||
- name: Ensure services are present in group group1, again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'http/' + fqdn_at_domain }}"
|
||||
@@ -259,8 +254,6 @@
|
||||
|
||||
- name: Ensure services are absent in group group1
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
@@ -272,8 +265,6 @@
|
||||
|
||||
- name: Ensure services are absent in group group1, again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
@@ -283,12 +274,10 @@
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
# user
|
||||
# user
|
||||
|
||||
- name: Ensure users user1, user2 and user3 are present in group group1
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
user:
|
||||
- user1
|
||||
@@ -300,8 +289,6 @@
|
||||
|
||||
- name: Ensure users user1, user2 and user3 are present in group group1 again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
user:
|
||||
- user1
|
||||
@@ -312,8 +299,6 @@
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
#- ipagroup:
|
||||
# ipaadmin_password: SomeADMINpassword
|
||||
# ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
# name: group1
|
||||
# user:
|
||||
# - user7
|
||||
@@ -321,8 +306,6 @@
|
||||
|
||||
- name: Ensure user user7 is absent in group group1
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
user:
|
||||
- user7
|
||||
@@ -333,8 +316,6 @@
|
||||
|
||||
- name: Ensure group group4 is absent
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group4
|
||||
state: absent
|
||||
register: result
|
||||
@@ -342,8 +323,6 @@
|
||||
|
||||
- name: Ensure groups group3, group2, and group1 are absent
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group3,group2,group1
|
||||
state: absent
|
||||
register: result
|
||||
@@ -351,16 +330,12 @@
|
||||
|
||||
- name: Ensure group group1 is present
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure users user1, user2 are present in group group1
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
user:
|
||||
- user1
|
||||
@@ -371,8 +346,6 @@
|
||||
|
||||
- name: Ensure users user1, user2 and user3 are present in group group1
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
user:
|
||||
- user1
|
||||
@@ -384,8 +357,6 @@
|
||||
|
||||
- name: Ensure users user1, user2 are present in group group1, again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
user:
|
||||
- user1
|
||||
@@ -396,8 +367,6 @@
|
||||
|
||||
- name: Ensure users user1, user2 and user3 are present in group group1, again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
user:
|
||||
- user1
|
||||
@@ -409,8 +378,6 @@
|
||||
|
||||
- name: Ensure group group1 is absent
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
state: absent
|
||||
register: result
|
||||
@@ -418,8 +385,6 @@
|
||||
|
||||
- name: Ensure group group1 with users user1, user2 is present
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
user:
|
||||
- user1
|
||||
@@ -429,8 +394,6 @@
|
||||
|
||||
- name: Ensure group group1 with users user1, user2 and user3 is present
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
user:
|
||||
- user1
|
||||
@@ -441,8 +404,6 @@
|
||||
|
||||
- name: Ensure group group1 with users user1, user2 and user3 is present, again
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
user:
|
||||
- user1
|
||||
@@ -454,8 +415,6 @@
|
||||
|
||||
- name: Ensure only users user1, user2 are present in group group1
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
user:
|
||||
- user1
|
||||
@@ -467,8 +426,6 @@
|
||||
|
||||
- name: Ensure group group3, group2 and group1 are absent
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group3,group2,group1
|
||||
state: absent
|
||||
register: result
|
||||
@@ -476,8 +433,6 @@
|
||||
|
||||
- name: Ensure users user1, user2 and user3 are absent
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: user1,user2,user3
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
250
tests/group/test_group_case_insensitive.yml
Normal file
250
tests/group/test_group_case_insensitive.yml
Normal file
@@ -0,0 +1,250 @@
|
||||
---
|
||||
- name: Test group 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) }}"
|
||||
|
||||
vars:
|
||||
test_users:
|
||||
- { name: useR1, first: user1, last: last }
|
||||
- { name: User2, first: user2, last: last }
|
||||
user_names: "{{ test_users | map(attribute='name') }}"
|
||||
test_groups:
|
||||
- name: Group1
|
||||
- name: Group2
|
||||
group_names: "{{ test_groups | map(attribute='name') }}"
|
||||
|
||||
tasks:
|
||||
- name: Include tasks ../env_freeipa_facts.yml
|
||||
ansible.builtin.include_tasks: ../env_freeipa_facts.yml
|
||||
|
||||
- name: Test in all supported versions of IPA
|
||||
block:
|
||||
# setup environment
|
||||
- name: Ensure testgroup is absent
|
||||
ipagroup:
|
||||
name: testgroup
|
||||
state: absent
|
||||
|
||||
- name: Ensure test users are present
|
||||
ipauser:
|
||||
users: "{{ test_users }}"
|
||||
|
||||
- name: Ensure test groups are present
|
||||
ipagroup:
|
||||
groups: "{{ test_groups }}"
|
||||
|
||||
# tests
|
||||
- name: Test group presence with user members
|
||||
vars:
|
||||
test_cases:
|
||||
- { id: 1, value: "{{ user_names[0] | lower }}", expected: true }
|
||||
- { id: 2, value: "{{ user_names[0] | upper }}", expected: false }
|
||||
- { id: 3, value: "{{ user_names[0] }}", expected: false }
|
||||
- { id: 4, value: "{{ user_names }}", expected: true }
|
||||
- { id: 5, value: "{{ user_names | upper }}", expected: false }
|
||||
- { id: 6, value: "{{ user_names | lower }}", expected: false }
|
||||
- { id: 7, value: "{{ user_names[1] }}", expected: true }
|
||||
- { id: 8, value: "{{ user_names[1] | upper }}", expected: false }
|
||||
- { id: 9, value: "{{ user_names[1] | lower }}", expected: false }
|
||||
- { id: 10, value: [], expected: true }
|
||||
block:
|
||||
- name: Ensure group with user parameter present
|
||||
ipagroup:
|
||||
name: testgroup
|
||||
user: "{{ 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 group presence with group parameter
|
||||
vars:
|
||||
test_cases:
|
||||
- { id: 1, value: "{{ group_names[0] | lower }}", expected: true }
|
||||
- { id: 2, value: "{{ group_names[0] | upper }}", expected: false }
|
||||
- { id: 3, value: "{{ group_names[0] }}", expected: false }
|
||||
- { id: 4, value: "{{ group_names }}", expected: true }
|
||||
- { id: 5, value: "{{ group_names | upper }}", expected: false }
|
||||
- { id: 6, value: "{{ group_names | lower }}", expected: false }
|
||||
- { id: 7, value: "{{ group_names[1] }}", expected: true }
|
||||
- { id: 8, value: "{{ group_names[1] | upper }}", expected: false }
|
||||
- { id: 9, value: "{{ group_names[1] | lower }}", expected: false }
|
||||
- { id: 10, value: [], expected: true }
|
||||
block:
|
||||
- name: Ensure group with group present
|
||||
ipagroup:
|
||||
name: testgroup
|
||||
group: "{{ 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 group with group and user parameters, action member
|
||||
vars:
|
||||
test_cases:
|
||||
- { id: 1, user: "{{ user_names }}", group: "{{ group_names }}", expected: true }
|
||||
- { id: 2, user: "{{ user_names[0] }}", state: "absent", expected: true }
|
||||
- { id: 3, user: "{{ user_names[1] }}", state: "present", expected: false }
|
||||
- { id: 4, user: "{{ user_names[1] | upper }}", state: "present", expected: false }
|
||||
- { id: 5, user: "{{ user_names[1] | lower }}", state: "present", expected: false }
|
||||
- { id: 6, group: "{{ group_names[0] | upper }}", state: "present", expected: false }
|
||||
- { id: 7, group: "{{ group_names[0] | lower }}", state: "present", expected: false }
|
||||
- { id: 8, group: "{{ group_names[0] }}", state: "present", expected: false }
|
||||
- { id: 9, user: "{{ user_names[0] }}", group: "{{ group_names[0] }}", state: "absent", expected: true }
|
||||
- { id: 10, user: "{{ user_names[0] | lower }}", group: "{{ group_names[0] | upper }}", state: "absent", expected: false }
|
||||
- { id: 11, user: "{{ user_names[0] | upper }}", group: "{{ group_names[0] | lower }}", state: "absent", expected: false }
|
||||
- { id: 12, user: "{{ user_names[0] }}", group: "{{ group_names[0] }}", state: "absent", expected: false }
|
||||
- { id: 13, group: "{{ group_names[0] | upper }}", state: "present", expected: true }
|
||||
- { id: 14, group: "{{ group_names[0] | lower }}", state: "present", expected: false }
|
||||
- { id: 15, group: "{{ group_names[0] }}", state: "present", expected: false }
|
||||
- { id: 16, group: "{{ group_names[1] | upper }}", state: "present", expected: false }
|
||||
- { id: 17, group: "{{ group_names[1] | lower }}", state: "present", expected: false }
|
||||
- { id: 18, group: "{{ group_names[1] }}", state: "present", expected: false }
|
||||
- { id: 19, user: "{{ user_names[1] | upper }}", state: "present", expected: false }
|
||||
- { id: 20, user: "{{ user_names[1] | lower }}", state: "present", expected: false }
|
||||
- { id: 21, user: "{{ user_names[1] }}", state: "present", expected: false }
|
||||
block:
|
||||
- name: Ensure group works with group/user attributes and action member
|
||||
ipagroup:
|
||||
name: testgroup
|
||||
user: "{{ item.user | default(omit) }}"
|
||||
group: "{{ item.group | default(omit) }}"
|
||||
action: member
|
||||
state: "{{ item.state | default('present') }}"
|
||||
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 test groups test_groups are absent"
|
||||
ipagroup:
|
||||
name: "{{ group_names + ['testgroup'] }}"
|
||||
state: absent
|
||||
|
||||
- name: "Ensure test users test_users are absent"
|
||||
ipauser:
|
||||
users: "{{ test_users }}"
|
||||
state: absent
|
||||
|
||||
- name: Test in all IPA versions 8.4.4+
|
||||
when: ipa_version is version('4.8.4', '>=')
|
||||
block:
|
||||
# setup environment
|
||||
- name: Ensure test users are present
|
||||
ipauser:
|
||||
users: "{{ test_users }}"
|
||||
|
||||
- name: Ensure test groups are present
|
||||
ipagroup:
|
||||
groups: "{{ test_groups }}"
|
||||
|
||||
# tests
|
||||
- name: Test group presence with memembermanager_user members
|
||||
vars:
|
||||
test_cases:
|
||||
- { id: 1, value: "{{ user_names[0] | lower }}", expected: true }
|
||||
- { id: 2, value: "{{ user_names[0] | upper }}", expected: false }
|
||||
- { id: 3, value: "{{ user_names[0] }}", expected: false }
|
||||
- { id: 4, value: "{{ user_names }}", expected: true }
|
||||
- { id: 5, value: "{{ user_names | upper }}", expected: false }
|
||||
- { id: 6, value: "{{ user_names | lower }}", expected: false }
|
||||
- { id: 7, value: "{{ user_names[1] }}", expected: true }
|
||||
- { id: 8, value: "{{ user_names[1] | upper }}", expected: false }
|
||||
- { id: 9, value: "{{ user_names[1] | lower }}", expected: false }
|
||||
- { id: 10, value: [], expected: true }
|
||||
block:
|
||||
- name: Ensure group with membermanager_user parameter present
|
||||
ipagroup:
|
||||
name: testgroup
|
||||
membermanager_user: "{{ 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 group presence with membermanager_group parameter
|
||||
vars:
|
||||
test_cases:
|
||||
- { id: 1, value: "{{ group_names[0] | lower }}", expected: true }
|
||||
- { id: 2, value: "{{ group_names[0] | upper }}", expected: false }
|
||||
- { id: 3, value: "{{ group_names[0] }}", expected: false }
|
||||
- { id: 4, value: "{{ group_names }}", expected: true }
|
||||
- { id: 5, value: "{{ group_names | upper }}", expected: false }
|
||||
- { id: 6, value: "{{ group_names | lower }}", expected: false }
|
||||
- { id: 7, value: "{{ group_names[1] }}", expected: true }
|
||||
- { id: 8, value: "{{ group_names[1] | upper }}", expected: false }
|
||||
- { id: 9, value: "{{ group_names[1] | lower }}", expected: false }
|
||||
- { id: 10, value: [], expected: true }
|
||||
block:
|
||||
- name: Ensure group with membermanager_group present
|
||||
ipagroup:
|
||||
name: testgroup
|
||||
membermanager_group: "{{ 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 group with membermanager_group and membermanager_user parameters, action member
|
||||
vars:
|
||||
test_cases:
|
||||
- { id: 1, user: "{{ user_names }}", group: "{{ group_names }}", expected: true }
|
||||
- { id: 2, user: "{{ user_names[0] }}", state: "absent", expected: true }
|
||||
- { id: 3, user: "{{ user_names[1] }}", state: "present", expected: false }
|
||||
- { id: 4, user: "{{ user_names[1] | upper }}", state: "present", expected: false }
|
||||
- { id: 5, user: "{{ user_names[1] | lower }}", state: "present", expected: false }
|
||||
- { id: 6, group: "{{ group_names[0] | upper }}", state: "present", expected: false }
|
||||
- { id: 7, group: "{{ group_names[0] | lower }}", state: "present", expected: false }
|
||||
- { id: 8, group: "{{ group_names[0] }}", state: "present", expected: false }
|
||||
- { id: 9, user: "{{ user_names[0] }}", group: "{{ group_names[0] }}", state: "absent", expected: true }
|
||||
- { id: 10, user: "{{ user_names[0] | lower }}", group: "{{ group_names[0] | upper }}", state: "absent", expected: false }
|
||||
- { id: 11, user: "{{ user_names[0] | upper }}", group: "{{ group_names[0] | lower }}", state: "absent", expected: false }
|
||||
- { id: 12, user: "{{ user_names[0] }}", group: "{{ group_names[0] }}", state: "absent", expected: false }
|
||||
- { id: 13, group: "{{ group_names[0] | upper }}", state: "present", expected: true }
|
||||
- { id: 14, group: "{{ group_names[0] | lower }}", state: "present", expected: false }
|
||||
- { id: 15, group: "{{ group_names[0] }}", state: "present", expected: false }
|
||||
- { id: 16, group: "{{ group_names[1] | upper }}", state: "present", expected: false }
|
||||
- { id: 17, group: "{{ group_names[1] | lower }}", state: "present", expected: false }
|
||||
- { id: 18, group: "{{ group_names[1] }}", state: "present", expected: false }
|
||||
- { id: 19, user: "{{ user_names[1] | upper }}", state: "present", expected: false }
|
||||
- { id: 20, user: "{{ user_names[1] | lower }}", state: "present", expected: false }
|
||||
- { id: 21, user: "{{ user_names[1] }}", state: "present", expected: false }
|
||||
block:
|
||||
- name: Ensure group works with group/user attributes and action member
|
||||
ipagroup:
|
||||
name: testgroup
|
||||
membermanager_user: "{{ item.user | default(omit) }}"
|
||||
membermanager_group: "{{ item.group | default(omit) }}"
|
||||
action: member
|
||||
state: "{{ item.state | default('present') }}"
|
||||
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 test groups test_groups are absent"
|
||||
ipagroup:
|
||||
name: "{{ group_names + ['testgroup'] }}"
|
||||
state: absent
|
||||
|
||||
- name: "Ensure test users test_users are absent"
|
||||
ipauser:
|
||||
name: "{{ user_names }}"
|
||||
state: absent
|
||||
@@ -19,7 +19,7 @@
|
||||
- name: Remove test groups
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: group1,group2,group3,group4,group5,group6,group7,group8,group9,group10
|
||||
name: group1,group2,group3,group4,group5,group6,group7,group8,group9,group10,newgroup1,newgroup2
|
||||
state: absent
|
||||
|
||||
- name: Remove test users
|
||||
@@ -130,10 +130,53 @@
|
||||
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: Ensure group1 and group2 exist
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
groups:
|
||||
- name: group1
|
||||
- name: group2
|
||||
|
||||
- name: Rename group1 and group2 to newgroup1 and newgroup2, respectively
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
groups:
|
||||
- name: group1
|
||||
rename: newgroup1
|
||||
- name: group2
|
||||
rename: newgroup2
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Rename newgroup1 and newgroup2 to the same name
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
groups:
|
||||
- name: newgroup1
|
||||
rename: newgroup1
|
||||
- name: newgroup2
|
||||
rename: newgroup2
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Rename newgroup1 and newgroup2 back to group1 and group2, respectively
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
groups:
|
||||
- name: newgroup1
|
||||
rename: group1
|
||||
- name: newgroup2
|
||||
rename: group2
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Remove test groups
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: group1,group2,group3,group4,group5,group6,group7,group8,group9,group10
|
||||
name: group1,group2,group3,group4,group5,group6,group7,group8,group9,group10,newgroup1,newgroup2
|
||||
state: absent
|
||||
|
||||
- name: Remove test users
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
tasks:
|
||||
- name: Include groups.json
|
||||
ansible.builtin.include_vars:
|
||||
file: groups.json # noqa 505
|
||||
file: groups.json
|
||||
|
||||
- name: Initialize groups_names
|
||||
ansible.builtin.set_fact:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
tasks:
|
||||
- name: Include groups.json
|
||||
ansible.builtin.include_vars:
|
||||
file: groups.json # noqa 505
|
||||
file: groups.json
|
||||
|
||||
- name: Groups present len:{{ group_list | length }}
|
||||
ipagroup:
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
tasks:
|
||||
- name: Include groups.json
|
||||
ansible.builtin.include_vars:
|
||||
file: groups.json # noqa 505
|
||||
file: groups.json
|
||||
|
||||
- name: Size of groups slice.
|
||||
ansible.builtin.debug:
|
||||
|
||||
@@ -468,11 +468,51 @@
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
# Specifically test 'Sudo', as FreeIPA adds a "Sudo" hbacsvcgroup instead of "sudo"
|
||||
- name: Ensure 'sudo' works as hbacsvcgroup.
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "test_sudo"
|
||||
hbacsvcgroup:
|
||||
- sudo
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure 'sudo' works as hbacsvcgroup, again.
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "test_sudo"
|
||||
hbacsvcgroup:
|
||||
- sudo
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure 'sudo' works as hbacsvcgroup, action member.
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "test_sudo"
|
||||
hbacsvcgroup:
|
||||
- sudo
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure 'Sudo' works as hbacsvcgroup, action member.
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "test_sudo"
|
||||
hbacsvcgroup:
|
||||
- Sudo
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
always:
|
||||
- name: Ensure test hbacrule is absent
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: testrule
|
||||
name:
|
||||
- testrule
|
||||
- test_sudo
|
||||
state: absent
|
||||
|
||||
- name: Ensure test users are absent
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Remove certificate files. # noqa: deprecated-command-syntax
|
||||
- name: Remove certificate files.
|
||||
ansible.builtin.shell:
|
||||
cmd: rm -f "private{{ item }}.key" "cert{{ item }}.pem" "cert{{ item }}.der" "cert{{ item }}.b64"
|
||||
with_items: [1, 2, 3]
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Remove certificate files. # noqa: deprecated-command-syntax
|
||||
- name: Remove certificate files.
|
||||
ansible.builtin.shell:
|
||||
cmd: rm -f "private{{ item }}.key" "cert{{ item }}.pem" "cert{{ item }}.der" "cert{{ item }}.b64"
|
||||
with_items: [1, 2, 3]
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
ansible.builtin.set_fact:
|
||||
host1_fqdn: "{{ 'host1.' + ipaserver_domain }}"
|
||||
host2_fqdn: "{{ 'host2.' + ipaserver_domain }}"
|
||||
server_fqdn: "{{ ansible_facts['fqdn'] }}"
|
||||
|
||||
- name: Test hosts absent
|
||||
ipahost:
|
||||
@@ -86,10 +87,8 @@
|
||||
- name: Assert randompassword is defined for host1 and host2.
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ipahost.host["{{ host1_fqdn }}"].randompassword is
|
||||
defined
|
||||
- ipahost.host["{{ host2_fqdn }}"].randompassword is
|
||||
defined
|
||||
- ipahost.host[host1_fqdn].randompassword is defined
|
||||
- ipahost.host[host2_fqdn].randompassword is defined
|
||||
|
||||
- name: Print generated random password for "{{ host1_fqdn }}"
|
||||
ansible.builtin.debug:
|
||||
@@ -99,11 +98,11 @@
|
||||
ansible.builtin.debug:
|
||||
var: ipahost.host["{{ host2_fqdn }}"].randompassword
|
||||
|
||||
- name: Enrolled host "{{ ansible_facts['fqdn'] }}" fails to set random password with update_password always
|
||||
- name: Enrolled host "{{ server_fqdn }}" fails to set random password with update_password always
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
hosts:
|
||||
- name: "{{ ansible_facts['fqdn'] }}"
|
||||
- name: "{{ server_fqdn }}"
|
||||
random: yes
|
||||
update_password: always
|
||||
register: ipahost
|
||||
@@ -112,8 +111,7 @@
|
||||
- name: Assert randompassword is not defined for 'ansible_fqdn'.
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ipahost.host["{{ ansible_facts['fqdn'] }}"].randompassword is
|
||||
not defined
|
||||
- ipahost.host[server_fqdn].randompassword is not defined
|
||||
- "'Password cannot be set on enrolled host' in ipahost.msg"
|
||||
|
||||
- name: Hosts "{{ host1_fqdn }}" and "{{ host2_fqdn }}" absent
|
||||
|
||||
144
tests/hostgroup/test_hostgroup_case_insensitive.yml
Normal file
144
tests/hostgroup/test_hostgroup_case_insensitive.yml
Normal 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
|
||||
@@ -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
|
||||
@@ -558,7 +558,7 @@
|
||||
name: test_idview
|
||||
state: absent
|
||||
|
||||
- name: Remove certificate files. # noqa: deprecated-command-syntax
|
||||
- name: Remove certificate files.
|
||||
ansible.builtin.shell:
|
||||
cmd: rm -f "private{{ item }}.key" "cert{{ item }}.pem" "cert{{ item }}.der" "cert{{ item }}.b64"
|
||||
with_items: [1, 2, 3]
|
||||
|
||||
@@ -62,6 +62,162 @@
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp is present with all params
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
organization: main
|
||||
base_url: https://keycloak.idm.example.com:8443/auth
|
||||
keys_uri: https://keycloak.idm.example.com:8443/certs
|
||||
issuer_url: https://keycloak.idm.example.com:8443/issuer
|
||||
secret: secret
|
||||
scope: https://keycloak.idm.example.com:8443/scope
|
||||
idp_user_id: testuser
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp is present with all params, again
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
organization: main
|
||||
base_url: https://keycloak.idm.example.com:8443/auth
|
||||
keys_uri: https://keycloak.idm.example.com:8443/certs
|
||||
issuer_url: https://keycloak.idm.example.com:8443/issuer
|
||||
secret: secret
|
||||
scope: https://keycloak.idm.example.com:8443/scope
|
||||
idp_user_id: testuser
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
# failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp auth_uri is empty
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
auth_uri: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp auth_uri is empty, again
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
auth_uri: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp dev_auth_uri is empty
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
dev_auth_uri: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp dev_auth_uri is empty, again
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
dev_auth_uri: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp token_uri is empty
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
token_uri: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp token_uri is empty, again
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
token_uri: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp userinfo_uri is empty
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
userinfo_uri: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp userinfo_uri is empty, again
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
userinfo_uri: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp keys_uri is empty
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
keys_uri: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp keys_uri is empty, again
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
keys_uri: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp issuer_url is empty
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
issuer_url: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp issuer_url is empty, again
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
issuer_url: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp scope is empty
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
scope: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp scope is empty, again
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
scope: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp idp_user_id is empty
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
idp_user_id: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure keycloak idp my-keycloak-idp idp_user_id is empty, again
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
idp_user_id: ""
|
||||
client_id: my-client-id
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure idp my-keycloak-idp is absent
|
||||
ipaidp:
|
||||
name: my-keycloak-idp
|
||||
|
||||
@@ -176,21 +176,10 @@
|
||||
minlength: ""
|
||||
register: result
|
||||
failed_when:
|
||||
result.changed or
|
||||
(result.failed and not
|
||||
("an internal error has occurred" in result.msg or
|
||||
"int() argument must be" in result.msg))
|
||||
when: ipa_version is version("4.9", ">=")
|
||||
|
||||
- name: Ensure minlength is not cleared due to FreeIPA issue
|
||||
ipapwpolicy:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: ops
|
||||
minlength: ""
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
when: ipa_version is version("4.7", "<")
|
||||
("an internal error has occurred" in result.msg or
|
||||
"int() argument must be" in result.msg))
|
||||
or (not result.failed and not result.changed)
|
||||
|
||||
- name: Execute tests if ipa_version >= 4.9.0
|
||||
when: ipa_version is version("4.9", ">=")
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
update_dns: yes
|
||||
state: absent
|
||||
|
||||
- name: Remove certificate files. # noqa: deprecated-command-syntax
|
||||
- name: Remove certificate files.
|
||||
ansible.builtin.shell:
|
||||
cmd: rm -f "private{{ item }}.key" "cert{{ item }}.pem" "cert{{ item }}.der" "cert{{ item }}.b64"
|
||||
with_items: [1, 2]
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Remove certificate files. # noqa: deprecated-command-syntax
|
||||
- name: Remove certificate files.
|
||||
ansible.builtin.shell:
|
||||
cmd: rm -f "private{{ item }}.key" "cert{{ item }}.pem" "cert{{ item }}.der" "cert{{ item }}.b64"
|
||||
with_items: [1, 2, 3]
|
||||
|
||||
@@ -306,7 +306,7 @@
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Remove certificate files. # noqa: deprecated-command-syntax
|
||||
- name: Remove certificate files.
|
||||
ansible.builtin.shell:
|
||||
cmd: rm -f "private{{ item }}.key" "cert{{ item }}.pem" "cert{{ item }}.der" "cert{{ item }}.b64"
|
||||
with_items: [11, 12, 13, 21, 22, 23, 31, 32, 33]
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
- name: Destroy Kerberos tickets.
|
||||
ansible.builtin.shell: kdestroy -A -q -c ${KRB5CCNAME}
|
||||
|
||||
- name: Remove certificate files. # noqa: deprecated-command-syntax
|
||||
- name: Remove certificate files.
|
||||
ansible.builtin.shell:
|
||||
cmd: rm -f "private{{ item }}.key" "cert{{ item }}.pem" "cert{{ item }}.der" "cert{{ item }}.b64"
|
||||
with_items: [1]
|
||||
|
||||
@@ -8,21 +8,7 @@
|
||||
tasks:
|
||||
|
||||
# setup
|
||||
- name: Ensure user is absent
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: user01
|
||||
state: absent
|
||||
|
||||
- name: Ensure group is absent
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group01
|
||||
state: absent
|
||||
|
||||
- name: Ensure user is present
|
||||
- name: Ensure test user is present
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
@@ -30,13 +16,19 @@
|
||||
first: user
|
||||
last: zeroone
|
||||
|
||||
- name: Ensure group is present, with user01 on it.
|
||||
- name: Ensure group01 is present, with user01 on it.
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group01
|
||||
user: user01
|
||||
|
||||
- name: Ensure group02 is present
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group02
|
||||
|
||||
- name: Ensure sudocmdgroup is absent
|
||||
ipasudocmdgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
@@ -154,6 +146,100 @@
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure group01 is on the list of users sudorule execute as.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testrule1
|
||||
runasuser_group:
|
||||
- group01
|
||||
action: member
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure group01 is on the list of users sudorule execute as, again.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testrule1
|
||||
runasuser_group:
|
||||
- group01
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure group01 and group2 are on the list of users sudorule execute as.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testrule1
|
||||
runasuser_group:
|
||||
- group01
|
||||
- group02
|
||||
action: member
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure group01 and group2 are on the list of users sudorule execute as, again.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testrule1
|
||||
runasuser_group:
|
||||
- group01
|
||||
- group02
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Check if group02 is on the list of users sudorule execute as.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testrule1
|
||||
runasuser_group:
|
||||
- group02
|
||||
action: member
|
||||
register: result
|
||||
check_mode: true
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure group01 is not on the list of users sudorule execute as.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testrule1
|
||||
runasuser_group:
|
||||
- group01
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure group01 is not on the list of users sudorule execute as, again.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testrule1
|
||||
runasuser_group:
|
||||
- group01
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Check if group02 is on the list of users sudorule execute as.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testrule1
|
||||
runasuser_group:
|
||||
- group02
|
||||
action: member
|
||||
register: result
|
||||
check_mode: true
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure group01 is on the list of group sudorule execute as.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
@@ -1155,3 +1241,19 @@
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: cluster
|
||||
state: absent
|
||||
|
||||
- name: Ensure groups are absent
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name:
|
||||
- group01
|
||||
- group02
|
||||
state: absent
|
||||
|
||||
- name: Ensure user is absent
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: user01
|
||||
state: absent
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Remove certificate files. # noqa: deprecated-command-syntax
|
||||
- name: Remove certificate files.
|
||||
ansible.builtin.shell:
|
||||
cmd: rm -f "private{{ item }}.key" "cert{{ item }}.pem" "cert{{ item }}.der" "cert{{ item }}.b64"
|
||||
with_items: [1, 2, 3]
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Remove certificate files. # noqa: deprecated-command-syntax
|
||||
- name: Remove certificate files.
|
||||
ansible.builtin.shell:
|
||||
cmd: rm -f "private{{ item }}.key" "cert{{ item }}.pem" "cert{{ item }}.der" "cert{{ item }}.b64"
|
||||
with_items: [1, 2, 3]
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Remove certificate files. # noqa: deprecated-command-syntax
|
||||
- name: Remove certificate files.
|
||||
ansible.builtin.shell:
|
||||
cmd: rm -f "private{{ item }}.key" "cert{{ item }}.pem" "cert{{ item }}.der" "cert{{ item }}.b64"
|
||||
with_items: [1, 2, 3]
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Remove certificate files. # noqa: deprecated-command-syntax
|
||||
- name: Remove certificate files.
|
||||
ansible.builtin.shell:
|
||||
cmd: rm -f "private{{ item }}.key" "cert{{ item }}.pem" "cert{{ item }}.der" "cert{{ item }}.b64"
|
||||
with_items: [1, 2, 3]
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: manager1,manager2,manager3,pinky,pinky2,igagarin
|
||||
name: manager1,manager2,manager3,pinky,pinky2,igagarin,reddy
|
||||
state: absent
|
||||
|
||||
- name: User manager1 present
|
||||
@@ -87,6 +87,17 @@
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure user presence with 'random:false'
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: pinky
|
||||
first: pinky
|
||||
last: Acme
|
||||
random: false
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Set street, again
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
@@ -341,6 +352,46 @@
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Rename user pinky to reddy
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: pinky
|
||||
rename: reddy
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Rename user pinky to reddy, again
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: pinky
|
||||
rename: reddy
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: not result.failed or "No user 'pinky'" not in result.msg
|
||||
|
||||
- name: Rename user reddy to reddy
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: reddy
|
||||
rename: reddy
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Rename user reddy back to pinky
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: reddy
|
||||
rename: pinky
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: User pinky absent and preserved for future exclusion.
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
|
||||
@@ -5,6 +5,12 @@
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Remove test users
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: manager1,manager2,manager3,pinky,pinky2,mod1,mod2
|
||||
state: absent
|
||||
|
||||
- name: Remove test users
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
@@ -48,7 +54,7 @@
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Users user1..10 present
|
||||
- name: Users user1..10 present, again
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users:
|
||||
@@ -85,6 +91,42 @@
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Rename users user1 and user2 to mod1 and mod1
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users:
|
||||
- name: user1
|
||||
rename: mod1
|
||||
- name: user2
|
||||
rename: mod2
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Rename users mod1 and mod2 to the same name
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users:
|
||||
- name: mod1
|
||||
rename: mod1
|
||||
- name: mod2
|
||||
rename: mod2
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Rename users mod1 and mod2 back to user1 and user2
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users:
|
||||
- name: mod1
|
||||
rename: user1
|
||||
- name: mod2
|
||||
rename: user2
|
||||
state: renamed
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
# failed_when: not result.failed has been added as this test needs to
|
||||
# fail because two users with the same name should be added in the same
|
||||
# task.
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Remove certificate files. # noqa: deprecated-command-syntax
|
||||
- name: Remove certificate files.
|
||||
ansible.builtin.shell:
|
||||
cmd: rm -f "private{{ item }}.key" "cert{{ item }}.pem" "cert{{ item }}.der" "cert{{ item }}.b64"
|
||||
with_items: [1, 2]
|
||||
|
||||
Reference in New Issue
Block a user