mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-05-14 21:42:17 +00:00
Compare commits
37 Commits
v0.1.12
...
fix-role-r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd6dd1fd84 | ||
|
|
4e89da8536 | ||
|
|
5b5cce1943 | ||
|
|
8c889e9b0b | ||
|
|
643b3f950d | ||
|
|
0f3691979f | ||
|
|
b33c5a7bab | ||
|
|
97601ceb9a | ||
|
|
ffba096dc5 | ||
|
|
5364cf8046 | ||
|
|
ab1b24570f | ||
|
|
22ec1c505e | ||
|
|
7a2eaa6f53 | ||
|
|
c8ae3c3a02 | ||
|
|
4d8a4a14e4 | ||
|
|
8ce5fd147a | ||
|
|
ffa0c6eef8 | ||
|
|
80aac15de9 | ||
|
|
097a3426a6 | ||
|
|
957b5910b4 | ||
|
|
464eae16a1 | ||
|
|
0303f15375 | ||
|
|
6132a947e6 | ||
|
|
c97a15f8d4 | ||
|
|
78b635ae78 | ||
|
|
1d7fb31b8b | ||
|
|
34f1a45641 | ||
|
|
9b69caff49 | ||
|
|
8da6a69379 | ||
|
|
857fb82eb9 | ||
|
|
bf864469a1 | ||
|
|
e57e4908f9 | ||
|
|
0165506514 | ||
|
|
1d223c2b63 | ||
|
|
3f785bc0e9 | ||
|
|
f8ebca760d | ||
|
|
f0f933b463 |
@@ -49,7 +49,7 @@ Example playbook to ensure presence of a forwardzone to ipa DNS:
|
|||||||
tasks:
|
tasks:
|
||||||
- name: ensure presence of forwardzone for DNS requests for example.com to 8.8.8.8
|
- name: ensure presence of forwardzone for DNS requests for example.com to 8.8.8.8
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
state: present
|
state: present
|
||||||
name: example.com
|
name: example.com
|
||||||
forwarders:
|
forwarders:
|
||||||
@@ -59,13 +59,13 @@ Example playbook to ensure presence of a forwardzone to ipa DNS:
|
|||||||
|
|
||||||
- name: ensure the forward zone is disabled
|
- name: ensure the forward zone is disabled
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: example.com
|
name: example.com
|
||||||
state: disabled
|
state: disabled
|
||||||
|
|
||||||
- name: ensure presence of multiple upstream DNS servers for example.com
|
- name: ensure presence of multiple upstream DNS servers for example.com
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
state: present
|
state: present
|
||||||
name: example.com
|
name: example.com
|
||||||
forwarders:
|
forwarders:
|
||||||
@@ -74,7 +74,7 @@ Example playbook to ensure presence of a forwardzone to ipa DNS:
|
|||||||
|
|
||||||
- name: ensure presence of another forwarder to any existing ones for example.com
|
- name: ensure presence of another forwarder to any existing ones for example.com
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
state: present
|
state: present
|
||||||
name: example.com
|
name: example.com
|
||||||
forwarders:
|
forwarders:
|
||||||
@@ -83,7 +83,7 @@ Example playbook to ensure presence of a forwardzone to ipa DNS:
|
|||||||
|
|
||||||
- name: ensure the forwarder for example.com does not exists (delete it if needed)
|
- name: ensure the forwarder for example.com does not exists (delete it if needed)
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: example.com
|
name: example.com
|
||||||
state: absent
|
state: absent
|
||||||
```
|
```
|
||||||
@@ -99,9 +99,12 @@ Variable | Description | Required
|
|||||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
||||||
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||||
`name` \| `cn` | Zone name (FQDN). | yes if `state` == `present`
|
`name` \| `cn` | Zone name (FQDN). | yes if `state` == `present`
|
||||||
`forwarders` \| `idnsforwarders` | Per-zone conditional forwarding policy. Possible values are `only`, `first`, `none`) | no
|
`forwarders` \| `idnsforwarders` | Per-zone forwarders. A custom port can be specified for each forwarder. Options | no
|
||||||
`forwardpolicy` \| `idnsforwardpolicy` | Per-zone conditional forwarding policy. Set to "none" to disable forwarding to global forwarder for this zone. In that case, conditional zone forwarders are disregarded. | 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
|
||||||
`skip_overlap_check` | Force DNS zone creation even if it will overlap with an existing zone. Defaults to False. | 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
|
`action` | Work on group or member level. It can be on of `member` or `dnsforwardzone` and defaults to `dnsforwardzone`. | no
|
||||||
`state` | The state to ensure. It can be one of `present`, `absent`, `enabled` or `disabled`, default: `present`. | yes
|
`state` | The state to ensure. It can be one of `present`, `absent`, `enabled` or `disabled`, default: `present`. | yes
|
||||||
|
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ Variable | Description | Required
|
|||||||
`name` \| `cn` | The list of group name strings. | no
|
`name` \| `cn` | The list of group name strings. | no
|
||||||
`description` | The group description string. | no
|
`description` | The group description string. | no
|
||||||
`gid` \| `gidnumber` | The GID integer. | no
|
`gid` \| `gidnumber` | The GID integer. | no
|
||||||
|
`posix` | Create a non-POSIX group or change a non-POSIX to a posix group. (bool) | no
|
||||||
`nonposix` | Create as a non-POSIX group. (bool) | no
|
`nonposix` | Create as a non-POSIX group. (bool) | no
|
||||||
`external` | Allow adding external non-IPA members from trusted domains. (bool) | no
|
`external` | Allow adding external non-IPA members from trusted domains. (bool) | no
|
||||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||||
|
|||||||
@@ -355,7 +355,7 @@ Variable | Description | Required
|
|||||||
`mac_address` \| `macaddress` | List of hardware MAC addresses. | no
|
`mac_address` \| `macaddress` | List of hardware MAC addresses. | no
|
||||||
`sshpubkey` \| `ipasshpubkey` | List of SSH public keys | no
|
`sshpubkey` \| `ipasshpubkey` | List of SSH public keys | no
|
||||||
`userclass` \| `class` | Host category (semantics placed on this attribute are for local interpretation) | no
|
`userclass` \| `class` | Host category (semantics placed on this attribute are for local interpretation) | no
|
||||||
`auth_ind` \| `krbprincipalauthind` | Defines a whitelist for Authentication Indicators. Use 'otp' to allow OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA authentications. Use empty string to reset auth_ind to the initial value. Other values may be used for custom configurations. choices: ["radius", "otp", "pkinit", "hardened", ""] | no
|
`auth_ind` \| `krbprincipalauthind` | Defines an allow list for Authentication Indicators. Use 'otp' to allow OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA authentications. Use empty string to reset auth_ind to the initial value. Other values may be used for custom configurations. choices: ["radius", "otp", "pkinit", "hardened", ""] | no
|
||||||
`requires_pre_auth` \| `ipakrbrequirespreauth` | Pre-authentication is required for the service (bool) | no
|
`requires_pre_auth` \| `ipakrbrequirespreauth` | Pre-authentication is required for the service (bool) | no
|
||||||
`ok_as_delegate` \| `ipakrbokasdelegate` | Client credentials may be delegated to the service (bool) | no
|
`ok_as_delegate` \| `ipakrbokasdelegate` | Client credentials may be delegated to the service (bool) | no
|
||||||
`ok_to_auth_as_delegate` \| `ipakrboktoauthasdelegate` | The service is allowed to authenticate on behalf of a client (bool) | no
|
`ok_to_auth_as_delegate` \| `ipakrboktoauthasdelegate` | The service is allowed to authenticate on behalf of a client (bool) | no
|
||||||
|
|||||||
264
README-role.md
Normal file
264
README-role.md
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
Role module
|
||||||
|
===========
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The role module allows to ensure presence, absence of roles and members of roles.
|
||||||
|
|
||||||
|
The role module is as compatible as possible to the Ansible upstream `ipa_role` module, but additionally offers role member management.
|
||||||
|
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
* Role management
|
||||||
|
|
||||||
|
|
||||||
|
Supported FreeIPA Versions
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
FreeIPA versions 4.4.0 and up are supported by the iparole 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 make sure role is present with all members:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role with members.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
user:
|
||||||
|
- pinky
|
||||||
|
group:
|
||||||
|
- group01
|
||||||
|
host:
|
||||||
|
- host01.example.com
|
||||||
|
hostgroup:
|
||||||
|
- hostgroup01
|
||||||
|
privilege:
|
||||||
|
- Group Administrators
|
||||||
|
- User Administrators
|
||||||
|
service:
|
||||||
|
- service01
|
||||||
|
```
|
||||||
|
|
||||||
|
Example playbook to rename a role:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
rename: anotherrole
|
||||||
|
```
|
||||||
|
|
||||||
|
Example playbook to make sure role is absent:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
state: absent
|
||||||
|
```
|
||||||
|
|
||||||
|
Example playbook to ensure a user is a member of a role:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
user:
|
||||||
|
- pinky
|
||||||
|
action: member
|
||||||
|
```
|
||||||
|
|
||||||
|
Example playbook to ensure a group is a member of a role:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
host:
|
||||||
|
- host01.example.com
|
||||||
|
action: member
|
||||||
|
```
|
||||||
|
|
||||||
|
Example playbook to ensure a host is a member of a role:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
host:
|
||||||
|
- host01.example.com
|
||||||
|
action: member
|
||||||
|
```
|
||||||
|
|
||||||
|
Example playbook to ensure a hostgroup is a member of a role:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
hostgroup:
|
||||||
|
- hostgroup01
|
||||||
|
action: member
|
||||||
|
```
|
||||||
|
|
||||||
|
Example playbook to ensure a service is a member of a role:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
service:
|
||||||
|
- service01
|
||||||
|
action: member
|
||||||
|
```
|
||||||
|
|
||||||
|
Example playbook to ensure a privilege is a member of a role:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
privilege:
|
||||||
|
- Group Administrators
|
||||||
|
- User Administrators
|
||||||
|
action: member
|
||||||
|
```
|
||||||
|
|
||||||
|
Example playbook to ensure that different members are not associated with a role.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
user:
|
||||||
|
- pinky
|
||||||
|
group:
|
||||||
|
- group01
|
||||||
|
host:
|
||||||
|
- host01.example.com
|
||||||
|
hostgroup:
|
||||||
|
- hostgroup01
|
||||||
|
privilege:
|
||||||
|
- Group Administrators
|
||||||
|
- User Administrators
|
||||||
|
service:
|
||||||
|
- service01
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Variables
|
||||||
|
---------
|
||||||
|
|
||||||
|
iparole
|
||||||
|
-------
|
||||||
|
|
||||||
|
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
|
||||||
|
`name` \| `cn` | The list of role name strings. | yes
|
||||||
|
`description` | A description for the role. | no
|
||||||
|
`rename` | Rename the role object. | no
|
||||||
|
`privileges` | Privileges associated to this role. | no
|
||||||
|
`user` | List of users to be assigned or not assigned to the role. | no
|
||||||
|
`group` | List of groups to be assigned or not assigned to the role. | no
|
||||||
|
`host` | List of hosts to be assigned or not assigned to the role. | no
|
||||||
|
`hostgroup` | List of hostgroups to be assigned or not assigned to the role. | no
|
||||||
|
`service` | List of services to be assigned or not assigned to the role. | no
|
||||||
|
`action` | Work on role or member level. It can be on of `member` or `role` and defaults to `role`. | no
|
||||||
|
`state` | The state to ensure. It can be one of `present`, `absent`, default: `present`. | no
|
||||||
|
|
||||||
|
|
||||||
|
Authors
|
||||||
|
=======
|
||||||
|
|
||||||
|
Rafael Jeffman
|
||||||
@@ -294,7 +294,7 @@ Variable | Description | Required
|
|||||||
`name` \| `service` | The list of service name strings. | yes
|
`name` \| `service` | The list of service name strings. | yes
|
||||||
`certificate` \| `usercertificate` | Base-64 encoded service certificate. | no
|
`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
|
`pac_type` \| `ipakrbauthzdata` | Supported PAC type. It can be one of `MS-PAC`, `PAD`, or `NONE`. | no
|
||||||
`auth_ind` \| `krbprincipalauthind` | Defines a whitelist for Authentication Indicators. It can be any of `otp`, `radius`, `pkinit`, or `hardened`. | no
|
`auth_ind` \| `krbprincipalauthind` | Defines an allow list for Authentication Indicators. It can be any of `otp`, `radius`, `pkinit`, or `hardened`. | no
|
||||||
`requires_pre_auth` \| `ipakrbrequirespreauth` | Pre-authentication is required for the service. Default to true. (bool) | 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_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
|
`ok_to_auth_as_delegate` \| `ipakrboktoauthasdelegate` | The service is allowed to authenticate on behalf of a client. Default to false. (bool) | no
|
||||||
|
|||||||
@@ -165,6 +165,22 @@ Example playbook to make sure vault data is absent in a symmetric vault:
|
|||||||
state: absent
|
state: absent
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Example playbook to change the password of a symmetric:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Playbook to handle vaults
|
||||||
|
hosts: ipaserver
|
||||||
|
become: true
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- ipavault:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: symvault
|
||||||
|
old_password: SomeVAULTpassword
|
||||||
|
new_password: SomeNEWpassword
|
||||||
|
```
|
||||||
|
|
||||||
Example playbook to make sure vault is absent:
|
Example playbook to make sure vault is absent:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -197,8 +213,11 @@ Variable | Description | Required
|
|||||||
`name` \| `cn` | The list of vault name strings. | yes
|
`name` \| `cn` | The list of vault name strings. | yes
|
||||||
`description` | The vault description string. | no
|
`description` | The vault description string. | no
|
||||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||||
`password ` \| `vault_password` \| `ipavaultpassword` | Vault password. | no
|
`password` \| `vault_password` \| `ipavaultpassword` \| `old_password`| Vault password. | no
|
||||||
`public_key ` \| `vault_public_key` \| `ipavaultpublickey` | Base64 encoded vault public key. | no
|
`password_file` \| `vault_password_file` \| `old_password_file`| File containing Base64 encoded Vault password. | no
|
||||||
|
`new_password` | Vault new password. | no
|
||||||
|
`new_password_file` | File containing Base64 encoded new Vault password. | no
|
||||||
|
`public_key ` \| `vault_public_key` \| `old_password_file` | Base64 encoded vault public key. | no
|
||||||
`public_key_file` \| `vault_public_key_file` | Path to file with public key. | no
|
`public_key_file` \| `vault_public_key_file` | Path to file with public key. | no
|
||||||
`private_key `\| `vault_private_key` | Base64 encoded vault private key. Used only to retrieve data. | no
|
`private_key `\| `vault_private_key` | Base64 encoded vault private key. Used only to retrieve data. | no
|
||||||
`private_key_file` \| `vault_private_key_file` | Path to file with private key. Used only to retrieve data. | no
|
`private_key_file` \| `vault_private_key_file` | Path to file with private key. Used only to retrieve data. | no
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ Features
|
|||||||
* Modules for host management
|
* Modules for host management
|
||||||
* Modules for hostgroup management
|
* Modules for hostgroup management
|
||||||
* Modules for pwpolicy management
|
* Modules for pwpolicy management
|
||||||
|
* Modules for role management
|
||||||
* Modules for service management
|
* Modules for service management
|
||||||
* Modules for sudocmd management
|
* Modules for sudocmd management
|
||||||
* Modules for sudocmdgroup management
|
* Modules for sudocmdgroup management
|
||||||
@@ -421,6 +422,7 @@ Modules in plugin/modules
|
|||||||
* [ipahost](README-host.md)
|
* [ipahost](README-host.md)
|
||||||
* [ipahostgroup](README-hostgroup.md)
|
* [ipahostgroup](README-hostgroup.md)
|
||||||
* [ipapwpolicy](README-pwpolicy.md)
|
* [ipapwpolicy](README-pwpolicy.md)
|
||||||
|
* [iparole](README-role.md)
|
||||||
* [ipaservice](README-service.md)
|
* [ipaservice](README-service.md)
|
||||||
* [ipasudocmd](README-sudocmd.md)
|
* [ipasudocmd](README-sudocmd.md)
|
||||||
* [ipasudocmdgroup](README-sudocmdgroup.md)
|
* [ipasudocmdgroup](README-sudocmdgroup.md)
|
||||||
|
|||||||
11
playbooks/role/role-is-absent.yml
Normal file
11
playbooks/role/role-is-absent.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
state: absent
|
||||||
11
playbooks/role/role-is-present.yml
Normal file
11
playbooks/role/role-is-present.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
description: A role in IPA.
|
||||||
14
playbooks/role/role-member-group-absent.yml
Normal file
14
playbooks/role/role-member-group-absent.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
group:
|
||||||
|
- group01
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
13
playbooks/role/role-member-group-present.yml
Normal file
13
playbooks/role/role-member-group-present.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
group:
|
||||||
|
- group01
|
||||||
|
action: member
|
||||||
14
playbooks/role/role-member-host-absent.yml
Normal file
14
playbooks/role/role-member-host-absent.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
host:
|
||||||
|
- host01.example.com
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
13
playbooks/role/role-member-host-present.yml
Normal file
13
playbooks/role/role-member-host-present.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
host:
|
||||||
|
- host01.example.com
|
||||||
|
action: member
|
||||||
14
playbooks/role/role-member-hostgroup-absent.yml
Normal file
14
playbooks/role/role-member-hostgroup-absent.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
hostgroup:
|
||||||
|
- hostgroup01
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
13
playbooks/role/role-member-hostgroup-present.yml
Normal file
13
playbooks/role/role-member-hostgroup-present.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
hostgroup:
|
||||||
|
- hostgroup01
|
||||||
|
action: member
|
||||||
15
playbooks/role/role-member-privilege-absent.yml
Normal file
15
playbooks/role/role-member-privilege-absent.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
privilege:
|
||||||
|
- Group Administrators
|
||||||
|
- User Administrators
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
14
playbooks/role/role-member-privilege-present.yml
Normal file
14
playbooks/role/role-member-privilege-present.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
privilege:
|
||||||
|
- Group Administrators
|
||||||
|
- User Administrators
|
||||||
|
action: member
|
||||||
14
playbooks/role/role-member-service-absent.yml
Normal file
14
playbooks/role/role-member-service-absent.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
service:
|
||||||
|
- http/www.example.com
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
13
playbooks/role/role-member-service-present.yml
Normal file
13
playbooks/role/role-member-service-present.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
service:
|
||||||
|
- service01
|
||||||
|
action: member
|
||||||
14
playbooks/role/role-member-user-absent.yml
Normal file
14
playbooks/role/role-member-user-absent.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
user:
|
||||||
|
- pinky
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
13
playbooks/role/role-member-user-present.yml
Normal file
13
playbooks/role/role-member-user-present.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
user:
|
||||||
|
- pinky
|
||||||
|
action: member
|
||||||
25
playbooks/role/role-members-absent.yml
Normal file
25
playbooks/role/role-members-absent.yml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role member.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
user:
|
||||||
|
- pinky
|
||||||
|
group:
|
||||||
|
- group01
|
||||||
|
host:
|
||||||
|
- host01.example.com
|
||||||
|
hostgroup:
|
||||||
|
- hostgroup01
|
||||||
|
privilege:
|
||||||
|
- Group Administrators
|
||||||
|
- User Administrators
|
||||||
|
service:
|
||||||
|
- service01
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
23
playbooks/role/role-members-present.yml
Normal file
23
playbooks/role/role-members-present.yml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role with members.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
user:
|
||||||
|
- pinky
|
||||||
|
group:
|
||||||
|
- group01
|
||||||
|
host:
|
||||||
|
- host01.example.com
|
||||||
|
hostgroup:
|
||||||
|
- hostgroup01
|
||||||
|
privilege:
|
||||||
|
- Group Administrators
|
||||||
|
- User Administrators
|
||||||
|
service:
|
||||||
|
- service01
|
||||||
11
playbooks/role/role-rename.yml
Normal file
11
playbooks/role/role-rename.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
- name: Playbook to manage IPA role.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
rename: anotherrole
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: symvault
|
name: symvault
|
||||||
password: SomeVAULTpassword
|
password: SomeVAULTpassword
|
||||||
- name: Change vault passord.
|
- name: Change vault password.
|
||||||
ipavault:
|
ipavault:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: symvault
|
name: symvault
|
||||||
|
|||||||
@@ -54,9 +54,16 @@ options:
|
|||||||
forwarders:
|
forwarders:
|
||||||
description:
|
description:
|
||||||
- List of the DNS servers to forward to
|
- List of the DNS servers to forward to
|
||||||
required: true
|
|
||||||
type: list
|
|
||||||
aliases: ["idnsforwarders"]
|
aliases: ["idnsforwarders"]
|
||||||
|
options:
|
||||||
|
ip_address:
|
||||||
|
description: Forwarder IP address (either IPv4 or IPv6).
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
port:
|
||||||
|
description: Forwarder port.
|
||||||
|
required: false
|
||||||
|
type: int
|
||||||
forwardpolicy:
|
forwardpolicy:
|
||||||
description: Per-zone conditional forwarding policy
|
description: Per-zone conditional forwarding policy
|
||||||
required: false
|
required: false
|
||||||
@@ -68,6 +75,11 @@ options:
|
|||||||
- Force DNS zone creation even if it will overlap with an existing zone.
|
- Force DNS zone creation even if it will overlap with an existing zone.
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
|
permission:
|
||||||
|
description:
|
||||||
|
- Allow DNS Forward Zone to be managed.
|
||||||
|
required: false
|
||||||
|
type: bool
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
@@ -128,20 +140,41 @@ def gen_args(forwarders, forwardpolicy, skip_overlap_check):
|
|||||||
return _args
|
return _args
|
||||||
|
|
||||||
|
|
||||||
|
def forwarder_list(forwarders):
|
||||||
|
"""Convert the forwarder dict into a list compatible with IPA API."""
|
||||||
|
if forwarders is None:
|
||||||
|
return None
|
||||||
|
fwd_list = []
|
||||||
|
for forwarder in forwarders:
|
||||||
|
if forwarder.get('port', None) is not None:
|
||||||
|
formatter = "{ip_address} port {port}"
|
||||||
|
else:
|
||||||
|
formatter = "{ip_address}"
|
||||||
|
fwd_list.append(formatter.format(**forwarder))
|
||||||
|
return fwd_list
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
ansible_module = AnsibleModule(
|
ansible_module = AnsibleModule(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
# general
|
# general
|
||||||
ipaadmin_principal=dict(type="str", default="admin"),
|
ipaadmin_principal=dict(type="str", default="admin"),
|
||||||
ipaadmin_password=dict(type="str", required=False, no_log=True),
|
ipaadmin_password=dict(type="str", required=False, no_log=True),
|
||||||
name=dict(type="str", aliases=["cn"], default=None,
|
name=dict(type="list", aliases=["cn"], default=None,
|
||||||
required=True),
|
required=True),
|
||||||
forwarders=dict(type='list', aliases=["idnsforwarders"],
|
forwarders=dict(type="list", default=None, required=False,
|
||||||
required=False),
|
aliases=["idnsforwarders"], elements='dict',
|
||||||
|
options=dict(
|
||||||
|
ip_address=dict(type='str', required=True),
|
||||||
|
port=dict(type='int', required=False,
|
||||||
|
default=None),
|
||||||
|
)),
|
||||||
forwardpolicy=dict(type='str', aliases=["idnsforwardpolicy"],
|
forwardpolicy=dict(type='str', aliases=["idnsforwardpolicy"],
|
||||||
required=False,
|
required=False,
|
||||||
choices=['only', 'first', 'none']),
|
choices=['only', 'first', 'none']),
|
||||||
skip_overlap_check=dict(type='bool', required=False),
|
skip_overlap_check=dict(type='bool', required=False),
|
||||||
|
permission=dict(type='bool', required=False,
|
||||||
|
aliases=['managedby']),
|
||||||
action=dict(type="str", default="dnsforwardzone",
|
action=dict(type="str", default="dnsforwardzone",
|
||||||
choices=["member", "dnsforwardzone"]),
|
choices=["member", "dnsforwardzone"]),
|
||||||
# state
|
# state
|
||||||
@@ -158,14 +191,22 @@ def main():
|
|||||||
"ipaadmin_principal")
|
"ipaadmin_principal")
|
||||||
ipaadmin_password = module_params_get(ansible_module,
|
ipaadmin_password = module_params_get(ansible_module,
|
||||||
"ipaadmin_password")
|
"ipaadmin_password")
|
||||||
name = module_params_get(ansible_module, "name")
|
names = module_params_get(ansible_module, "name")
|
||||||
action = module_params_get(ansible_module, "action")
|
action = module_params_get(ansible_module, "action")
|
||||||
forwarders = module_params_get(ansible_module, "forwarders")
|
forwarders = forwarder_list(
|
||||||
|
module_params_get(ansible_module, "forwarders"))
|
||||||
forwardpolicy = module_params_get(ansible_module, "forwardpolicy")
|
forwardpolicy = module_params_get(ansible_module, "forwardpolicy")
|
||||||
skip_overlap_check = module_params_get(ansible_module,
|
skip_overlap_check = module_params_get(ansible_module,
|
||||||
"skip_overlap_check")
|
"skip_overlap_check")
|
||||||
|
permission = module_params_get(ansible_module, "permission")
|
||||||
state = module_params_get(ansible_module, "state")
|
state = module_params_get(ansible_module, "state")
|
||||||
|
|
||||||
|
if state == 'present' and len(names) != 1:
|
||||||
|
ansible_module.fail_json(
|
||||||
|
msg="Only one dnsforwardzone can be added at a time.")
|
||||||
|
if state == 'absent' and len(names) < 1:
|
||||||
|
ansible_module.fail_json(msg="No name given.")
|
||||||
|
|
||||||
# absent stae means delete if the action is NOT member but update if it is
|
# absent stae means delete if the action is NOT member but update if it is
|
||||||
# if action is member then update an exisiting resource
|
# if action is member then update an exisiting resource
|
||||||
# and if action is not member then create a resource
|
# and if action is not member then create a resource
|
||||||
@@ -176,18 +217,30 @@ def main():
|
|||||||
else:
|
else:
|
||||||
operation = "add"
|
operation = "add"
|
||||||
|
|
||||||
if state == "disabled":
|
if state in ["enabled", "disabled"]:
|
||||||
wants_enable = False
|
if action == "member":
|
||||||
else:
|
ansible_module.fail_json(
|
||||||
wants_enable = True
|
msg="Action `member` cannot be used with state `%s`"
|
||||||
|
% (state))
|
||||||
if operation == "del":
|
invalid = [
|
||||||
invalid = ["forwarders", "forwardpolicy", "skip_overlap_check"]
|
"forwarders", "forwardpolicy", "skip_overlap_check", "permission"
|
||||||
|
]
|
||||||
for x in invalid:
|
for x in invalid:
|
||||||
if vars()[x] is not None:
|
if vars()[x] is not None:
|
||||||
ansible_module.fail_json(
|
ansible_module.fail_json(
|
||||||
msg="Argument '%s' can not be used with action "
|
msg="Argument '%s' can not be used with action "
|
||||||
"'%s'" % (x, action))
|
"'%s', state `%s`" % (x, action, state))
|
||||||
|
wants_enable = (state == "enabled")
|
||||||
|
|
||||||
|
if operation == "del":
|
||||||
|
invalid = [
|
||||||
|
"forwarders", "forwardpolicy", "skip_overlap_check", "permission"
|
||||||
|
]
|
||||||
|
for x in invalid:
|
||||||
|
if vars()[x] is not None:
|
||||||
|
ansible_module.fail_json(
|
||||||
|
msg="Argument '%s' can not be used with action "
|
||||||
|
"'%s', state `%s`" % (x, action, state))
|
||||||
|
|
||||||
changed = False
|
changed = False
|
||||||
exit_args = {}
|
exit_args = {}
|
||||||
@@ -207,99 +260,116 @@ def main():
|
|||||||
ipaadmin_password)
|
ipaadmin_password)
|
||||||
api_connect()
|
api_connect()
|
||||||
|
|
||||||
# Make sure forwardzone exists
|
for name in names:
|
||||||
existing_resource = find_dnsforwardzone(ansible_module, name)
|
commands = []
|
||||||
|
|
||||||
if existing_resource is None and operation == "update":
|
|
||||||
# does not exist and is updating
|
|
||||||
# trying to update something that doesn't exist, so error
|
|
||||||
ansible_module.fail_json(msg="""dnsforwardzone '%s' is not
|
|
||||||
valid""" % (name))
|
|
||||||
elif existing_resource is None and operation == "del":
|
|
||||||
# does not exists and should be absent
|
|
||||||
# set command
|
|
||||||
command = None
|
command = None
|
||||||
# enabled or disabled?
|
|
||||||
is_enabled = "IGNORE"
|
|
||||||
elif existing_resource is not None and operation == "del":
|
|
||||||
# exists but should be absent
|
|
||||||
# set command
|
|
||||||
command = "dnsforwardzone_del"
|
|
||||||
# enabled or disabled?
|
|
||||||
is_enabled = "IGNORE"
|
|
||||||
elif forwarders is None:
|
|
||||||
# forwarders are not defined its not a delete, update state?
|
|
||||||
# set command
|
|
||||||
command = None
|
|
||||||
# enabled or disabled?
|
|
||||||
if existing_resource is not None:
|
|
||||||
is_enabled = existing_resource["idnszoneactive"][0]
|
|
||||||
else:
|
|
||||||
is_enabled = "IGNORE"
|
|
||||||
elif existing_resource is not None and operation == "update":
|
|
||||||
# exists and is updating
|
|
||||||
# calculate the new forwarders and mod
|
|
||||||
# determine args
|
|
||||||
if state != "absent":
|
|
||||||
forwarders = list(set(existing_resource["idnsforwarders"]
|
|
||||||
+ forwarders))
|
|
||||||
else:
|
|
||||||
forwarders = list(set(existing_resource["idnsforwarders"])
|
|
||||||
- set(forwarders))
|
|
||||||
args = gen_args(forwarders, forwardpolicy,
|
|
||||||
skip_overlap_check)
|
|
||||||
if skip_overlap_check is not None:
|
|
||||||
del args['skip_overlap_check']
|
|
||||||
|
|
||||||
# command
|
# Make sure forwardzone exists
|
||||||
if not compare_args_ipa(ansible_module, args, existing_resource):
|
existing_resource = find_dnsforwardzone(ansible_module, name)
|
||||||
command = "dnsforwardzone_mod"
|
|
||||||
else:
|
|
||||||
command = None
|
|
||||||
|
|
||||||
# enabled or disabled?
|
# validate parameters
|
||||||
is_enabled = existing_resource["idnszoneactive"][0]
|
if state == 'present':
|
||||||
|
if existing_resource is None and not forwarders:
|
||||||
|
ansible_module.fail_json(msg='No forwarders specified.')
|
||||||
|
|
||||||
elif existing_resource is None and operation == "add":
|
if existing_resource is None:
|
||||||
# does not exist but should be present
|
if operation == "add":
|
||||||
# determine args
|
# does not exist but should be present
|
||||||
args = gen_args(forwarders, forwardpolicy,
|
# determine args
|
||||||
skip_overlap_check)
|
args = gen_args(forwarders, forwardpolicy,
|
||||||
# set command
|
skip_overlap_check)
|
||||||
command = "dnsforwardzone_add"
|
# set command
|
||||||
# enabled or disabled?
|
command = "dnsforwardzone_add"
|
||||||
is_enabled = "TRUE"
|
# enabled or disabled?
|
||||||
|
|
||||||
elif existing_resource is not None and operation == "add":
|
elif operation == "update":
|
||||||
# exists and should be present, has it changed?
|
# does not exist and is updating
|
||||||
# determine args
|
# trying to update something that doesn't exist, so error
|
||||||
args = gen_args(forwarders, forwardpolicy, skip_overlap_check)
|
ansible_module.fail_json(
|
||||||
if skip_overlap_check is not None:
|
msg="dnsforwardzone '%s' not found." % (name))
|
||||||
del args['skip_overlap_check']
|
|
||||||
|
|
||||||
# set command
|
elif operation == "del":
|
||||||
if not compare_args_ipa(ansible_module, args, existing_resource):
|
# there's nothnig to do.
|
||||||
command = "dnsforwardzone_mod"
|
continue
|
||||||
else:
|
|
||||||
command = None
|
|
||||||
|
|
||||||
# enabled or disabled?
|
else: # existing_resource is not None
|
||||||
is_enabled = existing_resource["idnszoneactive"][0]
|
if state != "absent":
|
||||||
|
if forwarders:
|
||||||
|
forwarders = list(
|
||||||
|
set(existing_resource["idnsforwarders"]
|
||||||
|
+ forwarders))
|
||||||
|
else:
|
||||||
|
if forwarders:
|
||||||
|
forwarders = list(
|
||||||
|
set(existing_resource["idnsforwarders"])
|
||||||
|
- set(forwarders))
|
||||||
|
|
||||||
# if command is set then run it with the args
|
if operation == "add":
|
||||||
if command is not None:
|
# exists and should be present, has it changed?
|
||||||
api_command(ansible_module, command, name, args)
|
# determine args
|
||||||
changed = True
|
args = gen_args(
|
||||||
|
forwarders, forwardpolicy, skip_overlap_check)
|
||||||
|
if 'skip_overlap_check' in args:
|
||||||
|
del args['skip_overlap_check']
|
||||||
|
|
||||||
# does the enabled state match what we want (if we care)
|
# set command
|
||||||
if is_enabled != "IGNORE":
|
if not compare_args_ipa(
|
||||||
if wants_enable and is_enabled != "TRUE":
|
ansible_module, args, existing_resource):
|
||||||
api_command(ansible_module, "dnsforwardzone_enable",
|
command = "dnsforwardzone_mod"
|
||||||
name, {})
|
|
||||||
changed = True
|
elif operation == "del":
|
||||||
elif not wants_enable and is_enabled != "FALSE":
|
# exists but should be absent
|
||||||
api_command(ansible_module, "dnsforwardzone_disable",
|
# set command
|
||||||
name, {})
|
command = "dnsforwardzone_del"
|
||||||
|
args = {}
|
||||||
|
|
||||||
|
elif operation == "update":
|
||||||
|
# exists and is updating
|
||||||
|
# calculate the new forwarders and mod
|
||||||
|
args = gen_args(
|
||||||
|
forwarders, forwardpolicy, skip_overlap_check)
|
||||||
|
if "skip_overlap_check" in args:
|
||||||
|
del args['skip_overlap_check']
|
||||||
|
|
||||||
|
# command
|
||||||
|
if not compare_args_ipa(
|
||||||
|
ansible_module, args, existing_resource):
|
||||||
|
command = "dnsforwardzone_mod"
|
||||||
|
|
||||||
|
if state in ['enabled', 'disabled']:
|
||||||
|
if existing_resource is not None:
|
||||||
|
is_enabled = existing_resource["idnszoneactive"][0]
|
||||||
|
else:
|
||||||
|
ansible_module.fail_json(
|
||||||
|
msg="dnsforwardzone '%s' not found." % (name))
|
||||||
|
|
||||||
|
# does the enabled state match what we want (if we care)
|
||||||
|
if is_enabled != "IGNORE":
|
||||||
|
if wants_enable and is_enabled != "TRUE":
|
||||||
|
commands.append([name, "dnsforwardzone_enable", {}])
|
||||||
|
elif not wants_enable and is_enabled != "FALSE":
|
||||||
|
commands.append([name, "dnsforwardzone_disable", {}])
|
||||||
|
|
||||||
|
# if command is set...
|
||||||
|
if command is not None:
|
||||||
|
commands.append([name, command, args])
|
||||||
|
|
||||||
|
if permission is not None:
|
||||||
|
if existing_resource is None:
|
||||||
|
managedby = None
|
||||||
|
else:
|
||||||
|
managedby = existing_resource.get('managedby', None)
|
||||||
|
if permission and managedby is None:
|
||||||
|
commands.append(
|
||||||
|
[name, 'dnsforwardzone_add_permission', {}]
|
||||||
|
)
|
||||||
|
elif not permission and managedby is not None:
|
||||||
|
commands.append(
|
||||||
|
[name, 'dnsforwardzone_remove_permission', {}]
|
||||||
|
)
|
||||||
|
|
||||||
|
for name, command, args in commands:
|
||||||
|
api_command(ansible_module, command, name, args)
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ options:
|
|||||||
description: Allow adding external non-IPA members from trusted domains
|
description: Allow adding external non-IPA members from trusted domains
|
||||||
required: false
|
required: false
|
||||||
type: bool
|
type: bool
|
||||||
|
posix:
|
||||||
|
description:
|
||||||
|
Create a non-POSIX group or change a non-POSIX to a posix group.
|
||||||
|
required: false
|
||||||
|
type: bool
|
||||||
nomembers:
|
nomembers:
|
||||||
description: Suppress processing of membership attributes
|
description: Suppress processing of membership attributes
|
||||||
required: false
|
required: false
|
||||||
@@ -140,10 +145,23 @@ EXAMPLES = """
|
|||||||
- sysops
|
- sysops
|
||||||
- appops
|
- appops
|
||||||
|
|
||||||
# Remove goups sysops, appops and ops
|
|
||||||
|
# Create a non-POSIX group
|
||||||
- ipagroup:
|
- ipagroup:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: sysops,appops,ops
|
name: nongroup
|
||||||
|
nonposix: yes
|
||||||
|
|
||||||
|
# Turn a non-POSIX group into a POSIX group.
|
||||||
|
- ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: nonposix
|
||||||
|
posix: yes
|
||||||
|
|
||||||
|
# Remove goups sysops, appops, ops and nongroup
|
||||||
|
- ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: sysops,appops,ops, nongroup
|
||||||
state: absent
|
state: absent
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -173,16 +191,12 @@ def find_group(module, name):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def gen_args(description, gid, nonposix, external, nomembers):
|
def gen_args(description, gid, nomembers):
|
||||||
_args = {}
|
_args = {}
|
||||||
if description is not None:
|
if description is not None:
|
||||||
_args["description"] = description
|
_args["description"] = description
|
||||||
if gid is not None:
|
if gid is not None:
|
||||||
_args["gidnumber"] = gid
|
_args["gidnumber"] = gid
|
||||||
if nonposix is not None:
|
|
||||||
_args["nonposix"] = nonposix
|
|
||||||
if external is not None:
|
|
||||||
_args["external"] = external
|
|
||||||
if nomembers is not None:
|
if nomembers is not None:
|
||||||
_args["nomembers"] = nomembers
|
_args["nomembers"] = nomembers
|
||||||
|
|
||||||
@@ -201,6 +215,41 @@ def gen_member_args(user, group, service):
|
|||||||
return _args
|
return _args
|
||||||
|
|
||||||
|
|
||||||
|
def check_objectclass_args(module, res_find, nonposix, posix, external):
|
||||||
|
if res_find and 'posixgroup' in res_find['objectclass']:
|
||||||
|
if (
|
||||||
|
(posix is not None and posix is False)
|
||||||
|
or nonposix
|
||||||
|
or external
|
||||||
|
):
|
||||||
|
module.fail_json(
|
||||||
|
msg="Cannot change `POSIX` status of a group "
|
||||||
|
"to `non-POSIX` or `external`.")
|
||||||
|
# Can't change an existing external group
|
||||||
|
if res_find and 'ipaexternalgroup' in res_find['objectclass']:
|
||||||
|
if (
|
||||||
|
posix
|
||||||
|
or (nonposix is not None and nonposix is False)
|
||||||
|
or (external is not None and external is False)
|
||||||
|
):
|
||||||
|
module.fail_json(
|
||||||
|
msg="Cannot change `external` status of group "
|
||||||
|
"to `POSIX` or `non-external`.")
|
||||||
|
|
||||||
|
|
||||||
|
def should_modify_group(module, res_find, args, nonposix, posix, external):
|
||||||
|
if not compare_args_ipa(module, args, res_find):
|
||||||
|
return True
|
||||||
|
if any([posix, nonposix]):
|
||||||
|
set_posix = posix or (nonposix is not None and not nonposix)
|
||||||
|
if set_posix and 'posixgroup' not in res_find['objectclass']:
|
||||||
|
return True
|
||||||
|
if 'ipaexternalgroup' not in res_find['objectclass'] and external:
|
||||||
|
if 'posixgroup' not in res_find['objectclass']:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
ansible_module = AnsibleModule(
|
ansible_module = AnsibleModule(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
@@ -215,6 +264,7 @@ def main():
|
|||||||
gid=dict(type="int", aliases=["gidnumber"], default=None),
|
gid=dict(type="int", aliases=["gidnumber"], default=None),
|
||||||
nonposix=dict(required=False, type='bool', default=None),
|
nonposix=dict(required=False, type='bool', default=None),
|
||||||
external=dict(required=False, type='bool', default=None),
|
external=dict(required=False, type='bool', default=None),
|
||||||
|
posix=dict(required=False, type='bool', default=None),
|
||||||
nomembers=dict(required=False, type='bool', default=None),
|
nomembers=dict(required=False, type='bool', default=None),
|
||||||
user=dict(required=False, type='list', default=None),
|
user=dict(required=False, type='list', default=None),
|
||||||
group=dict(required=False, type='list', default=None),
|
group=dict(required=False, type='list', default=None),
|
||||||
@@ -228,6 +278,7 @@ def main():
|
|||||||
state=dict(type="str", default="present",
|
state=dict(type="str", default="present",
|
||||||
choices=["present", "absent"]),
|
choices=["present", "absent"]),
|
||||||
),
|
),
|
||||||
|
mutually_exclusive=[['posix', 'nonposix']],
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -248,6 +299,7 @@ def main():
|
|||||||
gid = module_params_get(ansible_module, "gid")
|
gid = module_params_get(ansible_module, "gid")
|
||||||
nonposix = module_params_get(ansible_module, "nonposix")
|
nonposix = module_params_get(ansible_module, "nonposix")
|
||||||
external = module_params_get(ansible_module, "external")
|
external = module_params_get(ansible_module, "external")
|
||||||
|
posix = module_params_get(ansible_module, "posix")
|
||||||
nomembers = module_params_get(ansible_module, "nomembers")
|
nomembers = module_params_get(ansible_module, "nomembers")
|
||||||
user = module_params_get(ansible_module, "user")
|
user = module_params_get(ansible_module, "user")
|
||||||
group = module_params_get(ansible_module, "group")
|
group = module_params_get(ansible_module, "group")
|
||||||
@@ -267,7 +319,7 @@ def main():
|
|||||||
ansible_module.fail_json(
|
ansible_module.fail_json(
|
||||||
msg="Only one group can be added at a time.")
|
msg="Only one group can be added at a time.")
|
||||||
if action == "member":
|
if action == "member":
|
||||||
invalid = ["description", "gid", "nonposix", "external",
|
invalid = ["description", "gid", "posix", "nonposix", "external",
|
||||||
"nomembers"]
|
"nomembers"]
|
||||||
for x in invalid:
|
for x in invalid:
|
||||||
if vars()[x] is not None:
|
if vars()[x] is not None:
|
||||||
@@ -279,7 +331,8 @@ def main():
|
|||||||
if len(names) < 1:
|
if len(names) < 1:
|
||||||
ansible_module.fail_json(
|
ansible_module.fail_json(
|
||||||
msg="No name given.")
|
msg="No name given.")
|
||||||
invalid = ["description", "gid", "nonposix", "external", "nomembers"]
|
invalid = ["description", "gid", "posix", "nonposix", "external",
|
||||||
|
"nomembers"]
|
||||||
if action == "group":
|
if action == "group":
|
||||||
invalid.extend(["user", "group", "service"])
|
invalid.extend(["user", "group", "service"])
|
||||||
for x in invalid:
|
for x in invalid:
|
||||||
@@ -322,9 +375,12 @@ def main():
|
|||||||
|
|
||||||
# Create command
|
# Create command
|
||||||
if state == "present":
|
if state == "present":
|
||||||
|
# Can't change an existing posix group
|
||||||
|
check_objectclass_args(ansible_module, res_find, nonposix,
|
||||||
|
posix, external)
|
||||||
|
|
||||||
# Generate args
|
# Generate args
|
||||||
args = gen_args(description, gid, nonposix, external,
|
args = gen_args(description, gid, nomembers)
|
||||||
nomembers)
|
|
||||||
|
|
||||||
if action == "group":
|
if action == "group":
|
||||||
# Found the group
|
# Found the group
|
||||||
@@ -332,10 +388,21 @@ def main():
|
|||||||
# For all settings is args, check if there are
|
# For all settings is args, check if there are
|
||||||
# different settings in the find result.
|
# different settings in the find result.
|
||||||
# If yes: modify
|
# If yes: modify
|
||||||
if not compare_args_ipa(ansible_module, args,
|
if should_modify_group(ansible_module, res_find, args,
|
||||||
res_find):
|
nonposix, posix, external):
|
||||||
|
if (
|
||||||
|
posix
|
||||||
|
or (nonposix is not None and not nonposix)
|
||||||
|
):
|
||||||
|
args['posix'] = True
|
||||||
|
if external:
|
||||||
|
args['external'] = True
|
||||||
commands.append([name, "group_mod", args])
|
commands.append([name, "group_mod", args])
|
||||||
else:
|
else:
|
||||||
|
if nonposix or (posix is not None and not posix):
|
||||||
|
args['nonposix'] = True
|
||||||
|
if external:
|
||||||
|
args['external'] = True
|
||||||
commands.append([name, "group_add", args])
|
commands.append([name, "group_add", args])
|
||||||
# Set res_find to empty dict for next step
|
# Set res_find to empty dict for next step
|
||||||
res_find = {}
|
res_find = {}
|
||||||
@@ -507,16 +574,15 @@ def main():
|
|||||||
# All "already a member" and "not a member" failures in the
|
# All "already a member" and "not a member" failures in the
|
||||||
# result are ignored. All others are reported.
|
# result are ignored. All others are reported.
|
||||||
errors = []
|
errors = []
|
||||||
if "failed" in result and len(result["failed"]) > 0:
|
for failed_item in result.get("failed", []):
|
||||||
for item in result["failed"]:
|
failed = result["failed"][failed_item]
|
||||||
failed_item = result["failed"][item]
|
for member_type in failed:
|
||||||
for member_type in failed_item:
|
for member, failure in failed[member_type]:
|
||||||
for member, failure in failed_item[member_type]:
|
if "already a member" in failure \
|
||||||
if "already a member" in failure \
|
or "not a member" in failure:
|
||||||
or "not a member" in failure:
|
continue
|
||||||
continue
|
errors.append("%s: %s %s: %s" % (
|
||||||
errors.append("%s: %s %s: %s" % (
|
command, member_type, member, failure))
|
||||||
command, member_type, member, failure))
|
|
||||||
if len(errors) > 0:
|
if len(errors) > 0:
|
||||||
ansible_module.fail_json(msg=", ".join(errors))
|
ansible_module.fail_json(msg=", ".join(errors))
|
||||||
|
|
||||||
|
|||||||
@@ -799,10 +799,15 @@ def main():
|
|||||||
server_realm = api_get_realm()
|
server_realm = api_get_realm()
|
||||||
|
|
||||||
commands = []
|
commands = []
|
||||||
|
host_set = set()
|
||||||
|
|
||||||
for host in names:
|
for host in names:
|
||||||
if isinstance(host, dict):
|
if isinstance(host, dict):
|
||||||
name = host.get("name")
|
name = host.get("name")
|
||||||
|
if name in host_set:
|
||||||
|
ansible_module.fail_json(
|
||||||
|
msg="host '%s' is used more than once" % name)
|
||||||
|
host_set.add(name)
|
||||||
description = host.get("description")
|
description = host.get("description")
|
||||||
locality = host.get("locality")
|
locality = host.get("locality")
|
||||||
location = host.get("location")
|
location = host.get("location")
|
||||||
@@ -1337,6 +1342,8 @@ def main():
|
|||||||
else:
|
else:
|
||||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||||
|
|
||||||
|
del host_set
|
||||||
|
|
||||||
# Execute commands
|
# Execute commands
|
||||||
|
|
||||||
errors = []
|
errors = []
|
||||||
|
|||||||
@@ -423,14 +423,15 @@ def main():
|
|||||||
# All "already a member" and "not a member" failures in the
|
# All "already a member" and "not a member" failures in the
|
||||||
# result are ignored. All others are reported.
|
# result are ignored. All others are reported.
|
||||||
errors = []
|
errors = []
|
||||||
if "failed" in result and "member" in result["failed"]:
|
for failed_item in result.get("failed", []):
|
||||||
failed = result["failed"]["member"]
|
failed = result["failed"][failed_item]
|
||||||
for member_type in failed:
|
for member_type in failed:
|
||||||
for member, failure in failed[member_type]:
|
for member, failure in failed[member_type]:
|
||||||
if "already a member" not in failure \
|
if "already a member" in failure \
|
||||||
and "not a member" not in failure:
|
or "not a member" in failure:
|
||||||
errors.append("%s: %s %s: %s" % (
|
continue
|
||||||
command, member_type, member, failure))
|
errors.append("%s: %s %s: %s" % (
|
||||||
|
command, member_type, member, failure))
|
||||||
if len(errors) > 0:
|
if len(errors) > 0:
|
||||||
ansible_module.fail_json(msg=", ".join(errors))
|
ansible_module.fail_json(msg=", ".join(errors))
|
||||||
|
|
||||||
|
|||||||
485
plugins/modules/iparole.py
Normal file
485
plugins/modules/iparole.py
Normal file
@@ -0,0 +1,485 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""ansible-freeipa iparole module implementation."""
|
||||||
|
|
||||||
|
# Authors:
|
||||||
|
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||||
|
#
|
||||||
|
# Copyright (C) 2020 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/>.
|
||||||
|
|
||||||
|
ANSIBLE_METADATA = {
|
||||||
|
"metadata_version": "1.0",
|
||||||
|
"supported_by": "community",
|
||||||
|
"status": ["preview"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DOCUMENTATION = """
|
||||||
|
---
|
||||||
|
module: ipaservice
|
||||||
|
short description: Manage FreeIPA service
|
||||||
|
description: Manage FreeIPA service
|
||||||
|
options:
|
||||||
|
ipaadmin_principal:
|
||||||
|
description: The admin principal.
|
||||||
|
default: admin
|
||||||
|
ipaadmin_password:
|
||||||
|
description: The admin password.
|
||||||
|
required: false
|
||||||
|
role:
|
||||||
|
description: The list of role name strings.
|
||||||
|
required: true
|
||||||
|
aliases: ["cn"]
|
||||||
|
description:
|
||||||
|
descrpition: A description for the role.
|
||||||
|
required: false
|
||||||
|
rename:
|
||||||
|
descrpition: Rename the role object.
|
||||||
|
required: false
|
||||||
|
user:
|
||||||
|
description: List of users.
|
||||||
|
required: false
|
||||||
|
group:
|
||||||
|
description: List of groups.
|
||||||
|
required: false
|
||||||
|
host:
|
||||||
|
description: List of hosts.
|
||||||
|
required: false
|
||||||
|
hostgroup:
|
||||||
|
description: List of hostgroups.
|
||||||
|
required: false
|
||||||
|
service:
|
||||||
|
description: List of services.
|
||||||
|
required: false
|
||||||
|
action:
|
||||||
|
description: Work on service or member level.
|
||||||
|
choices: ["role", "member"]
|
||||||
|
default: role
|
||||||
|
required: false
|
||||||
|
state:
|
||||||
|
description: The state to ensure.
|
||||||
|
choices: ["present", "absent"]
|
||||||
|
default: present
|
||||||
|
required: true
|
||||||
|
"""
|
||||||
|
|
||||||
|
EXAMPLES = """
|
||||||
|
- name: Ensure a role named `somerole` is present.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
|
||||||
|
- name: Ensure user `pinky` is a memmer of role `somerole`.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
user:
|
||||||
|
- pinky
|
||||||
|
action: member
|
||||||
|
|
||||||
|
- name: Ensure a role named `somerole` is absent.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: somerole
|
||||||
|
state: absent
|
||||||
|
"""
|
||||||
|
|
||||||
|
# pylint: disable=wrong-import-position
|
||||||
|
# pylint: disable=import-error
|
||||||
|
# pylint: disable=no-name-in-module
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils._text import to_text
|
||||||
|
from ansible.module_utils.ansible_freeipa_module import \
|
||||||
|
temp_kinit, temp_kdestroy, valid_creds, api_connect, api_command, \
|
||||||
|
gen_add_del_lists, compare_args_ipa, module_params_get, api_get_realm
|
||||||
|
import six
|
||||||
|
|
||||||
|
|
||||||
|
if six.PY3:
|
||||||
|
unicode = str
|
||||||
|
|
||||||
|
|
||||||
|
def find_role(module, name):
|
||||||
|
"""Find if a role with the given name already exist."""
|
||||||
|
try:
|
||||||
|
_result = api_command(module, "role_show", name, {"all": True})
|
||||||
|
except Exception: # pylint: disable=broad-except
|
||||||
|
# An exception is raised if role name is not found.
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return _result["result"]
|
||||||
|
|
||||||
|
|
||||||
|
def gen_args(module):
|
||||||
|
"""Generate arguments for executing commands."""
|
||||||
|
arg_map = {
|
||||||
|
"description": "description",
|
||||||
|
"rename": "rename",
|
||||||
|
}
|
||||||
|
args = {}
|
||||||
|
|
||||||
|
for param, arg in arg_map.items():
|
||||||
|
value = module_params_get(module, param)
|
||||||
|
if value is not None:
|
||||||
|
args[arg] = value
|
||||||
|
|
||||||
|
return args
|
||||||
|
|
||||||
|
|
||||||
|
def check_parameters(module):
|
||||||
|
"""Check if parameters passed for module processing are valid."""
|
||||||
|
action = module_params_get(module, "action")
|
||||||
|
state = module_params_get(module, "state")
|
||||||
|
|
||||||
|
invalid = []
|
||||||
|
|
||||||
|
if state == "present":
|
||||||
|
if action == "member":
|
||||||
|
invalid.extend(['description', 'rename'])
|
||||||
|
|
||||||
|
if state == "absent":
|
||||||
|
invalid.extend(['description', 'rename'])
|
||||||
|
if action != "member":
|
||||||
|
invalid.extend(['privilege'])
|
||||||
|
|
||||||
|
for arg in invalid:
|
||||||
|
if module_params_get(module, arg) is not None:
|
||||||
|
module.fail_json(
|
||||||
|
msg="Argument '%s' can not be used with action '%s'" %
|
||||||
|
(arg, state))
|
||||||
|
|
||||||
|
|
||||||
|
def verify_credentials(module):
|
||||||
|
"""Ensure there are valid Kerberos credentials."""
|
||||||
|
ccache_dir = None
|
||||||
|
ccache_name = None
|
||||||
|
|
||||||
|
ipaadmin_principal = module_params_get(module, "ipaadmin_principal")
|
||||||
|
ipaadmin_password = module_params_get(module, "ipaadmin_password")
|
||||||
|
|
||||||
|
if not valid_creds(module, ipaadmin_principal):
|
||||||
|
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||||
|
ipaadmin_password)
|
||||||
|
|
||||||
|
return (ccache_dir, ccache_name)
|
||||||
|
|
||||||
|
|
||||||
|
def member_intersect(module, attr, memberof, res_find):
|
||||||
|
"""Filter member arguments from role found by intersection."""
|
||||||
|
params = module_params_get(module, attr)
|
||||||
|
if not res_find:
|
||||||
|
return params
|
||||||
|
filtered = []
|
||||||
|
if params:
|
||||||
|
existing = res_find.get(memberof, [])
|
||||||
|
filtered = list(set(params) & set(existing))
|
||||||
|
return filtered
|
||||||
|
|
||||||
|
|
||||||
|
def member_difference(module, attr, memberof, res_find):
|
||||||
|
"""Filter member arguments from role found by difference."""
|
||||||
|
params = module_params_get(module, attr)
|
||||||
|
if not res_find:
|
||||||
|
return params
|
||||||
|
filtered = []
|
||||||
|
if params:
|
||||||
|
existing = res_find.get(memberof, [])
|
||||||
|
filtered = list(set(params) - set(existing))
|
||||||
|
return filtered
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_absent_state(module, name, action, res_find):
|
||||||
|
"""Define commands to ensure absent state."""
|
||||||
|
commands = []
|
||||||
|
|
||||||
|
if action == "role":
|
||||||
|
commands.append([name, 'role_del', {}])
|
||||||
|
|
||||||
|
if action == "member":
|
||||||
|
|
||||||
|
members = member_intersect(
|
||||||
|
module, 'privilege', 'memberof_privilege', res_find)
|
||||||
|
if members:
|
||||||
|
commands.append([name, "role_remove_privilege",
|
||||||
|
{"privilege": members}])
|
||||||
|
|
||||||
|
member_args = {}
|
||||||
|
for key in ['user', 'group', 'host', 'hostgroup']:
|
||||||
|
items = member_intersect(
|
||||||
|
module, key, 'member_%s' % key, res_find)
|
||||||
|
if items:
|
||||||
|
member_args[key] = items
|
||||||
|
|
||||||
|
_services = filter_service(module, res_find,
|
||||||
|
lambda res, svc: res.startswith(svc))
|
||||||
|
if _services:
|
||||||
|
member_args['service'] = _services
|
||||||
|
|
||||||
|
# Only add remove command if there's at least one member no manage.
|
||||||
|
if member_args:
|
||||||
|
commands.append([name, "role_remove_member", member_args])
|
||||||
|
|
||||||
|
return commands
|
||||||
|
|
||||||
|
|
||||||
|
def filter_service(module, res_find, predicate):
|
||||||
|
"""
|
||||||
|
Filter service based on predicate.
|
||||||
|
|
||||||
|
Compare service name with existing ones matching
|
||||||
|
at least until `@` from principal name.
|
||||||
|
|
||||||
|
Predicate is a callable that accepts the existing service, and the
|
||||||
|
modified service to be compared to.
|
||||||
|
"""
|
||||||
|
_services = []
|
||||||
|
service = module_params_get(module, 'service')
|
||||||
|
if service:
|
||||||
|
existing = [to_text(x) for x in res_find.get('member_service', [])]
|
||||||
|
for svc in service:
|
||||||
|
svc = svc if '@' in svc else ('%s@' % svc)
|
||||||
|
found = [x for x in existing if predicate(x, svc)]
|
||||||
|
_services.extend(found)
|
||||||
|
return _services
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_role_with_members_is_present(module, name, res_find):
|
||||||
|
"""Define commands to ensure member are present for action `role`."""
|
||||||
|
commands = []
|
||||||
|
privilege_add, privilege_del = gen_add_del_lists(
|
||||||
|
module_params_get(module, "privilege"),
|
||||||
|
res_find.get('memberof_privilege', []))
|
||||||
|
|
||||||
|
if privilege_add:
|
||||||
|
commands.append([name, "role_add_privilege",
|
||||||
|
{"privilege": privilege_add}])
|
||||||
|
if privilege_del:
|
||||||
|
commands.append([name, "role_remove_privilege",
|
||||||
|
{"privilege": privilege_del}])
|
||||||
|
|
||||||
|
add_members = {}
|
||||||
|
del_members = {}
|
||||||
|
|
||||||
|
for key in ["user", "group", "host", "hostgroup"]:
|
||||||
|
add_list, del_list = gen_add_del_lists(
|
||||||
|
module_params_get(module, key),
|
||||||
|
res_find.get('member_%s' % key, [])
|
||||||
|
)
|
||||||
|
if add_list:
|
||||||
|
add_members[key] = add_list
|
||||||
|
if del_list:
|
||||||
|
del_members[key] = [to_text(item) for item in del_list]
|
||||||
|
|
||||||
|
service = [
|
||||||
|
to_text(svc) if '@' in svc else ('%s@%s' % (svc, api_get_realm()))
|
||||||
|
for svc in (module_params_get(module, 'service') or [])
|
||||||
|
]
|
||||||
|
existing = [str(svc) for svc in res_find.get('member_service', [])]
|
||||||
|
add_list, del_list = gen_add_del_lists(service, existing)
|
||||||
|
if add_list:
|
||||||
|
add_members['service'] = add_list
|
||||||
|
if del_list:
|
||||||
|
del_members['service'] = [to_text(item) for item in del_list]
|
||||||
|
|
||||||
|
if add_members:
|
||||||
|
commands.append([name, "role_add_member", add_members])
|
||||||
|
if del_members:
|
||||||
|
commands.append([name, "role_remove_member", del_members])
|
||||||
|
|
||||||
|
return commands
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_members_are_present(module, name, res_find):
|
||||||
|
"""Define commands to ensure members are present for action `member`."""
|
||||||
|
commands = []
|
||||||
|
|
||||||
|
members = member_difference(
|
||||||
|
module, 'privilege', 'memberof_privilege', res_find)
|
||||||
|
if members:
|
||||||
|
commands.append([name, "role_add_privilege",
|
||||||
|
{"privilege": members}])
|
||||||
|
|
||||||
|
member_args = {}
|
||||||
|
for key in ['user', 'group', 'host', 'hostgroup']:
|
||||||
|
items = member_difference(
|
||||||
|
module, key, 'member_%s' % key, res_find)
|
||||||
|
if items:
|
||||||
|
member_args[key] = items
|
||||||
|
|
||||||
|
_services = filter_service(module, res_find,
|
||||||
|
lambda res, svc: not res.startswith(svc))
|
||||||
|
if _services:
|
||||||
|
member_args['service'] = _services
|
||||||
|
|
||||||
|
if member_args:
|
||||||
|
commands.append([name, "role_add_member", member_args])
|
||||||
|
|
||||||
|
return commands
|
||||||
|
|
||||||
|
|
||||||
|
def process_command_failures(command, result):
|
||||||
|
"""Process the result of a command, looking for errors."""
|
||||||
|
# Get all errors
|
||||||
|
# All "already a member" and "not a member" failures in the
|
||||||
|
# result are ignored. All others are reported.
|
||||||
|
errors = []
|
||||||
|
if "failed" in result and len(result["failed"]) > 0:
|
||||||
|
for item in result["failed"]:
|
||||||
|
failed_item = result["failed"][item]
|
||||||
|
for member_type in failed_item:
|
||||||
|
for member, failure in failed_item[member_type]:
|
||||||
|
if "already a member" in failure \
|
||||||
|
or "not a member" in failure:
|
||||||
|
continue
|
||||||
|
errors.append("%s: %s %s: %s" % (
|
||||||
|
command, member_type, member, failure))
|
||||||
|
return errors
|
||||||
|
|
||||||
|
|
||||||
|
def process_commands(module, commands):
|
||||||
|
"""Process the list of IPA API commands."""
|
||||||
|
errors = []
|
||||||
|
exit_args = {}
|
||||||
|
changed = False
|
||||||
|
for name, command, args in commands:
|
||||||
|
try:
|
||||||
|
result = api_command(module, command, name, args)
|
||||||
|
if "completed" in result:
|
||||||
|
if result["completed"] > 0:
|
||||||
|
changed = True
|
||||||
|
else:
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
errors = process_command_failures(command, result)
|
||||||
|
except Exception as exception: # pylint: disable=broad-except
|
||||||
|
module.fail_json(
|
||||||
|
msg="%s: %s: %s" % (command, name, str(exception)))
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
module.fail_json(msg=", ".join(errors))
|
||||||
|
|
||||||
|
return changed, exit_args
|
||||||
|
|
||||||
|
|
||||||
|
def role_commands_for_name(module, state, action, name):
|
||||||
|
"""Define commands for the Role module."""
|
||||||
|
commands = []
|
||||||
|
|
||||||
|
rename = module_params_get(module, "rename")
|
||||||
|
|
||||||
|
res_find = find_role(module, name)
|
||||||
|
|
||||||
|
if state == "present":
|
||||||
|
args = gen_args(module)
|
||||||
|
|
||||||
|
if action == "role":
|
||||||
|
if res_find is None:
|
||||||
|
if rename is not None:
|
||||||
|
module.fail_json(msg="Cannot `rename` inexistent role.")
|
||||||
|
commands.append([name, 'role_add', args])
|
||||||
|
res_find = {}
|
||||||
|
else:
|
||||||
|
if not compare_args_ipa(module, args, res_find):
|
||||||
|
commands.append([name, 'role_mod', args])
|
||||||
|
|
||||||
|
if action == "member":
|
||||||
|
if res_find is None:
|
||||||
|
module.fail_json(msg="No role '%s'" % name)
|
||||||
|
|
||||||
|
cmds = ensure_role_with_members_is_present(module, name, res_find)
|
||||||
|
commands.extend(cmds)
|
||||||
|
|
||||||
|
if state == "absent" and res_find is not None:
|
||||||
|
cmds = ensure_absent_state(module, name, action, res_find)
|
||||||
|
commands.extend(cmds)
|
||||||
|
|
||||||
|
return commands
|
||||||
|
|
||||||
|
|
||||||
|
def create_module():
|
||||||
|
"""Create module description."""
|
||||||
|
ansible_module = AnsibleModule(
|
||||||
|
argument_spec=dict(
|
||||||
|
# generalgroups
|
||||||
|
ipaadmin_principal=dict(type="str", default="admin"),
|
||||||
|
ipaadmin_password=dict(type="str", required=False, no_log=True),
|
||||||
|
|
||||||
|
name=dict(type="list", aliases=["cn"], default=None,
|
||||||
|
required=True),
|
||||||
|
# present
|
||||||
|
description=dict(required=False, type="str", default=None),
|
||||||
|
rename=dict(required=False, type="str", default=None),
|
||||||
|
|
||||||
|
# members
|
||||||
|
privilege=dict(required=False, type='list', default=None),
|
||||||
|
user=dict(required=False, type='list', default=None),
|
||||||
|
group=dict(required=False, type='list', default=None),
|
||||||
|
host=dict(required=False, type='list', default=None),
|
||||||
|
hostgroup=dict(required=False, type='list', default=None),
|
||||||
|
service=dict(required=False, type='list', default=None),
|
||||||
|
|
||||||
|
# state
|
||||||
|
action=dict(type="str", default="role",
|
||||||
|
choices=["role", "member"]),
|
||||||
|
state=dict(type="str", default="present",
|
||||||
|
choices=["present", "absent"]),
|
||||||
|
),
|
||||||
|
supports_check_mode=True,
|
||||||
|
mutually_exclusive=[],
|
||||||
|
required_one_of=[]
|
||||||
|
)
|
||||||
|
|
||||||
|
ansible_module._ansible_debug = True # pylint: disable=protected-access
|
||||||
|
|
||||||
|
return ansible_module
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Process role module script."""
|
||||||
|
ansible_module = create_module()
|
||||||
|
check_parameters(ansible_module)
|
||||||
|
|
||||||
|
# Init
|
||||||
|
ccache_dir = None
|
||||||
|
ccache_name = None
|
||||||
|
try:
|
||||||
|
ccache_dir, ccache_name = verify_credentials(ansible_module)
|
||||||
|
api_connect()
|
||||||
|
|
||||||
|
state = module_params_get(ansible_module, "state")
|
||||||
|
action = module_params_get(ansible_module, "action")
|
||||||
|
names = module_params_get(ansible_module, "name")
|
||||||
|
commands = []
|
||||||
|
|
||||||
|
for name in names:
|
||||||
|
cmds = role_commands_for_name(ansible_module, state, action, name)
|
||||||
|
commands.extend(cmds)
|
||||||
|
|
||||||
|
changed, exit_args = process_commands(ansible_module, commands)
|
||||||
|
|
||||||
|
except Exception as exception: # pylint: disable=broad-except
|
||||||
|
ansible_module.fail_json(msg=str(exception))
|
||||||
|
|
||||||
|
finally:
|
||||||
|
temp_kdestroy(ccache_dir, ccache_name)
|
||||||
|
|
||||||
|
# Done
|
||||||
|
ansible_module.exit_json(changed=changed, **exit_args)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -812,9 +812,11 @@ def main():
|
|||||||
|
|
||||||
elif state == "disabled":
|
elif state == "disabled":
|
||||||
if action == "service":
|
if action == "service":
|
||||||
if res_find is not None and \
|
if res_find is not None:
|
||||||
len(res_find.get('usercertificate', [])) > 0:
|
has_cert = bool(res_find.get('usercertificate'))
|
||||||
commands.append([name, 'service_disable', {}])
|
has_keytab = res_find.get('has_keytab', False)
|
||||||
|
if has_cert or has_keytab:
|
||||||
|
commands.append([name, 'service_disable', {}])
|
||||||
else:
|
else:
|
||||||
ansible_module.fail_json(
|
ansible_module.fail_json(
|
||||||
msg="Invalid action '%s' for state '%s'" %
|
msg="Invalid action '%s' for state '%s'" %
|
||||||
|
|||||||
@@ -958,10 +958,15 @@ def main():
|
|||||||
# commands
|
# commands
|
||||||
|
|
||||||
commands = []
|
commands = []
|
||||||
|
user_set = set()
|
||||||
|
|
||||||
for user in names:
|
for user in names:
|
||||||
if isinstance(user, dict):
|
if isinstance(user, dict):
|
||||||
name = user.get("name")
|
name = user.get("name")
|
||||||
|
if name in user_set:
|
||||||
|
ansible_module.fail_json(
|
||||||
|
msg="user '%s' is used more than once" % name)
|
||||||
|
user_set.add(name)
|
||||||
# present
|
# present
|
||||||
first = user.get("first")
|
first = user.get("first")
|
||||||
last = user.get("last")
|
last = user.get("last")
|
||||||
@@ -1370,6 +1375,8 @@ def main():
|
|||||||
else:
|
else:
|
||||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||||
|
|
||||||
|
del user_set
|
||||||
|
|
||||||
# Execute commands
|
# Execute commands
|
||||||
|
|
||||||
errors = []
|
errors = []
|
||||||
|
|||||||
@@ -69,12 +69,20 @@ options:
|
|||||||
description: password to be used on symmetric vault.
|
description: password to be used on symmetric vault.
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
aliases: ["ipavaultpassword", "vault_password"]
|
aliases: ["ipavaultpassword", "vault_password", "old_password"]
|
||||||
password_file:
|
password_file:
|
||||||
description: file with password to be used on symmetric vault.
|
description: file with password to be used on symmetric vault.
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
aliases: ["vault_password_file"]
|
aliases: ["vault_password_file", "old_password_file"]
|
||||||
|
new_password:
|
||||||
|
description: new password to be used on symmetric vault.
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
new_password_file:
|
||||||
|
description: file with new password to be used on symmetric vault.
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
salt:
|
salt:
|
||||||
description: Vault salt.
|
description: Vault salt.
|
||||||
required: false
|
required: false
|
||||||
@@ -235,7 +243,15 @@ EXAMPLES = """
|
|||||||
state: retrieved
|
state: retrieved
|
||||||
register: result
|
register: result
|
||||||
- debug:
|
- debug:
|
||||||
msg: "{{ result.data | b64decode }}"
|
msg: "{{ result.data }}"
|
||||||
|
|
||||||
|
# Change password of a symmetric vault
|
||||||
|
- ipavault:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: symvault
|
||||||
|
username: admin
|
||||||
|
old_password: SomeVAULTpassword
|
||||||
|
new_password: SomeNEWpassword
|
||||||
|
|
||||||
# Ensure vault symvault is absent
|
# Ensure vault symvault is absent
|
||||||
- ipavault:
|
- ipavault:
|
||||||
@@ -416,18 +432,29 @@ def check_parameters(module, state, action, description, username, service,
|
|||||||
shared, users, groups, services, owners, ownergroups,
|
shared, users, groups, services, owners, ownergroups,
|
||||||
ownerservices, vault_type, salt, password, password_file,
|
ownerservices, vault_type, salt, password, password_file,
|
||||||
public_key, public_key_file, private_key,
|
public_key, public_key_file, private_key,
|
||||||
private_key_file, vault_data, datafile_in, datafile_out):
|
private_key_file, vault_data, datafile_in, datafile_out,
|
||||||
|
new_password, new_password_file):
|
||||||
invalid = []
|
invalid = []
|
||||||
if state == "present":
|
if state == "present":
|
||||||
invalid = ['private_key', 'private_key_file', 'datafile_out']
|
invalid = ['private_key', 'private_key_file', 'datafile_out']
|
||||||
|
|
||||||
|
if all([password, password_file]) \
|
||||||
|
or all([new_password, new_password_file]):
|
||||||
|
module.fail_json(msg="Password specified multiple times.")
|
||||||
|
|
||||||
|
if any([new_password, new_password_file]) \
|
||||||
|
and not any([password, password_file]):
|
||||||
|
module.fail_json(
|
||||||
|
msg="Either `password` or `password_file` must be provided to "
|
||||||
|
"change symmetric vault password.")
|
||||||
|
|
||||||
if action == "member":
|
if action == "member":
|
||||||
invalid.extend(['description'])
|
invalid.extend(['description'])
|
||||||
|
|
||||||
elif state == "absent":
|
elif state == "absent":
|
||||||
invalid = ['description', 'salt', 'vault_type', 'private_key',
|
invalid = ['description', 'salt', 'vault_type', 'private_key',
|
||||||
'private_key_file', 'datafile_in', 'datafile_out',
|
'private_key_file', 'datafile_in', 'datafile_out',
|
||||||
'vault_data']
|
'vault_data', 'new_password', 'new_password_file']
|
||||||
|
|
||||||
if action == "vault":
|
if action == "vault":
|
||||||
invalid.extend(['users', 'groups', 'services', 'owners',
|
invalid.extend(['users', 'groups', 'services', 'owners',
|
||||||
@@ -437,7 +464,7 @@ def check_parameters(module, state, action, description, username, service,
|
|||||||
elif state == "retrieved":
|
elif state == "retrieved":
|
||||||
invalid = ['description', 'salt', 'datafile_in', 'users', 'groups',
|
invalid = ['description', 'salt', 'datafile_in', 'users', 'groups',
|
||||||
'owners', 'ownergroups', 'public_key', 'public_key_file',
|
'owners', 'ownergroups', 'public_key', 'public_key_file',
|
||||||
'vault_data']
|
'vault_data', 'new_password', 'new_password_file']
|
||||||
if action == 'member':
|
if action == 'member':
|
||||||
module.fail_json(
|
module.fail_json(
|
||||||
msg="State `retrieved` do not support action `member`.")
|
msg="State `retrieved` do not support action `member`.")
|
||||||
@@ -458,11 +485,17 @@ def check_parameters(module, state, action, description, username, service,
|
|||||||
def check_encryption_params(module, state, action, vault_type, salt,
|
def check_encryption_params(module, state, action, vault_type, salt,
|
||||||
password, password_file, public_key,
|
password, password_file, public_key,
|
||||||
public_key_file, private_key, private_key_file,
|
public_key_file, private_key, private_key_file,
|
||||||
vault_data, datafile_in, datafile_out, res_find):
|
vault_data, datafile_in, datafile_out,
|
||||||
|
new_password, new_password_file, res_find):
|
||||||
vault_type_invalid = []
|
vault_type_invalid = []
|
||||||
|
|
||||||
|
if res_find is not None:
|
||||||
|
vault_type = res_find['ipavaulttype']
|
||||||
|
|
||||||
if vault_type == "standard":
|
if vault_type == "standard":
|
||||||
vault_type_invalid = ['public_key', 'public_key_file', 'password',
|
vault_type_invalid = ['public_key', 'public_key_file', 'password',
|
||||||
'password_file', 'salt']
|
'password_file', 'salt', 'new_password',
|
||||||
|
'new_password_file']
|
||||||
|
|
||||||
if vault_type is None or vault_type == "symmetric":
|
if vault_type is None or vault_type == "symmetric":
|
||||||
vault_type_invalid = ['public_key', 'public_key_file',
|
vault_type_invalid = ['public_key', 'public_key_file',
|
||||||
@@ -473,8 +506,14 @@ def check_encryption_params(module, state, action, vault_type, salt,
|
|||||||
msg="Symmetric vault requires password or password_file "
|
msg="Symmetric vault requires password or password_file "
|
||||||
"to store data or change `salt`.")
|
"to store data or change `salt`.")
|
||||||
|
|
||||||
|
if any([new_password, new_password_file]) and res_find is None:
|
||||||
|
module.fail_json(
|
||||||
|
msg="Cannot modify password of inexistent vault.")
|
||||||
|
|
||||||
if vault_type == "asymmetric":
|
if vault_type == "asymmetric":
|
||||||
vault_type_invalid = ['password', 'password_file']
|
vault_type_invalid = [
|
||||||
|
'password', 'password_file', 'new_password', 'new_password_file'
|
||||||
|
]
|
||||||
if not any([public_key, public_key_file]) and res_find is None:
|
if not any([public_key, public_key_file]) and res_find is None:
|
||||||
module.fail_json(
|
module.fail_json(
|
||||||
msg="Assymmetric vault requires public_key "
|
msg="Assymmetric vault requires public_key "
|
||||||
@@ -487,6 +526,43 @@ def check_encryption_params(module, state, action, vault_type, salt,
|
|||||||
(param, vault_type or 'symmetric'))
|
(param, vault_type or 'symmetric'))
|
||||||
|
|
||||||
|
|
||||||
|
def change_password(module, res_find, password, password_file, new_password,
|
||||||
|
new_password_file):
|
||||||
|
"""
|
||||||
|
Change the password of a symmetric vault.
|
||||||
|
|
||||||
|
To change the password of a vault, it is needed to retrieve the stored
|
||||||
|
data with the current password, and store the data again, with the new
|
||||||
|
password, forcing it to override the old one.
|
||||||
|
"""
|
||||||
|
# verify parameters.
|
||||||
|
if not any([new_password, new_password_file]):
|
||||||
|
return []
|
||||||
|
if res_find["ipavaulttype"][0] != "symmetric":
|
||||||
|
module.fail_json(msg="Cannot change password of `%s` vault."
|
||||||
|
% res_find["ipavaulttype"])
|
||||||
|
|
||||||
|
# prepare arguments to retrieve data.
|
||||||
|
name = res_find["cn"][0]
|
||||||
|
args = {}
|
||||||
|
if password:
|
||||||
|
args["password"] = password
|
||||||
|
if password_file:
|
||||||
|
args["password"] = password_file
|
||||||
|
# retrieve current stored data
|
||||||
|
result = api_command(module, 'vault_retrieve', name, args)
|
||||||
|
args['data'] = result['result']['data']
|
||||||
|
|
||||||
|
# modify arguments to store data with new password.
|
||||||
|
if password:
|
||||||
|
args["password"] = new_password
|
||||||
|
if password_file:
|
||||||
|
args["password"] = new_password_file
|
||||||
|
args["override_password"] = True
|
||||||
|
# return the command to store data with the new password.
|
||||||
|
return [(name, "vault_archive", args)]
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
ansible_module = AnsibleModule(
|
ansible_module = AnsibleModule(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
@@ -533,10 +609,18 @@ def main():
|
|||||||
datafile_out=dict(type="str", required=False, default=None,
|
datafile_out=dict(type="str", required=False, default=None,
|
||||||
aliases=['out']),
|
aliases=['out']),
|
||||||
vault_password=dict(type="str", required=False, default=None,
|
vault_password=dict(type="str", required=False, default=None,
|
||||||
aliases=['ipavaultpassword', 'password'],
|
no_log=True,
|
||||||
no_log=True),
|
aliases=['ipavaultpassword', 'password',
|
||||||
|
"old_password"]),
|
||||||
vault_password_file=dict(type="str", required=False, default=None,
|
vault_password_file=dict(type="str", required=False, default=None,
|
||||||
no_log=False, aliases=['password_file']),
|
no_log=False,
|
||||||
|
aliases=[
|
||||||
|
'password_file', "old_password_file"
|
||||||
|
]),
|
||||||
|
new_password=dict(type="str", required=False, default=None,
|
||||||
|
no_log=True),
|
||||||
|
new_password_file=dict(type="str", required=False, default=None,
|
||||||
|
no_log=False),
|
||||||
# state
|
# state
|
||||||
action=dict(type="str", default="vault",
|
action=dict(type="str", default="vault",
|
||||||
choices=["vault", "data", "member"]),
|
choices=["vault", "data", "member"]),
|
||||||
@@ -546,6 +630,7 @@ def main():
|
|||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
mutually_exclusive=[['username', 'service', 'shared'],
|
mutually_exclusive=[['username', 'service', 'shared'],
|
||||||
['datafile_in', 'vault_data'],
|
['datafile_in', 'vault_data'],
|
||||||
|
['new_password', 'new_password_file'],
|
||||||
['vault_password', 'vault_password_file'],
|
['vault_password', 'vault_password_file'],
|
||||||
['vault_public_key', 'vault_public_key_file']],
|
['vault_public_key', 'vault_public_key_file']],
|
||||||
)
|
)
|
||||||
@@ -576,6 +661,8 @@ def main():
|
|||||||
salt = module_params_get(ansible_module, "vault_salt")
|
salt = module_params_get(ansible_module, "vault_salt")
|
||||||
password = module_params_get(ansible_module, "vault_password")
|
password = module_params_get(ansible_module, "vault_password")
|
||||||
password_file = module_params_get(ansible_module, "vault_password_file")
|
password_file = module_params_get(ansible_module, "vault_password_file")
|
||||||
|
new_password = module_params_get(ansible_module, "new_password")
|
||||||
|
new_password_file = module_params_get(ansible_module, "new_password_file")
|
||||||
public_key = module_params_get(ansible_module, "vault_public_key")
|
public_key = module_params_get(ansible_module, "vault_public_key")
|
||||||
public_key_file = module_params_get(ansible_module,
|
public_key_file = module_params_get(ansible_module,
|
||||||
"vault_public_key_file")
|
"vault_public_key_file")
|
||||||
@@ -614,7 +701,8 @@ def main():
|
|||||||
service, shared, users, groups, services, owners,
|
service, shared, users, groups, services, owners,
|
||||||
ownergroups, ownerservices, vault_type, salt, password,
|
ownergroups, ownerservices, vault_type, salt, password,
|
||||||
password_file, public_key, public_key_file, private_key,
|
password_file, public_key, public_key_file, private_key,
|
||||||
private_key_file, vault_data, datafile_in, datafile_out)
|
private_key_file, vault_data, datafile_in, datafile_out,
|
||||||
|
new_password, new_password_file)
|
||||||
# Init
|
# Init
|
||||||
|
|
||||||
changed = False
|
changed = False
|
||||||
@@ -660,7 +748,7 @@ def main():
|
|||||||
ansible_module, state, action, vault_type, salt, password,
|
ansible_module, state, action, vault_type, salt, password,
|
||||||
password_file, public_key, public_key_file, private_key,
|
password_file, public_key, public_key_file, private_key,
|
||||||
private_key_file, vault_data, datafile_in, datafile_out,
|
private_key_file, vault_data, datafile_in, datafile_out,
|
||||||
res_find)
|
new_password, new_password_file, res_find)
|
||||||
|
|
||||||
# Found the vault
|
# Found the vault
|
||||||
if action == "vault":
|
if action == "vault":
|
||||||
@@ -721,7 +809,6 @@ def main():
|
|||||||
owner_add_args = gen_member_args(
|
owner_add_args = gen_member_args(
|
||||||
args, owner_add, ownergroups_add, ownerservice_add)
|
args, owner_add, ownergroups_add, ownerservice_add)
|
||||||
if owner_add_args is not None:
|
if owner_add_args is not None:
|
||||||
# ansible_module.warn("OWNER ADD: %s" % owner_add_args)
|
|
||||||
commands.append(
|
commands.append(
|
||||||
[name, 'vault_add_owner', owner_add_args])
|
[name, 'vault_add_owner', owner_add_args])
|
||||||
|
|
||||||
@@ -729,7 +816,6 @@ def main():
|
|||||||
owner_del_args = gen_member_args(
|
owner_del_args = gen_member_args(
|
||||||
args, owner_del, ownergroups_del, ownerservice_del)
|
args, owner_del, ownergroups_del, ownerservice_del)
|
||||||
if owner_del_args is not None:
|
if owner_del_args is not None:
|
||||||
# ansible_module.warn("OWNER DEL: %s" % owner_del_args)
|
|
||||||
commands.append(
|
commands.append(
|
||||||
[name, 'vault_remove_owner', owner_del_args])
|
[name, 'vault_remove_owner', owner_del_args])
|
||||||
|
|
||||||
@@ -758,19 +844,22 @@ def main():
|
|||||||
if any([vault_data, datafile_in]):
|
if any([vault_data, datafile_in]):
|
||||||
commands.append([name, "vault_archive", pwdargs])
|
commands.append([name, "vault_archive", pwdargs])
|
||||||
|
|
||||||
|
cmds = change_password(
|
||||||
|
ansible_module, res_find, password, password_file,
|
||||||
|
new_password, new_password_file)
|
||||||
|
commands.extend(cmds)
|
||||||
|
|
||||||
elif state == "retrieved":
|
elif state == "retrieved":
|
||||||
if res_find is None:
|
if res_find is None:
|
||||||
ansible_module.fail_json(
|
ansible_module.fail_json(
|
||||||
msg="Vault `%s` not found to retrieve data." % name)
|
msg="Vault `%s` not found to retrieve data." % name)
|
||||||
|
|
||||||
vault_type = res_find['cn']
|
|
||||||
|
|
||||||
# verify data encription args
|
# verify data encription args
|
||||||
check_encryption_params(
|
check_encryption_params(
|
||||||
ansible_module, state, action, vault_type, salt, password,
|
ansible_module, state, action, vault_type, salt, password,
|
||||||
password_file, public_key, public_key_file, private_key,
|
password_file, public_key, public_key_file, private_key,
|
||||||
private_key_file, vault_data, datafile_in, datafile_out,
|
private_key_file, vault_data, datafile_in, datafile_out,
|
||||||
res_find)
|
new_password, new_password_file, res_find)
|
||||||
|
|
||||||
pwdargs = data_storage_args(
|
pwdargs = data_storage_args(
|
||||||
args, vault_data, password, password_file, private_key,
|
args, vault_data, password, password_file, private_key,
|
||||||
@@ -813,7 +902,6 @@ def main():
|
|||||||
errors = []
|
errors = []
|
||||||
for name, command, args in commands:
|
for name, command, args in commands:
|
||||||
try:
|
try:
|
||||||
# ansible_module.warn("RUN: %s %s %s" % (command, name, args))
|
|
||||||
result = api_command(ansible_module, command, name, args)
|
result = api_command(ansible_module, command, name, args)
|
||||||
|
|
||||||
if command == 'vault_archive':
|
if command == 'vault_archive':
|
||||||
@@ -829,7 +917,6 @@ def main():
|
|||||||
raise Exception("No data retrieved.")
|
raise Exception("No data retrieved.")
|
||||||
changed = False
|
changed = False
|
||||||
else:
|
else:
|
||||||
# ansible_module.warn("RESULT: %s" % (result))
|
|
||||||
if "completed" in result:
|
if "completed" in result:
|
||||||
if result["completed"] > 0:
|
if result["completed"] > 0:
|
||||||
changed = True
|
changed = True
|
||||||
|
|||||||
@@ -164,7 +164,8 @@ class ActionModule(ActionBase):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
data = self._execute_module(module_name='ipaclient_get_facts',
|
data = self._execute_module(module_name='ipaclient_get_facts',
|
||||||
module_args=dict(), task_vars=None)
|
module_args=dict(), task_vars=task_vars)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
domain = data['ansible_facts']['ipa']['domain']
|
domain = data['ansible_facts']['ipa']['domain']
|
||||||
realm = data['ansible_facts']['ipa']['realm']
|
realm = data['ansible_facts']['ipa']['realm']
|
||||||
@@ -245,4 +246,3 @@ class ActionModule(ActionBase):
|
|||||||
finally:
|
finally:
|
||||||
# delete the local temp directory
|
# delete the local temp directory
|
||||||
shutil.rmtree(local_temp_dir, ignore_errors=True)
|
shutil.rmtree(local_temp_dir, ignore_errors=True)
|
||||||
run_cmd(['/usr/bin/kdestroy', '-c', tmp_ccache])
|
|
||||||
|
|||||||
@@ -134,7 +134,6 @@
|
|||||||
"Password cannot be set on enrolled host" not
|
"Password cannot be set on enrolled host" not
|
||||||
in result_ipaclient_get_otp.msg
|
in result_ipaclient_get_otp.msg
|
||||||
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
||||||
delegate_facts: yes
|
|
||||||
ignore_errors: yes
|
ignore_errors: yes
|
||||||
|
|
||||||
- name: Install - Report error for OTP generation
|
- name: Install - Report error for OTP generation
|
||||||
|
|||||||
1
roles/ipaclient/vars/OracleLinux-7.yml
Symbolic link
1
roles/ipaclient/vars/OracleLinux-7.yml
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
RedHat-7.yml
|
||||||
1
roles/ipaclient/vars/OracleLinux-8.yml
Symbolic link
1
roles/ipaclient/vars/OracleLinux-8.yml
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
RedHat-8.yml
|
||||||
@@ -95,7 +95,7 @@ ipareplica1.example.com
|
|||||||
ipareplica2.example.com
|
ipareplica2.example.com
|
||||||
|
|
||||||
[ipareplicas:vars]
|
[ipareplicas:vars]
|
||||||
ipaclient_domain=example.com
|
ipareplica_domain=example.com
|
||||||
ipaadmin_principal=admin
|
ipaadmin_principal=admin
|
||||||
ipaadmin_password=MySecretPassword123
|
ipaadmin_password=MySecretPassword123
|
||||||
ipadm_password=MySecretPassword456
|
ipadm_password=MySecretPassword456
|
||||||
|
|||||||
@@ -262,6 +262,7 @@ def main():
|
|||||||
config.subject_base = options.subject_base
|
config.subject_base = options.subject_base
|
||||||
config.dirman_password = dirman_password
|
config.dirman_password = dirman_password
|
||||||
config.ca_host_name = ca_host_name
|
config.ca_host_name = ca_host_name
|
||||||
|
config.setup_ca = options.setup_ca
|
||||||
|
|
||||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||||
installer._remote_api = remote_api
|
installer._remote_api = remote_api
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ def main():
|
|||||||
config = gen_ReplicaConfig()
|
config = gen_ReplicaConfig()
|
||||||
config.dirman_password = dirman_password
|
config.dirman_password = dirman_password
|
||||||
config.subject_base = options.subject_base
|
config.subject_base = options.subject_base
|
||||||
|
config.master_host_name = master_host_name
|
||||||
|
|
||||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||||
|
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ def main():
|
|||||||
config = gen_ReplicaConfig()
|
config = gen_ReplicaConfig()
|
||||||
config.dirman_password = dirman_password
|
config.dirman_password = dirman_password
|
||||||
config.subject_base = options.subject_base
|
config.subject_base = options.subject_base
|
||||||
|
config.master_host_name = master_host_name
|
||||||
|
|
||||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||||
# installer._remote_api = remote_api
|
# installer._remote_api = remote_api
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ def main():
|
|||||||
# additional
|
# additional
|
||||||
ccache=dict(required=True),
|
ccache=dict(required=True),
|
||||||
_top_dir=dict(required=True),
|
_top_dir=dict(required=True),
|
||||||
setup_ca=dict(required=True),
|
setup_ca=dict(required=True, type='bool'),
|
||||||
config_master_host_name=dict(required=True),
|
config_master_host_name=dict(required=True),
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
|
|||||||
@@ -169,6 +169,7 @@ def main():
|
|||||||
config.promote = installer.promote
|
config.promote = installer.promote
|
||||||
config.kra_enabled = kra_enabled
|
config.kra_enabled = kra_enabled
|
||||||
config.kra_host_name = kra_host_name
|
config.kra_host_name = kra_host_name
|
||||||
|
config.setup_ca = options.setup_ca
|
||||||
|
|
||||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ def main():
|
|||||||
config.subject_base = options.subject_base
|
config.subject_base = options.subject_base
|
||||||
config.dirman_password = dirman_password
|
config.dirman_password = dirman_password
|
||||||
config.setup_ca = options.setup_ca
|
config.setup_ca = options.setup_ca
|
||||||
# config.master_host_name = master_host_name
|
config.master_host_name = master_host_name
|
||||||
config.ca_host_name = ca_host_name
|
config.ca_host_name = ca_host_name
|
||||||
config.promote = installer.promote
|
config.promote = installer.promote
|
||||||
|
|
||||||
|
|||||||
@@ -120,6 +120,9 @@ options:
|
|||||||
_subject_base:
|
_subject_base:
|
||||||
description: The installer _subject_base setting
|
description: The installer _subject_base setting
|
||||||
required: no
|
required: no
|
||||||
|
dirman_password:
|
||||||
|
description: Directory Manager (master) password
|
||||||
|
required: no
|
||||||
author:
|
author:
|
||||||
- Thomas Woerner
|
- Thomas Woerner
|
||||||
'''
|
'''
|
||||||
@@ -173,10 +176,12 @@ def main():
|
|||||||
_ca_enabled=dict(required=False, type='bool'),
|
_ca_enabled=dict(required=False, type='bool'),
|
||||||
_kra_enabled=dict(required=False, type='bool'),
|
_kra_enabled=dict(required=False, type='bool'),
|
||||||
_kra_host_name=dict(required=False),
|
_kra_host_name=dict(required=False),
|
||||||
|
_ca_host_name=dict(required=False),
|
||||||
_top_dir=dict(required=True),
|
_top_dir=dict(required=True),
|
||||||
_add_to_ipaservers=dict(required=True, type='bool'),
|
_add_to_ipaservers=dict(required=True, type='bool'),
|
||||||
_ca_subject=dict(required=True),
|
_ca_subject=dict(required=True),
|
||||||
_subject_base=dict(required=True),
|
_subject_base=dict(required=True),
|
||||||
|
dirman_password=dict(required=True, no_log=True),
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
@@ -233,6 +238,7 @@ def main():
|
|||||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||||
kra_enabled = ansible_module.params.get('_kra_enabled')
|
kra_enabled = ansible_module.params.get('_kra_enabled')
|
||||||
kra_host_name = ansible_module.params.get('_kra_host_name')
|
kra_host_name = ansible_module.params.get('_kra_host_name')
|
||||||
|
ca_host_name = ansible_module.params.get('_ca_host_name')
|
||||||
|
|
||||||
options.subject_base = ansible_module.params.get('subject_base')
|
options.subject_base = ansible_module.params.get('subject_base')
|
||||||
if options.subject_base is not None:
|
if options.subject_base is not None:
|
||||||
@@ -243,6 +249,7 @@ def main():
|
|||||||
|
|
||||||
options._ca_subject = ansible_module.params.get('_ca_subject')
|
options._ca_subject = ansible_module.params.get('_ca_subject')
|
||||||
options._subject_base = ansible_module.params.get('_subject_base')
|
options._subject_base = ansible_module.params.get('_subject_base')
|
||||||
|
dirman_password = ansible_module.params.get('dirman_password')
|
||||||
|
|
||||||
# init #
|
# init #
|
||||||
|
|
||||||
@@ -254,14 +261,25 @@ def main():
|
|||||||
constants.DEFAULT_CONFIG)
|
constants.DEFAULT_CONFIG)
|
||||||
api_bootstrap_finalize(env)
|
api_bootstrap_finalize(env)
|
||||||
config = gen_ReplicaConfig()
|
config = gen_ReplicaConfig()
|
||||||
|
config.dirman_password = dirman_password
|
||||||
config.subject_base = options.subject_base
|
config.subject_base = options.subject_base
|
||||||
config.promote = installer.promote
|
config.promote = installer.promote
|
||||||
config.kra_enabled = kra_enabled
|
config.kra_enabled = kra_enabled
|
||||||
config.kra_host_name = kra_host_name
|
config.kra_host_name = kra_host_name
|
||||||
|
config.ca_host_name = ca_host_name
|
||||||
|
config.master_host_name = master_host_name
|
||||||
|
|
||||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||||
installer._remote_api = remote_api
|
installer._remote_api = remote_api
|
||||||
|
|
||||||
|
conn = remote_api.Backend.ldap2
|
||||||
|
ccache = os.environ['KRB5CCNAME']
|
||||||
|
|
||||||
|
# There is a api.Backend.ldap2.connect call somewhere in ca, ds, dns or
|
||||||
|
# ntpinstance
|
||||||
|
api.Backend.ldap2.connect()
|
||||||
|
conn.connect(ccache=ccache)
|
||||||
|
|
||||||
with redirect_stdout(ansible_log):
|
with redirect_stdout(ansible_log):
|
||||||
ansible_log.debug("-- INSTALL KRA --")
|
ansible_log.debug("-- INSTALL KRA --")
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ options:
|
|||||||
_top_dir:
|
_top_dir:
|
||||||
description: The installer _top_dir setting
|
description: The installer _top_dir setting
|
||||||
required: no
|
required: no
|
||||||
|
dirman_password:
|
||||||
|
description: Directory Manager (master) password
|
||||||
|
required: no
|
||||||
author:
|
author:
|
||||||
- Thomas Woerner
|
- Thomas Woerner
|
||||||
'''
|
'''
|
||||||
@@ -98,6 +101,7 @@ def main():
|
|||||||
ccache=dict(required=True),
|
ccache=dict(required=True),
|
||||||
_pkinit_pkcs12_info=dict(required=False, type='list'),
|
_pkinit_pkcs12_info=dict(required=False, type='list'),
|
||||||
_top_dir=dict(required=True),
|
_top_dir=dict(required=True),
|
||||||
|
dirman_password=dict(required=True, no_log=True),
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
@@ -126,6 +130,7 @@ def main():
|
|||||||
'_pkinit_pkcs12_info')
|
'_pkinit_pkcs12_info')
|
||||||
|
|
||||||
options._top_dir = ansible_module.params.get('_top_dir')
|
options._top_dir = ansible_module.params.get('_top_dir')
|
||||||
|
dirman_password = ansible_module.params.get('dirman_password')
|
||||||
|
|
||||||
# init #
|
# init #
|
||||||
|
|
||||||
@@ -141,8 +146,10 @@ def main():
|
|||||||
constants.DEFAULT_CONFIG)
|
constants.DEFAULT_CONFIG)
|
||||||
api_bootstrap_finalize(env)
|
api_bootstrap_finalize(env)
|
||||||
config = gen_ReplicaConfig()
|
config = gen_ReplicaConfig()
|
||||||
|
config.dirman_password = dirman_password
|
||||||
config.master_host_name = config_master_host_name
|
config.master_host_name = config_master_host_name
|
||||||
config.subject_base = options.subject_base
|
config.subject_base = options.subject_base
|
||||||
|
config.setup_ca = options.setup_ca
|
||||||
|
|
||||||
ccache = os.environ['KRB5CCNAME']
|
ccache = os.environ['KRB5CCNAME']
|
||||||
|
|
||||||
|
|||||||
@@ -226,6 +226,8 @@
|
|||||||
setup_adtrust: "{{ result_ipareplica_test.setup_adtrust }}"
|
setup_adtrust: "{{ result_ipareplica_test.setup_adtrust }}"
|
||||||
setup_kra: "{{ result_ipareplica_test.setup_kra }}"
|
setup_kra: "{{ result_ipareplica_test.setup_kra }}"
|
||||||
setup_dns: "{{ ipareplica_setup_dns }}"
|
setup_dns: "{{ ipareplica_setup_dns }}"
|
||||||
|
### server ###
|
||||||
|
setup_ca: "{{ ipareplica_setup_ca }}"
|
||||||
### ssl certificate ###
|
### ssl certificate ###
|
||||||
dirsrv_cert_files: "{{ ipareplica_dirsrv_cert_files | default([]) }}"
|
dirsrv_cert_files: "{{ ipareplica_dirsrv_cert_files | default([]) }}"
|
||||||
### client ###
|
### client ###
|
||||||
@@ -281,7 +283,7 @@
|
|||||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||||
installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}"
|
installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}"
|
||||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||||
_dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info }}"
|
_dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info if result_ipareplica_prepare._dirsrv_pkcs12_info != None else omit }}"
|
||||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||||
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
|
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
|
||||||
@@ -332,6 +334,7 @@
|
|||||||
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
||||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||||
|
setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||||
|
|
||||||
- name: Install - Setup KRB
|
- name: Install - Setup KRB
|
||||||
ipareplica_setup_krb:
|
ipareplica_setup_krb:
|
||||||
@@ -345,8 +348,9 @@
|
|||||||
config_master_host_name:
|
config_master_host_name:
|
||||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
|
||||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||||
|
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||||
|
|
||||||
# We need to point to the master in ipa default conf when certmonger
|
# We need to point to the master in ipa default conf when certmonger
|
||||||
# asks for HTTP certificate in newer ipa versions. In these versions
|
# asks for HTTP certificate in newer ipa versions. In these versions
|
||||||
@@ -388,6 +392,7 @@
|
|||||||
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
||||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||||
|
setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||||
master:
|
master:
|
||||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||||
when: result_ipareplica_test.change_master_for_certmonger
|
when: result_ipareplica_test.change_master_for_certmonger
|
||||||
@@ -407,8 +412,8 @@
|
|||||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||||
_dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info }}"
|
_dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info if result_ipareplica_prepare._dirsrv_pkcs12_info != None else omit }}"
|
||||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
|
||||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||||
ds_ca_subject: "{{ result_ipareplica_setup_ds.ds_ca_subject }}"
|
ds_ca_subject: "{{ result_ipareplica_setup_ds.ds_ca_subject }}"
|
||||||
@@ -429,7 +434,7 @@
|
|||||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||||
_http_pkcs12_info: "{{ result_ipareplica_prepare._http_pkcs12_info }}"
|
_http_pkcs12_info: "{{ result_ipareplica_prepare._http_pkcs12_info if result_ipareplica_prepare._http_pkcs12_info != None else omit }}"
|
||||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||||
|
|
||||||
@@ -471,6 +476,7 @@
|
|||||||
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
||||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||||
|
setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||||
when: result_ipareplica_test.change_master_for_certmonger
|
when: result_ipareplica_test.change_master_for_certmonger
|
||||||
|
|
||||||
- name: Install - Setup otpd
|
- name: Install - Setup otpd
|
||||||
@@ -507,7 +513,7 @@
|
|||||||
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
||||||
_kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}"
|
_kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}"
|
||||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
|
||||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||||
|
|
||||||
@@ -529,7 +535,7 @@
|
|||||||
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
||||||
_kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}"
|
_kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}"
|
||||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
|
||||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||||
config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||||
@@ -554,7 +560,7 @@
|
|||||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
|
||||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||||
|
|
||||||
@@ -574,7 +580,7 @@
|
|||||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
|
||||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||||
ds_ca_subject: "{{ result_ipareplica_setup_ds.ds_ca_subject }}"
|
ds_ca_subject: "{{ result_ipareplica_setup_ds.ds_ca_subject }}"
|
||||||
@@ -611,10 +617,12 @@
|
|||||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||||
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
||||||
_kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}"
|
_kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}"
|
||||||
|
_ca_host_name: "{{ result_ipareplica_prepare.config_ca_host_name }}"
|
||||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||||
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
|
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
|
||||||
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
||||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||||
|
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||||
when: result_ipareplica_test.setup_kra
|
when: result_ipareplica_test.setup_kra
|
||||||
|
|
||||||
- name: Install - Restart KDC
|
- name: Install - Restart KDC
|
||||||
|
|||||||
1
roles/ipareplica/vars/OracleLinux-7.yml
Symbolic link
1
roles/ipareplica/vars/OracleLinux-7.yml
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
RedHat-7.yml
|
||||||
1
roles/ipareplica/vars/OracleLinux-8.yml
Symbolic link
1
roles/ipareplica/vars/OracleLinux-8.yml
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
RedHat-8.yml
|
||||||
@@ -203,7 +203,7 @@
|
|||||||
# no_host_dns: "{{ result_ipaserver_test.no_host_dns }}"
|
# no_host_dns: "{{ result_ipaserver_test.no_host_dns }}"
|
||||||
dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}"
|
dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}"
|
||||||
dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default(omit) }}"
|
dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default(omit) }}"
|
||||||
_dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info }}"
|
_dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info if result_ipaserver_test._dirsrv_pkcs12_info != None else omit }}"
|
||||||
external_cert_files:
|
external_cert_files:
|
||||||
"{{ ipaserver_external_cert_files | default(omit) }}"
|
"{{ ipaserver_external_cert_files | default(omit) }}"
|
||||||
subject_base: "{{ result_ipaserver_prepare.subject_base }}"
|
subject_base: "{{ result_ipaserver_prepare.subject_base }}"
|
||||||
@@ -240,7 +240,7 @@
|
|||||||
no_hbac_allow: "{{ ipaserver_no_hbac_allow }}"
|
no_hbac_allow: "{{ ipaserver_no_hbac_allow }}"
|
||||||
idstart: "{{ result_ipaserver_test.idstart }}"
|
idstart: "{{ result_ipaserver_test.idstart }}"
|
||||||
idmax: "{{ result_ipaserver_test.idmax }}"
|
idmax: "{{ result_ipaserver_test.idmax }}"
|
||||||
_pkinit_pkcs12_info: "{{ result_ipaserver_test._pkinit_pkcs12_info }}"
|
_pkinit_pkcs12_info: "{{ result_ipaserver_test._pkinit_pkcs12_info if result_ipaserver_test._pkinit_pkcs12_info != None else omit }}"
|
||||||
|
|
||||||
- name: Install - Setup custodia
|
- name: Install - Setup custodia
|
||||||
ipaserver_setup_custodia:
|
ipaserver_setup_custodia:
|
||||||
@@ -270,7 +270,7 @@
|
|||||||
no_pkinit: "{{ result_ipaserver_test.no_pkinit }}"
|
no_pkinit: "{{ result_ipaserver_test.no_pkinit }}"
|
||||||
dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}"
|
dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}"
|
||||||
dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}"
|
dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}"
|
||||||
_dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info }}"
|
_dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info if result_ipaserver_test._dirsrv_pkcs12_info != None else omit }}"
|
||||||
external_ca: "{{ ipaserver_external_ca }}"
|
external_ca: "{{ ipaserver_external_ca }}"
|
||||||
external_ca_type: "{{ ipaserver_external_ca_type | default(omit) }}"
|
external_ca_type: "{{ ipaserver_external_ca_type | default(omit) }}"
|
||||||
external_ca_profile:
|
external_ca_profile:
|
||||||
@@ -334,7 +334,7 @@
|
|||||||
idmax: "{{ result_ipaserver_test.idmax }}"
|
idmax: "{{ result_ipaserver_test.idmax }}"
|
||||||
http_cert_files: "{{ ipaserver_http_cert_files | default([]) }}"
|
http_cert_files: "{{ ipaserver_http_cert_files | default([]) }}"
|
||||||
no_ui_redirect: "{{ ipaserver_no_ui_redirect }}"
|
no_ui_redirect: "{{ ipaserver_no_ui_redirect }}"
|
||||||
_http_pkcs12_info: "{{ result_ipaserver_test._http_pkcs12_info }}"
|
_http_pkcs12_info: "{{ result_ipaserver_test._http_pkcs12_info if result_ipaserver_test._http_pkcs12_info != None else omit }}"
|
||||||
|
|
||||||
- name: Install - Setup KRA
|
- name: Install - Setup KRA
|
||||||
ipaserver_setup_kra:
|
ipaserver_setup_kra:
|
||||||
@@ -394,7 +394,7 @@
|
|||||||
idstart: "{{ result_ipaserver_test.idstart }}"
|
idstart: "{{ result_ipaserver_test.idstart }}"
|
||||||
idmax: "{{ result_ipaserver_test.idmax }}"
|
idmax: "{{ result_ipaserver_test.idmax }}"
|
||||||
dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}"
|
dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}"
|
||||||
_dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info }}"
|
_dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info if result_ipaserver_test._dirsrv_pkcs12_info != None else omit }}"
|
||||||
|
|
||||||
- name: Install - Setup client
|
- name: Install - Setup client
|
||||||
include_role:
|
include_role:
|
||||||
|
|||||||
1
roles/ipaserver/vars/OracleLinux-7.yml
Symbolic link
1
roles/ipaserver/vars/OracleLinux-7.yml
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
RedHat-7.yml
|
||||||
1
roles/ipaserver/vars/OracleLinux-8.yml
Symbolic link
1
roles/ipaserver/vars/OracleLinux-8.yml
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
RedHat-8.yml
|
||||||
@@ -5,19 +5,21 @@
|
|||||||
gather_facts: false
|
gather_facts: false
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: ensure forwardzone example.com is absent - prep
|
- name: ensure test forwardzones are absent
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: example.com
|
name:
|
||||||
|
- example.com
|
||||||
|
- newfailzone.com
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: ensure forwardzone example.com is created
|
- name: ensure forwardzone example.com is created
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
state: present
|
state: present
|
||||||
name: example.com
|
name: example.com
|
||||||
forwarders:
|
forwarders:
|
||||||
- 8.8.8.8
|
- ip_address: 8.8.8.8
|
||||||
forwardpolicy: first
|
forwardpolicy: first
|
||||||
skip_overlap_check: true
|
skip_overlap_check: true
|
||||||
register: result
|
register: result
|
||||||
@@ -25,11 +27,11 @@
|
|||||||
|
|
||||||
- name: ensure forwardzone example.com is present again
|
- name: ensure forwardzone example.com is present again
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
state: present
|
state: present
|
||||||
name: example.com
|
name: example.com
|
||||||
forwarders:
|
forwarders:
|
||||||
- 8.8.8.8
|
- ip_address: 8.8.8.8
|
||||||
forwardpolicy: first
|
forwardpolicy: first
|
||||||
skip_overlap_check: true
|
skip_overlap_check: true
|
||||||
register: result
|
register: result
|
||||||
@@ -37,12 +39,13 @@
|
|||||||
|
|
||||||
- name: ensure forwardzone example.com has two forwarders
|
- name: ensure forwardzone example.com has two forwarders
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
state: present
|
state: present
|
||||||
name: example.com
|
name: example.com
|
||||||
forwarders:
|
forwarders:
|
||||||
- 8.8.8.8
|
- ip_address: 8.8.8.8
|
||||||
- 4.4.4.4
|
- ip_address: 4.4.4.4
|
||||||
|
port: 8053
|
||||||
forwardpolicy: first
|
forwardpolicy: first
|
||||||
skip_overlap_check: true
|
skip_overlap_check: true
|
||||||
register: result
|
register: result
|
||||||
@@ -50,165 +53,246 @@
|
|||||||
|
|
||||||
- name: ensure forwardzone example.com has one forwarder again
|
- name: ensure forwardzone example.com has one forwarder again
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: example.com
|
name: example.com
|
||||||
forwarders:
|
forwarders:
|
||||||
- 8.8.8.8
|
- ip_address: 8.8.8.8
|
||||||
forwardpolicy: first
|
forwardpolicy: first
|
||||||
skip_overlap_check: true
|
skip_overlap_check: true
|
||||||
state: present
|
state: present
|
||||||
register: result
|
register: result
|
||||||
failed_when: not result.changed
|
failed_when: result.changed
|
||||||
|
|
||||||
- name: skip_overlap_check can only be set on creation so change nothing
|
- name: skip_overlap_check can only be set on creation so change nothing
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: example.com
|
name: example.com
|
||||||
forwarders:
|
forwarders:
|
||||||
- 8.8.8.8
|
- ip_address: 8.8.8.8
|
||||||
forwardpolicy: first
|
forwardpolicy: first
|
||||||
skip_overlap_check: false
|
skip_overlap_check: false
|
||||||
state: present
|
state: present
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.changed
|
failed_when: result.changed
|
||||||
|
|
||||||
- name: change all the things at once
|
- name: ensure forwardzone example.com is absent.
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
state: present
|
|
||||||
name: example.com
|
name: example.com
|
||||||
forwarders:
|
state: absent
|
||||||
- 8.8.8.8
|
|
||||||
- 4.4.4.4
|
|
||||||
forwardpolicy: only
|
|
||||||
skip_overlap_check: false
|
|
||||||
register: result
|
register: result
|
||||||
failed_when: not result.changed
|
failed_when: not result.changed
|
||||||
|
|
||||||
- name: ensure forwardzone example.com is absent for next testset
|
- name: ensure forwardzone example.com is absent, again.
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: example.com
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: change all the things at once
|
||||||
|
ipadnsforwardzone:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
state: present
|
||||||
|
name: example.com
|
||||||
|
forwarders:
|
||||||
|
- ip_address: 8.8.8.8
|
||||||
|
- ip_address: 4.4.4.4
|
||||||
|
port: 8053
|
||||||
|
forwardpolicy: only
|
||||||
|
skip_overlap_check: true
|
||||||
|
permission: yes
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: change zone forward policy
|
||||||
|
ipadnsforwardzone:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: example.com
|
||||||
|
forwardpolicy: first
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: change zone forward policy, again
|
||||||
|
ipadnsforwardzone:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: example.com
|
||||||
|
forwardpolicy: first
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: ensure forwardzone example.com is absent.
|
||||||
|
ipadnsforwardzone:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: example.com
|
name: example.com
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: ensure forwardzone example.com is created with minimal args
|
- name: ensure forwardzone example.com is created with minimal args
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
state: present
|
state: present
|
||||||
name: example.com
|
name: example.com
|
||||||
skip_overlap_check: true
|
skip_overlap_check: true
|
||||||
forwarders:
|
forwarders:
|
||||||
- 8.8.8.8
|
- ip_address: 8.8.8.8
|
||||||
register: result
|
register: result
|
||||||
failed_when: not result.changed
|
failed_when: not result.changed
|
||||||
|
|
||||||
- name: add a forwarder to any existing ones
|
- name: add a forwarder to any existing ones
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
state: present
|
state: present
|
||||||
name: example.com
|
name: example.com
|
||||||
forwarders:
|
forwarders:
|
||||||
- 4.4.4.4
|
- ip_address: 4.4.4.4
|
||||||
|
port: 8053
|
||||||
action: member
|
action: member
|
||||||
register: result
|
register: result
|
||||||
failed_when: not result.changed
|
failed_when: not result.changed
|
||||||
|
|
||||||
- name: check the list of forwarders is what we expect
|
- name: check the list of forwarders is what we expect
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
state: present
|
state: present
|
||||||
name: example.com
|
name: example.com
|
||||||
forwarders:
|
forwarders:
|
||||||
- 4.4.4.4
|
- ip_address: 4.4.4.4
|
||||||
- 8.8.8.8
|
port: 8053
|
||||||
|
- ip_address: 8.8.8.8
|
||||||
action: member
|
action: member
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.changed
|
failed_when: result.changed
|
||||||
|
|
||||||
- name: remove a single forwarder
|
- name: remove a single forwarder
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
state: absent
|
state: absent
|
||||||
name: example.com
|
name: example.com
|
||||||
forwarders:
|
forwarders:
|
||||||
- 8.8.8.8
|
- ip_address: 8.8.8.8
|
||||||
action: member
|
action: member
|
||||||
register: result
|
register: result
|
||||||
failed_when: not result.changed
|
failed_when: not result.changed
|
||||||
|
|
||||||
- name: check the list of forwarders is what we expect now
|
- name: check the list of forwarders is what we expect now
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
state: present
|
state: present
|
||||||
name: example.com
|
name: example.com
|
||||||
forwarders:
|
forwarders:
|
||||||
- 4.4.4.4
|
- ip_address: 4.4.4.4
|
||||||
|
port: 8053
|
||||||
action: member
|
action: member
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.changed
|
failed_when: result.changed
|
||||||
|
|
||||||
- name: ensure forwardzone example.com is absent again
|
- name: Add a permission for per-forward zone access delegation.
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: example.com
|
name: example.com
|
||||||
state: absent
|
permission: yes
|
||||||
|
|
||||||
- name: try to create a new forwarder with action=member
|
|
||||||
ipadnsforwardzone:
|
|
||||||
ipaadmin_password: password01
|
|
||||||
state: present
|
|
||||||
name: example.com
|
|
||||||
forwarders:
|
|
||||||
- 4.4.4.4
|
|
||||||
action: member
|
action: member
|
||||||
skip_overlap_check: true
|
|
||||||
register: result
|
|
||||||
failed_when: result.changed
|
|
||||||
|
|
||||||
- name: ensure forwardzone example.com is absent - tidy up
|
|
||||||
ipadnsforwardzone:
|
|
||||||
ipaadmin_password: password01
|
|
||||||
name: example.com
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
- name: try to create a new forwarder is disabled state
|
|
||||||
ipadnsforwardzone:
|
|
||||||
ipaadmin_password: password01
|
|
||||||
state: disabled
|
|
||||||
name: example.com
|
|
||||||
forwarders:
|
|
||||||
- 4.4.4.4
|
|
||||||
skip_overlap_check: true
|
|
||||||
register: result
|
register: result
|
||||||
failed_when: not result.changed
|
failed_when: not result.changed
|
||||||
|
|
||||||
- name: enable the forwarder
|
- name: Add a permission for per-forward zone access delegation, again.
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: example.com
|
name: example.com
|
||||||
state: enabled
|
permission: yes
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Remove a permission for per-forward zone access delegation.
|
||||||
|
ipadnsforwardzone:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: example.com
|
||||||
|
permission: no
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Remove a permission for per-forward zone access delegation, again.
|
||||||
|
ipadnsforwardzone:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: example.com
|
||||||
|
permission: no
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: disable the forwarder
|
||||||
|
ipadnsforwardzone:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: example.com
|
||||||
|
state: disabled
|
||||||
register: result
|
register: result
|
||||||
failed_when: not result.changed
|
failed_when: not result.changed
|
||||||
|
|
||||||
- name: disable the forwarder again
|
- name: disable the forwarder again
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: example.com
|
|
||||||
state: disabled
|
|
||||||
action: member
|
|
||||||
register: result
|
|
||||||
failed_when: not result.changed
|
|
||||||
|
|
||||||
- name: ensure it stays disabled
|
|
||||||
ipadnsforwardzone:
|
|
||||||
ipaadmin_password: password01
|
|
||||||
name: example.com
|
name: example.com
|
||||||
state: disabled
|
state: disabled
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.changed
|
failed_when: result.changed
|
||||||
|
|
||||||
- name: ensure forwardzone example.com is absent - tidy up
|
- name: enable the forwarder
|
||||||
ipadnsforwardzone:
|
ipadnsforwardzone:
|
||||||
ipaadmin_password: password01
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: example.com
|
||||||
|
state: enabled
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: enable the forwarder, again
|
||||||
|
ipadnsforwardzone:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: example.com
|
||||||
|
state: enabled
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: ensure forwardzone example.com is absent again
|
||||||
|
ipadnsforwardzone:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: example.com
|
name: example.com
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
|
- name: try to create a new forwarder with action=member
|
||||||
|
ipadnsforwardzone:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
state: present
|
||||||
|
name: example.com
|
||||||
|
forwarders:
|
||||||
|
- ip_address: 4.4.4.4
|
||||||
|
port: 8053
|
||||||
|
action: member
|
||||||
|
skip_overlap_check: true
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "not found" not in result.msg
|
||||||
|
|
||||||
|
- name: try to create a new forwarder with disabled state
|
||||||
|
ipadnsforwardzone:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: example.com
|
||||||
|
state: disabled
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "not found" not in result.msg
|
||||||
|
|
||||||
|
- name: Ensure forwardzone is not added without forwarders, with correct message.
|
||||||
|
ipadnsforwardzone:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: newfailzone.com
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "No forwarders specified" not in result.msg
|
||||||
|
|
||||||
|
- name: ensure forwardzone example.com is absent - tidy up
|
||||||
|
ipadnsforwardzone:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name:
|
||||||
|
- example.com
|
||||||
|
- newfailzone.com
|
||||||
|
state: absent
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ if [ -z "$master" ]; then
|
|||||||
exit 0;
|
exit 0;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PASSWORD="SomeCApassword"
|
PASSWORD="SomeCApassword.123"
|
||||||
DBDIR="${master}-nssdb"
|
DBDIR="${master}-nssdb"
|
||||||
PWDFILE="$DBDIR/pwdfile.txt"
|
PWDFILE="$DBDIR/pwdfile.txt"
|
||||||
NOISE="$DBDIR/noise.txt"
|
NOISE="$DBDIR/noise.txt"
|
||||||
|
|||||||
133
tests/group/test_group_external_nonposix.yml
Normal file
133
tests/group/test_group_external_nonposix.yml
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
---
|
||||||
|
- name: Test group
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: yes
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Remove testing groups.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name:
|
||||||
|
- extgroup
|
||||||
|
- nonposixgroup
|
||||||
|
- posixgroup
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Add nonposix group.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: extgroup
|
||||||
|
nonposix: yes
|
||||||
|
register: result
|
||||||
|
failed_when: result.failed or not result.changed
|
||||||
|
|
||||||
|
- name: Add nonposix group, again.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: extgroup
|
||||||
|
nonposix: yes
|
||||||
|
register: result
|
||||||
|
failed_when: result.failed or result.changed
|
||||||
|
|
||||||
|
- name: Set group to be external
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: extgroup
|
||||||
|
external: yes
|
||||||
|
register: result
|
||||||
|
failed_when: result.failed or not result.changed
|
||||||
|
|
||||||
|
- name: Set group to be external, again.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: extgroup
|
||||||
|
external: yes
|
||||||
|
register: result
|
||||||
|
failed_when: result.failed or result.changed
|
||||||
|
|
||||||
|
- name: Set external group to be non-external.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: extgroup
|
||||||
|
external: no
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "Cannot change `external` status of group" not in result.msg
|
||||||
|
|
||||||
|
- name: Set external group to be posix.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: extgroup
|
||||||
|
posix: yes
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "Cannot change `external` status of group" not in result.msg
|
||||||
|
|
||||||
|
- name: Add nonposix group.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: posixgroup
|
||||||
|
nonposix: yes
|
||||||
|
register: result
|
||||||
|
failed_when: result.failed or not result.changed
|
||||||
|
|
||||||
|
- name: Set group to be posix
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: posixgroup
|
||||||
|
posix: yes
|
||||||
|
register: result
|
||||||
|
failed_when: result.failed or not result.changed
|
||||||
|
|
||||||
|
- name: Set group to be posix, again.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: posixgroup
|
||||||
|
posix: yes
|
||||||
|
register: result
|
||||||
|
failed_when: result.failed or result.changed
|
||||||
|
|
||||||
|
- name: Set posix group to be external.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: posixgroup
|
||||||
|
external: yes
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "Cannot change `POSIX` status of a group" not in result.msg
|
||||||
|
|
||||||
|
- name: Set posix group to be non-POSIX.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: posixgroup
|
||||||
|
posix: no
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "Cannot change `POSIX` status of a group" not in result.msg
|
||||||
|
|
||||||
|
- name: Set posix group to be non-POSIX.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: posixgroup
|
||||||
|
nonposix: yes
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "Cannot change `POSIX` status of a group" not in result.msg
|
||||||
|
|
||||||
|
- name: Add nonposix group.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: nonposixgroup
|
||||||
|
posix: no
|
||||||
|
register: result
|
||||||
|
failed_when: result.failed or not result.changed
|
||||||
|
|
||||||
|
- name: Add nonposix group, again.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: nonposixgroup
|
||||||
|
nonposix: yes
|
||||||
|
register: result
|
||||||
|
failed_when: result.failed or result.changed
|
||||||
|
|
||||||
|
- name: Remove testing groups.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: extgroup,nonposixgroup,posixgroup
|
||||||
|
state: absent
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
- name: Ensure user manangeruser1 and manageruser2 is absent
|
- name: Ensure user manangeruser1 and manageruser2 is absent
|
||||||
ipauser:
|
ipauser:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: manageruser1,manageruser2
|
name: manageruser1,manageruser2,unknown_user
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Ensure group testgroup, managergroup1 and managergroup2 are absent
|
- name: Ensure group testgroup, managergroup1 and managergroup2 are absent
|
||||||
@@ -185,6 +185,15 @@
|
|||||||
register: result
|
register: result
|
||||||
failed_when: not result.changed
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure unknown membermanager_user member failure
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testgroup
|
||||||
|
membermanager_user: unknown_user
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed or "no such entry" not in result.msg
|
||||||
|
|
||||||
- name: Ensure group testgroup, managergroup1 and managergroup2 are absent
|
- name: Ensure group testgroup, managergroup1 and managergroup2 are absent
|
||||||
ipagroup:
|
ipagroup:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
|||||||
@@ -96,3 +96,18 @@
|
|||||||
state: absent
|
state: absent
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.changed
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Duplicate names in hosts failure test
|
||||||
|
ipahost:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
hosts:
|
||||||
|
- name: "{{ host1_fqdn }}"
|
||||||
|
force: yes
|
||||||
|
- name: "{{ host2_fqdn }}"
|
||||||
|
force: yes
|
||||||
|
- name: "{{ host3_fqdn }}"
|
||||||
|
force: yes
|
||||||
|
- name: "{{ host3_fqdn }}"
|
||||||
|
force: yes
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed or "is used more than once" not in result.msg
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
- name: Ensure user manangeruser1 and manageruser2 is absent
|
- name: Ensure user manangeruser1 and manageruser2 is absent
|
||||||
ipauser:
|
ipauser:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: manageruser1,manageruser2
|
name: manageruser1,manageruser2,unknown_user
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Ensure group managergroup1 and managergroup2 are absent
|
- name: Ensure group managergroup1 and managergroup2 are absent
|
||||||
@@ -200,6 +200,15 @@
|
|||||||
register: result
|
register: result
|
||||||
failed_when: not result.changed
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure unknown membermanager_user member failure
|
||||||
|
ipahostgroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testhostgroup
|
||||||
|
membermanager_user: unknown_user
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed or "no such entry" not in result.msg
|
||||||
|
|
||||||
- name: Ensure host-group testhostgroup is absent
|
- name: Ensure host-group testhostgroup is absent
|
||||||
ipahostgroup:
|
ipahostgroup:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
|||||||
38
tests/role/env_cleanup.yml
Normal file
38
tests/role/env_cleanup.yml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
- name: Ensure test user is absent.
|
||||||
|
ipauser:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: user01
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Ensure test group is absent.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: group01
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Ensure test hostgroup is absent.
|
||||||
|
ipahostgroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: hostgroup01
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Ensure test host is absent.
|
||||||
|
ipahost:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: "{{ host1_fqdn }}"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Ensure test service is absent.
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: "service01/{{ host1_fqdn }}"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Ensure test roles are absent.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name:
|
||||||
|
- renamerole
|
||||||
|
- testrole
|
||||||
|
state: absent
|
||||||
14
tests/role/env_facts.yml
Normal file
14
tests/role/env_facts.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- name: Get Domain from server name
|
||||||
|
set_fact:
|
||||||
|
ipaserver_domain: "{{ ansible_fqdn | join ('.') }}"
|
||||||
|
when: ipaserver_domain is not defined
|
||||||
|
|
||||||
|
- name: Set fact for realm name
|
||||||
|
set_fact:
|
||||||
|
ipaserver_realm: "{{ ipaserver_domain }} | upper"
|
||||||
|
when: ipaserver_domain is not defined
|
||||||
|
|
||||||
|
- name: Create FQDN for host01
|
||||||
|
set_fact:
|
||||||
|
host1_fqdn: "host01.{{ ipaserver_domain }}"
|
||||||
34
tests/role/env_setup.yml
Normal file
34
tests/role/env_setup.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
- name: Cleanup environment.
|
||||||
|
import_tasks: env_cleanup.yml
|
||||||
|
|
||||||
|
- name: Ensure test user is present.
|
||||||
|
ipauser:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: user01
|
||||||
|
first: First
|
||||||
|
last: Last
|
||||||
|
|
||||||
|
- name: Ensure test group is present.
|
||||||
|
ipagroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: group01
|
||||||
|
|
||||||
|
- name: Ensure test host is present.
|
||||||
|
ipahost:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: "{{ host1_fqdn }}"
|
||||||
|
force: yes
|
||||||
|
|
||||||
|
- name: Ensure test hostgroup is present.
|
||||||
|
ipahostgroup:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: hostgroup01
|
||||||
|
host:
|
||||||
|
- "{{ host1_fqdn }}"
|
||||||
|
|
||||||
|
- name: Ensure test service is present.
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: "service01/{{ host1_fqdn }}"
|
||||||
|
force: yes
|
||||||
388
tests/role/test_role.yml
Normal file
388
tests/role/test_role.yml
Normal file
@@ -0,0 +1,388 @@
|
|||||||
|
---
|
||||||
|
- name: Test role module
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: yes
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Set environment facts.
|
||||||
|
import_tasks: env_facts.yml
|
||||||
|
|
||||||
|
- name: Setup environment.
|
||||||
|
import_tasks: env_setup.yml
|
||||||
|
|
||||||
|
# tests
|
||||||
|
- name: Ensure role is present.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: renamerole
|
||||||
|
description: A role in IPA.
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role is present, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: renamerole
|
||||||
|
description: A role in IPA.
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Rename role.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: renamerole
|
||||||
|
rename: testrole
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Rename role, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: renamerole
|
||||||
|
rename: testrole
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member has privileges.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
privilege:
|
||||||
|
- DNS Servers
|
||||||
|
- Host Administrators
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member has privileges, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
privilege:
|
||||||
|
- DNS Servers
|
||||||
|
- Host Administrators
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has less privileges.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
privilege:
|
||||||
|
- Host Administrators
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has less privileges, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
privilege:
|
||||||
|
- Host Administrators
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member has privileges restored.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
privilege:
|
||||||
|
- DNS Servers
|
||||||
|
- Host Administrators
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member has privileges restored, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
privilege:
|
||||||
|
- DNS Servers
|
||||||
|
- Host Administrators
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role member privileges are absent.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
privilege:
|
||||||
|
- DNS Servers
|
||||||
|
- Host Administrators
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role member privileges are absent, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
privilege:
|
||||||
|
- DNS Servers
|
||||||
|
- Host Administrators
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure invalid privileged is not assigned to role.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
privilege: Invalid Privilege
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "privilege not found" not in result.msg
|
||||||
|
|
||||||
|
- name: Ensure role has member user present.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
user:
|
||||||
|
- user01
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member user present, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
user:
|
||||||
|
- user01
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member user absent.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
user:
|
||||||
|
- user01
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member user absent, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
user:
|
||||||
|
- user01
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member group present.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
group:
|
||||||
|
- group01
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member group present, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
group:
|
||||||
|
- group01
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member group absent.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
group:
|
||||||
|
- group01
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member group absent, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
group:
|
||||||
|
- group01
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member host present.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
host:
|
||||||
|
- "{{ host1_fqdn }}"
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member host present, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
host:
|
||||||
|
- "{{ host1_fqdn }}"
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member host absent.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
host:
|
||||||
|
- "{{ host1_fqdn }}"
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member host absent, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
host:
|
||||||
|
- "{{ host1_fqdn }}"
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member hostgroup present.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
hostgroup:
|
||||||
|
- hostgroup01
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member hostgroup present, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
hostgroup:
|
||||||
|
- hostgroup01
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member hostgroup absent.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
hostgroup:
|
||||||
|
- hostgroup01
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member hostgroup absent, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
hostgroup:
|
||||||
|
- hostgroup01
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role is absent.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role is absent, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role with members is present.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
user:
|
||||||
|
- user01
|
||||||
|
group:
|
||||||
|
- group01
|
||||||
|
host:
|
||||||
|
- "{{ host1_fqdn }}"
|
||||||
|
hostgroup:
|
||||||
|
- hostgroup01
|
||||||
|
privilege:
|
||||||
|
- Group Administrators
|
||||||
|
- User Administrators
|
||||||
|
service:
|
||||||
|
- "service01/{{ host1_fqdn }}"
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role with members is present, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
user:
|
||||||
|
- user01
|
||||||
|
group:
|
||||||
|
- group01
|
||||||
|
host:
|
||||||
|
- "{{ host1_fqdn }}"
|
||||||
|
hostgroup:
|
||||||
|
- hostgroup01
|
||||||
|
privilege:
|
||||||
|
- Group Administrators
|
||||||
|
- User Administrators
|
||||||
|
service:
|
||||||
|
- "service01/{{ host1_fqdn }}"
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role is absent.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role is absent, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
- name: Cleanup environment.
|
||||||
|
include_tasks: env_cleanup.yml
|
||||||
95
tests/role/test_role_service_member.yml
Normal file
95
tests/role/test_role_service_member.yml
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
---
|
||||||
|
- name: Test service member in role module.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: yes
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Set environment facts.
|
||||||
|
import_tasks: env_facts.yml
|
||||||
|
|
||||||
|
- name: Setup environment.
|
||||||
|
import_tasks: env_setup.yml
|
||||||
|
|
||||||
|
# tests
|
||||||
|
|
||||||
|
- name: Ensure role with member service is present.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
service:
|
||||||
|
- "service01/{{ host1_fqdn }}"
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role with member service is present, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
service:
|
||||||
|
- "service01/{{ host1_fqdn }}"
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member service absent.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
service:
|
||||||
|
- "service01/{{ host1_fqdn }}"
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member service absent, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
service:
|
||||||
|
- "service01/{{ host1_fqdn }}"
|
||||||
|
action: member
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member service with principal name.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
service:
|
||||||
|
- "service01/{{ host1_fqdn }}@{{ ipaserver_realm }}"
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role has member service with principal name, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
service:
|
||||||
|
- "service01/{{ host1_fqdn }}@{{ ipaserver_realm }}"
|
||||||
|
action: member
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Ensure role is absent.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Ensure role is absent, again.
|
||||||
|
iparole:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: testrole
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
- name: Cleanup environment.
|
||||||
|
include_tasks: env_cleanup.yml
|
||||||
83
tests/service/test_service_disable.yml
Normal file
83
tests/service/test_service_disable.yml
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# Due to not having some Ansible modules for IPA, some tasks are executed
|
||||||
|
# in this playbook using the `shell` module, as a Kerberos tikcket is needed
|
||||||
|
# for these tasks.
|
||||||
|
# The Kerberos cache is cleaned in the end, so you might need to `kinit` on
|
||||||
|
# the testing target after running this playbook.
|
||||||
|
---
|
||||||
|
- name: Playbook to manage IPA service.
|
||||||
|
hosts: ipaserver
|
||||||
|
become: yes
|
||||||
|
gather_facts: yes
|
||||||
|
|
||||||
|
environment:
|
||||||
|
KRB5CCNAME: test_service_disable_ccache
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Get Kerberos ticket for `admin`.
|
||||||
|
shell: echo SomeADMINpassword | kinit -c ${KRB5CCNAME} admin
|
||||||
|
|
||||||
|
- name: Ensure service is absent
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: "mysvc1/{{ ansible_fqdn }}"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Ensure service is present
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: "mysvc1/{{ ansible_fqdn }}"
|
||||||
|
certificate:
|
||||||
|
- MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpHVkcDfVnNInE1Y/pFciegdzqTjMwUWlRL4Zt3u96GhaMLRbtk+OfEkzLUAhWBOwEraELJzMLJOMvjYF3C+TiGO7dStFLikZmccuSsSIXjnzIPwBXa8KvgRVRyGLoVvGbLJvmjfMXp0nIToTx/i74KF9S++WEes9H5ErJ99CDhLKFgq0amnvsgparYXhypHaRLnikn0vQINt55YoEd1s4KrvEcD2VdZkIMPbLRu2zFvMprF3cjQQG4LT9ggfEXNIPZ1nQWAnAsu7OJEkNF+E4Mkmpcxj9aGUVt5bsq1D+Tzj3GsidSX0nSNcZ2JltXRnL/5v63g5cZyE+nAgMBAAGjUzBRMB0GA1UdDgQWBBRV0j7JYukuH/r/t9+QeNlRLXDlEDAfBgNVHSMEGDAWgBRV0j7JYukuH/r/t9+QeNlRLXDlEDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCgVy1+1kNwHs5y1Zp0WjMWGCJC6/zw7FDG4OW5r2GJiCXZYdJ0UonY9ZtoVLJPrp2/DAv1m5DtnDhBYqicuPgLzEkOS1KdTi20Otm/J4yxLLrZC5W4x0XOeSVPXOJuQWfwQ5pPvKkn6WxYUYkGwIt1OH2nSMngkbami3CbSmKZOCpgQIiSlQeDJ8oGjWFMLDymYSHoVOIXHwNoooyEiaio3693l6noobyGv49zyCVLVR1DC7i6RJ186ql0av+D4vPoiF5mX7+sKC2E8xEj9uKQ5GTWRh59VnRBVC/SiMJ/H78tJnBAvoBwXxSEvj8Z3Kjm/BQqZfv4IBsA5yqV7MVq
|
||||||
|
force: no
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Obtain keytab
|
||||||
|
shell: ipa-getkeytab -s "{{ ansible_fqdn }}" -p "mysvc1/{{ ansible_fqdn }}" -k mysvc1.keytab
|
||||||
|
|
||||||
|
- name: Verify keytab
|
||||||
|
shell: ipa service-find "mysvc1/{{ ansible_fqdn }}"
|
||||||
|
register: result
|
||||||
|
failed_when: result.failed or result.stdout | regex_search(" Keytab. true")
|
||||||
|
|
||||||
|
- name: Ensure service is disabled
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: "mysvc1/{{ ansible_fqdn }}"
|
||||||
|
state: disabled
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Verify keytab
|
||||||
|
shell: ipa service-find "mysvc1/{{ ansible_fqdn }}"
|
||||||
|
register: result
|
||||||
|
failed_when: result.failed or result.stdout | regex_search(" Keytab. true")
|
||||||
|
|
||||||
|
- name: Obtain keytab
|
||||||
|
shell: ipa-getkeytab -s "{{ ansible_fqdn }}" -p "mysvc1/{{ ansible_fqdn }}" -k mysvc1.keytab
|
||||||
|
|
||||||
|
- name: Verify keytab
|
||||||
|
shell: ipa service-find "mysvc1/{{ ansible_fqdn }}"
|
||||||
|
register: result
|
||||||
|
failed_when: result.failed or result.stdout | regex_search(" Keytab. true")
|
||||||
|
|
||||||
|
- name: Ensure service is disabled
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: "mysvc1/{{ ansible_fqdn }}"
|
||||||
|
state: disabled
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Verify keytab
|
||||||
|
shell: ipa service-find "mysvc1/{{ ansible_fqdn }}"
|
||||||
|
register: result
|
||||||
|
failed_when: result.failed or result.stdout | regex_search(" Keytab. true")
|
||||||
|
|
||||||
|
- name: Ensure service is absent
|
||||||
|
ipaservice:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: "mysvc1/{{ ansible_fqdn }}"
|
||||||
|
|
||||||
|
- name: Destroy Kerberos tickets.
|
||||||
|
shell: kdestroy -A -q -c ${KRB5CCNAME}
|
||||||
@@ -85,6 +85,25 @@
|
|||||||
register: result
|
register: result
|
||||||
failed_when: result.changed
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Duplicate names in users failure test
|
||||||
|
ipauser:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
users:
|
||||||
|
- name: user1
|
||||||
|
givenname: user1
|
||||||
|
last: Last
|
||||||
|
- name: user2
|
||||||
|
first: user2
|
||||||
|
last: Last
|
||||||
|
- name: user3
|
||||||
|
first: user3
|
||||||
|
last: Last
|
||||||
|
- name: user3
|
||||||
|
first: user3
|
||||||
|
last: Last
|
||||||
|
register: result
|
||||||
|
failed_when: result.changed or "is used more than once" not in result.msg
|
||||||
|
|
||||||
- name: Remove test users
|
- name: Remove test users
|
||||||
ipauser:
|
ipauser:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
|||||||
@@ -178,6 +178,61 @@
|
|||||||
register: result
|
register: result
|
||||||
failed_when: result.data != 'Hello World.' or result.changed
|
failed_when: result.data != 'Hello World.' or result.changed
|
||||||
|
|
||||||
|
- name: Change vault password.
|
||||||
|
ipavault:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: symvault
|
||||||
|
password: SomeVAULTpassword
|
||||||
|
new_password: SomeNEWpassword
|
||||||
|
register: result
|
||||||
|
failed_when: not result.changed
|
||||||
|
|
||||||
|
- name: Retrieve data from symmetric vault, with wrong password.
|
||||||
|
ipavault:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: symvault
|
||||||
|
password: SomeVAULTpassword
|
||||||
|
state: retrieved
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "Invalid credentials" not in result.msg
|
||||||
|
|
||||||
|
- name: Change vault password, with wrong `old_password`.
|
||||||
|
ipavault:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: symvault
|
||||||
|
password: SomeVAULTpassword
|
||||||
|
new_password: SomeNEWpassword
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "Invalid credentials" not in result.msg
|
||||||
|
|
||||||
|
- name: Retrieve data from symmetric vault, with new password.
|
||||||
|
ipavault:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: symvault
|
||||||
|
password: SomeNEWpassword
|
||||||
|
state: retrieved
|
||||||
|
register: result
|
||||||
|
failed_when: result.data != 'Hello World.' or result.changed
|
||||||
|
|
||||||
|
- name: Try to add vault with multiple passwords.
|
||||||
|
ipavault:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: inexistentvault
|
||||||
|
password: SomeVAULTpassword
|
||||||
|
password_file: "{{ ansible_env.HOME }}/password.txt"
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "parameters are mutually exclusive" not in result.msg
|
||||||
|
|
||||||
|
- name: Try to add vault with multiple new passwords.
|
||||||
|
ipavault:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: inexistentvault
|
||||||
|
password: SomeVAULTpassword
|
||||||
|
new_password: SomeVAULTpassword
|
||||||
|
new_password_file: "{{ ansible_env.HOME }}/password.txt"
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "parameters are mutually exclusive" not in result.msg
|
||||||
|
|
||||||
- name: Ensure symmetric vault is absent
|
- name: Ensure symmetric vault is absent
|
||||||
ipavault:
|
ipavault:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
@@ -194,5 +249,14 @@
|
|||||||
register: result
|
register: result
|
||||||
failed_when: result.changed
|
failed_when: result.changed
|
||||||
|
|
||||||
|
- name: Try to change password of inexistent vault.
|
||||||
|
ipavault:
|
||||||
|
ipaadmin_password: SomeADMINpassword
|
||||||
|
name: inexistentvault
|
||||||
|
password: SomeVAULTpassword
|
||||||
|
new_password: SomeNEWpassword
|
||||||
|
register: result
|
||||||
|
failed_when: not result.failed or "Cannot modify password of inexistent vault" not in result.msg
|
||||||
|
|
||||||
- name: Cleanup testing environment.
|
- name: Cleanup testing environment.
|
||||||
import_tasks: env_cleanup.yml
|
import_tasks: env_cleanup.yml
|
||||||
|
|||||||
Reference in New Issue
Block a user