mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-03-27 13:53:06 +00:00
Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba3fe74b60 | ||
|
|
b9151f3069 | ||
|
|
6085fbf77d | ||
|
|
603bd61845 | ||
|
|
1a31f62a6f | ||
|
|
23e07a9a17 | ||
|
|
bd084ad37b | ||
|
|
099eb96b58 | ||
|
|
1276e38895 | ||
|
|
2fa9ed9127 | ||
|
|
766cf5a285 | ||
|
|
3ea452ef6f | ||
|
|
50b16cb33f | ||
|
|
9b0558a953 | ||
|
|
6124dc0cf1 | ||
|
|
423a6b0e12 | ||
|
|
a83bab9425 | ||
|
|
70f4b7d646 | ||
|
|
f2865efb1a | ||
|
|
ce143bad52 | ||
|
|
928fdf4b2d | ||
|
|
0d95b8ebcb | ||
|
|
0efe2c30d2 | ||
|
|
10e9c30af6 | ||
|
|
f770b5d581 | ||
|
|
9b020a56f3 | ||
|
|
09a0077b77 | ||
|
|
3779698e0a | ||
|
|
65adc7860e | ||
|
|
df87ff464a | ||
|
|
4b8358b897 | ||
|
|
68661d6922 | ||
|
|
461bd8b15b | ||
|
|
ef0e368741 | ||
|
|
f0a71eda84 | ||
|
|
d0402d7905 | ||
|
|
eebfdbca7a | ||
|
|
e30bcfd876 | ||
|
|
abf0cc3251 | ||
|
|
9decad4e4f | ||
|
|
03098c218d | ||
|
|
d05ad6b1f2 | ||
|
|
9981e5f84b | ||
|
|
4df2cab42a | ||
|
|
5d6324e2da | ||
|
|
8772379dcc | ||
|
|
29badaecca | ||
|
|
e88aaaf95a | ||
|
|
b54333358d | ||
|
|
c16ceac892 | ||
|
|
d303a81e4c | ||
|
|
d561d8f372 | ||
|
|
33c571ebb6 | ||
|
|
81d1896f0f | ||
|
|
75f5082ad0 | ||
|
|
a05eed6a4b | ||
|
|
cddb861fd9 | ||
|
|
15d3123ed3 | ||
|
|
7a1bf986a8 | ||
|
|
c89f6624b5 | ||
|
|
998a141482 | ||
|
|
d111f0d92b | ||
|
|
5ab9ae21ad | ||
|
|
3c130795e3 | ||
|
|
954c911a85 | ||
|
|
e681f25e5c | ||
|
|
8010d19be9 | ||
|
|
892cb037eb | ||
|
|
40d4150590 | ||
|
|
bc72bbd92e | ||
|
|
ae9c81139b | ||
|
|
d5fdaaf444 | ||
|
|
fdd4b19b18 | ||
|
|
dc62744f6a | ||
|
|
2af7602a8c | ||
|
|
1b74cf1692 | ||
|
|
19fc21cd1b | ||
|
|
804e633f13 | ||
|
|
ad37bed37b | ||
|
|
b00dc5daa5 | ||
|
|
2c278ab39d | ||
|
|
ef2adf54b4 | ||
|
|
a61c046abe | ||
|
|
1fee891aa4 | ||
|
|
1aca0c1304 | ||
|
|
60fd87c567 | ||
|
|
4aab1599bd | ||
|
|
0c36194038 |
@@ -14,6 +14,8 @@ exclude_paths:
|
||||
kinds:
|
||||
- playbook: '**/tests/**/test_*.yml'
|
||||
- playbook: '**/playbooks/**/*.yml'
|
||||
- tasks: '**/tasks_*.yml'
|
||||
- tasks: '**/env_*.yml'
|
||||
|
||||
parseable: true
|
||||
|
||||
|
||||
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@@ -68,7 +68,7 @@ jobs:
|
||||
python-version: "3.x"
|
||||
- name: Run pylint
|
||||
run: |
|
||||
pip install pylint==2.10.2
|
||||
pip install pylint==2.12.2
|
||||
pylint plugins roles --disable=import-error
|
||||
|
||||
shellcheck:
|
||||
|
||||
@@ -24,7 +24,7 @@ repos:
|
||||
hooks:
|
||||
- id: pydocstyle
|
||||
- repo: https://github.com/pycqa/pylint
|
||||
rev: v2.10.2
|
||||
rev: v2.12.2
|
||||
hooks:
|
||||
- id: pylint
|
||||
args:
|
||||
|
||||
@@ -129,7 +129,7 @@ Variable | Description | Required
|
||||
`forwarders` | The list of forwarders dicts. Each `forwarders` dict entry has:| no
|
||||
| `ip_address` - The IPv4 or IPv6 address of the DNS server. | yes
|
||||
| `port` - The custom port that should be used on this server. | no
|
||||
`forward_policy` | The global forwarding policy. It can be one of `only`, `first`, or `none`. | no
|
||||
`forward_policy` \| `forwardpolicy` | The global forwarding policy. It can be one of `only`, `first`, or `none`. | no
|
||||
`allow_sync_ptr` | Allow synchronization of forward (A, AAAA) and reverse (PTR) records (bool). | yes
|
||||
`action` | Work on dnsconfig or member level. It can be one of `member` or `dnsconfig` and defaults to `dnsconfig`. Only `forwarders` can be managed with `action: member`. | no
|
||||
`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. `absent` can only be used with `action: member` and `forwarders`. | yes
|
||||
|
||||
@@ -110,7 +110,7 @@ Variable | Description | Required
|
||||
`forwarders` \| `idnsforwarders` | Per-zone forwarders. A custom port can be specified for each forwarder. Options | no
|
||||
| `ip_address`: The forwarder IP address. | yes
|
||||
| `port`: The forwarder IP port. | no
|
||||
`forwardpolicy` \| `idnsforwardpolicy` | Per-zone conditional forwarding policy. Possible values are `only`, `first`, `none`. Set to "none" to disable forwarding to global forwarder for this zone. In that case, conditional zone forwarders are disregarded. | no
|
||||
`forwardpolicy` \| `idnsforwardpolicy` \| `forward_policy` | Per-zone conditional forwarding policy. Possible values are `only`, `first`, `none`. Set to "none" to disable forwarding to global forwarder for this zone. In that case, conditional zone forwarders are disregarded. | no
|
||||
`skip_overlap_check` | Force DNS zone creation even if it will overlap with an existing zone. Defaults to False. | no
|
||||
`permission` | Allow DNS Forward Zone to be managed. (bool) | no
|
||||
`action` | Work on group or member level. It can be on of `member` or `dnsforwardzone` and defaults to `dnsforwardzone`. | no
|
||||
|
||||
@@ -100,7 +100,7 @@ Example playbook to add group members to a group:
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Add group members sysops and appops to group sysops
|
||||
# Add group members sysops and appops to group ops
|
||||
- ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: ops
|
||||
@@ -166,6 +166,7 @@ Variable | Description | Required
|
||||
`membermanager_user` | List of member manager users assigned to this group. Only usable with IPA versions 4.8.4 and up. | no
|
||||
`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
|
||||
`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
|
||||
|
||||
|
||||
196
README-idrange.md
Normal file
196
README-idrange.md
Normal file
@@ -0,0 +1,196 @@
|
||||
Idrange module
|
||||
============
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The idrange module allows the management of ID ranges.
|
||||
|
||||
In general it is not necessary to modify or delete ID ranges. If there is no other way to achieve a certain configuration than to modify or delete an ID range it should be done with great care. Because UIDs are stored in the file system and are used for access control it might be possible that users are allowed to access files of other users if an ID range got deleted and reused for a different domain.
|
||||
|
||||
|
||||
Use cases
|
||||
---------
|
||||
|
||||
* Add an ID range from a transitively trusted domain
|
||||
|
||||
If the trusted domain (A) trusts another domain (B) as well and this trust is transitive 'ipa trust-add domain-A' will only create a range for domain A. The ID range for domain B must be added manually.
|
||||
|
||||
* Add an additional ID range for the local domain
|
||||
|
||||
If the ID range of the local domain is exhausted, i.e. no new IDs can be assigned to Posix users or groups by the DNA plugin, a new range has to be created to allow new users and groups to be added. (Currently there is no connection between this range CLI and the DNA plugin, but a future version might be able to modify the configuration of the DNS plugin as well).
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* ID Range management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipaidrange module.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.8+
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Example inventory file
|
||||
|
||||
```ini
|
||||
[ipaserver]
|
||||
ipaserver.test.local
|
||||
```
|
||||
|
||||
Example playbook to ensure a local domain idrange is present:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA idrange.
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure an ID Range for the local domain is present.
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: local_domain_id_range
|
||||
base_id: 150000
|
||||
range_size: 200000
|
||||
```
|
||||
|
||||
Example playbook to ensure a local domain idrange is present, with RID and secondary RID base values:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA idrange.
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure local idrange is present
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: local_domain_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
rid_base: 1000000
|
||||
secondary_rid_base: 200000000
|
||||
```
|
||||
|
||||
Example playbook to ensure an AD-trust idrange is present, with range type 'trust-ad' and using domain SID:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA idrange.
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure AD-trust idrange is present
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: ad_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
idrange_type: ipa-ad-trust
|
||||
dom_sid: S-1-5-21-2870384104-3340008087-3140804251
|
||||
```
|
||||
|
||||
Example playbook to ensure an AD-trust idrange is present, with range type 'trust-ad-posix' and using domain SID:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA idrange.
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure AD-trust idrange is present
|
||||
ipaidrange:
|
||||
name: ad_posix_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
idrange_type: ipa-ad-trust-posix
|
||||
dom_name: ad.ipa.test
|
||||
```
|
||||
|
||||
Example playbook to ensure an AD-trust idrange has auto creation of groups set to 'hybrid':
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA idrange.
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Modify AD-trust idrange 'auto_private_groups'
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: ad_id_range
|
||||
auto_private_groups: "hybrid"
|
||||
```
|
||||
|
||||
Example playbook to make sure an idrange is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA idrange.
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure ID range 'ad_id_range' is absent.
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: ad_id_range
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
---------
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`ipaapi_context` | The context in which the module will execute. Executing in a server context is preferred. If not provided context will be determined by the execution environment. Valid values are `server` and `client`. | no
|
||||
`ipaapi_ldap_cache` | Use LDAP cache for IPA connection. The bool setting defaults to yes. (bool) | no
|
||||
`name` \| `cn` | The list of idrange name strings. | yes
|
||||
`base_id` \| `ipabaseid` | First Posix ID of the range. (int) | yes, if `state: present`
|
||||
`range_size` \| `ipaidrangesize` | Number of IDs in the range. (int) | yes, if `state: present`
|
||||
`rid_base` \| `ipabaserid` | First RID of the corresponding RID range. (int) | no
|
||||
`secondary_rid_base` \| `ipasecondarybaserid` | First RID of the secondary RID range. (int) | no
|
||||
`dom_sid` \| `ipanttrusteddomainsid` | Domain SID of the trusted domain. | no
|
||||
`dom_name` \| `ipanttrusteddomainname` | Name of the trusted domain. | no
|
||||
`idrange_type` \| `iparangetype` | ID range type, one of `ipa-ad-trust`, `ipa-ad-trust-posix`, `ipa-local`. Only valid if idrange does not exist. | no
|
||||
`auto_private_groups` \| `ipaautoprivategroups` | Auto creation of private groups, one of `true`, `false`, `hybrid`. | no
|
||||
`delete_continue` \| `continue` | Continuous mode: don't stop on errors. Valid only if `state` is `absent`. Default: `no` (bool) | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, default: `present`. | no
|
||||
|
||||
|
||||
Notes
|
||||
=====
|
||||
|
||||
DNA plugin in 389-ds will allocate IDs based on the ranges configured for the local domain. Currently the DNA plugin *cannot* be reconfigured itself based on the local ranges set via this family of commands.
|
||||
|
||||
Manual configuration change has to be done in the DNA plugin configuration for the new local range. Specifically, The dnaNextRange attribute of 'cn=Posix IDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config' has to be modified to match the new range.
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Rafael Guterres Jeffman
|
||||
@@ -293,8 +293,8 @@ Variable | Description | Required
|
||||
`ipaapi_ldap_cache` | Use LDAP cache for IPA connection. The bool setting defaults to yes. (bool) | no
|
||||
`name` \| `service` | The list of service name strings. | yes
|
||||
`certificate` \| `usercertificate` | Base-64 encoded service certificate. | no
|
||||
`pac_type` \| `ipakrbauthzdata` | Supported PAC type. It can be one of `MS-PAC`, `PAD`, or `NONE`. | no
|
||||
`auth_ind` \| `krbprincipalauthind` | Defines an allow list for Authentication Indicators. It can be any of `otp`, `radius`, `pkinit`, or `hardened`. | no
|
||||
`pac_type` \| `ipakrbauthzdata` | Supported PAC type. It can be one of `MS-PAC`, `PAD`, or `NONE`. Use empty string to reset pac_type to the initial value. | no
|
||||
`auth_ind` \| `krbprincipalauthind` | Defines an allow list for Authentication Indicators. It can be any of `otp`, `radius`, `pkinit` or `hardened`. Use empty string to reset auth_ind to the initial value. | no
|
||||
`requires_pre_auth` \| `ipakrbrequirespreauth` | Pre-authentication is required for the service. Default to true. (bool) | no
|
||||
`ok_as_delegate` \| `ipakrbokasdelegate` | Client credentials may be delegated to the service. Default to false. (bool) | no
|
||||
`ok_to_auth_as_delegate` \| `ipakrboktoauthasdelegate` | The service is allowed to authenticate on behalf of a client. Default to false. (bool) | no
|
||||
|
||||
172
README-servicedelegationrule.md
Normal file
172
README-servicedelegationrule.md
Normal file
@@ -0,0 +1,172 @@
|
||||
Servicedelegationrule module
|
||||
============
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The servicedelegationrule module allows to ensure presence and absence of servicedelegationrules and servicedelegationrule members.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Servicedelegationrule management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipaservicedelegationrule module.
|
||||
|
||||
Host princpals are only usable with IPA versions 4.9.0 and up.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.8+
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Example inventory file
|
||||
|
||||
```ini
|
||||
[ipaserver]
|
||||
ipaserver.test.local
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure servicedelegationrule delegation-rule is present:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA servicedelegationrule
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationrule delegation-rule is present
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-rule
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure servicedelegationrule delegation-rule member principal test/example.com is present:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA servicedelegationrule
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationrule delegation-rule member principal test/example.com is present
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-rule
|
||||
principal: test/example.com
|
||||
action: member
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure servicedelegationrule delegation-rule member principal test/example.com is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA servicedelegationrule
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationrule delegation-rule member principal test/example.com is absent
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-rule
|
||||
principal: test/example.com
|
||||
action: member
|
||||
state: absent
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure servicedelegationrule delegation-rule member target delegation-target is present:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA servicedelegationrule
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationrule delegation-rule member target delegation-target is present
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-rule
|
||||
target: delegation-target
|
||||
action: member
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure servicedelegationrule delegation-rule member target delegation-target is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA servicedelegationrule
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationrule delegation-rule member target delegation-target is absent
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-rule
|
||||
target: delegation-target
|
||||
action: member
|
||||
state: absent
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure servicedelegationrule delegation-rule is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA servicedelegationrule
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationrule delegation-rule is absent
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-rule
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
---------
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`ipaapi_context` | The context in which the module will execute. Executing in a server context is preferred. If not provided context will be determined by the execution environment. Valid values are `server` and `client`. | no
|
||||
`ipaapi_ldap_cache` | Use LDAP cache for IPA connection. The bool setting defaults to yes. (bool) | no
|
||||
`name` \| `cn` | The list of servicedelegationrule name strings. | yes
|
||||
`principal` | The list of principals. A principal can be of the format: fqdn, fqdn@REALM, service/fqdn, service/fqdn@REALM, host/fqdn, host/fqdn@REALM, alias$, alias$@REALM, where fqdn and fqdn@REALM are host principals and the same as host/fqdn and host/fqdn@REALM. Host princpals are only usable with IPA versions 4.9.0 and up. | no
|
||||
`target` \| `servicedelegationtarget` | The list of service delegation targets. | no
|
||||
`action` | Work on servicedelegationrule or member level. It can be on of `member` or `servicedelegationrule` and defaults to `servicedelegationrule`. | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, default: `present`. | no
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
133
README-servicedelegationtarget.md
Normal file
133
README-servicedelegationtarget.md
Normal file
@@ -0,0 +1,133 @@
|
||||
Servicedelegationtarget module
|
||||
============
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The servicedelegationtarget module allows to ensure presence and absence of servicedelegationtargets and servicedelegationtarget members.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Servicedelegationtarget management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipaservicedelegationtarget module.
|
||||
|
||||
Host princpals are only usable with IPA versions 4.9.0 and up.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.8+
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Example inventory file
|
||||
|
||||
```ini
|
||||
[ipaserver]
|
||||
ipaserver.test.local
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure servicedelegationtarget delegation-target is present:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA servicedelegationtarget
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationtarget delegation-target is present
|
||||
ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-target
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure servicedelegationtarget delegation-target member principal test/example.com is present:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA servicedelegationtarget
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationtarget delegation-target member principal test/example.com is present
|
||||
ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-target
|
||||
principal: test/example.com
|
||||
action: member
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure servicedelegationtarget delegation-target member principal test/example.com is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA servicedelegationtarget
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationtarget delegation-target member principal test/example.com is absent
|
||||
ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-target
|
||||
principal: test/example.com
|
||||
action: member
|
||||
state: absent
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure servicedelegationtarget delegation-target is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA servicedelegationtarget
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationtarget delegation-target is absent
|
||||
ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-target
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
---------
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`ipaapi_context` | The context in which the module will execute. Executing in a server context is preferred. If not provided context will be determined by the execution environment. Valid values are `server` and `client`. | no
|
||||
`ipaapi_ldap_cache` | Use LDAP cache for IPA connection. The bool setting defaults to yes. (bool) | no
|
||||
`name` \| `cn` | The list of servicedelegationtarget name strings. | yes
|
||||
`principal` | The list of principals. A principal can be of the format: fqdn, fqdn@REALM, service/fqdn, service/fqdn@REALM, host/fqdn, host/fqdn@REALM, alias$, alias$@REALM, where fqdn and fqdn@REALM are host principals and the same as host/fqdn and host/fqdn@REALM. Host princpals are only usable with IPA versions 4.9.0 and up. | no
|
||||
`action` | Work on servicedelegationtarget or member level. It can be on of `member` or `servicedelegationtarget` and defaults to `servicedelegationtarget`. | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, default: `present`. | no
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
@@ -105,6 +105,7 @@ Variable | Description | Required
|
||||
`password` | Active Directory domain administrator's password string. | no
|
||||
`server` | Domain controller for the Active Directory domain string. | no
|
||||
`trust_secret` | Shared secret for the trust string. | no
|
||||
`trust_type` | Trust type. Currently, only 'ad' for Active Directory is supported. | no
|
||||
`base_id` | First posix id for the trusted domain integer. | no
|
||||
`range_size` | Size of the ID range reserved for the trusted domain integer. | no
|
||||
`range_type` | Type of trusted domain ID range, It can be one of `ipa-ad-trust` or `ipa-ad-trust-posix`and defaults to `ipa-ad-trust`. | no
|
||||
|
||||
@@ -28,6 +28,7 @@ Features
|
||||
* Modules for hbacsvcgroup management
|
||||
* Modules for host management
|
||||
* Modules for hostgroup management
|
||||
* Modules for idrange management
|
||||
* Modules for location management
|
||||
* Modules for permission management
|
||||
* Modules for privilege management
|
||||
@@ -36,6 +37,8 @@ Features
|
||||
* Modules for self service management
|
||||
* Modules for server management
|
||||
* Modules for service management
|
||||
* Modules for service delegation rule management
|
||||
* Modules for service delegation target management
|
||||
* Modules for sudocmd management
|
||||
* Modules for sudocmdgroup management
|
||||
* Modules for sudorule management
|
||||
@@ -442,6 +445,7 @@ Modules in plugin/modules
|
||||
* [ipahbacsvcgroup](README-hbacsvcgroup.md)
|
||||
* [ipahost](README-host.md)
|
||||
* [ipahostgroup](README-hostgroup.md)
|
||||
* [idrange](README-idrange.md)
|
||||
* [ipalocation](README-location.md)
|
||||
* [ipapermission](README-permission.md)
|
||||
* [ipaprivilege](README-privilege.md)
|
||||
@@ -450,6 +454,8 @@ Modules in plugin/modules
|
||||
* [ipaselfservice](README-selfservice.md)
|
||||
* [ipaserver](README-server.md)
|
||||
* [ipaservice](README-service.md)
|
||||
* [ipaservicedelegationrule](README-servicedelegationrule.md)
|
||||
* [ipaservicedelegationtarget](README-servicedelegationtarget.md)
|
||||
* [ipasudocmd](README-sudocmd.md)
|
||||
* [ipasudocmdgroup](README-sudocmdgroup.md)
|
||||
* [ipasudorule](README-sudorule.md)
|
||||
|
||||
30
molecule/c8s-build/Dockerfile
Normal file
30
molecule/c8s-build/Dockerfile
Normal file
@@ -0,0 +1,30 @@
|
||||
FROM quay.io/centos/centos:stream8
|
||||
ENV container=docker
|
||||
|
||||
RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
|
||||
dnf makecache; \
|
||||
dnf --assumeyes install \
|
||||
/usr/bin/python3 \
|
||||
/usr/bin/python3-config \
|
||||
/usr/bin/dnf-3 \
|
||||
sudo \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
iproute && \
|
||||
dnf clean all; \
|
||||
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/*;\
|
||||
rm -f /etc/systemd/system/*.wants/*;\
|
||||
rm -f /lib/systemd/system/local-fs.target.wants/*; \
|
||||
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
|
||||
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
|
||||
rm -f /lib/systemd/system/basic.target.wants/*;\
|
||||
rm -f /lib/systemd/system/anaconda.target.wants/*; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
VOLUME ["/sys/fs/cgroup"]
|
||||
|
||||
CMD ["/usr/sbin/init"]
|
||||
19
molecule/c8s-build/molecule.yml
Normal file
19
molecule/c8s-build/molecule.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: c8s-build
|
||||
image: "quay.io/centos/centos:stream8"
|
||||
dockerfile: Dockerfile
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
- 8.8.8.8
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
command: /usr/sbin/init
|
||||
privileged: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare-build.yml
|
||||
prerun: false
|
||||
@@ -2,8 +2,8 @@
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: centos-9
|
||||
image: quay.io/ansible-freeipa/upstream-tests:centos-9
|
||||
- name: c8s
|
||||
image: quay.io/ansible-freeipa/upstream-tests:c8s
|
||||
pre_build_image: true
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
@@ -16,3 +16,4 @@ provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare.yml
|
||||
prerun: false
|
||||
@@ -5,7 +5,6 @@ RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
|
||||
dnf makecache; \
|
||||
dnf --assumeyes install \
|
||||
/usr/bin/python3 \
|
||||
/usr/bin/python3-config \
|
||||
/usr/bin/dnf-3 \
|
||||
sudo \
|
||||
bash \
|
||||
@@ -2,7 +2,7 @@
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: centos-9-build
|
||||
- name: c9s-build
|
||||
image: "quay.io/centos/centos:stream9"
|
||||
dockerfile: Dockerfile
|
||||
hostname: ipaserver.test.local
|
||||
@@ -16,3 +16,4 @@ provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare-build.yml
|
||||
prerun: false
|
||||
19
molecule/c9s/molecule.yml
Normal file
19
molecule/c9s/molecule.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: c9s
|
||||
image: quay.io/ansible-freeipa/upstream-tests:c9s
|
||||
pre_build_image: true
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
- 127.0.0.1
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
command: /usr/sbin/init
|
||||
privileged: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare.yml
|
||||
prerun: false
|
||||
@@ -16,3 +16,4 @@ provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare-build.yml
|
||||
prerun: false
|
||||
|
||||
@@ -16,3 +16,4 @@ provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare.yml
|
||||
prerun: false
|
||||
|
||||
@@ -16,3 +16,4 @@ provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare-build.yml
|
||||
prerun: false
|
||||
|
||||
@@ -16,3 +16,4 @@ provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare.yml
|
||||
prerun: false
|
||||
|
||||
@@ -16,3 +16,4 @@ provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare-build.yml
|
||||
prerun: false
|
||||
|
||||
@@ -16,3 +16,4 @@ provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare.yml
|
||||
prerun: false
|
||||
|
||||
Binary file not shown.
@@ -5,7 +5,7 @@
|
||||
tasks:
|
||||
- name: Ensure aumount key TestKey is renamed to NewKeyName
|
||||
ipaautomountkey:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
automountlocationcn: TestLocation
|
||||
automountmapname: TestMap
|
||||
automountkey: TestKey
|
||||
|
||||
@@ -6,4 +6,5 @@
|
||||
tasks:
|
||||
- name: Disable global forwarders.
|
||||
ipadnsconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
forward_policy: none
|
||||
|
||||
@@ -6,4 +6,5 @@
|
||||
tasks:
|
||||
- name: Disallow reverse record synchronization.
|
||||
ipadnsconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
allow_sync_ptr: no
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
tasks:
|
||||
- name: Set dnsconfig forwarders.
|
||||
ipadnsconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
forwarders:
|
||||
- ip_address: 8.8.4.4
|
||||
- ip_address: 2001:4860:4860::8888
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
tasks:
|
||||
- name: Set dnsconfig forwarders.
|
||||
ipadnsconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
forwarders:
|
||||
- ip_address: 8.8.4.4
|
||||
- ip_address: 2001:4860:4860::8888
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
tasks:
|
||||
- name: Set dnsconfig.
|
||||
ipadnsconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
forwarders:
|
||||
- ip_address: 8.8.4.4
|
||||
- ip_address: 2001:4860:4860::8888
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
tasks:
|
||||
- name: Ensure that 'host04' has CNAME, with cname_hostname, is absent
|
||||
ipadnsrecord:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
zone_name: example.com
|
||||
name: host04
|
||||
cname_hostname: host04.example.com
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
tasks:
|
||||
- name: Ensure that 'host04' has CNAME, with cname_hostname, is present
|
||||
ipadnsrecord:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
zone_name: example.com
|
||||
name: host04
|
||||
cname_hostname: host04.example.com
|
||||
|
||||
11
playbooks/idrange/idrange-absent.yml
Normal file
11
playbooks/idrange/idrange-absent.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Idrange absent example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure idrange is absent
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: id_range
|
||||
state: absent
|
||||
15
playbooks/idrange/idrange-ad-posix-present.yml
Normal file
15
playbooks/idrange/idrange-ad-posix-present.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: Playbook to manage idrange
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure AD-trust idrange is present
|
||||
ipaidrange:
|
||||
name: id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
rid_base: 1000000
|
||||
idrange_type: ipa-ad-trust-posix
|
||||
dom_name: ad.ipa.test
|
||||
auto_private_groups: "false"
|
||||
16
playbooks/idrange/idrange-ad-present.yml
Normal file
16
playbooks/idrange/idrange-ad-present.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
- name: Playbook to manage idrange
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure AD-trust idrange is present
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: ad_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
rid_base: 1000000
|
||||
idrange_type: ipa-ad-trust
|
||||
dom_sid: S-1-5-21-2870384104-3340008087-3140804251
|
||||
auto_private_groups: "true"
|
||||
14
playbooks/idrange/idrange-present.yml
Normal file
14
playbooks/idrange/idrange-present.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Playbook to manage idrange
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure local idrange is present
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
rid_base: 1000000
|
||||
secondary_rid_base: 200000000
|
||||
@@ -6,5 +6,6 @@
|
||||
tasks:
|
||||
- name: Ensure privilege "Broad Privilege" is absent
|
||||
ipaprivilege:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: Broad Privilege
|
||||
state: absent
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Servicedelegationrule absent example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationrule test-delegation-rule is absent
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: test-delegation-rule
|
||||
state: absent
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: Servicedelegationrule present example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationrule test-delegation-rule is present
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: test-delegation-rule
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Servicedelegationrule principal member absent example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure principal member test/example.com is absent in servicedelegationrule test-delegation-rule
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: test-delegation-rule
|
||||
principal: test/example.com
|
||||
action: member
|
||||
state: absent
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Servicedelegationrule principal member present example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure principal member test/example.com is present in servicedelegationrule test-delegation-rule
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: test-delegation-rule
|
||||
principal: test/example.com
|
||||
action: member
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Servicedelegationrule absent example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure member test/example.com is absent in servicedelegationrule test-delegation-rule
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: test-delegation-rule
|
||||
principal: test/example.com
|
||||
action: member
|
||||
state: absent
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Servicedelegationrule member present example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure member test/example.com is present in servicedelegationrule test-delegation-rule
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: test-delegation-rule
|
||||
principal: test/example.com
|
||||
action: member
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Servicedelegationtarget absent example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationtarget test-delegation-target is absent
|
||||
ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: test-delegation-target
|
||||
state: absent
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Servicedelegationtarget absent example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure member test/example.com is absent in servicedelegationtarget test-delegation-target
|
||||
ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: test-delegation-target
|
||||
principal: test/example.com
|
||||
action: member
|
||||
state: absent
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Servicedelegationtarget member present example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure member test/example.com is present in servicedelegationtarget test-delegation-target
|
||||
ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: test-delegation-target
|
||||
principal: test/example.com
|
||||
action: member
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: Servicedelegationtarget present example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure servicedelegationtarget test-delegation-target is present
|
||||
ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: test-delegation-target
|
||||
@@ -6,7 +6,7 @@
|
||||
tasks:
|
||||
- name: Ensure sudocmdgroup is absent
|
||||
ipasudocmdgroup:
|
||||
ipaadmin_password: pass1234
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: network
|
||||
state: absent
|
||||
action: sudocmdgroup
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
tasks:
|
||||
- name: Ensure sudocmdgroup sudocmds are present
|
||||
ipasudocmdgroup:
|
||||
ipaadmin_password: pass1234
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: network
|
||||
description: Group of important commands.
|
||||
sudocmd:
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
tasks:
|
||||
- name: Ensure sudorule command is absent
|
||||
ipasudorule:
|
||||
ipaadmin_password: pass1234
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: testrule1
|
||||
state: absent
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
tasks:
|
||||
- name: Add topology segment
|
||||
ipatopologysegment:
|
||||
ipaadmin_password: "{{ ipaadmin_password }}"
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
suffix: "{{ item.suffix }}"
|
||||
name: "{{ item.name | default(omit) }}"
|
||||
left: "{{ item.left }}"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
tasks:
|
||||
- name: Add topology segment
|
||||
ipatopologysegment:
|
||||
ipaadmin_password: "{{ ipaadmin_password }}"
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
suffix: "{{ item.suffix }}"
|
||||
name: "{{ item.name | default(omit) }}"
|
||||
left: "{{ item.left }}"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
tasks:
|
||||
- name: Add topology segment
|
||||
ipatopologysegment:
|
||||
ipaadmin_password: "{{ ipaadmin_password }}"
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
suffix: "{{ item.suffix }}"
|
||||
name: "{{ item.name | default(omit) }}"
|
||||
left: "{{ item.left }}"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
tasks:
|
||||
- name: ensure the trust is present
|
||||
ipatrust:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
realm: windows.local
|
||||
admin: Administrator
|
||||
password: secret_password
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
tasks:
|
||||
- name: ensure the trust is absent
|
||||
ipatrust:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
realm: windows.local
|
||||
state: absent
|
||||
|
||||
@@ -45,3 +45,13 @@ options:
|
||||
type: bool
|
||||
default: true
|
||||
"""
|
||||
|
||||
DELETE_CONTINUE = r"""
|
||||
options:
|
||||
delete_continue:
|
||||
description: |
|
||||
Continuous mode. Don't stop on errors. Valid only if `state` is `absent`.
|
||||
aliases: ["continue"]
|
||||
type: bool
|
||||
default: True
|
||||
"""
|
||||
|
||||
@@ -86,6 +86,7 @@ else:
|
||||
from ipaplatform.paths import paths
|
||||
from ipalib.krb_utils import get_credentials_if_valid
|
||||
from ipapython.dnsutil import DNSName
|
||||
from ipapython import kerberos
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import jsonify
|
||||
@@ -309,15 +310,49 @@ else:
|
||||
raise ValueError("Invalid date '%s'" % value)
|
||||
|
||||
def compare_args_ipa(module, args, ipa, ignore=None): # noqa
|
||||
"""Compare IPA obj attrs with the command args.
|
||||
"""Compare IPA object attributes against command arguments.
|
||||
|
||||
This function compares IPA objects attributes with the args the
|
||||
module is intending to use to call a command. ignore can be a list
|
||||
of attributes, that should be ignored in the comparison.
|
||||
This is useful to know if a call to IPA server will be needed or not.
|
||||
In order to compare we have to perform slight changes in data formats.
|
||||
This function compares 'ipa' attributes with the 'args' the module
|
||||
is intending to use as parameters to an IPA API command. A list of
|
||||
attribute names that should be ignored during comparison may be
|
||||
provided.
|
||||
|
||||
Returns True if they are the same and False otherwise.
|
||||
The comparison will be performed on every attribute provided in
|
||||
'args'. If the attribute in 'args' or 'ipa' is not a scalar value
|
||||
(including strings) the comparison will be performed as if the
|
||||
attribute is a set of values, so duplicate values will count as a
|
||||
single one. If both values are scalar values, then a direct
|
||||
comparison is performed.
|
||||
|
||||
If an attribute is not available in 'ipa', its value is considered
|
||||
to be a list with an empty string (['']), possibly forcing the
|
||||
conversion of the 'args' attribute to a list for comparison. This
|
||||
allows, for example, the usage of empty strings which should compare
|
||||
as equals to inexistent attributes (None), as is done in IPA API.
|
||||
|
||||
This function is mostly useful to evaluate the need of a call to
|
||||
IPA server when provided arguments are equivalent to the existing
|
||||
values for a given IPA object.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
module: AnsibleModule
|
||||
The AnsibleModule used to log debug messages.
|
||||
|
||||
args: dict
|
||||
The set of attributes provided by the playbook task.
|
||||
|
||||
ipa: dict
|
||||
The set of attributes from the IPA object retrieved.
|
||||
|
||||
ignore: list
|
||||
An optional list of attribute names that should be ignored and
|
||||
not evaluated.
|
||||
|
||||
Return
|
||||
------
|
||||
True is returned if all attribute values in 'args' are
|
||||
equivalent to the corresponding attribute value in 'ipa'.
|
||||
"""
|
||||
base_debug_msg = "Ansible arguments and IPA commands differed. "
|
||||
|
||||
@@ -337,52 +372,45 @@ else:
|
||||
filtered_args = [key for key in args if key not in ignore]
|
||||
|
||||
for key in filtered_args:
|
||||
if key not in ipa: # pylint: disable=no-else-return
|
||||
module.debug(
|
||||
base_debug_msg + "Command key not present in IPA: %s" % key
|
||||
)
|
||||
return False
|
||||
arg = args[key]
|
||||
ipa_arg = ipa.get(key, [""])
|
||||
# If ipa_arg is a list and arg is not, replace arg
|
||||
# with list containing arg. Most args in a find result
|
||||
# are lists, but not all.
|
||||
if isinstance(ipa_arg, (list, tuple)):
|
||||
if not isinstance(arg, list):
|
||||
arg = [arg]
|
||||
if len(ipa_arg) != len(arg):
|
||||
module.debug(
|
||||
base_debug_msg
|
||||
+ "List length doesn't match for key %s: %d %d"
|
||||
% (key, len(arg), len(ipa_arg),)
|
||||
)
|
||||
return False
|
||||
# ensure list elements types are the same.
|
||||
if not (
|
||||
isinstance(ipa_arg[0], type(arg[0]))
|
||||
or isinstance(arg[0], type(ipa_arg[0]))
|
||||
):
|
||||
arg = [to_text(_arg) for _arg in arg]
|
||||
try:
|
||||
arg_set = set(arg)
|
||||
ipa_arg_set = set(ipa_arg)
|
||||
except TypeError:
|
||||
if arg != ipa_arg:
|
||||
module.debug(
|
||||
base_debug_msg
|
||||
+ "Different values: %s %s" % (arg, ipa_arg)
|
||||
)
|
||||
return False
|
||||
else:
|
||||
arg = args[key]
|
||||
ipa_arg = ipa[key]
|
||||
# If ipa_arg is a list and arg is not, replace arg
|
||||
# with list containing arg. Most args in a find result
|
||||
# are lists, but not all.
|
||||
if isinstance(ipa_arg, tuple):
|
||||
ipa_arg = list(ipa_arg)
|
||||
if isinstance(ipa_arg, list):
|
||||
if not isinstance(arg, list):
|
||||
arg = [arg]
|
||||
if len(ipa_arg) != len(arg):
|
||||
module.debug(
|
||||
base_debug_msg
|
||||
+ "List length doesn't match for key %s: %d %d"
|
||||
% (key, len(arg), len(ipa_arg),)
|
||||
)
|
||||
return False
|
||||
if isinstance(ipa_arg[0], str) and isinstance(arg[0], int):
|
||||
arg = [to_text(_arg) for _arg in arg]
|
||||
if isinstance(ipa_arg[0], unicode) \
|
||||
and isinstance(arg[0], int):
|
||||
arg = [to_text(_arg) for _arg in arg]
|
||||
try:
|
||||
arg_set = set(arg)
|
||||
ipa_arg_set = set(ipa_arg)
|
||||
except TypeError:
|
||||
if arg != ipa_arg:
|
||||
module.debug(
|
||||
base_debug_msg
|
||||
+ "Different values: %s %s" % (arg, ipa_arg)
|
||||
)
|
||||
return False
|
||||
else:
|
||||
if arg_set != ipa_arg_set:
|
||||
module.debug(
|
||||
base_debug_msg
|
||||
+ "Different set content: %s %s"
|
||||
% (arg_set, ipa_arg_set,)
|
||||
)
|
||||
return False
|
||||
if arg_set != ipa_arg_set:
|
||||
module.debug(
|
||||
base_debug_msg
|
||||
+ "Different set content: %s %s"
|
||||
% (arg_set, ipa_arg_set,)
|
||||
)
|
||||
return False
|
||||
return True
|
||||
|
||||
def _afm_convert(value):
|
||||
@@ -397,11 +425,32 @@ else:
|
||||
|
||||
return value
|
||||
|
||||
def module_params_get(module, name):
|
||||
return _afm_convert(module.params.get(name))
|
||||
|
||||
def module_params_get_lowercase(module, name):
|
||||
def module_params_get(module, name, allow_empty_string=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.
|
||||
# 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.
|
||||
# Ansible issue https://github.com/ansible/ansible/issues/77108
|
||||
if isinstance(value, list):
|
||||
for val in value:
|
||||
if isinstance(val, (str, unicode)) and not val:
|
||||
if not allow_empty_string:
|
||||
module.fail_json(
|
||||
msg="Parameter '%s' contains an empty string" %
|
||||
name)
|
||||
elif len(value) > 1:
|
||||
module.fail_json(
|
||||
msg="Parameter '%s' may not contain another "
|
||||
"entry together with an empty string" % name)
|
||||
|
||||
return value
|
||||
|
||||
def module_params_get_lowercase(module, name, allow_empty_string=False):
|
||||
value = module_params_get(module, name, allow_empty_string)
|
||||
if isinstance(value, list):
|
||||
value = [v.lower() for v in value]
|
||||
if isinstance(value, (str, unicode)):
|
||||
@@ -550,6 +599,89 @@ else:
|
||||
return False
|
||||
return True
|
||||
|
||||
def servicedelegation_normalize_principals(module, principal,
|
||||
check_exists=False):
|
||||
"""
|
||||
Normalize servicedelegation principals.
|
||||
|
||||
The principals can be service and with IPA 4.9.0+ also host principals.
|
||||
"""
|
||||
|
||||
def _normalize_principal_name(name, realm):
|
||||
# Normalize principal name
|
||||
# Copied from ipaserver/plugins/servicedelegation.py
|
||||
try:
|
||||
princ = kerberos.Principal(name, realm=realm)
|
||||
except ValueError as _err:
|
||||
raise ipalib_errors.ValidationError(
|
||||
name='principal',
|
||||
reason="Malformed principal: %s" % str(_err))
|
||||
|
||||
if len(princ.components) == 1 and \
|
||||
not princ.components[0].endswith('$'):
|
||||
nprinc = 'host/' + unicode(princ)
|
||||
else:
|
||||
nprinc = unicode(princ)
|
||||
return nprinc
|
||||
|
||||
def _check_exists(module, _type, name):
|
||||
# Check if item of type _type exists using the show command
|
||||
try:
|
||||
module.ipa_command("%s_show" % _type, name, {})
|
||||
except ipalib_errors.NotFound as e:
|
||||
msg = str(e)
|
||||
if "%s not found" % _type in msg:
|
||||
return False
|
||||
module.fail_json(msg="%s_show failed: %s" % (_type, msg))
|
||||
return True
|
||||
|
||||
ipa_realm = module.ipa_get_realm()
|
||||
_principal = []
|
||||
for _princ in principal:
|
||||
princ = _princ
|
||||
realm = ipa_realm
|
||||
|
||||
# Get principal and realm from _princ if there is a realm
|
||||
if '@' in _princ:
|
||||
princ, realm = _princ.rsplit('@', 1)
|
||||
|
||||
# Lowercase principal
|
||||
princ = princ.lower()
|
||||
|
||||
# Normalize principal
|
||||
try:
|
||||
nprinc = _normalize_principal_name(princ, realm)
|
||||
except ipalib_errors.ValidationError as err:
|
||||
module.fail_json(msg="%s: %s" % (_princ, str(err)))
|
||||
princ = unicode(nprinc)
|
||||
|
||||
# Check that host principal exists
|
||||
if princ.startswith("host/"):
|
||||
if module.ipa_check_version("<", "4.9.0"):
|
||||
module.fail_json(
|
||||
msg="The use of host principals is not supported "
|
||||
"by your IPA version")
|
||||
|
||||
# Get host FQDN (no leading 'host/' and no trailing realm)
|
||||
# (There is no removeprefix and removesuffix in Python2)
|
||||
_host = princ[5:]
|
||||
if _host.endswith("@%s" % realm):
|
||||
_host = _host[:-len(realm) - 1]
|
||||
|
||||
# Seach for host
|
||||
if check_exists and not _check_exists(module, "host", _host):
|
||||
module.fail_json(msg="Host '%s' does not exist" % _host)
|
||||
|
||||
# Check the service principal exists
|
||||
else:
|
||||
if check_exists and \
|
||||
not _check_exists(module, "service", princ):
|
||||
module.fail_json(msg="Service %s does not exist" % princ)
|
||||
|
||||
_principal.append(princ)
|
||||
|
||||
return _principal
|
||||
|
||||
def exit_raw_json(module, **kwargs):
|
||||
"""
|
||||
Print the raw parameters in JSON format, without masking.
|
||||
@@ -742,6 +874,12 @@ else:
|
||||
ipaapi_ldap_cache=dict(type="bool", default="True"),
|
||||
)
|
||||
|
||||
ipa_module_options_spec = dict(
|
||||
delete_continue=dict(
|
||||
type="bool", default=True, aliases=["continue"]
|
||||
)
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# Extend argument_spec with ipa_module_base_spec
|
||||
if "argument_spec" in kwargs:
|
||||
@@ -749,6 +887,16 @@ else:
|
||||
_spec.update(self.ipa_module_base_spec)
|
||||
kwargs["argument_spec"] = _spec
|
||||
|
||||
if "ipa_module_options" in kwargs:
|
||||
_update = {
|
||||
k: self.ipa_module_options_spec[k]
|
||||
for k in kwargs["ipa_module_options"]
|
||||
}
|
||||
_spec = kwargs.get("argument_spec", {})
|
||||
_spec.update(_update)
|
||||
kwargs["argument_spec"] = _spec
|
||||
del kwargs["ipa_module_options"]
|
||||
|
||||
# pylint: disable=super-with-arguments
|
||||
super(IPAAnsibleModule, self).__init__(*args, **kwargs)
|
||||
|
||||
@@ -797,7 +945,7 @@ else:
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
def params_get(self, name):
|
||||
def params_get(self, name, allow_empty_string=False):
|
||||
"""
|
||||
Retrieve value set for module parameter.
|
||||
|
||||
@@ -805,11 +953,13 @@ else:
|
||||
----------
|
||||
name: string
|
||||
The name of the parameter to retrieve.
|
||||
allow_empty_string: bool
|
||||
The parameter allowes to have empty strings in a list
|
||||
|
||||
"""
|
||||
return module_params_get(self, name)
|
||||
return module_params_get(self, name, allow_empty_string)
|
||||
|
||||
def params_get_lowercase(self, name):
|
||||
def params_get_lowercase(self, name, allow_empty_string=False):
|
||||
"""
|
||||
Retrieve value set for module parameter as lowercase, if not None.
|
||||
|
||||
@@ -817,9 +967,11 @@ else:
|
||||
----------
|
||||
name: string
|
||||
The name of the parameter to retrieve.
|
||||
allow_empty_string: bool
|
||||
The parameter allowes to have empty strings in a list
|
||||
|
||||
"""
|
||||
return module_params_get_lowercase(self, name)
|
||||
return module_params_get_lowercase(self, name, allow_empty_string)
|
||||
|
||||
def params_fail_used_invalid(self, invalid_params, state, action=None):
|
||||
"""
|
||||
|
||||
@@ -587,7 +587,6 @@ def main():
|
||||
commands.append([None,
|
||||
'automember_default_group_remove',
|
||||
{'type': automember_type}])
|
||||
ansible_module.warn("commands: %s" % repr(commands))
|
||||
|
||||
else:
|
||||
dn_default_group = [DN(('cn', default_group),
|
||||
|
||||
@@ -112,21 +112,23 @@ class AutomountMap(IPAAnsibleModule):
|
||||
state = self.params_get("state")
|
||||
if state == "present":
|
||||
if len(name) != 1:
|
||||
self.fail_json(msg="Exactly one name must be provided \
|
||||
for state=present.")
|
||||
self.fail_json(msg="Exactly one name must be provided for"
|
||||
" 'state: present'.")
|
||||
if state == "absent":
|
||||
if len(name) == 0:
|
||||
self.fail_json(msg="Argument 'map_type' can not be used with "
|
||||
"state 'absent'")
|
||||
self.fail_json(msg="At least one 'name' must be provided for"
|
||||
" 'state: absent'")
|
||||
invalid = ["desc"]
|
||||
|
||||
self.params_fail_used_invalid(invalid, state)
|
||||
|
||||
def get_args(self, mapname, desc): # pylint: disable=no-self-use
|
||||
_args = {}
|
||||
if mapname:
|
||||
_args["automountmapname"] = mapname
|
||||
if desc:
|
||||
# automountmapname is required for all automountmap operations.
|
||||
if not mapname:
|
||||
self.fail_json(msg="automountmapname cannot be None or empty.")
|
||||
_args = {"automountmapname": mapname}
|
||||
# An empty string is valid and will clear the attribute.
|
||||
if desc is not None:
|
||||
_args["description"] = desc
|
||||
return _args
|
||||
|
||||
|
||||
@@ -346,11 +346,13 @@ def main():
|
||||
"ca_renewal_master_server": "ca_renewal_master_server",
|
||||
"domain_resolution_order": "ipadomainresolutionorder"
|
||||
}
|
||||
allow_empty_string = ["pac_type", "user_auth_type", "configstring"]
|
||||
reverse_field_map = {v: k for k, v in field_map.items()}
|
||||
|
||||
params = {}
|
||||
for x in field_map:
|
||||
val = ansible_module.params_get(x)
|
||||
val = ansible_module.params_get(
|
||||
x, allow_empty_string=(x in allow_empty_string))
|
||||
|
||||
if val is not None:
|
||||
params[field_map.get(x, x)] = val
|
||||
@@ -401,6 +403,10 @@ def main():
|
||||
k: v for k, v in params.items()
|
||||
if k not in result or result[k] != v
|
||||
}
|
||||
# Remove empty string args from params if result arg is not set
|
||||
for k in ["ipakrbauthzdata", "ipauserauthtype", "ipaconfigstring"]:
|
||||
if k not in result and k in params and params[k] == [""]:
|
||||
del params[k]
|
||||
if params \
|
||||
and not compare_args_ipa(ansible_module, params, result):
|
||||
changed = True
|
||||
@@ -441,6 +447,13 @@ def main():
|
||||
raise ValueError(
|
||||
"Unexpected attribute type: %s" % arg_type)
|
||||
exit_args[k] = type_map[arg_type](value)
|
||||
# Add empty pac_type and user_auth_type if they are not set
|
||||
for key in ["pac_type", "user_auth_type"]:
|
||||
if key not in exit_args:
|
||||
exit_args[key] = ""
|
||||
# Add empty domain_resolution_order if it is not set
|
||||
if "domain_resolution_order" not in exit_args:
|
||||
exit_args["domain_resolution_order"] = []
|
||||
|
||||
# Done
|
||||
ansible_module.exit_json(changed=changed, config=exit_args)
|
||||
|
||||
@@ -54,6 +54,7 @@ options:
|
||||
global forwarders.
|
||||
required: false
|
||||
choices: ['only', 'first', 'none']
|
||||
alias: ["forwardpolicy"]
|
||||
allow_sync_ptr:
|
||||
description:
|
||||
Allow synchronization of forward (A, AAAA) and reverse (PTR) records.
|
||||
@@ -189,7 +190,8 @@ def main():
|
||||
forwarders=dict(type='list', default=None, required=False,
|
||||
options=dict(**forwarder_spec)),
|
||||
forward_policy=dict(type='str', required=False, default=None,
|
||||
choices=['only', 'first', 'none']),
|
||||
choices=['only', 'first', 'none'],
|
||||
aliases=["forwardpolicy"]),
|
||||
allow_sync_ptr=dict(type='bool', required=False, default=None),
|
||||
|
||||
# general
|
||||
|
||||
@@ -68,7 +68,7 @@ options:
|
||||
required: false
|
||||
default: only
|
||||
choices: ["only", "first", "none"]
|
||||
aliases: ["idnsforwarders"]
|
||||
aliases: ["idnsforwarders", "forward_policy"]
|
||||
skip_overlap_check:
|
||||
description:
|
||||
- Force DNS zone creation even if it will overlap with an existing zone.
|
||||
@@ -189,7 +189,8 @@ def main():
|
||||
port=dict(type='int', required=False,
|
||||
default=None),
|
||||
)),
|
||||
forwardpolicy=dict(type='str', aliases=["idnsforwardpolicy"],
|
||||
forwardpolicy=dict(type='str',
|
||||
aliases=["idnsforwardpolicy", "forward_policy"],
|
||||
required=False,
|
||||
choices=['only', 'first', 'none']),
|
||||
skip_overlap_check=dict(type='bool', required=False),
|
||||
|
||||
@@ -97,6 +97,11 @@ options:
|
||||
required: false
|
||||
type: list
|
||||
ailases: ["ipaexternalmember", "external_member"]
|
||||
idoverrideuser:
|
||||
description:
|
||||
- User ID overrides to add
|
||||
required: false
|
||||
type: list
|
||||
action:
|
||||
description: Work on group or member level
|
||||
default: group
|
||||
@@ -184,7 +189,7 @@ RETURN = """
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, \
|
||||
gen_add_list, gen_intersection_list
|
||||
gen_add_list, gen_intersection_list, api_check_param
|
||||
|
||||
|
||||
def find_group(module, name):
|
||||
@@ -223,7 +228,7 @@ def gen_args(description, gid, nomembers):
|
||||
return _args
|
||||
|
||||
|
||||
def gen_member_args(user, group, service, externalmember):
|
||||
def gen_member_args(user, group, service, externalmember, idoverrideuser):
|
||||
_args = {}
|
||||
if user is not None:
|
||||
_args["member_user"] = user
|
||||
@@ -233,6 +238,8 @@ def gen_member_args(user, group, service, externalmember):
|
||||
_args["member_service"] = service
|
||||
if externalmember is not None:
|
||||
_args["member_external"] = externalmember
|
||||
if idoverrideuser is not None:
|
||||
_args["member_idoverrideuser"] = idoverrideuser
|
||||
|
||||
return _args
|
||||
|
||||
@@ -280,6 +287,7 @@ def main():
|
||||
user=dict(required=False, type='list', default=None),
|
||||
group=dict(required=False, type='list', default=None),
|
||||
service=dict(required=False, type='list', default=None),
|
||||
idoverrideuser=dict(required=False, type='list', default=None),
|
||||
membermanager_user=dict(required=False, type='list', default=None),
|
||||
membermanager_group=dict(required=False, type='list',
|
||||
default=None),
|
||||
@@ -312,6 +320,7 @@ def main():
|
||||
gid = ansible_module.params_get("gid")
|
||||
nonposix = ansible_module.params_get("nonposix")
|
||||
external = ansible_module.params_get("external")
|
||||
idoverrideuser = ansible_module.params_get("idoverrideuser")
|
||||
posix = ansible_module.params_get("posix")
|
||||
nomembers = ansible_module.params_get("nomembers")
|
||||
user = ansible_module.params_get("user")
|
||||
@@ -379,6 +388,13 @@ def main():
|
||||
"by your IPA version"
|
||||
)
|
||||
|
||||
has_idoverrideuser = api_check_param(
|
||||
"group_add_member", "idoverrideuser")
|
||||
if idoverrideuser is not None and not has_idoverrideuser:
|
||||
ansible_module.fail_json(
|
||||
msg="Managing a idoverrideuser as part of a group is not "
|
||||
"supported by your IPA version")
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
@@ -389,6 +405,7 @@ def main():
|
||||
group_add, group_del = [], []
|
||||
service_add, service_del = [], []
|
||||
externalmember_add, externalmember_del = [], []
|
||||
idoverrides_add, idoverrides_del = [], []
|
||||
membermanager_user_add, membermanager_user_del = [], []
|
||||
membermanager_group_add, membermanager_group_del = [], []
|
||||
|
||||
@@ -438,7 +455,7 @@ def main():
|
||||
res_find["objectclass"].append("posixgroup")
|
||||
|
||||
member_args = gen_member_args(
|
||||
user, group, service, externalmember
|
||||
user, group, service, externalmember, idoverrideuser
|
||||
)
|
||||
if not compare_args_ipa(ansible_module, member_args,
|
||||
res_find):
|
||||
@@ -456,6 +473,12 @@ def main():
|
||||
externalmember_del) = gen_add_del_lists(
|
||||
externalmember, res_find.get("member_external"))
|
||||
|
||||
(idoverrides_add,
|
||||
idoverrides_del) = gen_add_del_lists(
|
||||
idoverrideuser,
|
||||
res_find.get("member_idoverrideuser")
|
||||
)
|
||||
|
||||
membermanager_user_add, membermanager_user_del = \
|
||||
gen_add_del_lists(
|
||||
membermanager_user,
|
||||
@@ -483,6 +506,8 @@ def main():
|
||||
service, res_find.get("member_service"))
|
||||
externalmember_add = gen_add_list(
|
||||
externalmember, res_find.get("member_external"))
|
||||
idoverrides_add = gen_add_list(
|
||||
idoverrideuser, res_find.get("member_idoverrideuser"))
|
||||
|
||||
membermanager_user_add = gen_add_list(
|
||||
membermanager_user,
|
||||
@@ -516,6 +541,8 @@ def main():
|
||||
service, res_find.get("member_service"))
|
||||
externalmember_del = gen_intersection_list(
|
||||
externalmember, res_find.get("member_external"))
|
||||
idoverrides_del = gen_intersection_list(
|
||||
idoverrideuser, res_find.get("member_idoverrideuser"))
|
||||
|
||||
membermanager_user_del = gen_intersection_list(
|
||||
membermanager_user, res_find.get("membermanager_user"))
|
||||
@@ -532,10 +559,16 @@ def main():
|
||||
"user": user_add,
|
||||
"group": group_add,
|
||||
}
|
||||
|
||||
del_member_args = {
|
||||
"user": user_del,
|
||||
"group": group_del,
|
||||
}
|
||||
|
||||
if has_idoverrideuser:
|
||||
add_member_args["idoverrideuser"] = idoverrides_add
|
||||
del_member_args["idoverrideuser"] = idoverrides_del
|
||||
|
||||
if has_add_member_service:
|
||||
add_member_args["service"] = service_add
|
||||
del_member_args["service"] = service_del
|
||||
@@ -550,15 +583,16 @@ def main():
|
||||
msg="Cannot add external members to a "
|
||||
"non-external group."
|
||||
)
|
||||
|
||||
# Add members
|
||||
add_members = any([user_add, group_add,
|
||||
add_members = any([user_add, group_add, idoverrides_add,
|
||||
service_add, externalmember_add])
|
||||
if add_members:
|
||||
commands.append(
|
||||
[name, "group_add_member", add_member_args]
|
||||
)
|
||||
# Remove members
|
||||
remove_members = any([user_del, group_del,
|
||||
remove_members = any([user_del, group_del, idoverrides_del,
|
||||
service_del, externalmember_del])
|
||||
if remove_members:
|
||||
commands.append(
|
||||
|
||||
@@ -360,28 +360,28 @@ def main():
|
||||
res_find = {}
|
||||
|
||||
# Generate addition and removal lists
|
||||
if host:
|
||||
if host is not None:
|
||||
host_add, host_del = gen_add_del_lists(
|
||||
host, res_find.get("memberhost_host"))
|
||||
|
||||
if hostgroup:
|
||||
if hostgroup is not None:
|
||||
hostgroup_add, hostgroup_del = gen_add_del_lists(
|
||||
hostgroup, res_find.get("memberhost_hostgroup"))
|
||||
|
||||
if hbacsvc:
|
||||
if hbacsvc is not None:
|
||||
hbacsvc_add, hbacsvc_del = gen_add_del_lists(
|
||||
hbacsvc, res_find.get("memberservice_hbacsvc"))
|
||||
|
||||
if hbacsvcgroup:
|
||||
if hbacsvcgroup is not None:
|
||||
hbacsvcgroup_add, hbacsvcgroup_del = gen_add_del_lists(
|
||||
hbacsvcgroup,
|
||||
res_find.get("memberservice_hbacsvcgroup"))
|
||||
|
||||
if user:
|
||||
if user is not None:
|
||||
user_add, user_del = gen_add_del_lists(
|
||||
user, res_find.get("memberuser_user"))
|
||||
|
||||
if group:
|
||||
if group is not None:
|
||||
group_add, group_del = gen_add_del_lists(
|
||||
group, res_find.get("memberuser_group"))
|
||||
|
||||
@@ -395,7 +395,7 @@ def main():
|
||||
if host:
|
||||
host_add = gen_add_list(
|
||||
host, res_find.get("memberhost_host"))
|
||||
if hostgroup is not None:
|
||||
if hostgroup:
|
||||
hostgroup_add = gen_add_list(
|
||||
hostgroup, res_find.get("memberhost_hostgroup"))
|
||||
|
||||
|
||||
@@ -709,7 +709,7 @@ def main():
|
||||
elements='dict', required=False),
|
||||
|
||||
# mod
|
||||
update_password=dict(type='str', default=None,
|
||||
update_password=dict(type='str', default=None, no_log=False,
|
||||
choices=['always', 'on_create']),
|
||||
|
||||
# general
|
||||
@@ -764,7 +764,7 @@ def main():
|
||||
mac_address = ansible_module.params_get("mac_address")
|
||||
sshpubkey = ansible_module.params_get("sshpubkey")
|
||||
userclass = ansible_module.params_get("userclass")
|
||||
auth_ind = ansible_module.params_get("auth_ind")
|
||||
auth_ind = ansible_module.params_get("auth_ind", allow_empty_string=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(
|
||||
|
||||
332
plugins/modules/ipaidrange.py
Normal file
332
plugins/modules/ipaidrange.py
Normal file
@@ -0,0 +1,332 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
"metadata_version": "1.0",
|
||||
"supported_by": "community",
|
||||
"status": ["preview"],
|
||||
}
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaidrange
|
||||
short description: Manage FreeIPA idrange
|
||||
description: Manage FreeIPA idrange
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
- ipamodule_base_docs.delete_continue
|
||||
options:
|
||||
name:
|
||||
description: The list of idrange name strings.
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
base_id:
|
||||
description: First Posix ID of the range.
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["ipabaseid"]
|
||||
range_size:
|
||||
description: Number of IDs in the range.
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["ipaidrangesize"]
|
||||
rid_base:
|
||||
description: First RID of the corresponding RID range.
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["ipabaserid"]
|
||||
secondary_rid_base:
|
||||
description: First RID of the secondary RID range.
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["ipasecondarybaserid"]
|
||||
idrange_type:
|
||||
description: ID range type.
|
||||
type: string
|
||||
required: false
|
||||
choices: ["ipa-ad-trust", "ipa-ad-trust-posix", "ipa-local"]
|
||||
aliases: ["iparangetype"]
|
||||
dom_sid:
|
||||
description: Domain SID of the trusted domain.
|
||||
type: string
|
||||
required: false
|
||||
aliases: ["ipanttrusteddomainsid"]
|
||||
dom_name:
|
||||
description: Domain name of the trusted domain.
|
||||
type: string
|
||||
required: false
|
||||
aliases: ["ipanttrusteddomainname"]
|
||||
auto_private_groups:
|
||||
description: Auto creation of private groups.
|
||||
type: string
|
||||
required: false
|
||||
choices: ["true", "false", "hybrid"]
|
||||
aliases: ["ipaautoprivategroups"]
|
||||
state:
|
||||
description: The state to ensure.
|
||||
choices: ["present", "absent"]
|
||||
default: present
|
||||
required: true
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Ensure local domain idrange is present
|
||||
- ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
rid_base: 1000000
|
||||
secondary_rid_base: 200000000
|
||||
|
||||
# Ensure local domain idrange is absent
|
||||
- ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: id_range
|
||||
state: absent
|
||||
|
||||
# Ensure AD-trust idrange is present
|
||||
- ipaidrange:
|
||||
name: id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
rid_base: 1000000
|
||||
idrange_type: ipa-ad-trust
|
||||
dom_sid: S-1-5-21-2870384104-3340008087-3140804251
|
||||
auto_private_groups: "false"
|
||||
|
||||
# Ensure AD-trust idrange is present, with range type ad-trust-posix,
|
||||
# and using domain name
|
||||
- ipaidrange:
|
||||
name: id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
rid_base: 1000000
|
||||
idrange_type: ipa-ad-trust-posix
|
||||
dom_name: ad.ipa.test
|
||||
auto_private_groups: "hybrid"
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, compare_args_ipa
|
||||
from ansible.module_utils import six
|
||||
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
|
||||
|
||||
def find_idrange(module, name):
|
||||
"""Find if a idrange with the given name already exist."""
|
||||
try:
|
||||
_result = module.ipa_command("idrange_show", name, {"all": True})
|
||||
except Exception: # pylint: disable=broad-except
|
||||
# An exception is raised if idrange name is not found.
|
||||
return None
|
||||
else:
|
||||
return _result["result"]
|
||||
|
||||
|
||||
def gen_args(
|
||||
base_id, range_size, rid_base, secondary_rid_base, idrange_type, dom_sid,
|
||||
auto_private_groups
|
||||
):
|
||||
_args = {}
|
||||
# Integer parameters are stored as strings.
|
||||
# Converting them here allows the proper use of compare_args_ipa.
|
||||
if base_id is not None:
|
||||
_args["ipabaseid"] = base_id
|
||||
if range_size is not None:
|
||||
_args["ipaidrangesize"] = range_size
|
||||
if rid_base is not None:
|
||||
_args["ipabaserid"] = rid_base
|
||||
if secondary_rid_base is not None:
|
||||
_args["ipasecondarybaserid"] = secondary_rid_base
|
||||
if idrange_type is not None:
|
||||
_args["iparangetype"] = idrange_type
|
||||
if dom_sid is not None:
|
||||
_args["ipanttrusteddomainsid"] = dom_sid
|
||||
if auto_private_groups is not None:
|
||||
_args["ipaautoprivategroups"] = auto_private_groups
|
||||
return _args
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"],
|
||||
default=None, required=True),
|
||||
# present
|
||||
base_id=dict(required=False, type='int',
|
||||
aliases=["ipabaseid"], default=None),
|
||||
range_size=dict(required=False, type='int',
|
||||
aliases=["ipaidrangesize"], default=None),
|
||||
rid_base=dict(required=False, type='int',
|
||||
aliases=["ipabaserid"], default=None),
|
||||
secondary_rid_base=dict(required=False, type='int', default=None,
|
||||
aliases=["ipasecondarybaserid"]),
|
||||
idrange_type=dict(required=False, aliases=["iparangetype"],
|
||||
type="str", default=None,
|
||||
choices=["ipa-ad-trust", "ipa-ad-trust-posix",
|
||||
"ipa-local"]),
|
||||
dom_sid=dict(required=False, type='str', default=None,
|
||||
aliases=["ipanttrusteddomainsid"]),
|
||||
dom_name=dict(required=False, type='str', default=None,
|
||||
aliases=["ipanttrusteddomainname"]),
|
||||
auto_private_groups=dict(required=False, type='str', default=None,
|
||||
aliases=["ipaautoprivategroups"],
|
||||
choices=['true', 'false', 'hybrid']),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
),
|
||||
mutually_exclusive=[
|
||||
["dom_sid", "secondary_rid_base"],
|
||||
["dom_name", "secondary_rid_base"],
|
||||
["dom_sid", "dom_name"],
|
||||
],
|
||||
supports_check_mode=True,
|
||||
ipa_module_options=["delete_continue"],
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
names = ansible_module.params_get("name")
|
||||
delete_continue = ansible_module.params_get("delete_continue")
|
||||
|
||||
# present
|
||||
base_id = ansible_module.params_get("base_id")
|
||||
range_size = ansible_module.params_get("range_size")
|
||||
rid_base = ansible_module.params_get("rid_base")
|
||||
secondary_rid_base = ansible_module.params_get("secondary_rid_base")
|
||||
idrange_type = ansible_module.params_get("idrange_type")
|
||||
dom_sid = ansible_module.params_get("dom_sid")
|
||||
auto_private_groups = \
|
||||
ansible_module.params_get_lowercase("auto_private_groups")
|
||||
|
||||
# state
|
||||
state = ansible_module.params_get("state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
invalid = []
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Only one idrange can be added at a time.")
|
||||
|
||||
if state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(msg="No name given.")
|
||||
invalid = ["base_id", "range_size", "idrange_type", "dom_sid"]
|
||||
|
||||
ansible_module.params_fail_used_invalid(invalid, state)
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
|
||||
range_types = {
|
||||
"Active Directory domain range": "ipa-ad-trust",
|
||||
"Active Directory trust range with POSIX attributes":
|
||||
"ipa-ad-trust-posix",
|
||||
"local domain range": "ipa-local",
|
||||
}
|
||||
|
||||
# Connect to IPA API
|
||||
with ansible_module.ipa_connect():
|
||||
|
||||
commands = []
|
||||
for name in names:
|
||||
# Make sure idrange exists
|
||||
res_find = find_idrange(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
|
||||
# Generate args
|
||||
args = gen_args(
|
||||
base_id, range_size, rid_base, secondary_rid_base,
|
||||
idrange_type, dom_sid, auto_private_groups
|
||||
)
|
||||
|
||||
# Found the idrange
|
||||
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, ignore=["iparangetype"]
|
||||
):
|
||||
res_type = range_types.get(
|
||||
res_find.get("iparangetype")[0]
|
||||
)
|
||||
if res_type == "local_id_range":
|
||||
ansible_module.fail_json(
|
||||
"Cannot modify local IPA domain idrange."
|
||||
)
|
||||
|
||||
arg_type = args.get("iparangetype")
|
||||
if arg_type:
|
||||
if arg_type != res_type:
|
||||
ansible_module.fail_json(
|
||||
"Cannot modify idrange type."
|
||||
)
|
||||
del args["iparangetype"]
|
||||
commands.append([name, "idrange_mod", args])
|
||||
else:
|
||||
commands.append([name, "idrange_add", args])
|
||||
|
||||
elif state == "absent":
|
||||
if res_find is not None:
|
||||
commands.append([
|
||||
name,
|
||||
"idrange_del",
|
||||
{"continue": delete_continue or False}
|
||||
])
|
||||
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute commands
|
||||
|
||||
changed = ansible_module.execute_ipa_commands(commands)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -50,13 +50,13 @@ options:
|
||||
pac_type:
|
||||
description: Supported PAC type.
|
||||
required: false
|
||||
choices: ["MS-PAC", "PAD", "NONE"]
|
||||
choices: ["MS-PAC", "PAD", "NONE", ""]
|
||||
type: list
|
||||
aliases: ["pac_type", "ipakrbauthzdata"]
|
||||
auth_ind:
|
||||
description: Defines a whitelist for Authentication Indicators.
|
||||
required: false
|
||||
choices: ["otp", "radius", "pkinit", "hardened"]
|
||||
choices: ["otp", "radius", "pkinit", "hardened", ""]
|
||||
aliases: ["krbprincipalauthind"]
|
||||
skip_host_check:
|
||||
description: Skip checking if host object exists.
|
||||
@@ -356,7 +356,7 @@ def init_ansible_module():
|
||||
smb=dict(type="bool", required=False),
|
||||
netbiosname=dict(type="str", required=False),
|
||||
pac_type=dict(type="list", aliases=["ipakrbauthzdata"],
|
||||
choices=["MS-PAC", "PAD", "NONE"]),
|
||||
choices=["MS-PAC", "PAD", "NONE", ""]),
|
||||
auth_ind=dict(type="list",
|
||||
aliases=["krbprincipalauthind"],
|
||||
choices=["otp", "radius", "pkinit", "hardened", ""]),
|
||||
@@ -420,8 +420,8 @@ def main():
|
||||
# service attributes
|
||||
principal = ansible_module.params_get("principal")
|
||||
certificate = ansible_module.params_get("certificate")
|
||||
pac_type = ansible_module.params_get("pac_type")
|
||||
auth_ind = ansible_module.params_get("auth_ind")
|
||||
pac_type = ansible_module.params_get("pac_type", allow_empty_string=True)
|
||||
auth_ind = ansible_module.params_get("auth_ind", allow_empty_string=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")
|
||||
@@ -537,6 +537,15 @@ def main():
|
||||
if remove in args:
|
||||
del args[remove]
|
||||
|
||||
if (
|
||||
"ipakrbauthzdata" in args
|
||||
and (
|
||||
args.get("ipakrbauthzdata", [""]) ==
|
||||
res_find.get("ipakrbauthzdata", [""])
|
||||
)
|
||||
):
|
||||
del args["ipakrbauthzdata"]
|
||||
|
||||
if (
|
||||
"krbprincipalauthind" in args
|
||||
and (
|
||||
|
||||
352
plugins/modules/ipaservicedelegationrule.py
Normal file
352
plugins/modules/ipaservicedelegationrule.py
Normal file
@@ -0,0 +1,352 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
"metadata_version": "1.0",
|
||||
"supported_by": "community",
|
||||
"status": ["preview"],
|
||||
}
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaservicedelegationrule
|
||||
short description: Manage FreeIPA servicedelegationrule
|
||||
description: |
|
||||
Manage FreeIPA servicedelegationrule and servicedelegationrule members
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The list of servicedelegationrule name strings.
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
principal:
|
||||
description: |
|
||||
The list of principals. A principal can be of the format:
|
||||
fqdn, fqdn@REALM, service/fqdn, service/fqdn@REALM, host/fqdn,
|
||||
host/fqdn@REALM, alias$, alias$@REALM, where fqdn and fqdn@REALM
|
||||
are host principals and the same as host/fqdn and host/fqd
|
||||
Host princpals are only usable with IPA versions 4.9.0 and up.
|
||||
required: false
|
||||
target:
|
||||
description: |
|
||||
The list of service delegation targets.
|
||||
required: false
|
||||
aliases: ["servicedelegationtarget"]
|
||||
action:
|
||||
description: Work on servicedelegationrule or member level.
|
||||
choices: ["servicedelegationrule", "member"]
|
||||
default: servicedelegationrule
|
||||
required: false
|
||||
state:
|
||||
description: The state to ensure.
|
||||
choices: ["present", "absent"]
|
||||
default: present
|
||||
required: true
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Ensure servicedelegationrule delegation-rule is present
|
||||
- ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-rule
|
||||
|
||||
# Ensure servicedelegationrule delegation-rule member principal
|
||||
# test/example.com is present
|
||||
- ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-rule
|
||||
principal: test/example.com
|
||||
action: member
|
||||
|
||||
# Ensure servicedelegationrule delegation-rule member principal
|
||||
# test/example.com is absent
|
||||
- ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-rule
|
||||
principal: test/example.com
|
||||
action: member
|
||||
state: absent
|
||||
|
||||
# Ensure servicedelegationrule delegation-rule member target
|
||||
# test/example.com is present
|
||||
- ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-rule
|
||||
target: delegation-target
|
||||
action: member
|
||||
|
||||
# Ensure servicedelegationrule delegation-rule member target
|
||||
# test/example.com is absent
|
||||
- ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-rule
|
||||
target: delegation-target
|
||||
action: member
|
||||
state: absent
|
||||
|
||||
# Ensure servicedelegationrule delegation-rule is absent
|
||||
- ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-rule
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, gen_add_del_lists, gen_add_list, gen_intersection_list, \
|
||||
servicedelegation_normalize_principals, ipalib_errors
|
||||
from ansible.module_utils import six
|
||||
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
|
||||
|
||||
def find_servicedelegationrule(module, name):
|
||||
"""Find if a servicedelegationrule with the given name already exist."""
|
||||
try:
|
||||
_result = module.ipa_command("servicedelegationrule_show", name,
|
||||
{"all": True})
|
||||
except Exception: # pylint: disable=broad-except
|
||||
# An exception is raised if servicedelegationrule name is not found.
|
||||
return None
|
||||
else:
|
||||
return _result["result"]
|
||||
|
||||
|
||||
def check_targets(module, targets):
|
||||
def _check_exists(module, _type, name):
|
||||
# Check if item of type _type exists using the show command
|
||||
try:
|
||||
module.ipa_command("%s_show" % _type, name, {})
|
||||
except ipalib_errors.NotFound as e:
|
||||
msg = str(e)
|
||||
if "%s not found" % _type in msg:
|
||||
return False
|
||||
module.fail_json(msg="%s_show failed: %s" % (_type, msg))
|
||||
return True
|
||||
|
||||
for _target in targets:
|
||||
if not _check_exists(module, "servicedelegationtarget", _target):
|
||||
module.fail_json(
|
||||
msg="Service delegation target '%s' does not exist" % _target)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
required=True),
|
||||
# present
|
||||
principal=dict(required=False, type='list', default=None),
|
||||
target=dict(required=False, type='list',
|
||||
aliases=["servicedelegationtarget"], default=None),
|
||||
|
||||
action=dict(type="str", default="servicedelegationrule",
|
||||
choices=["member", "servicedelegationrule"]),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
names = ansible_module.params_get("name")
|
||||
|
||||
# present
|
||||
principal = ansible_module.params_get("principal")
|
||||
target = ansible_module.params_get("target")
|
||||
|
||||
action = ansible_module.params_get("action")
|
||||
|
||||
# state
|
||||
state = ansible_module.params_get("state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
invalid = []
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Only one servicedelegationrule can be added at a time.")
|
||||
|
||||
if state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(msg="No name given.")
|
||||
if action == "servicedelegationrule":
|
||||
invalid = ["principal", "target"]
|
||||
|
||||
ansible_module.params_fail_used_invalid(invalid, state, action)
|
||||
|
||||
# Init
|
||||
|
||||
membertarget = "ipaallowedtarget_servicedelegationtarget"
|
||||
changed = False
|
||||
exit_args = {}
|
||||
|
||||
# Connect to IPA API
|
||||
with ansible_module.ipa_connect():
|
||||
|
||||
# Normalize principals
|
||||
if principal:
|
||||
principal = servicedelegation_normalize_principals(
|
||||
ansible_module, principal, state == "present")
|
||||
if target and state == "present":
|
||||
check_targets(ansible_module, target)
|
||||
|
||||
commands = []
|
||||
principal_add = principal_del = []
|
||||
target_add = target_del = []
|
||||
for name in names:
|
||||
# Make sure servicedelegationrule exists
|
||||
res_find = find_servicedelegationrule(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
|
||||
if action == "servicedelegationrule":
|
||||
# A servicedelegationrule does not have normal options.
|
||||
# There is no servicedelegationtarget-mod command.
|
||||
# Principal members are handled with the _add_member and
|
||||
# _remove_member commands further down.
|
||||
if res_find is None:
|
||||
commands.append([name, "servicedelegationrule_add",
|
||||
{}])
|
||||
res_find = {}
|
||||
|
||||
# Generate addition and removal lists for principal
|
||||
principal_add, principal_del = gen_add_del_lists(
|
||||
principal, res_find.get("memberprincipal"))
|
||||
|
||||
# Generate addition and removal lists for target
|
||||
target_add, target_del = gen_add_del_lists(
|
||||
target, res_find.get(membertarget))
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(
|
||||
msg="No servicedelegationrule '%s'" % name)
|
||||
|
||||
# Reduce add lists for principal
|
||||
# to new entries only that are not in res_find.
|
||||
if principal is not None and \
|
||||
"memberprincipal" in res_find:
|
||||
principal_add = gen_add_list(
|
||||
principal, res_find["memberprincipal"])
|
||||
else:
|
||||
principal_add = principal
|
||||
|
||||
# Reduce add lists for target
|
||||
# to new entries only that are not in res_find.
|
||||
if target is not None and membertarget in res_find:
|
||||
target_add = gen_add_list(
|
||||
target, res_find[membertarget])
|
||||
else:
|
||||
target_add = target
|
||||
|
||||
elif state == "absent":
|
||||
if action == "servicedelegationrule":
|
||||
if res_find is not None:
|
||||
commands.append([name, "servicedelegationrule_del",
|
||||
{}])
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(
|
||||
msg="No servicedelegationrule '%s'" % name)
|
||||
|
||||
# Reduce del lists of principals to the entries only
|
||||
# that are in res_find.
|
||||
if principal is not None:
|
||||
principal_del = gen_intersection_list(
|
||||
principal, res_find.get("memberprincipal"))
|
||||
else:
|
||||
principal_del = principal
|
||||
|
||||
# Reduce del lists of targets to the entries only
|
||||
# that are in res_find.
|
||||
if target is not None:
|
||||
target_del = gen_intersection_list(
|
||||
target, res_find.get(membertarget))
|
||||
else:
|
||||
target_del = target
|
||||
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Handle members
|
||||
|
||||
# Add principal members
|
||||
if principal_add is not None and len(principal_add) > 0:
|
||||
commands.append(
|
||||
[name, "servicedelegationtarget_add_member",
|
||||
{
|
||||
"principal": principal_add,
|
||||
}])
|
||||
# Remove principal members
|
||||
if principal_del is not None and len(principal_del) > 0:
|
||||
commands.append(
|
||||
[name, "servicedelegationtarget_remove_member",
|
||||
{
|
||||
"principal": principal_del,
|
||||
}])
|
||||
|
||||
# Add target members
|
||||
if target_add is not None and len(target_add) > 0:
|
||||
commands.append(
|
||||
[name, "servicedelegationrule_add_target",
|
||||
{
|
||||
"servicedelegationtarget": target_add,
|
||||
}])
|
||||
# Remove target members
|
||||
if target_del is not None and len(target_del) > 0:
|
||||
commands.append(
|
||||
[name, "servicedelegationrule_remove_target",
|
||||
{
|
||||
"servicedelegationtarget": target_del,
|
||||
}])
|
||||
|
||||
# Execute commands
|
||||
|
||||
changed = ansible_module.execute_ipa_commands(
|
||||
commands, fail_on_member_errors=True)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
270
plugins/modules/ipaservicedelegationtarget.py
Normal file
270
plugins/modules/ipaservicedelegationtarget.py
Normal file
@@ -0,0 +1,270 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
"metadata_version": "1.0",
|
||||
"supported_by": "community",
|
||||
"status": ["preview"],
|
||||
}
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaservicedelegationtarget
|
||||
short description: Manage FreeIPA servicedelegationtarget
|
||||
description: |
|
||||
Manage FreeIPA servicedelegationtarget and servicedelegationtarget members
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The list of servicedelegationtarget name strings.
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
principal:
|
||||
description: |
|
||||
The list of principals. A principal can be of the format:
|
||||
fqdn, fqdn@REALM, service/fqdn, service/fqdn@REALM, host/fqdn,
|
||||
host/fqdn@REALM, alias$, alias$@REALM, where fqdn and fqdn@REALM
|
||||
are host principals and the same as host/fqdn and host/fqdn@REALM.
|
||||
Host princpals are only usable with IPA versions 4.9.0 and up.
|
||||
required: false
|
||||
action:
|
||||
description: Work on servicedelegationtarget or member level.
|
||||
choices: ["servicedelegationtarget", "member"]
|
||||
default: servicedelegationtarget
|
||||
required: false
|
||||
state:
|
||||
description: The state to ensure.
|
||||
choices: ["present", "absent"]
|
||||
default: present
|
||||
required: true
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Ensure servicedelegationtarget delegation-target is present
|
||||
- ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-target
|
||||
|
||||
# Ensure servicedelegationtarget delegation-target member principal
|
||||
# test/example.com is present
|
||||
- ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-target
|
||||
principal: test/example.com
|
||||
action: member
|
||||
|
||||
# Ensure servicedelegationtarget delegation-target member principal
|
||||
# test/example.com is absent
|
||||
- ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-target
|
||||
principal: test/example.com
|
||||
action: member
|
||||
state: absent
|
||||
|
||||
# Ensure servicedelegationtarget delegation-target is absent
|
||||
- ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: delegation-target
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, gen_add_del_lists, gen_add_list, gen_intersection_list, \
|
||||
servicedelegation_normalize_principals
|
||||
from ansible.module_utils import six
|
||||
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
|
||||
|
||||
def find_servicedelegationtarget(module, name):
|
||||
"""Find if a servicedelegationtarget with the given name already exist."""
|
||||
try:
|
||||
_result = module.ipa_command("servicedelegationtarget_show", name,
|
||||
{"all": True})
|
||||
except Exception: # pylint: disable=broad-except
|
||||
# An exception is raised if servicedelegationtarget name is not found.
|
||||
return None
|
||||
else:
|
||||
return _result["result"]
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
required=True),
|
||||
# present
|
||||
principal=dict(required=False, type='list', default=None),
|
||||
|
||||
action=dict(type="str", default="servicedelegationtarget",
|
||||
choices=["member", "servicedelegationtarget"]),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
names = ansible_module.params_get("name")
|
||||
|
||||
# present
|
||||
principal = ansible_module.params_get("principal")
|
||||
|
||||
action = ansible_module.params_get("action")
|
||||
|
||||
# state
|
||||
state = ansible_module.params_get("state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
invalid = []
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Only one servicedelegationtarget can be added at a time.")
|
||||
|
||||
if state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(msg="No name given.")
|
||||
if action == "servicedelegationtarget":
|
||||
invalid.append("principal")
|
||||
|
||||
ansible_module.params_fail_used_invalid(invalid, state, action)
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
|
||||
# Connect to IPA API
|
||||
with ansible_module.ipa_connect():
|
||||
|
||||
# Normalize principals
|
||||
if principal:
|
||||
principal = servicedelegation_normalize_principals(
|
||||
ansible_module, principal, state == "present")
|
||||
|
||||
commands = []
|
||||
principal_add = principal_del = []
|
||||
for name in names:
|
||||
# Make sure servicedelegationtarget exists
|
||||
res_find = find_servicedelegationtarget(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
|
||||
if action == "servicedelegationtarget":
|
||||
# A servicedelegationtarget does not have normal options.
|
||||
# There is no servicedelegationtarget-mod command.
|
||||
# Principal members are handled with the _add_member and
|
||||
# _remove_member commands further down.
|
||||
if res_find is None:
|
||||
commands.append([name, "servicedelegationtarget_add",
|
||||
{}])
|
||||
res_find = {}
|
||||
|
||||
# Generate addition and removal lists
|
||||
principal_add, principal_del = gen_add_del_lists(
|
||||
principal, res_find.get("memberprincipal"))
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(
|
||||
msg="No servicedelegationtarget '%s'" % name)
|
||||
|
||||
# Reduce add lists for principal
|
||||
# to new entries only that are not in res_find.
|
||||
if principal is not None and \
|
||||
"memberprincipal" in res_find:
|
||||
principal_add = gen_add_list(
|
||||
principal, res_find["memberprincipal"])
|
||||
else:
|
||||
principal_add = principal
|
||||
|
||||
elif state == "absent":
|
||||
if action == "servicedelegationtarget":
|
||||
if res_find is not None:
|
||||
commands.append([name, "servicedelegationtarget_del",
|
||||
{}])
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(
|
||||
msg="No servicedelegationtarget '%s'" % name)
|
||||
|
||||
# Reduce del lists of principal
|
||||
# to the entries only that are in res_find.
|
||||
if principal is not None:
|
||||
principal_del = gen_intersection_list(
|
||||
principal, res_find.get("memberprincipal"))
|
||||
else:
|
||||
principal_del = principal
|
||||
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Handle members
|
||||
|
||||
# Add principal members
|
||||
if principal_add is not None and len(principal_add) > 0:
|
||||
commands.append(
|
||||
[name, "servicedelegationtarget_add_member",
|
||||
{
|
||||
"principal": principal_add,
|
||||
}])
|
||||
# Remove principal members
|
||||
if principal_del is not None and len(principal_del) > 0:
|
||||
commands.append(
|
||||
[name, "servicedelegationtarget_remove_member",
|
||||
{
|
||||
"principal": principal_del,
|
||||
}])
|
||||
|
||||
# Execute commands
|
||||
|
||||
changed = ansible_module.execute_ipa_commands(
|
||||
commands, fail_on_member_errors=True)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -44,7 +44,8 @@ options:
|
||||
description:
|
||||
- Trust type (ad for Active Directory, default)
|
||||
default: ad
|
||||
required: true
|
||||
required: false
|
||||
choices: ["ad"]
|
||||
admin:
|
||||
description:
|
||||
- Active Directory domain administrator
|
||||
@@ -103,7 +104,7 @@ EXAMPLES = """
|
||||
realm: ad.example.test
|
||||
trust_type: ad
|
||||
admin: Administrator
|
||||
password: Welcome2020!
|
||||
password: SomeW1Npassword
|
||||
state: present
|
||||
|
||||
# delete ad-trust
|
||||
@@ -157,7 +158,7 @@ def add_trust(module, realm, args):
|
||||
|
||||
|
||||
def gen_args(trust_type, admin, password, server, trust_secret, base_id,
|
||||
range_size, _range_type, two_way, external):
|
||||
range_size, range_type, two_way, external):
|
||||
_args = {}
|
||||
if trust_type is not None:
|
||||
_args["trust_type"] = trust_type
|
||||
@@ -173,6 +174,8 @@ def gen_args(trust_type, admin, password, server, trust_secret, base_id,
|
||||
_args["base_id"] = base_id
|
||||
if range_size is not None:
|
||||
_args["range_size"] = range_size
|
||||
if range_type is not None:
|
||||
_args["range_type"] = range_type
|
||||
if two_way is not None:
|
||||
_args["bidirectional"] = two_way
|
||||
if external is not None:
|
||||
@@ -190,7 +193,8 @@ def main():
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
# present
|
||||
trust_type=dict(type="str", default="ad", required=False),
|
||||
trust_type=dict(type="str", default="ad", required=False,
|
||||
choices=["ad"]),
|
||||
admin=dict(type="str", default=None, required=False),
|
||||
password=dict(type="str", default=None,
|
||||
required=False, no_log=True),
|
||||
|
||||
@@ -892,8 +892,10 @@ def main():
|
||||
title = ansible_module.params_get("title")
|
||||
manager = ansible_module.params_get("manager")
|
||||
carlicense = ansible_module.params_get("carlicense")
|
||||
sshpubkey = ansible_module.params_get("sshpubkey")
|
||||
userauthtype = ansible_module.params_get("userauthtype")
|
||||
sshpubkey = ansible_module.params_get("sshpubkey",
|
||||
allow_empty_string=True)
|
||||
userauthtype = ansible_module.params_get("userauthtype",
|
||||
allow_empty_string=True)
|
||||
userclass = ansible_module.params_get("userclass")
|
||||
radius = ansible_module.params_get("radius")
|
||||
radiususer = ansible_module.params_get("radiususer")
|
||||
@@ -1101,13 +1103,6 @@ def main():
|
||||
if "noprivate" in args:
|
||||
del args["noprivate"]
|
||||
|
||||
# Ignore userauthtype if it is empty (for resetting)
|
||||
# and not set in for the user
|
||||
if "ipauserauthtype" not in res_find and \
|
||||
"ipauserauthtype" in args and \
|
||||
args["ipauserauthtype"] == ['']:
|
||||
del args["ipauserauthtype"]
|
||||
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
ipdb
|
||||
pre-commit
|
||||
flake8-bugbear
|
||||
pylint==2.10.2
|
||||
pylint==2.12.2
|
||||
|
||||
@@ -207,7 +207,7 @@ else:
|
||||
cli_realm, cli_domain, cli_server, cli_kdc, dnsok,
|
||||
filename, client_domain, client_hostname, force=False,
|
||||
configure_sssd=True):
|
||||
# pylint: disable=global-statement
|
||||
# pylint: disable=global-variable-not-assigned
|
||||
global options
|
||||
options.force = force
|
||||
options.sssd = configure_sssd
|
||||
|
||||
@@ -216,15 +216,18 @@
|
||||
ipaclient_force_join)
|
||||
|
||||
- block:
|
||||
- fail:
|
||||
- name: krb5 configuration not correct
|
||||
fail:
|
||||
msg: >
|
||||
The krb5 configuration is not correct, please enable allow_repair
|
||||
to fix this.
|
||||
when: not result_ipaclient_test_keytab.krb5_conf_ok
|
||||
- fail:
|
||||
- name: IPA test failed
|
||||
fail:
|
||||
msg: "The IPA test failed, please enable allow_repair to fix this."
|
||||
when: not result_ipaclient_test_keytab.ping_test_ok
|
||||
- fail:
|
||||
- name: ca.crt file is missing
|
||||
fail:
|
||||
msg: >
|
||||
The ca.crt file is missing, please enable allow_repair to fix this.
|
||||
when: not result_ipaclient_test_keytab.ca_crt_exists
|
||||
|
||||
@@ -34,6 +34,7 @@ ignore = D1,D212,D203
|
||||
|
||||
[pylint.MASTER]
|
||||
disable =
|
||||
consider-using-f-string, # f-string is not supported on Python2
|
||||
unspecified-encoding, # open() does not provide `encoding` in Python2
|
||||
use-maxsplit-arg,
|
||||
redundant-u-string-prefix,
|
||||
|
||||
@@ -71,6 +71,24 @@
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: ensure map TestMap has an empty description
|
||||
ipaautomountmap:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: TestMap
|
||||
location: TestLocation
|
||||
desc: ""
|
||||
register: result
|
||||
failed_when: result.failed or not result.changed
|
||||
|
||||
- name: ensure map TestMap has an empty description, again
|
||||
ipaautomountmap:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: TestMap
|
||||
location: TestLocation
|
||||
desc: ""
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: ensure map TestMap is removed
|
||||
ipaautomountmap:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
|
||||
@@ -18,28 +18,39 @@ stages:
|
||||
scenario: fedora-latest
|
||||
ansible_version: ">=2.9,<2.10"
|
||||
|
||||
# CentOS 9
|
||||
# CentOS 9 Stream
|
||||
|
||||
- stage: CentOS9_Ansible_2_9
|
||||
- stage: c9s_Ansible_2_9
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-9
|
||||
scenario: c9s
|
||||
ansible_version: ">=2.9,<2.10"
|
||||
|
||||
# CentOS 8
|
||||
# CentOS 8 Stream
|
||||
|
||||
- stage: CentOS8_Ansible_2_9
|
||||
- stage: c8s_Ansible_2_9
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-8
|
||||
scenario: c8s
|
||||
ansible_version: ">=2.9,<2.10"
|
||||
|
||||
# # CentOS 8
|
||||
#
|
||||
# - stage: CentOS8_Ansible_2_9
|
||||
# dependsOn: []
|
||||
# jobs:
|
||||
# - template: templates/group_tests.yml
|
||||
# parameters:
|
||||
# build_number: $(Build.BuildNumber)
|
||||
# scenario: centos-8
|
||||
# ansible_version: ">=2.9,<2.10"
|
||||
|
||||
# CentOS 7
|
||||
|
||||
- stage: CentOS7_Ansible_2_9
|
||||
|
||||
@@ -21,17 +21,23 @@ jobs:
|
||||
container_name: centos-7
|
||||
build_scenario_name: centos-7-build
|
||||
|
||||
- template: templates/build_container.yml
|
||||
parameters:
|
||||
job_name_suffix: Centos8
|
||||
container_name: centos-8
|
||||
build_scenario_name: centos-8-build
|
||||
# - template: templates/build_container.yml
|
||||
# parameters:
|
||||
# job_name_suffix: Centos8
|
||||
# container_name: centos-8
|
||||
# build_scenario_name: centos-8-build
|
||||
|
||||
- template: templates/build_container.yml
|
||||
parameters:
|
||||
job_name_suffix: Centos9
|
||||
container_name: centos-9
|
||||
build_scenario_name: centos-9-build
|
||||
job_name_suffix: C8S
|
||||
container_name: c8s
|
||||
build_scenario_name: c8s-build
|
||||
|
||||
- template: templates/build_container.yml
|
||||
parameters:
|
||||
job_name_suffix: C9S
|
||||
container_name: c9s
|
||||
build_scenario_name: c9s-build
|
||||
|
||||
- template: templates/build_container.yml
|
||||
parameters:
|
||||
|
||||
@@ -52,73 +52,120 @@ stages:
|
||||
scenario: fedora-latest
|
||||
ansible_version: ""
|
||||
|
||||
# CentoOS 9
|
||||
# CentoOS 9 Stream
|
||||
|
||||
- stage: CentOS9_Ansible_2_9
|
||||
- stage: c9s_Ansible_2_9
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-9
|
||||
scenario: c9s
|
||||
ansible_version: ">=2.9,<2.10"
|
||||
|
||||
- stage: CentOS9_Ansible_Core_2_11
|
||||
- stage: c9s_Ansible_Core_2_11
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-9
|
||||
scenario: c9s
|
||||
ansible_version: "-core >=2.11,<2.12"
|
||||
|
||||
- stage: CentOS9_Ansible_latest
|
||||
- stage: c9s_Ansible_Core_2_12
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-9
|
||||
ansible_version: ""
|
||||
|
||||
# CentOS 8
|
||||
|
||||
- stage: CentOS8_Ansible_2_9
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-8
|
||||
ansible_version: ">=2.9,<2.10"
|
||||
|
||||
- stage: CentOS8_Ansible_Core_2_11
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-8
|
||||
ansible_version: "-core >=2.11,<2.12"
|
||||
|
||||
- stage: CentOS8_Ansible_Core_2_12
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-8
|
||||
scenario: c9s
|
||||
ansible_version: "-core >=2.12,<2.13"
|
||||
|
||||
- stage: CentOS8_Ansible_latest
|
||||
- stage: c9s_Ansible_latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-8
|
||||
scenario: c9s
|
||||
ansible_version: ""
|
||||
|
||||
# CentOS 8 Stream
|
||||
|
||||
- stage: c8s_Ansible_2_9
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c8s
|
||||
ansible_version: ">=2.9,<2.10"
|
||||
|
||||
- stage: c8s_Ansible_Core_2_11
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c8s
|
||||
ansible_version: "-core >=2.11,<2.12"
|
||||
|
||||
- stage: c8s_Ansible_Core_2_12
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c8s
|
||||
ansible_version: "-core >=2.12,<2.13"
|
||||
|
||||
- stage: c8s_Ansible_latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c8s
|
||||
ansible_version: ""
|
||||
|
||||
# # CentOS 8
|
||||
#
|
||||
# - stage: CentOS8_Ansible_2_9
|
||||
# dependsOn: []
|
||||
# jobs:
|
||||
# - template: templates/group_tests.yml
|
||||
# parameters:
|
||||
# build_number: $(Build.BuildNumber)
|
||||
# scenario: centos-8
|
||||
# ansible_version: ">=2.9,<2.10"
|
||||
#
|
||||
# - stage: CentOS8_Ansible_Core_2_11
|
||||
# dependsOn: []
|
||||
# jobs:
|
||||
# - template: templates/group_tests.yml
|
||||
# parameters:
|
||||
# build_number: $(Build.BuildNumber)
|
||||
# scenario: centos-8
|
||||
# ansible_version: "-core >=2.11,<2.12"
|
||||
#
|
||||
# - stage: CentOS8_Ansible_Core_2_12
|
||||
# dependsOn: []
|
||||
# jobs:
|
||||
# - template: templates/group_tests.yml
|
||||
# parameters:
|
||||
# build_number: $(Build.BuildNumber)
|
||||
# scenario: centos-8
|
||||
# ansible_version: "-core >=2.12,<2.13"
|
||||
#
|
||||
# - stage: CentOS8_Ansible_latest
|
||||
# dependsOn: []
|
||||
# jobs:
|
||||
# - template: templates/group_tests.yml
|
||||
# parameters:
|
||||
# build_number: $(Build.BuildNumber)
|
||||
# scenario: centos-8
|
||||
# ansible_version: ""
|
||||
|
||||
# CentOS 7
|
||||
|
||||
- stage: CentOS7_Ansible_2_9
|
||||
|
||||
@@ -6,6 +6,9 @@ parameters:
|
||||
type: string
|
||||
- name: build_scenario_name
|
||||
type: string
|
||||
- name: python_version
|
||||
type: string
|
||||
default: 3.x
|
||||
|
||||
jobs:
|
||||
- job: BuildTestImage${{ parameters.job_name_suffix }}
|
||||
@@ -13,7 +16,7 @@ jobs:
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '3.6'
|
||||
versionSpec: '${{ parameters.python_version }}'
|
||||
|
||||
- script: python -m pip install --upgrade pip setuptools wheel ansible
|
||||
displayName: Install tools
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
parameters:
|
||||
- name: scenario
|
||||
type: string
|
||||
default: centos-8
|
||||
default: fedora-latest
|
||||
- name: build_number
|
||||
type: string
|
||||
- name: ansible_version
|
||||
|
||||
@@ -8,7 +8,7 @@ parameters:
|
||||
default: 1
|
||||
- name: scenario
|
||||
type: string
|
||||
default: centos-8
|
||||
default: fedora-latest
|
||||
- name: ansible_version
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
@@ -4,6 +4,7 @@ parameters:
|
||||
type: string
|
||||
- name: scenario
|
||||
type: string
|
||||
default: fedora-latest
|
||||
- name: ansible_version
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
@@ -56,9 +56,9 @@
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
pac_type: ""
|
||||
|
||||
- name: set maxhostname to 255
|
||||
block:
|
||||
- ipaconfig:
|
||||
- block:
|
||||
- name: set maxhostname to 255
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
maxhostname: 255
|
||||
@@ -221,16 +221,17 @@
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: set maxhostname to 77
|
||||
block:
|
||||
- ipaconfig:
|
||||
- block:
|
||||
- name: set maxhostname to 77
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
maxhostname: 77
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- ipaconfig:
|
||||
- name: set maxhostname to 77, again
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
maxhostname: 77
|
||||
@@ -409,9 +410,9 @@
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: reset maxhostname
|
||||
block:
|
||||
- ipaconfig:
|
||||
- block:
|
||||
- name: reset maxhostname
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
maxhostname: '{{ previousconfig.config.maxhostname | default(omit) }}'
|
||||
@@ -444,9 +445,9 @@
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: reset maxhostname
|
||||
block:
|
||||
- ipaconfig:
|
||||
- block:
|
||||
- name: reset maxhostname
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
maxhostname: '{{ previousconfig.config.maxhostname | default(omit) }}'
|
||||
|
||||
143
tests/config/test_config_empty_string_params.yml
Normal file
143
tests/config/test_config_empty_string_params.yml
Normal file
@@ -0,0 +1,143 @@
|
||||
---
|
||||
- name: Test config
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: yes
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
|
||||
# GET CURRENT CONFIG
|
||||
|
||||
- name: Return current values of the global configuration options
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
register: previousconfig
|
||||
|
||||
- name: Ensure config with empty pac_type, user_auth_type and configstring
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
pac_type: ""
|
||||
user_auth_type: ""
|
||||
configstring: ""
|
||||
|
||||
# TESTS
|
||||
|
||||
- name: Ensure config with pac_type "nfs:NONE" and PAD
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
pac_type:
|
||||
- "nfs:NONE"
|
||||
- PAD
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure config with pac_type "nfs:NONE" and PAD, again
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
pac_type:
|
||||
- "nfs:NONE"
|
||||
- PAD
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure config with empty pac_type
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
pac_type: ""
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure config with empty pac_type, again
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
pac_type: ""
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure config with user_auth_type otp and radius
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
user_auth_type:
|
||||
- otp
|
||||
- radius
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure config with user_auth_type otp and radius, again
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
user_auth_type:
|
||||
- otp
|
||||
- radius
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure config with empty user_auth_type
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
user_auth_type: ""
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure config with empty user_auth_type, again
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
user_auth_type: ""
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure config with configstring AllowNThash and "KDC:Disable Lockout"
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
configstring:
|
||||
- AllowNThash
|
||||
- "KDC:Disable Lockout"
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure config with configstring AllowNThash and "KDC:Disable Lockout", again
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
configstring:
|
||||
- AllowNThash
|
||||
- "KDC:Disable Lockout"
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure config with empty configstring
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
configstring: ""
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure config with empty configstring, again
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
configstring: ""
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
# REVERT TO PREVIOUS CONFIG
|
||||
|
||||
- name: Reset to previous pac_type and user_auth_type
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
pac_type: '{{ previousconfig.config.pac_type }}'
|
||||
user_auth_type: '{{ previousconfig.config.user_auth_type }}'
|
||||
configstring: '{{ previousconfig.config.configstring }}'
|
||||
@@ -31,4 +31,3 @@
|
||||
dnssec: yes
|
||||
skip_nameserver_check: yes
|
||||
skip_overlap_check: yes
|
||||
ignore_errors: yes
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
- name: Verify if host is an IPA server or client.
|
||||
shell:
|
||||
cmd: |
|
||||
echo SomeADMINpassword | kinit -c {{ KRB5CCNAME }} admin
|
||||
RESULT=$(KRB5CCNAME={{ KRB5CCNAME }} ipa server-show `hostname` && echo SERVER || echo CLIENT)
|
||||
kdestroy -A -c {{ KRB5CCNAME }}
|
||||
echo SomeADMINpassword | kinit -c {{ krb5ccname }} admin
|
||||
RESULT=$(KRB5CCNAME={{ krb5ccname }} ipa server-show `hostname` && echo SERVER || echo CLIENT)
|
||||
kdestroy -A -c {{ krb5ccname }}
|
||||
echo $RESULT
|
||||
vars:
|
||||
KRB5CCNAME: "__check_ipa_host_is_client_or_server__"
|
||||
krb5ccname: "__check_ipa_host_is_client_or_server__"
|
||||
register: output
|
||||
|
||||
- name: Set FreeIPA facts.
|
||||
|
||||
@@ -2,23 +2,17 @@
|
||||
- name: Test group
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: true
|
||||
gather_facts: false
|
||||
gather_facts: true
|
||||
|
||||
tasks:
|
||||
# setup
|
||||
- include_tasks: ../env_freeipa_facts.yml
|
||||
|
||||
# GET DOMAIN AND REALM
|
||||
# GET FQDN_AT_DOMAIN
|
||||
|
||||
- name: Get Domain from server name
|
||||
- name: Get fqdn_at_domain
|
||||
set_fact:
|
||||
ipaserver_domain: "{{ ansible_facts['fqdn'].split('.')[1:] | join ('.') }}"
|
||||
when: ipaserver_domain is not defined
|
||||
|
||||
- name: Get Realm from server name
|
||||
set_fact:
|
||||
ipaserver_realm: "{{ ansible_facts['fqdn'].split('.')[1:] | join ('.') | upper }}"
|
||||
when: ipaserver_realm is not defined
|
||||
fqdn_at_domain: "{{ ansible_facts['fqdn'] + '@' + ipaserver_realm }}"
|
||||
|
||||
# CLEANUP TEST ITEMS
|
||||
|
||||
@@ -144,93 +138,93 @@
|
||||
|
||||
- block:
|
||||
|
||||
- name: Ensure service "{{ 'HTTP/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}" is present in group group1
|
||||
- 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/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
action: member
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure service "{{ 'HTTP/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}" is present in group group1, again
|
||||
- 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/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure service "{{ 'ldap/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}" is present in group group1
|
||||
- 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/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'ldap/' + fqdn_at_domain }}"
|
||||
action: member
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure service "{{ 'ldap/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}" is present in group group1, again
|
||||
- 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/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'ldap/' + fqdn_at_domain }}"
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure service "{{ 'HTTP/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}" is absent in group group1
|
||||
- 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/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure service "{{ 'HTTP/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}" is absent in group group1, again
|
||||
- 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/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure service "{{ 'ldap/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}" is absent in group group1
|
||||
- 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/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'ldap/' + fqdn_at_domain }}"
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure service "{{ 'ldap/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}" is absent in group group1, again
|
||||
- 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/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'ldap/' + fqdn_at_domain }}"
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
@@ -242,8 +236,8 @@
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'HTTP/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'ldap/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
- "{{ 'ldap/' + fqdn_at_domain }}"
|
||||
action: member
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
@@ -254,8 +248,8 @@
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'http/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'ldap/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'http/' + fqdn_at_domain }}"
|
||||
- "{{ 'ldap/' + fqdn_at_domain }}"
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
@@ -266,8 +260,8 @@
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'HTTP/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'LDAP/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
- "{{ 'LDAP/' + fqdn_at_domain }}"
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
@@ -279,8 +273,8 @@
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: group1
|
||||
service:
|
||||
- "{{ 'HTTP/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'ldap/ipaserver.' + ipaserver_domain + '@' + ipaserver_realm }}"
|
||||
- "{{ 'HTTP/' + fqdn_at_domain }}"
|
||||
- "{{ 'ldap/' + fqdn_at_domain }}"
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
104
tests/group/test_group_idoverrideuser.yml
Normal file
104
tests/group/test_group_idoverrideuser.yml
Normal file
@@ -0,0 +1,104 @@
|
||||
---
|
||||
- name: Test group
|
||||
hosts: ipaserver
|
||||
become: yes
|
||||
gather_facts: yes
|
||||
|
||||
vars:
|
||||
ad_user: "{{ test_ad_user | default('AD\\aduser') }}"
|
||||
ad_domain: "{{ test_ad_domain | default('ad.ipa.test') }}"
|
||||
|
||||
tasks:
|
||||
- include_tasks: ../env_freeipa_facts.yml
|
||||
|
||||
- block:
|
||||
- name: Create idoverrideuser.
|
||||
shell: |
|
||||
kinit -c idoverride_cache admin <<< SomeADMINpassword
|
||||
ipa idoverrideuser-add "Default Trust View" {{ ad_user }}
|
||||
kdestroy -A -q -c idoverride_cache
|
||||
|
||||
- name: Remove testing groups.
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name:
|
||||
- idovergroup
|
||||
state: absent
|
||||
|
||||
- name: Add group with idoverrideuser.
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: idovergroup
|
||||
idoverrideuser: "{{ ad_user }}"
|
||||
register: result
|
||||
failed_when: result.failed or not result.changed
|
||||
|
||||
- name: Add group with idoverrideuser, again.
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: idovergroup
|
||||
idoverrideuser: "{{ ad_user }}"
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: Remove idoverrideuser member.
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: idovergroup
|
||||
idoverrideuser: "{{ ad_user }}"
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: result.failed or not result.changed
|
||||
|
||||
- name: Remove idoverrideuser member, again.
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: idovergroup
|
||||
idoverrideuser: "{{ ad_user }}"
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: Add idoverrideuser member.
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: idovergroup
|
||||
idoverrideuser: "{{ ad_user }}"
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.failed or not result.changed
|
||||
|
||||
- name: Add idoverrideuser member, again.
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: idovergroup
|
||||
idoverrideuser: "{{ ad_user }}"
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: Cleanup idoverrideuser member.
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: idovergroup
|
||||
idoverrideuser: "{{ ad_user }}"
|
||||
state: absent
|
||||
|
||||
- name: Remove testing groups.
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name:
|
||||
- idovergroup
|
||||
state: absent
|
||||
|
||||
always:
|
||||
- name: Remove idoverrideuser.
|
||||
shell: |
|
||||
kinit -c idoverride_cache admin <<< SomeADMINpassword
|
||||
ipa idoverrideuser-del "Default Trust View" {{ ad_user }}
|
||||
kdestroy -A -q -c idoverride_cache
|
||||
when:
|
||||
|
||||
when: ipa_version is version("4.8.7", ">=") and trust_test_is_supported | default(false)
|
||||
296
tests/hbacrule/test_hbacrule_member_empty.yml
Normal file
296
tests/hbacrule/test_hbacrule_member_empty.yml
Normal file
@@ -0,0 +1,296 @@
|
||||
---
|
||||
- name: Test hbacrule
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Get Domain from server name
|
||||
set_fact:
|
||||
ipaserver_domain: "{{ ansible_facts['fqdn'].split('.')[1:] | join ('.') }}"
|
||||
when: ipaserver_domain is not defined
|
||||
|
||||
- block:
|
||||
# SETUP:
|
||||
- name: Ensure test HBAC rule is absent
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
state: absent
|
||||
|
||||
- name: Ensure test hosts are present
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
hosts:
|
||||
- name: "{{ 'testhost03.' + ipaserver_domain }}"
|
||||
force: yes
|
||||
- name: "{{ 'testhost04.' + ipaserver_domain }}"
|
||||
force: yes
|
||||
|
||||
- name: Ensure test hostgroups are present
|
||||
ipahostgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ item }}"
|
||||
with_items:
|
||||
- testhostgroup03
|
||||
- testhostgroup04
|
||||
|
||||
- name: Ensure test users are present
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
users:
|
||||
- name: testuser03
|
||||
first: test
|
||||
last: user03
|
||||
- name: testuser04
|
||||
first: test
|
||||
last: user04
|
||||
|
||||
- name: Ensure test groups are present
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ item }}"
|
||||
with_items:
|
||||
- testgroup03
|
||||
- testgroup04
|
||||
|
||||
- name: Ensure test HBAC Services are present
|
||||
ipahbacsvc:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ item }}"
|
||||
with_items:
|
||||
- testhbacsvc03
|
||||
- testhbacsvc04
|
||||
|
||||
- name: Ensure test HBAC Service Groups are present
|
||||
ipahbacsvcgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ item }}"
|
||||
with_items:
|
||||
- testhbacsvcgroup03
|
||||
- testhbacsvcgroup04
|
||||
|
||||
- name: Ensure test HBAC rule hbacrule01 is absent
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
state: absent
|
||||
|
||||
# Ensure members are empty.
|
||||
- name: Ensure HBAC rule is present with known members
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
host:
|
||||
- "{{ 'testhost03.' + ipaserver_domain }}"
|
||||
- "{{ 'testhost04.' + ipaserver_domain }}"
|
||||
hostgroup: testhostgroup03,testhostgroup04
|
||||
user: testuser03,testuser04
|
||||
group: testgroup03,testgroup04
|
||||
hbacsvc: testhbacsvc03,testhbacsvc04
|
||||
hbacsvcgroup: testhbacsvcgroup03,testhbacsvcgroup04
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure test HBAC rule host is empty
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
host: []
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure test HBAC rule host is empty, again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
host: []
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure test HBAC rule hostgroup is empty
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
hostgroup: []
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure test HBAC rule hostgroup is empty, again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
hostgroup: []
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure test HBAC rule user is empty
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
user: []
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure test HBAC rule user is empty, again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
user: []
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure test HBAC rule group is empty
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
group: []
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure test HBAC rule group is empty, again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
group: []
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure test HBAC rule hbacsvc is empty
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
hbacsvc: []
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure test HBAC rule hbacsvc is empty, again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
hbacsvc: []
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure test HBAC rule hbacsvcgroup is empty
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
hbacsvcgroup: []
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure test HBAC rule hbacsvcgroup is empty, again
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
hbacsvcgroup: []
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Verify HBAC rule is present with only members would not require changes.
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
host: []
|
||||
hostgroup: []
|
||||
user: []
|
||||
group: []
|
||||
hbacsvc: []
|
||||
hbacsvcgroup: []
|
||||
check_mode: yes
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Verify HBAC rule is present with known members would require changes.
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
host:
|
||||
- "{{ 'testhost03.' + ipaserver_domain }}"
|
||||
- "{{ 'testhost04.' + ipaserver_domain }}"
|
||||
hostgroup: testhostgroup03,testhostgroup04
|
||||
user: testuser03,testuser04
|
||||
group: testgroup03,testgroup04
|
||||
hbacsvc: testhbacsvc03,testhbacsvc04
|
||||
hbacsvcgroup: testhbacsvcgroup03,testhbacsvcgroup04
|
||||
check_mode: yes
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
always:
|
||||
# CLEANUP
|
||||
- name: Ensure test HBAC rule is absent
|
||||
ipahbacrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: hbacrule01
|
||||
state: absent
|
||||
|
||||
- name: Ensure test HBAC Service Groups are absent
|
||||
ipahbacsvcgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testhbacsvcgroup01,testhbacsvcgroup02,testhbacsvcgroup03,testhbacsvcgroup04
|
||||
state: absent
|
||||
|
||||
- name: Ensure test HBAC Services are absent
|
||||
ipahbacsvc:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testhbacsvc01,testhbacsvc02,testhbacsvc03,testhbacsvc04
|
||||
state: absent
|
||||
|
||||
- name: Ensure test hostgroups are absent
|
||||
ipahostgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testhostgroup01,testhostgroup02,testhostgroup03,testhostgroup04
|
||||
state: absent
|
||||
|
||||
- name: Ensure test hosts are absent
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name:
|
||||
- "{{ 'testhost01.' + ipaserver_domain }}"
|
||||
- "{{ 'testhost02.' + ipaserver_domain }}"
|
||||
- "{{ 'testhost03.' + ipaserver_domain }}"
|
||||
- "{{ 'testhost04.' + ipaserver_domain }}"
|
||||
state: absent
|
||||
|
||||
- name: Ensure test user groups are absent
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testgroup01,testgroup02,testgroup03,testgroup04
|
||||
state: absent
|
||||
|
||||
- name: Ensure test users are absent
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: testuser01,testuser02,testuser03,testuser04
|
||||
state: absent
|
||||
86
tests/host/test_host_empty_string_params.yml
Normal file
86
tests/host/test_host_empty_string_params.yml
Normal file
@@ -0,0 +1,86 @@
|
||||
---
|
||||
- name: Test host
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: yes
|
||||
gather_facts: yes
|
||||
|
||||
tasks:
|
||||
- name: Get Domain from server name
|
||||
set_fact:
|
||||
ipaserver_domain: "{{ ansible_facts['fqdn'].split('.')[1:] | join ('.') }}"
|
||||
when: ipaserver_domain is not defined
|
||||
|
||||
- name: Set host1_fqdn .. host6_fqdn
|
||||
set_fact:
|
||||
host1_fqdn: "{{ 'host1.' + ipaserver_domain }}"
|
||||
|
||||
# CLEANUP TEST ITEMS
|
||||
|
||||
- name: Ensure host "{{ host1_fqdn }}" absent
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ host1_fqdn }}"
|
||||
state: absent
|
||||
|
||||
# CREATE TEST ITEMS
|
||||
|
||||
- name: Ensure host "{{ host1_fqdn }}" present
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ host1_fqdn }}"
|
||||
force: yes
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
# TESTS
|
||||
|
||||
- name: Ensure host "{{ host1_fqdn }}" present with auth_ind otp and radius
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ host1_fqdn }}"
|
||||
auth_ind:
|
||||
- otp
|
||||
- radius
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure host "{{ host1_fqdn }}" present with auth_ind otp and radius, again
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ host1_fqdn }}"
|
||||
auth_ind:
|
||||
- otp
|
||||
- radius
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure host "{{ host1_fqdn }}" present with empty auth_ind
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ host1_fqdn }}"
|
||||
auth_ind: ""
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure host "{{ host1_fqdn }}" present with empty auth_ind, again
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ host1_fqdn }}"
|
||||
auth_ind: ""
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
# CLEANUP TEST ITEMS
|
||||
|
||||
- name: Ensure host "{{ host1_fqdn }}" absent
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ host1_fqdn }}"
|
||||
state: absent
|
||||
24
tests/idrange/tasks_remove_trust.yml
Normal file
24
tests/idrange/tasks_remove_trust.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
- name: Ensure testing trust is absent
|
||||
ipatrust:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
realm: "{{ adserver.domain }}"
|
||||
state: absent
|
||||
|
||||
- name: Ensure testing idranges are absent
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name:
|
||||
- "{{ adserver.realm }}_id_range"
|
||||
continue: yes
|
||||
state: absent
|
||||
|
||||
- name: Remove dns forward zone
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ adserver.domain }}"
|
||||
state: absent
|
||||
when: trust_dnszone is defined and trust_dnszone.changed
|
||||
36
tests/idrange/tasks_set_trust.yml
Normal file
36
tests/idrange/tasks_set_trust.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
- name: Ensure DNS forward zone to Windows AD
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ adserver.domain }}"
|
||||
forwarders:
|
||||
- ip_address: "{{ adserver.ip_address }}"
|
||||
forwardpolicy: first
|
||||
register: trust_dnszone
|
||||
|
||||
- name: Set trust to Widows AD
|
||||
ipatrust:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
realm: "{{ adserver.domain }}"
|
||||
admin: Administrator
|
||||
password: "{{ adserver.password }}"
|
||||
base_id: "{{ trust_base_id | default(omit) }}"
|
||||
range_type: "{{ trust_range_type | default(omit) }}"
|
||||
range_size: "{{ trust_range_size | default(omit) }}"
|
||||
register: result
|
||||
failed_when: result.failed
|
||||
|
||||
- name: Retrieve Domain Security Identifier
|
||||
shell:
|
||||
cmd: |
|
||||
kinit -c test_krb5_cache admin <<< SomeADMINpassword > /dev/null
|
||||
KRB5CCNAME=test_krb5_cache ipa trust-show {{ adserver.domain }} | sed -n "/Domain Security Identifier/s/ //gp" | cut -d":" -f2
|
||||
kdestroy -c test_krb5_cache -A -q > /dev/null
|
||||
register: getsid
|
||||
no_log: yes
|
||||
|
||||
- name: Set ipa_domain_sid.
|
||||
set_fact:
|
||||
ipa_domain_sid: "{{ getsid.stdout }}"
|
||||
280
tests/idrange/test_idrange.yml
Normal file
280
tests/idrange/test_idrange.yml
Normal file
@@ -0,0 +1,280 @@
|
||||
---
|
||||
- name: Test idrange
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
vars:
|
||||
adserver:
|
||||
domain: "{{ winserver_domain | default('windows.local')}}"
|
||||
realm: "{{ winserver_realm | default(winserver_domain) | default('windows.local') | upper }}"
|
||||
password: "{{ winserver_admin_password | default('SomeW1Npassword') }}"
|
||||
ip_address: "{{ winserver_ip | default(omit) }}"
|
||||
|
||||
tasks:
|
||||
# CLEANUP TEST ITEMS
|
||||
- name: Remove test trust.
|
||||
include_tasks: tasks_remove_trust.yml
|
||||
when: trust_test_is_supported | default(false)
|
||||
|
||||
- name: Ensure testing idranges are absent
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name:
|
||||
- "{{ adserver.realm }}_id_range"
|
||||
- local_id_range
|
||||
- ad_id_range
|
||||
- ad_posix_id_range
|
||||
continue: yes
|
||||
state: absent
|
||||
|
||||
# CREATE TEST ITEMS
|
||||
|
||||
# TESTS
|
||||
|
||||
# Test local idrange, only if ipa-adtrust-install was not executed.
|
||||
- block:
|
||||
- name: Ensure idrange with minimal attributes is present
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: local_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
register: result
|
||||
failed_when:
|
||||
not (result.failed or result.changed) or (result.failed and 'ipa-adtrust-install has already been run' not in result.msg)
|
||||
|
||||
- name: Ensure idrange with minimal attributes is present, again
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: local_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
register: result
|
||||
failed_when:
|
||||
result.changed or (result.failed and 'ipa-adtrust-install has already been run' not in result.msg)
|
||||
|
||||
- name: Ensure idrange with minimal attributes is absent
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: local_id_range
|
||||
state: absent
|
||||
register: range_delete
|
||||
failed_when: range_delete.failed or (result.changed and not range_delete.changed)
|
||||
|
||||
# Test local idrange, even after ipa-adtrust-install.
|
||||
- name: Ensure local idrange is present
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: local_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
rid_base: 1000000
|
||||
secondary_rid_base: 200000000
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure local idrange is present again
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: local_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
rid_base: 1000000
|
||||
secondary_rid_base: 200000000
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure local idrange is absent
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: local_id_range
|
||||
state: absent
|
||||
continue: no
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure local idrange is absent again
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: local_id_range
|
||||
state: absent
|
||||
continue: no
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
rescue:
|
||||
- name: Ensure local idranges is absent
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: local_id_range
|
||||
|
||||
- block:
|
||||
# Create trust with range_type: ipa-ad-trust-posix
|
||||
- name: Create trust with range_type 'ipa-ad-trust'
|
||||
include_tasks: tasks_set_trust.yml
|
||||
vars:
|
||||
trust_base_id: 10000000
|
||||
trust_range_size: 200000
|
||||
trust_range_type: ipa-ad-trust
|
||||
|
||||
# Can't user secondary_rid_base with dom_sid/dom_name
|
||||
- name: Ensure AD-trust idrange is present
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: ad_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
rid_base: 1000000
|
||||
idrange_type: ipa-ad-trust
|
||||
dom_sid: "{{ ipa_domain_sid }}"
|
||||
auto_private_groups: "false"
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure AD-trust idrange is present again
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: ad_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
rid_base: 1000000
|
||||
idrange_type: ipa-ad-trust
|
||||
dom_sid: "{{ ipa_domain_sid }}"
|
||||
auto_private_groups: "false"
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Check if AD-trust idrange is present, uning domain name
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: ad_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
rid_base: 1000000
|
||||
idrange_type: ipa-ad-trust
|
||||
dom_name: "{{ adserver.domain }}"
|
||||
auto_private_groups: "false"
|
||||
check_mode: true
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Modify AD-trust idrange 'base_id'
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: ad_id_range
|
||||
base_id: 151230000
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Modify AD-trust idrange 'base_id', again
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: ad_id_range
|
||||
base_id: 151230000
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Modify AD-trust idrange 'range_size'
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: ad_id_range
|
||||
range_size: 100000
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Modify AD-trust idrange 'rid_base'
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: ad_id_range
|
||||
rid_base: 12345678
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Modify AD-trust idrange 'auto_private_groups'
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: ad_id_range
|
||||
auto_private_groups: "hybrid"
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
# Remove trust and idrange
|
||||
- name: Remove test trust.
|
||||
include_tasks: tasks_remove_trust.yml
|
||||
|
||||
- name: Ensure AD-trust idrange is absent
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: ad_id_range
|
||||
state: absent
|
||||
|
||||
# Create trust with range_type: ipa-ad-trust-posix
|
||||
- name: Create trust with range_type 'ipa-ad-trust-posix'
|
||||
include_tasks: tasks_set_trust.yml
|
||||
vars:
|
||||
trust_base_id: 10000000
|
||||
trust_range_size: 2000000
|
||||
trust_range_type: ipa-ad-trust-posix
|
||||
|
||||
# Can't user secondary_rid_base or rid_base with "ad-trust-posix"
|
||||
- name: Ensure AD-trust-posix idrange is present
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: ad_posix_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
idrange_type: ipa-ad-trust-posix
|
||||
dom_sid: "{{ ipa_domain_sid }}"
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure AD-trust-posix idrange is present again
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: ad_posix_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
idrange_type: ipa-ad-trust-posix
|
||||
dom_sid: "{{ ipa_domain_sid }}"
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
always:
|
||||
# CLEANUP TEST ITEMS
|
||||
- name: Remove test trust.
|
||||
include_tasks: tasks_remove_trust.yml
|
||||
|
||||
- name: Ensure testing idranges are absent
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name:
|
||||
- "{{ adserver.realm }}_id_range"
|
||||
- local_id_range
|
||||
- ad_id_range
|
||||
- ad_posix_id_range
|
||||
continue: yes
|
||||
state: absent
|
||||
|
||||
when: trust_test_is_supported | default(false)
|
||||
39
tests/idrange/test_idrange_client_context.yml
Normal file
39
tests/idrange/test_idrange_client_context.yml
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
- name: Test idrange
|
||||
hosts: ipaclients, ipaserver
|
||||
# Change "become" or "gather_facts" to "yes",
|
||||
# if you test playbook requires any.
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Include FreeIPA facts.
|
||||
include_tasks: ../env_freeipa_facts.yml
|
||||
|
||||
# Test will only be executed if host is not a server.
|
||||
- name: Execute with server context in the client.
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: server
|
||||
name: ThisShouldNotWork
|
||||
register: result
|
||||
failed_when: not (result.failed and result.msg is regex("No module named '*ipaserver'*"))
|
||||
when: ipa_host_is_client
|
||||
|
||||
# Import basic module tests, and execute with ipa_context set to 'client'.
|
||||
# If ipaclients is set, it will be executed using the client, if not,
|
||||
# ipaserver will be used.
|
||||
#
|
||||
# With this setup, tests can be executed against an IPA client, against
|
||||
# an IPA server using "client" context, and ensure that tests are executed
|
||||
# in upstream CI.
|
||||
|
||||
- name: Test idrange using client context, in client host.
|
||||
import_playbook: test_idrange.yml
|
||||
when: groups['ipaclients']
|
||||
vars:
|
||||
ipa_test_host: ipaclients
|
||||
|
||||
- name: Test idrange using client context, in server host.
|
||||
import_playbook: test_idrange.yml
|
||||
when: groups['ipaclients'] is not defined or not groups['ipaclients']
|
||||
@@ -43,9 +43,9 @@
|
||||
- name: Verify role privileges.
|
||||
shell:
|
||||
cmd: |
|
||||
echo SomeADMINpassword | kinit -c {{ KRB5CCNAME }} admin
|
||||
KRB5CCNAME={{ KRB5CCNAME }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ KRB5CCNAME }}
|
||||
echo SomeADMINpassword | kinit -c {{ krb5ccname }} admin
|
||||
KRB5CCNAME={{ krb5ccname }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ krb5ccname }}
|
||||
register: result
|
||||
failed_when: |
|
||||
result.failed or not (
|
||||
@@ -57,7 +57,7 @@
|
||||
and "Group Administrators" in result.stdout
|
||||
)
|
||||
vars:
|
||||
KRB5CCNAME: verify_issue_409
|
||||
krb5ccname: verify_issue_409
|
||||
# End of test fix for https://github.com/freeipa/ansible-freeipa/issues/409
|
||||
|
||||
# Test fix for https://github.com/freeipa/ansible-freeipa/issues/412
|
||||
@@ -73,9 +73,9 @@
|
||||
- name: Verify role users.
|
||||
shell:
|
||||
cmd: |
|
||||
echo SomeADMINpassword | kinit -c {{ KRB5CCNAME }} admin
|
||||
KRB5CCNAME={{ KRB5CCNAME }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ KRB5CCNAME }}
|
||||
echo SomeADMINpassword | kinit -c {{ krb5ccname }} admin
|
||||
KRB5CCNAME={{ krb5ccname }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ krb5ccname }}
|
||||
register: result
|
||||
failed_when: |
|
||||
result.failed or not (
|
||||
@@ -83,7 +83,7 @@
|
||||
and "user02" in result.stdout
|
||||
)
|
||||
vars:
|
||||
KRB5CCNAME: verify_issue_412
|
||||
krb5ccname: verify_issue_412
|
||||
|
||||
- name: Add new group to role.
|
||||
iparole:
|
||||
@@ -97,9 +97,9 @@
|
||||
- name: Verify role group.
|
||||
shell:
|
||||
cmd: |
|
||||
echo SomeADMINpassword | kinit -c {{ KRB5CCNAME }} admin
|
||||
KRB5CCNAME={{ KRB5CCNAME }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ KRB5CCNAME }}
|
||||
echo SomeADMINpassword | kinit -c {{ krb5ccname }} admin
|
||||
KRB5CCNAME={{ krb5ccname }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ krb5ccname }}
|
||||
register: result
|
||||
failed_when: |
|
||||
result.failed or not (
|
||||
@@ -107,7 +107,7 @@
|
||||
and "group02" in result.stdout
|
||||
)
|
||||
vars:
|
||||
KRB5CCNAME: verify_issue_412
|
||||
krb5ccname: verify_issue_412
|
||||
|
||||
- name: Add new host to role.
|
||||
iparole:
|
||||
@@ -121,9 +121,9 @@
|
||||
- name: Verify role hosts.
|
||||
shell:
|
||||
cmd: |
|
||||
echo SomeADMINpassword | kinit -c {{ KRB5CCNAME }} admin
|
||||
KRB5CCNAME={{ KRB5CCNAME }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ KRB5CCNAME }}
|
||||
echo SomeADMINpassword | kinit -c {{ krb5ccname }} admin
|
||||
KRB5CCNAME={{ krb5ccname }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ krb5ccname }}
|
||||
register: result
|
||||
failed_when: |
|
||||
result.failed or not (
|
||||
@@ -131,7 +131,7 @@
|
||||
and host2 in result.stdout
|
||||
)
|
||||
vars:
|
||||
KRB5CCNAME: verify_issue_412
|
||||
krb5ccname: verify_issue_412
|
||||
host1: " {{ host1_fqdn }}"
|
||||
host2: " {{ host2_fqdn }}"
|
||||
|
||||
@@ -147,9 +147,9 @@
|
||||
- name: Verify role hostgroups.
|
||||
shell:
|
||||
cmd: |
|
||||
echo SomeADMINpassword | kinit -c {{ KRB5CCNAME }} admin
|
||||
KRB5CCNAME={{ KRB5CCNAME }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ KRB5CCNAME }}
|
||||
echo SomeADMINpassword | kinit -c {{ krb5ccname }} admin
|
||||
KRB5CCNAME={{ krb5ccname }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ krb5ccname }}
|
||||
register: result
|
||||
failed_when: |
|
||||
result.failed or not (
|
||||
@@ -157,7 +157,7 @@
|
||||
and " hostgroup02" in result.stdout
|
||||
)
|
||||
vars:
|
||||
KRB5CCNAME: verify_issue_412
|
||||
krb5ccname: verify_issue_412
|
||||
|
||||
- name: Add new service to role.
|
||||
iparole:
|
||||
@@ -171,9 +171,9 @@
|
||||
- name: Verify role services.
|
||||
shell:
|
||||
cmd: |
|
||||
echo SomeADMINpassword | kinit -c {{ KRB5CCNAME }} admin
|
||||
KRB5CCNAME={{ KRB5CCNAME }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ KRB5CCNAME }}
|
||||
echo SomeADMINpassword | kinit -c {{ krb5ccname }} admin
|
||||
KRB5CCNAME={{ krb5ccname }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ krb5ccname }}
|
||||
register: result
|
||||
failed_when: |
|
||||
result.failed or not (
|
||||
@@ -181,7 +181,7 @@
|
||||
and service1 in result.stdout
|
||||
)
|
||||
vars:
|
||||
KRB5CCNAME: verify_issue_412
|
||||
krb5ccname: verify_issue_412
|
||||
service1: "service01/{{ host1_fqdn }}"
|
||||
service2: "service02/{{ host2_fqdn }}"
|
||||
# End of test fix for https://github.com/freeipa/ansible-freeipa/issues/412
|
||||
@@ -199,9 +199,9 @@
|
||||
- name: Verify role services.
|
||||
shell:
|
||||
cmd: |
|
||||
echo SomeADMINpassword | kinit -c {{ KRB5CCNAME }} admin
|
||||
KRB5CCNAME={{ KRB5CCNAME }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ KRB5CCNAME }}
|
||||
echo SomeADMINpassword | kinit -c {{ krb5ccname }} admin
|
||||
KRB5CCNAME={{ krb5ccname }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ krb5ccname }}
|
||||
register: result
|
||||
failed_when: |
|
||||
result.failed or not (
|
||||
@@ -210,7 +210,7 @@
|
||||
and "user03" in result.stdout
|
||||
)
|
||||
vars:
|
||||
KRB5CCNAME: verify_issue_413
|
||||
krb5ccname: verify_issue_413
|
||||
service1: "service01/{{ host1_fqdn }}"
|
||||
service2: "service02/{{ host2_fqdn }}"
|
||||
|
||||
@@ -227,9 +227,9 @@
|
||||
- name: Verify role services.
|
||||
shell:
|
||||
cmd: |
|
||||
echo SomeADMINpassword | kinit -c {{ KRB5CCNAME }} admin
|
||||
KRB5CCNAME={{ KRB5CCNAME }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ KRB5CCNAME }}
|
||||
echo SomeADMINpassword | kinit -c {{ krb5ccname }} admin
|
||||
KRB5CCNAME={{ krb5ccname }} ipa role-show testrole
|
||||
kdestroy -A -q -c {{ krb5ccname }}
|
||||
register: result
|
||||
failed_when: |
|
||||
result.failed or not (
|
||||
@@ -238,7 +238,7 @@
|
||||
and "user03" not in result.stdout
|
||||
)
|
||||
vars:
|
||||
KRB5CCNAME: verify_issue_413
|
||||
krb5ccname: verify_issue_413
|
||||
service1: "service01/{{ host1_fqdn }}"
|
||||
service2: "service02/{{ host2_fqdn }}"
|
||||
# End of test fix for https://github.com/freeipa/ansible-freeipa/issues/413
|
||||
|
||||
110
tests/service/test_service_empty_string_params.yml
Normal file
110
tests/service/test_service_empty_string_params.yml
Normal file
@@ -0,0 +1,110 @@
|
||||
---
|
||||
- name: Test service
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: yes
|
||||
gather_facts: yes
|
||||
|
||||
tasks:
|
||||
|
||||
# CLEANUP TEST ITEMS
|
||||
|
||||
- name: Ensure service "test-service/{{ ansible_facts['fqdn'] }}" is absent.
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "test-service/{{ ansible_facts['fqdn'] }}"
|
||||
continue: yes
|
||||
state: absent
|
||||
|
||||
# CREATE TEST ITEMS
|
||||
|
||||
- name: Ensure service "test-service/{{ ansible_facts['fqdn'] }}" is present
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "test-service/{{ ansible_facts['fqdn'] }}"
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
# TESTS
|
||||
|
||||
- name: Ensure service "test-service/{{ ansible_facts['fqdn'] }}" is present with pac_type MS-PAC and PAD
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "test-service/{{ ansible_facts['fqdn'] }}"
|
||||
pac_type:
|
||||
- MS-PAC
|
||||
- PAD
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure service "test-service/{{ ansible_facts['fqdn'] }}" is present with pac_type MS-PAC and PAD, again
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "test-service/{{ ansible_facts['fqdn'] }}"
|
||||
pac_type:
|
||||
- MS-PAC
|
||||
- PAD
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure service "test-service/{{ ansible_facts['fqdn'] }}" is present with empty pac_type
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "test-service/{{ ansible_facts['fqdn'] }}"
|
||||
pac_type: ""
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure service "test-service/{{ ansible_facts['fqdn'] }}" is present with empty pac_type, again
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "test-service/{{ ansible_facts['fqdn'] }}"
|
||||
pac_type: ""
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure service "test-service/{{ ansible_facts['fqdn'] }}" is present with auth_ind otp and radius
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "test-service/{{ ansible_facts['fqdn'] }}"
|
||||
auth_ind:
|
||||
- otp
|
||||
- radius
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure service "test-service/{{ ansible_facts['fqdn'] }}" is present with auth_ind otp and radius, again
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "test-service/{{ ansible_facts['fqdn'] }}"
|
||||
auth_ind:
|
||||
- otp
|
||||
- radius
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure service "test-service/{{ ansible_facts['fqdn'] }}" is present with empty auth_ind
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "test-service/{{ ansible_facts['fqdn'] }}"
|
||||
auth_ind: ""
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure service "test-service/{{ ansible_facts['fqdn'] }}" is present with empty auth_ind, again
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "test-service/{{ ansible_facts['fqdn'] }}"
|
||||
auth_ind: ""
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
# CLEANUP TEST ITEMS
|
||||
|
||||
- name: Ensure service "test-service/{{ ansible_facts['fqdn'] }}" is absent.
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "test-service/{{ ansible_facts['fqdn'] }}"
|
||||
continue: yes
|
||||
state: absent
|
||||
214
tests/servicedelegationrule/test_servicedelegationrule.yml
Normal file
214
tests/servicedelegationrule/test_servicedelegationrule.yml
Normal file
@@ -0,0 +1,214 @@
|
||||
---
|
||||
- name: Test servicedelegationrule
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
# Change "become" or "gather_facts" to "yes",
|
||||
# if you test playbook requires any.
|
||||
become: no
|
||||
gather_facts: yes
|
||||
|
||||
tasks:
|
||||
|
||||
# CLEANUP TEST ITEMS
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-rule is absent
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
state: absent
|
||||
|
||||
- name: Ensure service is absent
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name:
|
||||
- "{{ 'test-service/' + ansible_facts['fqdn'] }}"
|
||||
- "{{ 'not-existing-test-service/' + ansible_facts['fqdn'] }}"
|
||||
state: absent
|
||||
continue: yes
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-target is absent
|
||||
ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name:
|
||||
- test-delegation-target
|
||||
- not-existing-test-delegation-target
|
||||
state: absent
|
||||
|
||||
# CREATE TEST ITEMS
|
||||
|
||||
- name: Ensure service test-sevice is present
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ 'test-service/' + ansible_facts['fqdn'] }}"
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-target is present
|
||||
ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-target
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
# TESTS
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-rule is present
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-rule is present again
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Do not fail to ensure absence of not existing servicedelegationrule test-delegation-rule member principal
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
principal: "{{ 'not-existing-test-service/' + ansible_facts['fqdn'] }}"
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Do not fail to ensure absence of not existing servicedelegationrule test-delegation-rule member target
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
target: not-existing-test-delegation-target
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-rule member target test-delegation-target is present
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
target: test-delegation-target
|
||||
action: member
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-rule member target test-delegation-target is present, again
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
target: test-delegation-target
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-rule member principal "{{ 'test-service/' + ansible_facts['fqdn'] }}" is present
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
principal: "{{ 'test-service/' + ansible_facts['fqdn'] }}"
|
||||
action: member
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-rule member principal "{{ 'test-service/' + ansible_facts['fqdn'] }}" is present again
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
principal: "{{ 'test-service/' + ansible_facts['fqdn'] }}"
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-rule member principal "{{ 'test-service/' + ansible_facts['fqdn'] }}" is absent
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
principal: "{{ 'test-service/' + ansible_facts['fqdn'] }}"
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-rule member principal "{{ 'test-service/' + ansible_facts['fqdn'] }}" is present absent
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
principal: "{{ 'test-service/' + ansible_facts['fqdn'] }}"
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-rule member target test-delegation-target is absent
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
target: test-delegation-target
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-rule member target test-delegation-target is absent, again
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
target: test-delegation-target
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-rule is absent
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-rule is absent again
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-rule
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
# CLEANUP TEST ITEMS
|
||||
|
||||
- name: Ensure servicedelegationrule test-delegation-target is absent
|
||||
ipaservicedelegationtarget:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: test-delegation-target
|
||||
state: absent
|
||||
|
||||
- name: Ensure service is absent
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
name: "{{ 'test-service/' + ansible_facts['fqdn'] }}"
|
||||
state: absent
|
||||
continue: yes
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
- name: Test servicedelegationrule
|
||||
hosts: ipaclients, ipaserver
|
||||
# Change "become" or "gather_facts" to "yes",
|
||||
# if you test playbook requires any.
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Include FreeIPA facts.
|
||||
include_tasks: ../env_freeipa_facts.yml
|
||||
|
||||
# Test will only be executed if host is not a server.
|
||||
- name: Execute with server context in the client.
|
||||
ipaservicedelegationrule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: server
|
||||
name: ThisShouldNotWork
|
||||
register: result
|
||||
failed_when: not (result.failed and result.msg is regex("No module named '*ipaserver'*"))
|
||||
when: ipa_host_is_client
|
||||
|
||||
# Import basic module tests, and execute with ipa_context set to 'client'.
|
||||
# If ipaclients is set, it will be executed using the client, if not,
|
||||
# ipaserver will be used.
|
||||
#
|
||||
# With this setup, tests can be executed against an IPA client, against
|
||||
# an IPA server using "client" context, and ensure that tests are executed
|
||||
# in upstream CI.
|
||||
|
||||
- name: Test servicedelegationrule using client context, in client host.
|
||||
import_playbook: test_servicedelegationrule.yml
|
||||
when: groups['ipaclients']
|
||||
vars:
|
||||
ipa_test_host: ipaclients
|
||||
|
||||
- name: Test servicedelegationrule using client context, in server host.
|
||||
import_playbook: test_servicedelegationrule.yml
|
||||
when: groups['ipaclients'] is not defined or not groups['ipaclients']
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user