mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-05-13 21:12:02 +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:
|
||||
- name: ensure presence of forwardzone for DNS requests for example.com to 8.8.8.8
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
state: present
|
||||
name: example.com
|
||||
forwarders:
|
||||
@@ -59,13 +59,13 @@ Example playbook to ensure presence of a forwardzone to ipa DNS:
|
||||
|
||||
- name: ensure the forward zone is disabled
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: example.com
|
||||
state: disabled
|
||||
|
||||
- name: ensure presence of multiple upstream DNS servers for example.com
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
state: present
|
||||
name: example.com
|
||||
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
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
state: present
|
||||
name: example.com
|
||||
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)
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: example.com
|
||||
state: absent
|
||||
```
|
||||
@@ -99,9 +99,12 @@ 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` | Zone name (FQDN). | yes if `state` == `present`
|
||||
`forwarders` \| `idnsforwarders` | Per-zone conditional forwarding policy. Possible values are `only`, `first`, `none`) | 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
|
||||
`forwarders` \| `idnsforwarders` | Per-zone forwarders. A custom port can be specified for each forwarder. Options | no
|
||||
| `ip_address`: The forwarder IP address. | yes
|
||||
| `port`: The forwarder IP port. | no
|
||||
`forwardpolicy` \| `idnsforwardpolicy` | Per-zone conditional forwarding policy. Possible values are `only`, `first`, `none`. Set to "none" to disable forwarding to global forwarder for this zone. In that case, conditional zone forwarders are disregarded. | no
|
||||
`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
|
||||
`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
|
||||
`description` | The group description string. | 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
|
||||
`external` | Allow adding external non-IPA members from trusted domains. (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
|
||||
`sshpubkey` \| `ipasshpubkey` | List of SSH public keys | 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
|
||||
`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
|
||||
|
||||
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
|
||||
`certificate` \| `usercertificate` | Base-64 encoded service certificate. | no
|
||||
`pac_type` \| `ipakrbauthzdata` | Supported PAC type. It can be one of `MS-PAC`, `PAD`, or `NONE`. | no
|
||||
`auth_ind` \| `krbprincipalauthind` | Defines 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
|
||||
`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
|
||||
|
||||
@@ -165,6 +165,22 @@ Example playbook to make sure vault data is absent in a symmetric vault:
|
||||
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:
|
||||
|
||||
```yaml
|
||||
@@ -197,8 +213,11 @@ Variable | Description | Required
|
||||
`name` \| `cn` | The list of vault name strings. | yes
|
||||
`description` | The vault description string. | no
|
||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||
`password ` \| `vault_password` \| `ipavaultpassword` | Vault password. | no
|
||||
`public_key ` \| `vault_public_key` \| `ipavaultpublickey` | Base64 encoded vault public key. | no
|
||||
`password` \| `vault_password` \| `ipavaultpassword` \| `old_password`| Vault password. | 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
|
||||
`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
|
||||
|
||||
@@ -21,6 +21,7 @@ Features
|
||||
* Modules for host management
|
||||
* Modules for hostgroup management
|
||||
* Modules for pwpolicy management
|
||||
* Modules for role management
|
||||
* Modules for service management
|
||||
* Modules for sudocmd management
|
||||
* Modules for sudocmdgroup management
|
||||
@@ -421,6 +422,7 @@ Modules in plugin/modules
|
||||
* [ipahost](README-host.md)
|
||||
* [ipahostgroup](README-hostgroup.md)
|
||||
* [ipapwpolicy](README-pwpolicy.md)
|
||||
* [iparole](README-role.md)
|
||||
* [ipaservice](README-service.md)
|
||||
* [ipasudocmd](README-sudocmd.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
|
||||
name: symvault
|
||||
password: SomeVAULTpassword
|
||||
- name: Change vault passord.
|
||||
- name: Change vault password.
|
||||
ipavault:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: symvault
|
||||
|
||||
@@ -54,9 +54,16 @@ options:
|
||||
forwarders:
|
||||
description:
|
||||
- List of the DNS servers to forward to
|
||||
required: true
|
||||
type: list
|
||||
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:
|
||||
description: Per-zone conditional forwarding policy
|
||||
required: false
|
||||
@@ -68,6 +75,11 @@ options:
|
||||
- Force DNS zone creation even if it will overlap with an existing zone.
|
||||
required: false
|
||||
default: false
|
||||
permission:
|
||||
description:
|
||||
- Allow DNS Forward Zone to be managed.
|
||||
required: false
|
||||
type: bool
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -128,20 +140,41 @@ def gen_args(forwarders, forwardpolicy, skip_overlap_check):
|
||||
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():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
ipaadmin_principal=dict(type="str", default="admin"),
|
||||
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),
|
||||
forwarders=dict(type='list', aliases=["idnsforwarders"],
|
||||
required=False),
|
||||
forwarders=dict(type="list", default=None, 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"],
|
||||
required=False,
|
||||
choices=['only', 'first', 'none']),
|
||||
skip_overlap_check=dict(type='bool', required=False),
|
||||
permission=dict(type='bool', required=False,
|
||||
aliases=['managedby']),
|
||||
action=dict(type="str", default="dnsforwardzone",
|
||||
choices=["member", "dnsforwardzone"]),
|
||||
# state
|
||||
@@ -158,14 +191,22 @@ def main():
|
||||
"ipaadmin_principal")
|
||||
ipaadmin_password = module_params_get(ansible_module,
|
||||
"ipaadmin_password")
|
||||
name = module_params_get(ansible_module, "name")
|
||||
names = module_params_get(ansible_module, "name")
|
||||
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")
|
||||
skip_overlap_check = module_params_get(ansible_module,
|
||||
"skip_overlap_check")
|
||||
permission = module_params_get(ansible_module, "permission")
|
||||
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
|
||||
# if action is member then update an exisiting resource
|
||||
# and if action is not member then create a resource
|
||||
@@ -176,18 +217,30 @@ def main():
|
||||
else:
|
||||
operation = "add"
|
||||
|
||||
if state == "disabled":
|
||||
wants_enable = False
|
||||
else:
|
||||
wants_enable = True
|
||||
|
||||
if operation == "del":
|
||||
invalid = ["forwarders", "forwardpolicy", "skip_overlap_check"]
|
||||
if state in ["enabled", "disabled"]:
|
||||
if action == "member":
|
||||
ansible_module.fail_json(
|
||||
msg="Action `member` cannot be used with state `%s`"
|
||||
% (state))
|
||||
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'" % (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
|
||||
exit_args = {}
|
||||
@@ -207,99 +260,116 @@ def main():
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
|
||||
# Make sure forwardzone exists
|
||||
existing_resource = find_dnsforwardzone(ansible_module, name)
|
||||
|
||||
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
|
||||
for name in names:
|
||||
commands = []
|
||||
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
|
||||
if not compare_args_ipa(ansible_module, args, existing_resource):
|
||||
command = "dnsforwardzone_mod"
|
||||
else:
|
||||
command = None
|
||||
# Make sure forwardzone exists
|
||||
existing_resource = find_dnsforwardzone(ansible_module, name)
|
||||
|
||||
# enabled or disabled?
|
||||
is_enabled = existing_resource["idnszoneactive"][0]
|
||||
# validate parameters
|
||||
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":
|
||||
# does not exist but should be present
|
||||
# determine args
|
||||
args = gen_args(forwarders, forwardpolicy,
|
||||
skip_overlap_check)
|
||||
# set command
|
||||
command = "dnsforwardzone_add"
|
||||
# enabled or disabled?
|
||||
is_enabled = "TRUE"
|
||||
if existing_resource is None:
|
||||
if operation == "add":
|
||||
# does not exist but should be present
|
||||
# determine args
|
||||
args = gen_args(forwarders, forwardpolicy,
|
||||
skip_overlap_check)
|
||||
# set command
|
||||
command = "dnsforwardzone_add"
|
||||
# enabled or disabled?
|
||||
|
||||
elif existing_resource is not None and operation == "add":
|
||||
# exists and should be present, has it changed?
|
||||
# determine args
|
||||
args = gen_args(forwarders, forwardpolicy, skip_overlap_check)
|
||||
if skip_overlap_check is not None:
|
||||
del args['skip_overlap_check']
|
||||
elif 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' not found." % (name))
|
||||
|
||||
# set command
|
||||
if not compare_args_ipa(ansible_module, args, existing_resource):
|
||||
command = "dnsforwardzone_mod"
|
||||
else:
|
||||
command = None
|
||||
elif operation == "del":
|
||||
# there's nothnig to do.
|
||||
continue
|
||||
|
||||
# enabled or disabled?
|
||||
is_enabled = existing_resource["idnszoneactive"][0]
|
||||
else: # existing_resource is not None
|
||||
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 command is not None:
|
||||
api_command(ansible_module, command, name, args)
|
||||
changed = True
|
||||
if operation == "add":
|
||||
# exists and should be present, has it changed?
|
||||
# determine args
|
||||
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)
|
||||
if is_enabled != "IGNORE":
|
||||
if wants_enable and is_enabled != "TRUE":
|
||||
api_command(ansible_module, "dnsforwardzone_enable",
|
||||
name, {})
|
||||
changed = True
|
||||
elif not wants_enable and is_enabled != "FALSE":
|
||||
api_command(ansible_module, "dnsforwardzone_disable",
|
||||
name, {})
|
||||
# set command
|
||||
if not compare_args_ipa(
|
||||
ansible_module, args, existing_resource):
|
||||
command = "dnsforwardzone_mod"
|
||||
|
||||
elif operation == "del":
|
||||
# exists but should be absent
|
||||
# set command
|
||||
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
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -57,6 +57,11 @@ options:
|
||||
description: Allow adding external non-IPA members from trusted domains
|
||||
required: false
|
||||
type: bool
|
||||
posix:
|
||||
description:
|
||||
Create a non-POSIX group or change a non-POSIX to a posix group.
|
||||
required: false
|
||||
type: bool
|
||||
nomembers:
|
||||
description: Suppress processing of membership attributes
|
||||
required: false
|
||||
@@ -140,10 +145,23 @@ EXAMPLES = """
|
||||
- sysops
|
||||
- appops
|
||||
|
||||
# Remove goups sysops, appops and ops
|
||||
|
||||
# Create a non-POSIX group
|
||||
- ipagroup:
|
||||
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
|
||||
"""
|
||||
|
||||
@@ -173,16 +191,12 @@ def find_group(module, name):
|
||||
return None
|
||||
|
||||
|
||||
def gen_args(description, gid, nonposix, external, nomembers):
|
||||
def gen_args(description, gid, nomembers):
|
||||
_args = {}
|
||||
if description is not None:
|
||||
_args["description"] = description
|
||||
if gid is not None:
|
||||
_args["gidnumber"] = gid
|
||||
if nonposix is not None:
|
||||
_args["nonposix"] = nonposix
|
||||
if external is not None:
|
||||
_args["external"] = external
|
||||
if nomembers is not None:
|
||||
_args["nomembers"] = nomembers
|
||||
|
||||
@@ -201,6 +215,41 @@ def gen_member_args(user, group, service):
|
||||
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():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
@@ -215,6 +264,7 @@ def main():
|
||||
gid=dict(type="int", aliases=["gidnumber"], default=None),
|
||||
nonposix=dict(required=False, type='bool', default=None),
|
||||
external=dict(required=False, type='bool', default=None),
|
||||
posix=dict(required=False, type='bool', default=None),
|
||||
nomembers=dict(required=False, type='bool', default=None),
|
||||
user=dict(required=False, type='list', default=None),
|
||||
group=dict(required=False, type='list', default=None),
|
||||
@@ -228,6 +278,7 @@ def main():
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
),
|
||||
mutually_exclusive=[['posix', 'nonposix']],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
@@ -248,6 +299,7 @@ def main():
|
||||
gid = module_params_get(ansible_module, "gid")
|
||||
nonposix = module_params_get(ansible_module, "nonposix")
|
||||
external = module_params_get(ansible_module, "external")
|
||||
posix = module_params_get(ansible_module, "posix")
|
||||
nomembers = module_params_get(ansible_module, "nomembers")
|
||||
user = module_params_get(ansible_module, "user")
|
||||
group = module_params_get(ansible_module, "group")
|
||||
@@ -267,7 +319,7 @@ def main():
|
||||
ansible_module.fail_json(
|
||||
msg="Only one group can be added at a time.")
|
||||
if action == "member":
|
||||
invalid = ["description", "gid", "nonposix", "external",
|
||||
invalid = ["description", "gid", "posix", "nonposix", "external",
|
||||
"nomembers"]
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
@@ -279,7 +331,8 @@ def main():
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(
|
||||
msg="No name given.")
|
||||
invalid = ["description", "gid", "nonposix", "external", "nomembers"]
|
||||
invalid = ["description", "gid", "posix", "nonposix", "external",
|
||||
"nomembers"]
|
||||
if action == "group":
|
||||
invalid.extend(["user", "group", "service"])
|
||||
for x in invalid:
|
||||
@@ -322,9 +375,12 @@ def main():
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
# Can't change an existing posix group
|
||||
check_objectclass_args(ansible_module, res_find, nonposix,
|
||||
posix, external)
|
||||
|
||||
# Generate args
|
||||
args = gen_args(description, gid, nonposix, external,
|
||||
nomembers)
|
||||
args = gen_args(description, gid, nomembers)
|
||||
|
||||
if action == "group":
|
||||
# Found the group
|
||||
@@ -332,10 +388,21 @@ def main():
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
if not compare_args_ipa(ansible_module, args,
|
||||
res_find):
|
||||
if should_modify_group(ansible_module, res_find, args,
|
||||
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])
|
||||
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])
|
||||
# Set res_find to empty dict for next step
|
||||
res_find = {}
|
||||
@@ -507,16 +574,15 @@ def main():
|
||||
# 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))
|
||||
for failed_item in result.get("failed", []):
|
||||
failed = result["failed"][failed_item]
|
||||
for member_type in failed:
|
||||
for member, failure in failed[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))
|
||||
if len(errors) > 0:
|
||||
ansible_module.fail_json(msg=", ".join(errors))
|
||||
|
||||
|
||||
@@ -799,10 +799,15 @@ def main():
|
||||
server_realm = api_get_realm()
|
||||
|
||||
commands = []
|
||||
host_set = set()
|
||||
|
||||
for host in names:
|
||||
if isinstance(host, dict):
|
||||
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")
|
||||
locality = host.get("locality")
|
||||
location = host.get("location")
|
||||
@@ -1337,6 +1342,8 @@ def main():
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
del host_set
|
||||
|
||||
# Execute commands
|
||||
|
||||
errors = []
|
||||
|
||||
@@ -423,14 +423,15 @@ def main():
|
||||
# All "already a member" and "not a member" failures in the
|
||||
# result are ignored. All others are reported.
|
||||
errors = []
|
||||
if "failed" in result and "member" in result["failed"]:
|
||||
failed = result["failed"]["member"]
|
||||
for failed_item in result.get("failed", []):
|
||||
failed = result["failed"][failed_item]
|
||||
for member_type in failed:
|
||||
for member, failure in failed[member_type]:
|
||||
if "already a member" not in failure \
|
||||
and "not a member" not in failure:
|
||||
errors.append("%s: %s %s: %s" % (
|
||||
command, member_type, member, failure))
|
||||
if "already a member" in failure \
|
||||
or "not a member" in failure:
|
||||
continue
|
||||
errors.append("%s: %s %s: %s" % (
|
||||
command, member_type, member, failure))
|
||||
if len(errors) > 0:
|
||||
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":
|
||||
if action == "service":
|
||||
if res_find is not None and \
|
||||
len(res_find.get('usercertificate', [])) > 0:
|
||||
commands.append([name, 'service_disable', {}])
|
||||
if res_find is not None:
|
||||
has_cert = bool(res_find.get('usercertificate'))
|
||||
has_keytab = res_find.get('has_keytab', False)
|
||||
if has_cert or has_keytab:
|
||||
commands.append([name, 'service_disable', {}])
|
||||
else:
|
||||
ansible_module.fail_json(
|
||||
msg="Invalid action '%s' for state '%s'" %
|
||||
|
||||
@@ -958,10 +958,15 @@ def main():
|
||||
# commands
|
||||
|
||||
commands = []
|
||||
user_set = set()
|
||||
|
||||
for user in names:
|
||||
if isinstance(user, dict):
|
||||
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
|
||||
first = user.get("first")
|
||||
last = user.get("last")
|
||||
@@ -1370,6 +1375,8 @@ def main():
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
del user_set
|
||||
|
||||
# Execute commands
|
||||
|
||||
errors = []
|
||||
|
||||
@@ -69,12 +69,20 @@ options:
|
||||
description: password to be used on symmetric vault.
|
||||
required: false
|
||||
type: string
|
||||
aliases: ["ipavaultpassword", "vault_password"]
|
||||
aliases: ["ipavaultpassword", "vault_password", "old_password"]
|
||||
password_file:
|
||||
description: file with password to be used on symmetric vault.
|
||||
required: false
|
||||
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:
|
||||
description: Vault salt.
|
||||
required: false
|
||||
@@ -235,7 +243,15 @@ EXAMPLES = """
|
||||
state: retrieved
|
||||
register: result
|
||||
- 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
|
||||
- ipavault:
|
||||
@@ -416,18 +432,29 @@ def check_parameters(module, state, action, description, username, service,
|
||||
shared, users, groups, services, owners, ownergroups,
|
||||
ownerservices, vault_type, salt, password, 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):
|
||||
invalid = []
|
||||
if state == "present":
|
||||
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":
|
||||
invalid.extend(['description'])
|
||||
|
||||
elif state == "absent":
|
||||
invalid = ['description', 'salt', 'vault_type', 'private_key',
|
||||
'private_key_file', 'datafile_in', 'datafile_out',
|
||||
'vault_data']
|
||||
'vault_data', 'new_password', 'new_password_file']
|
||||
|
||||
if action == "vault":
|
||||
invalid.extend(['users', 'groups', 'services', 'owners',
|
||||
@@ -437,7 +464,7 @@ def check_parameters(module, state, action, description, username, service,
|
||||
elif state == "retrieved":
|
||||
invalid = ['description', 'salt', 'datafile_in', 'users', 'groups',
|
||||
'owners', 'ownergroups', 'public_key', 'public_key_file',
|
||||
'vault_data']
|
||||
'vault_data', 'new_password', 'new_password_file']
|
||||
if action == 'member':
|
||||
module.fail_json(
|
||||
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,
|
||||
password, password_file, public_key,
|
||||
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 = []
|
||||
|
||||
if res_find is not None:
|
||||
vault_type = res_find['ipavaulttype']
|
||||
|
||||
if vault_type == "standard":
|
||||
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":
|
||||
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 "
|
||||
"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":
|
||||
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:
|
||||
module.fail_json(
|
||||
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'))
|
||||
|
||||
|
||||
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():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
@@ -533,10 +609,18 @@ def main():
|
||||
datafile_out=dict(type="str", required=False, default=None,
|
||||
aliases=['out']),
|
||||
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,
|
||||
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
|
||||
action=dict(type="str", default="vault",
|
||||
choices=["vault", "data", "member"]),
|
||||
@@ -546,6 +630,7 @@ def main():
|
||||
supports_check_mode=True,
|
||||
mutually_exclusive=[['username', 'service', 'shared'],
|
||||
['datafile_in', 'vault_data'],
|
||||
['new_password', 'new_password_file'],
|
||||
['vault_password', 'vault_password_file'],
|
||||
['vault_public_key', 'vault_public_key_file']],
|
||||
)
|
||||
@@ -576,6 +661,8 @@ def main():
|
||||
salt = module_params_get(ansible_module, "vault_salt")
|
||||
password = module_params_get(ansible_module, "vault_password")
|
||||
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_file = module_params_get(ansible_module,
|
||||
"vault_public_key_file")
|
||||
@@ -614,7 +701,8 @@ def main():
|
||||
service, shared, users, groups, services, owners,
|
||||
ownergroups, ownerservices, vault_type, salt, password,
|
||||
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
|
||||
|
||||
changed = False
|
||||
@@ -660,7 +748,7 @@ def main():
|
||||
ansible_module, state, action, vault_type, salt, password,
|
||||
password_file, public_key, public_key_file, private_key,
|
||||
private_key_file, vault_data, datafile_in, datafile_out,
|
||||
res_find)
|
||||
new_password, new_password_file, res_find)
|
||||
|
||||
# Found the vault
|
||||
if action == "vault":
|
||||
@@ -721,7 +809,6 @@ def main():
|
||||
owner_add_args = gen_member_args(
|
||||
args, owner_add, ownergroups_add, ownerservice_add)
|
||||
if owner_add_args is not None:
|
||||
# ansible_module.warn("OWNER ADD: %s" % owner_add_args)
|
||||
commands.append(
|
||||
[name, 'vault_add_owner', owner_add_args])
|
||||
|
||||
@@ -729,7 +816,6 @@ def main():
|
||||
owner_del_args = gen_member_args(
|
||||
args, owner_del, ownergroups_del, ownerservice_del)
|
||||
if owner_del_args is not None:
|
||||
# ansible_module.warn("OWNER DEL: %s" % owner_del_args)
|
||||
commands.append(
|
||||
[name, 'vault_remove_owner', owner_del_args])
|
||||
|
||||
@@ -758,19 +844,22 @@ def main():
|
||||
if any([vault_data, datafile_in]):
|
||||
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":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(
|
||||
msg="Vault `%s` not found to retrieve data." % name)
|
||||
|
||||
vault_type = res_find['cn']
|
||||
|
||||
# verify data encription args
|
||||
check_encryption_params(
|
||||
ansible_module, state, action, vault_type, salt, password,
|
||||
password_file, public_key, public_key_file, private_key,
|
||||
private_key_file, vault_data, datafile_in, datafile_out,
|
||||
res_find)
|
||||
new_password, new_password_file, res_find)
|
||||
|
||||
pwdargs = data_storage_args(
|
||||
args, vault_data, password, password_file, private_key,
|
||||
@@ -813,7 +902,6 @@ def main():
|
||||
errors = []
|
||||
for name, command, args in commands:
|
||||
try:
|
||||
# ansible_module.warn("RUN: %s %s %s" % (command, name, args))
|
||||
result = api_command(ansible_module, command, name, args)
|
||||
|
||||
if command == 'vault_archive':
|
||||
@@ -829,7 +917,6 @@ def main():
|
||||
raise Exception("No data retrieved.")
|
||||
changed = False
|
||||
else:
|
||||
# ansible_module.warn("RESULT: %s" % (result))
|
||||
if "completed" in result:
|
||||
if result["completed"] > 0:
|
||||
changed = True
|
||||
|
||||
@@ -164,7 +164,8 @@ class ActionModule(ActionBase):
|
||||
return result
|
||||
|
||||
data = self._execute_module(module_name='ipaclient_get_facts',
|
||||
module_args=dict(), task_vars=None)
|
||||
module_args=dict(), task_vars=task_vars)
|
||||
|
||||
try:
|
||||
domain = data['ansible_facts']['ipa']['domain']
|
||||
realm = data['ansible_facts']['ipa']['realm']
|
||||
@@ -245,4 +246,3 @@ class ActionModule(ActionBase):
|
||||
finally:
|
||||
# delete the local temp directory
|
||||
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
|
||||
in result_ipaclient_get_otp.msg
|
||||
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
||||
delegate_facts: yes
|
||||
ignore_errors: yes
|
||||
|
||||
- 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
|
||||
|
||||
[ipareplicas:vars]
|
||||
ipaclient_domain=example.com
|
||||
ipareplica_domain=example.com
|
||||
ipaadmin_principal=admin
|
||||
ipaadmin_password=MySecretPassword123
|
||||
ipadm_password=MySecretPassword456
|
||||
|
||||
@@ -262,6 +262,7 @@ def main():
|
||||
config.subject_base = options.subject_base
|
||||
config.dirman_password = dirman_password
|
||||
config.ca_host_name = ca_host_name
|
||||
config.setup_ca = options.setup_ca
|
||||
|
||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||
installer._remote_api = remote_api
|
||||
|
||||
@@ -177,6 +177,7 @@ def main():
|
||||
config = gen_ReplicaConfig()
|
||||
config.dirman_password = dirman_password
|
||||
config.subject_base = options.subject_base
|
||||
config.master_host_name = master_host_name
|
||||
|
||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||
|
||||
|
||||
@@ -173,6 +173,7 @@ def main():
|
||||
config = gen_ReplicaConfig()
|
||||
config.dirman_password = dirman_password
|
||||
config.subject_base = options.subject_base
|
||||
config.master_host_name = master_host_name
|
||||
|
||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||
# installer._remote_api = remote_api
|
||||
|
||||
@@ -110,7 +110,7 @@ def main():
|
||||
# additional
|
||||
ccache=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),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
|
||||
@@ -169,6 +169,7 @@ def main():
|
||||
config.promote = installer.promote
|
||||
config.kra_enabled = kra_enabled
|
||||
config.kra_host_name = kra_host_name
|
||||
config.setup_ca = options.setup_ca
|
||||
|
||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ def main():
|
||||
config.subject_base = options.subject_base
|
||||
config.dirman_password = dirman_password
|
||||
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.promote = installer.promote
|
||||
|
||||
|
||||
@@ -120,6 +120,9 @@ options:
|
||||
_subject_base:
|
||||
description: The installer _subject_base setting
|
||||
required: no
|
||||
dirman_password:
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -173,10 +176,12 @@ def main():
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_kra_enabled=dict(required=False, type='bool'),
|
||||
_kra_host_name=dict(required=False),
|
||||
_ca_host_name=dict(required=False),
|
||||
_top_dir=dict(required=True),
|
||||
_add_to_ipaservers=dict(required=True, type='bool'),
|
||||
_ca_subject=dict(required=True),
|
||||
_subject_base=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
@@ -233,6 +238,7 @@ def main():
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
kra_enabled = ansible_module.params.get('_kra_enabled')
|
||||
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')
|
||||
if options.subject_base is not None:
|
||||
@@ -243,6 +249,7 @@ def main():
|
||||
|
||||
options._ca_subject = ansible_module.params.get('_ca_subject')
|
||||
options._subject_base = ansible_module.params.get('_subject_base')
|
||||
dirman_password = ansible_module.params.get('dirman_password')
|
||||
|
||||
# init #
|
||||
|
||||
@@ -254,14 +261,25 @@ def main():
|
||||
constants.DEFAULT_CONFIG)
|
||||
api_bootstrap_finalize(env)
|
||||
config = gen_ReplicaConfig()
|
||||
config.dirman_password = dirman_password
|
||||
config.subject_base = options.subject_base
|
||||
config.promote = installer.promote
|
||||
config.kra_enabled = kra_enabled
|
||||
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)
|
||||
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):
|
||||
ansible_log.debug("-- INSTALL KRA --")
|
||||
|
||||
|
||||
@@ -63,6 +63,9 @@ options:
|
||||
_top_dir:
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
dirman_password:
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -98,6 +101,7 @@ def main():
|
||||
ccache=dict(required=True),
|
||||
_pkinit_pkcs12_info=dict(required=False, type='list'),
|
||||
_top_dir=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
@@ -126,6 +130,7 @@ def main():
|
||||
'_pkinit_pkcs12_info')
|
||||
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
dirman_password = ansible_module.params.get('dirman_password')
|
||||
|
||||
# init #
|
||||
|
||||
@@ -141,8 +146,10 @@ def main():
|
||||
constants.DEFAULT_CONFIG)
|
||||
api_bootstrap_finalize(env)
|
||||
config = gen_ReplicaConfig()
|
||||
config.dirman_password = dirman_password
|
||||
config.master_host_name = config_master_host_name
|
||||
config.subject_base = options.subject_base
|
||||
config.setup_ca = options.setup_ca
|
||||
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
|
||||
|
||||
@@ -226,6 +226,8 @@
|
||||
setup_adtrust: "{{ result_ipareplica_test.setup_adtrust }}"
|
||||
setup_kra: "{{ result_ipareplica_test.setup_kra }}"
|
||||
setup_dns: "{{ ipareplica_setup_dns }}"
|
||||
### server ###
|
||||
setup_ca: "{{ ipareplica_setup_ca }}"
|
||||
### ssl certificate ###
|
||||
dirsrv_cert_files: "{{ ipareplica_dirsrv_cert_files | default([]) }}"
|
||||
### client ###
|
||||
@@ -281,7 +283,7 @@
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}"
|
||||
_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 }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
|
||||
@@ -332,6 +334,7 @@
|
||||
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
|
||||
- name: Install - Setup KRB
|
||||
ipareplica_setup_krb:
|
||||
@@ -345,8 +348,9 @@
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
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 }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
|
||||
# We need to point to the master in ipa default conf when certmonger
|
||||
# asks for HTTP certificate in newer ipa versions. In these versions
|
||||
@@ -388,6 +392,7 @@
|
||||
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
master:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
when: result_ipareplica_test.change_master_for_certmonger
|
||||
@@ -407,8 +412,8 @@
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||
_dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info }}"
|
||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_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 if result_ipareplica_prepare._pkinit_pkcs12_info != None else omit }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
ds_ca_subject: "{{ result_ipareplica_setup_ds.ds_ca_subject }}"
|
||||
@@ -429,7 +434,7 @@
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_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 }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
|
||||
@@ -471,6 +476,7 @@
|
||||
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
when: result_ipareplica_test.change_master_for_certmonger
|
||||
|
||||
- name: Install - Setup otpd
|
||||
@@ -507,7 +513,7 @@
|
||||
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
||||
_kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}"
|
||||
_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 }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
|
||||
@@ -529,7 +535,7 @@
|
||||
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
||||
_kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}"
|
||||
_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 }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
@@ -554,7 +560,7 @@
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_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 }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
|
||||
@@ -574,7 +580,7 @@
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_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 }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
ds_ca_subject: "{{ result_ipareplica_setup_ds.ds_ca_subject }}"
|
||||
@@ -611,10 +617,12 @@
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
||||
_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 }}"
|
||||
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
|
||||
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
when: result_ipareplica_test.setup_kra
|
||||
|
||||
- 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 }}"
|
||||
dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | 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:
|
||||
"{{ ipaserver_external_cert_files | default(omit) }}"
|
||||
subject_base: "{{ result_ipaserver_prepare.subject_base }}"
|
||||
@@ -240,7 +240,7 @@
|
||||
no_hbac_allow: "{{ ipaserver_no_hbac_allow }}"
|
||||
idstart: "{{ result_ipaserver_test.idstart }}"
|
||||
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
|
||||
ipaserver_setup_custodia:
|
||||
@@ -270,7 +270,7 @@
|
||||
no_pkinit: "{{ result_ipaserver_test.no_pkinit }}"
|
||||
dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}"
|
||||
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_type: "{{ ipaserver_external_ca_type | default(omit) }}"
|
||||
external_ca_profile:
|
||||
@@ -334,7 +334,7 @@
|
||||
idmax: "{{ result_ipaserver_test.idmax }}"
|
||||
http_cert_files: "{{ ipaserver_http_cert_files | default([]) }}"
|
||||
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
|
||||
ipaserver_setup_kra:
|
||||
@@ -394,7 +394,7 @@
|
||||
idstart: "{{ result_ipaserver_test.idstart }}"
|
||||
idmax: "{{ result_ipaserver_test.idmax }}"
|
||||
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
|
||||
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
|
||||
|
||||
tasks:
|
||||
- name: ensure forwardzone example.com is absent - prep
|
||||
- name: ensure test forwardzones are absent
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
name: example.com
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name:
|
||||
- example.com
|
||||
- newfailzone.com
|
||||
state: absent
|
||||
|
||||
- name: ensure forwardzone example.com is created
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
state: present
|
||||
name: example.com
|
||||
forwarders:
|
||||
- 8.8.8.8
|
||||
- ip_address: 8.8.8.8
|
||||
forwardpolicy: first
|
||||
skip_overlap_check: true
|
||||
register: result
|
||||
@@ -25,11 +27,11 @@
|
||||
|
||||
- name: ensure forwardzone example.com is present again
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
state: present
|
||||
name: example.com
|
||||
forwarders:
|
||||
- 8.8.8.8
|
||||
- ip_address: 8.8.8.8
|
||||
forwardpolicy: first
|
||||
skip_overlap_check: true
|
||||
register: result
|
||||
@@ -37,12 +39,13 @@
|
||||
|
||||
- name: ensure forwardzone example.com has two forwarders
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
state: present
|
||||
name: example.com
|
||||
forwarders:
|
||||
- 8.8.8.8
|
||||
- 4.4.4.4
|
||||
- ip_address: 8.8.8.8
|
||||
- ip_address: 4.4.4.4
|
||||
port: 8053
|
||||
forwardpolicy: first
|
||||
skip_overlap_check: true
|
||||
register: result
|
||||
@@ -50,165 +53,246 @@
|
||||
|
||||
- name: ensure forwardzone example.com has one forwarder again
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: example.com
|
||||
forwarders:
|
||||
- 8.8.8.8
|
||||
- ip_address: 8.8.8.8
|
||||
forwardpolicy: first
|
||||
skip_overlap_check: true
|
||||
state: present
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
failed_when: result.changed
|
||||
|
||||
- name: skip_overlap_check can only be set on creation so change nothing
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: example.com
|
||||
forwarders:
|
||||
- 8.8.8.8
|
||||
- ip_address: 8.8.8.8
|
||||
forwardpolicy: first
|
||||
skip_overlap_check: false
|
||||
state: present
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- name: change all the things at once
|
||||
- name: ensure forwardzone example.com is absent.
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
state: present
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: example.com
|
||||
forwarders:
|
||||
- 8.8.8.8
|
||||
- 4.4.4.4
|
||||
forwardpolicy: only
|
||||
skip_overlap_check: false
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- name: ensure forwardzone example.com is absent for next testset
|
||||
- name: ensure forwardzone example.com is absent, again.
|
||||
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
|
||||
state: absent
|
||||
|
||||
- name: ensure forwardzone example.com is created with minimal args
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
state: present
|
||||
name: example.com
|
||||
skip_overlap_check: true
|
||||
forwarders:
|
||||
- 8.8.8.8
|
||||
- ip_address: 8.8.8.8
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- name: add a forwarder to any existing ones
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
state: present
|
||||
name: example.com
|
||||
forwarders:
|
||||
- 4.4.4.4
|
||||
- ip_address: 4.4.4.4
|
||||
port: 8053
|
||||
action: member
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- name: check the list of forwarders is what we expect
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
state: present
|
||||
name: example.com
|
||||
forwarders:
|
||||
- 4.4.4.4
|
||||
- 8.8.8.8
|
||||
- ip_address: 4.4.4.4
|
||||
port: 8053
|
||||
- ip_address: 8.8.8.8
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- name: remove a single forwarder
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
state: absent
|
||||
name: example.com
|
||||
forwarders:
|
||||
- 8.8.8.8
|
||||
- ip_address: 8.8.8.8
|
||||
action: member
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- name: check the list of forwarders is what we expect now
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
state: present
|
||||
name: example.com
|
||||
forwarders:
|
||||
- 4.4.4.4
|
||||
- ip_address: 4.4.4.4
|
||||
port: 8053
|
||||
action: member
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- name: ensure forwardzone example.com is absent again
|
||||
- name: Add a permission for per-forward zone access delegation.
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: example.com
|
||||
state: absent
|
||||
|
||||
- name: try to create a new forwarder with action=member
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
state: present
|
||||
name: example.com
|
||||
forwarders:
|
||||
- 4.4.4.4
|
||||
permission: yes
|
||||
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
|
||||
failed_when: not result.changed
|
||||
|
||||
- name: enable the forwarder
|
||||
- name: Add a permission for per-forward zone access delegation, again.
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
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
|
||||
failed_when: not result.changed
|
||||
|
||||
- name: disable the forwarder again
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
name: example.com
|
||||
state: disabled
|
||||
action: member
|
||||
register: result
|
||||
failed_when: not result.changed
|
||||
|
||||
- name: ensure it stays disabled
|
||||
ipadnsforwardzone:
|
||||
ipaadmin_password: password01
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: example.com
|
||||
state: disabled
|
||||
register: result
|
||||
failed_when: result.changed
|
||||
|
||||
- name: ensure forwardzone example.com is absent - tidy up
|
||||
- name: enable the forwarder
|
||||
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
|
||||
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;
|
||||
fi
|
||||
|
||||
PASSWORD="SomeCApassword"
|
||||
PASSWORD="SomeCApassword.123"
|
||||
DBDIR="${master}-nssdb"
|
||||
PWDFILE="$DBDIR/pwdfile.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
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: manageruser1,manageruser2
|
||||
name: manageruser1,manageruser2,unknown_user
|
||||
state: absent
|
||||
|
||||
- name: Ensure group testgroup, managergroup1 and managergroup2 are absent
|
||||
@@ -185,6 +185,15 @@
|
||||
register: result
|
||||
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
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
|
||||
@@ -96,3 +96,18 @@
|
||||
state: absent
|
||||
register: result
|
||||
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
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: manageruser1,manageruser2
|
||||
name: manageruser1,manageruser2,unknown_user
|
||||
state: absent
|
||||
|
||||
- name: Ensure group managergroup1 and managergroup2 are absent
|
||||
@@ -200,6 +200,15 @@
|
||||
register: result
|
||||
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
|
||||
ipahostgroup:
|
||||
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
|
||||
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
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
|
||||
@@ -178,6 +178,61 @@
|
||||
register: result
|
||||
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
|
||||
ipavault:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
@@ -194,5 +249,14 @@
|
||||
register: result
|
||||
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.
|
||||
import_tasks: env_cleanup.yml
|
||||
|
||||
Reference in New Issue
Block a user