mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-03-29 14:53:06 +00:00
Compare commits
98 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1dd2b54e77 | ||
|
|
a62e355f9c | ||
|
|
fbe2880452 | ||
|
|
94b1f25b37 | ||
|
|
5d7f2788f3 | ||
|
|
e77f4daaa9 | ||
|
|
8da4b73b44 | ||
|
|
608614110d | ||
|
|
16cbb87126 | ||
|
|
db49ac66d7 | ||
|
|
c36cb9543b | ||
|
|
b5f209225b | ||
|
|
6ad82e6bc7 | ||
|
|
63924dd6fc | ||
|
|
d7a109b7bf | ||
|
|
439552ed8a | ||
|
|
80d9c05e66 | ||
|
|
f816d3e7ff | ||
|
|
539e15aab3 | ||
|
|
f7eef810af | ||
|
|
1e3235e281 | ||
|
|
12408e0143 | ||
|
|
b06ef3fc09 | ||
|
|
dba8c204ff | ||
|
|
2f62160846 | ||
|
|
209e471553 | ||
|
|
0e64c80cd1 | ||
|
|
0c30020a7b | ||
|
|
d36d25d62a | ||
|
|
6af0d9b7c7 | ||
|
|
dd2e1d3aaa | ||
|
|
d8cddb3c7c | ||
|
|
1aaa3b30e0 | ||
|
|
ff9ce6b86a | ||
|
|
a4a15defa9 | ||
|
|
6e6e193ab2 | ||
|
|
4b9860e1d2 | ||
|
|
5a462ece9b | ||
|
|
a9cf33f3b9 | ||
|
|
42eaadfbbf | ||
|
|
13eb30f1e2 | ||
|
|
b3fd3a518e | ||
|
|
5d435c375c | ||
|
|
ccc001ada0 | ||
|
|
fce3935d03 | ||
|
|
12c4227385 | ||
|
|
5d962c06ca | ||
|
|
bf664f6861 | ||
|
|
40713e71f9 | ||
|
|
1428143d73 | ||
|
|
8932842288 | ||
|
|
b1a8427132 | ||
|
|
b16280455c | ||
|
|
3390d6742d | ||
|
|
57188c890a | ||
|
|
bc0f211c29 | ||
|
|
6e2fa7e7d6 | ||
|
|
4d5a2c2437 | ||
|
|
74e954b97f | ||
|
|
c5e0b1b453 | ||
|
|
00066d2c28 | ||
|
|
2a197cc7b1 | ||
|
|
e8173dd9b5 | ||
|
|
0324ffd56d | ||
|
|
e814b1faf5 | ||
|
|
dd85868cc2 | ||
|
|
2abebc683b | ||
|
|
74ea40f66f | ||
|
|
8a56962ce6 | ||
|
|
4fc722f73b | ||
|
|
5bb44245c6 | ||
|
|
f4680ceb5a | ||
|
|
3a3fb51109 | ||
|
|
09ab29b4e7 | ||
|
|
c69d0bc53f | ||
|
|
455ca83ef5 | ||
|
|
1d5b5d38b7 | ||
|
|
d43b4429e6 | ||
|
|
45af7348fe | ||
|
|
b636ab3112 | ||
|
|
ff08ee7ee6 | ||
|
|
ab25078b47 | ||
|
|
781ac6e90b | ||
|
|
5179514e0c | ||
|
|
203735e143 | ||
|
|
01b2f8efcf | ||
|
|
c212b43516 | ||
|
|
f786658606 | ||
|
|
e4497c18e9 | ||
|
|
ad7e17ea94 | ||
|
|
515f57eb09 | ||
|
|
62097ee368 | ||
|
|
4cd4f2cf71 | ||
|
|
4fc9ebe5d8 | ||
|
|
d1af0ff44b | ||
|
|
bf7902b7cc | ||
|
|
0240ec34a5 | ||
|
|
5790f4a703 |
@@ -4,9 +4,9 @@ Group module
|
||||
Description
|
||||
-----------
|
||||
|
||||
The group module allows to add, remove, enable, disable, unlock und undelete groups.
|
||||
The group module allows to ensure presence and absence of groups and members of groups.
|
||||
|
||||
The group module is as compatible as possible to the Ansible upstream `ipa_group` module, but addtionally offers to add users to a group and also to remove users from a group.
|
||||
The group module is as compatible as possible to the Ansible upstream `ipa_group` module, but additionally offers to add users to a group and also to remove users from a group.
|
||||
|
||||
|
||||
Features
|
||||
@@ -142,9 +142,9 @@ Variable | Description | Required
|
||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||
`user` | List of user name strings assigned to this group. | no
|
||||
`group` | List of group name strings assigned to this group. | no
|
||||
`service` | List of service name strings assigned to this group | no
|
||||
`service` | List of service name strings assigned to this group. Only usable with IPA versions 4.7 and up. | no
|
||||
`action` | Work on group or member level. It can be on of `member` or `group` and defaults to `group`. | no
|
||||
`state` | The state to ensure. It can be one of `present` or `absent`, defauilt: `present`. | yes
|
||||
`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | yes
|
||||
|
||||
|
||||
Authors
|
||||
|
||||
158
README-hbacrule.md
Normal file
158
README-hbacrule.md
Normal file
@@ -0,0 +1,158 @@
|
||||
HBACrule module
|
||||
===============
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The hbacrule (HBAC Rule) module allows to ensure presence and absence of HBAC Rules and host, hostgroups, HBAC Services, HBAC Service Groups, users, and user groups as members of HBAC Rule.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
* HBAC Rule management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipahbacrule 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 HBAC Rule login exists:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacrules
|
||||
hbacsvcs: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure HBAC Rule login is present
|
||||
- ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure HBAC Rule login exists with the only HBAC Service sshd:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacrules
|
||||
hbacsvcs: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure HBAC Rule login is present with the only HBAC Service sshd
|
||||
- ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
hbacsvc:
|
||||
- sshd
|
||||
```
|
||||
|
||||
Example playbook to make sure HBAC Service sshd is present in HBAC Rule login:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacrules
|
||||
hbacsvcs: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure HBAC Service sshd is present in HBAC Rule login
|
||||
- ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
hbacsvc:
|
||||
- sshd
|
||||
action: member
|
||||
```
|
||||
|
||||
Example playbook to make sure HBAC Service sshd is absent in HBAC Rule login:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacrules
|
||||
hbacsvcs: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure HBAC Service sshd is present in HBAC Rule login
|
||||
- ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
hbacsvc:
|
||||
- sshd
|
||||
action: member
|
||||
state: absent
|
||||
```
|
||||
|
||||
Example playbook to make sure HBAC Rule login is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacrules
|
||||
hbacsvcs: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure HBAC Rule login is present
|
||||
- ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
=========
|
||||
|
||||
ipahbacrule
|
||||
---------------
|
||||
|
||||
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 hbacrule name strings. | yes
|
||||
`description` | The hbacrule description string. | no
|
||||
`usercategory` \| `usercat` | User category the rule applies to. Choices: ["all"] | no
|
||||
`hostcategory` \| `hostcat` | Host category the rule applies to. Choices: ["all"] | no
|
||||
`servicecategory` \| `servicecat` | HBAC service category the rule applies to. Choices: ["all"] | no
|
||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||
`host` | List of host name strings assigned to this hbacrule. | no
|
||||
`hostgroup` | List of host group name strings assigned to this hbacrule. | no
|
||||
`hbacsvc` | List of HBAC Service name strings assigned to this hbacrule. | no
|
||||
`hbacsvcgroup` | List of HBAC Service Group name strings assigned to this hbacrule. | no
|
||||
`user` | List of user name strings assigned to this hbacrule. | no
|
||||
`group` | List of user group name strings assigned to this hbacrule. | no
|
||||
`action` | Work on hbacrule or member level. It can be on of `member` or `hbacrule` and defaults to `hbacrule`. | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, `enabled` or `disabled`, default: `present`. | no
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
109
README-hbacsvc.md
Normal file
109
README-hbacsvc.md
Normal file
@@ -0,0 +1,109 @@
|
||||
HBACsvc module
|
||||
==============
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The hbacsvc (HBAC Service) module allows to ensure presence and absence of HBAC Services.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
* HBACsvc management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipahbacsvc 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 HBAC Service for http is present
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle HBAC Services
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure HBAC Service for http is present
|
||||
- ipahbacsvc:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: http
|
||||
description: Web service
|
||||
```
|
||||
|
||||
Example playbook to make sure HBAC Service for tftp is present
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle HBAC Services
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure HBAC Service for tftp is present
|
||||
- ipahbacsvc:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: tftp
|
||||
description: TFTPWeb service
|
||||
```
|
||||
|
||||
Example playbook to make sure HBAC Services for http and tftp are absent
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle HBAC Services
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure HBAC Service for http and tftp are absent
|
||||
- ipahbacsvc:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: http,tftp
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
=========
|
||||
|
||||
ipahbacsvc
|
||||
----------
|
||||
|
||||
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` \| `service` | The list of hbacsvc name strings. | no
|
||||
`description` | The hbacsvc description string. | no
|
||||
`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | no
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
150
README-hbacsvcgroup.md
Normal file
150
README-hbacsvcgroup.md
Normal file
@@ -0,0 +1,150 @@
|
||||
HBACsvcgroup module
|
||||
===================
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The hbacsvcgroup (HBAC Service Group) module allows to ensure presence and absence of HBAP Service Groups and members of the groups.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
* HBAC Service Group management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipahbacsvcgroup 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 HBAC Service Group login exists:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacsvcgroups
|
||||
hbacsvcs: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure HBAC Service Group login is present
|
||||
- ipahbacsvcgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure HBAC Service Group login exists with the only HBAC Service sshd:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacsvcgroups
|
||||
hbacsvcs: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure HBAC Service Group login is present with the only HBAC Service sshd
|
||||
- ipahbacsvcgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
hbacsvc:
|
||||
- sshd
|
||||
```
|
||||
|
||||
Example playbook to make sure HBAC Service sshd is present in HBAC Service Group login:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacsvcgroups
|
||||
hbacsvcs: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure HBAC Service sshd is present in HBAC Service Group login
|
||||
- ipahbacsvcgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
hbacsvc:
|
||||
- sshd
|
||||
action: member
|
||||
```
|
||||
|
||||
Example playbook to make sure HBAC Service sshd is absent in HBAC Service Group login:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacsvcgroups
|
||||
hbacsvcs: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure HBAC Service sshd is present in HBAC Service Group login
|
||||
- ipahbacsvcgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
hbacsvc:
|
||||
- sshd
|
||||
action: member
|
||||
state: absent
|
||||
```
|
||||
|
||||
Example playbook to make sure HBAC Service Group login is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacsvcgroups
|
||||
hbacsvcs: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure HBAC Service Group login is present
|
||||
- ipahbacsvcgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
=========
|
||||
|
||||
ipahbacsvcgroup
|
||||
---------------
|
||||
|
||||
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 hbacsvcgroup name strings. | no
|
||||
`description` | The hbacsvcgroup description string. | no
|
||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||
`hbacsvc` | List of hbacsvc name strings assigned to this hbacsvcgroup. | no
|
||||
`action` | Work on hbacsvcgroup or member level. It can be on of `member` or `hbacsvcgroup` and defaults to `hbacsvcgroup`. | no
|
||||
`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | no
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
311
README-host.md
Normal file
311
README-host.md
Normal file
@@ -0,0 +1,311 @@
|
||||
Host module
|
||||
===========
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The host module allows to ensure presence, absence and disablement of hosts.
|
||||
|
||||
The host module is as compatible as possible to the Ansible upstream `ipa_host` module, but additionally offers to disable hosts.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
* Host management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipahost module.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.8+
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Example inventory file
|
||||
|
||||
```ini
|
||||
[ipaserver]
|
||||
ipaserver.test.local
|
||||
```
|
||||
|
||||
|
||||
Example playbook to ensure host presence:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hosts
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure host is present
|
||||
- ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
description: Example host
|
||||
ip_address: 192.168.0.123
|
||||
locality: Lab
|
||||
ns_host_location: Lab
|
||||
ns_os_version: CentOS 7
|
||||
ns_hardware_platform: Lenovo T61
|
||||
mac_address:
|
||||
- "08:00:27:E3:B1:2D"
|
||||
- "52:54:00:BD:97:1E"
|
||||
state: present
|
||||
```
|
||||
|
||||
|
||||
Example playbook to ensure host presence without DNS:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hosts
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure host is present without DNS
|
||||
- ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host02.example.com
|
||||
description: Example host
|
||||
force: yes
|
||||
```
|
||||
|
||||
|
||||
Example playbook to ensure host presence with a random password:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Ensure host with random password
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host01.example.com present with random password
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
random: yes
|
||||
force: yes
|
||||
register: ipahost
|
||||
|
||||
- name: Print generated random password
|
||||
debug:
|
||||
var: ipahost.host.randompassword
|
||||
```
|
||||
Please remember that the `force` tag will also force the generation of a new random password even if the host already exists and if `update_password` is limited to `on_create`.
|
||||
|
||||
|
||||
Example playbook to ensure presence of several hosts with a random password:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Ensure hosts with random password
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Hosts host01.example.com and host01.example.com present with random passwords
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
hosts:
|
||||
- name: host01.example.com
|
||||
random: yes
|
||||
force: yes
|
||||
- name: host02.example.com
|
||||
random: yes
|
||||
force: yes
|
||||
register: ipahost
|
||||
|
||||
- name: Print generated random password for host01.example.com
|
||||
debug:
|
||||
var: ipahost.host["host01.example.com"].randompassword
|
||||
|
||||
- name: Print generated random password for host02.example.com
|
||||
debug:
|
||||
var: ipahost.host["host02.example.com"].randompassword
|
||||
```
|
||||
Please remember that the `force` tag will also force the generation of a new random password even if the host alreay exists and if `update_password` is limited to `on_create`.
|
||||
|
||||
|
||||
Example playbook to ensure presence of host member principal:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Host present with principal
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host01.example.com present with principals host/testhost01.example.com and host/myhost01.example.com
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
principal:
|
||||
- host/testhost01.example.com
|
||||
- host/myhost01.example.com
|
||||
action: member
|
||||
```
|
||||
|
||||
|
||||
Example playbook to ensure presence of host member certificate:
|
||||
|
||||
```yaml
|
||||
- name: Host present with certificate
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host01.example.com present with certificate
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
certificate:
|
||||
- MIIC/zCCAeegAwIBAg...
|
||||
action: member
|
||||
```
|
||||
|
||||
|
||||
Example playbook to ensure presence of member managedby_host for serveral hosts:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Host present with managedby_host
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
hosts:
|
||||
- name: host01.exmaple.com
|
||||
managedby_host: server.exmaple.com
|
||||
- name: host02.exmaple.com
|
||||
managedby_host: server.exmaple.com
|
||||
action: member
|
||||
```
|
||||
|
||||
|
||||
Example playbook to disable a host:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hosts
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure host is disabled
|
||||
- ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
update_dns: yes
|
||||
state: disabled
|
||||
```
|
||||
`update_dns` controls if the DNS entries will be updated.
|
||||
|
||||
|
||||
Example playbook to ensure a host is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hosts
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure host is absent
|
||||
- ipahost:
|
||||
ipaadmin_password: password1
|
||||
name: host01.example.com
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
=========
|
||||
|
||||
ipahost
|
||||
-------
|
||||
|
||||
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` \| `fqdn` | The list of host name strings. `name` with *host variables* or `hosts` containing *host variables* need to be used. | no
|
||||
**Host variables** | Only used with `name` variable in the first level. | no
|
||||
`hosts` | The list of host dicts. Each `hosts` dict entry can contain **host variables**.<br>There is one required option in the `hosts` dict:| no
|
||||
| `name` \| `fqdn` - The user name string of the entry. | yes
|
||||
| **Host variables** | no
|
||||
`update_password` | Set password for a host in present state only on creation or always. It can be one of `always` or `on_create` and defaults to `always`. | no
|
||||
`action` | Work on host or member level. It can be on of `member` or `host` and defaults to `host`. | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent` or `disabled`, default: `present`. | yes
|
||||
|
||||
|
||||
**Host Variables:**
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`description` | The host description. | no
|
||||
`locality` | Host locality (e.g. "Baltimore, MD"). | no
|
||||
`location` \| `ns_host_location` | Host location (e.g. "Lab 2"). | no
|
||||
`platform` \| `ns_hardware_platform` | Host hardware platform (e.g. "Lenovo T61"). | no
|
||||
`os` \| `ns_os_version` | Host operating system and version (e.g. "Fedora 9"). | no
|
||||
`password` \| `user_password` \| `userpassword` | Password used in bulk enrollment. | no
|
||||
`random` \| `random_password` | Initiate the generation of a random password to be used in bulk enrollment. | no
|
||||
`certificate` \| `usercertificate` | List of base-64 encoded host certificates | no
|
||||
`managedby` \| `principalname` \| `krbprincipalname` | List of hosts that can manage this host | no
|
||||
`principal` \| `principalname` \| `krbprincipalname` | List of principal aliases for this host | no
|
||||
`allow_create_keytab_user` \| `ipaallowedtoperform_write_keys_user` | Users allowed to create a keytab of this host. <br>Options: | no
|
||||
`allow_create_keytab_group` \| `ipaallowedtoperform_write_keys_group` | Groups allowed to create a keytab of this host. <br>Options: | no
|
||||
`allow_create_keytab_host` \| `ipaallowedtoperform_write_keys_host` | Hosts allowed to create a keytab of this host. <br>Options: | no
|
||||
`allow_create_keytab_hostgroup` \| `ipaallowedtoperform_write_keys_hostgroup` | Host groups allowed to create a keytab of this host. <br>Options: | no
|
||||
`allow_retrieve_keytab_user` \| `ipaallowedtoperform_read_keys_user` | Users allowed to retieve a keytab of this host. <br>Options: | no
|
||||
`allow_retrieve_keytab_group` \| `ipaallowedtoperform_read_keys_group` | Groups allowed to retieve a keytab of this host. <br>Options: | no
|
||||
`allow_retrieve_keytab_host` \| `ipaallowedtoperform_read_keys_host` | Hosts allowed to retieve a keytab of this host. <br>Options: | no
|
||||
`allow_retrieve_keytab_hostgroup` \| `ipaallowedtoperform_read_keys_hostgroup` | Host groups allowed to retieve a keytab of this host. <br>Options: | no
|
||||
`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. 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
|
||||
`force` | Force host name even if not in DNS. | no
|
||||
`reverse` | Reverse DNS detection. | no
|
||||
`ip_address` \| `ipaddress` | The host IP address. | no
|
||||
`update_dns` | Update DNS entries. | no
|
||||
|
||||
|
||||
Return Values
|
||||
=============
|
||||
|
||||
ipahost
|
||||
-------
|
||||
|
||||
There are only return values if one or more random passwords have been generated.
|
||||
|
||||
Variable | Description | Returned When
|
||||
-------- | ----------- | -------------
|
||||
`host` | Host dict with random password. (dict) <br>Options: | If random is yes and host did not exist or update_password is yes
|
||||
| `randompassword` - The generated random password | If only one host is handled by the module
|
||||
| `name` - The host name of the host that got a new random password. (dict) <br> Options: <br> `randompassword` - The generated random password | If several hosts are handled by the module
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
147
README-hostgroup.md
Normal file
147
README-hostgroup.md
Normal file
@@ -0,0 +1,147 @@
|
||||
Hostgroup module
|
||||
================
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The hostgroup module allows to ensure presence and absence of hostgroups and members of hostgroups.
|
||||
|
||||
The hostgroup module is as compatible as possible to the Ansible upstream `ipa_hostgroup` module, but additionally offers to make sure that hosts are present or absent in a hostgroup.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
* Hostgroup management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipahostgroup 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 hostgroup databases exists:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hostgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure host-group databases is present
|
||||
- ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
host:
|
||||
- db.example.com
|
||||
hostgroup:
|
||||
- mysql-server
|
||||
- oracle-server
|
||||
```
|
||||
|
||||
Example playbook to make sure that hosts and hostgroups are present in existing databases hostgroup:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hostgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure hosts and hostgroups are present in existing databases hostgroup
|
||||
- ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
host:
|
||||
- db.example.com
|
||||
hostgroup:
|
||||
- mysql-server
|
||||
- oracle-server
|
||||
action: member
|
||||
```
|
||||
`action` controls if a the hostgroup or member will be handled. To add or remove members, set `action` to `member`.
|
||||
|
||||
Example playbook to make sure hosts and hostgroups are absent in databases hostgroup:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hostgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure hosts and hostgroups are absent in databases hostgroup
|
||||
- ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
host:
|
||||
- db.example.com
|
||||
hostgroup:
|
||||
- mysql-server
|
||||
- oracle-server
|
||||
action: member
|
||||
state: absent
|
||||
```
|
||||
|
||||
Example playbook to make sure host-group databases is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hostgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure host-group databases is absent
|
||||
- ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
=========
|
||||
|
||||
ipahostgroup
|
||||
-------
|
||||
|
||||
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 hostgroup name strings. | no
|
||||
`description` | The hostgroup description string. | no
|
||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||
`host` | List of host name strings assigned to this hostgroup. | no
|
||||
`hostgroup` | List of hostgroup name strings assigned to this hostgroup. | no
|
||||
`action` | Work on hostgroup or member level. It can be on of `member` or `hostgroup` and defaults to `hostgroup`. | no
|
||||
`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | no
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
102
README-pwpolicy.md
Normal file
102
README-pwpolicy.md
Normal file
@@ -0,0 +1,102 @@
|
||||
Pwpolicy module
|
||||
===============
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The pwpolicy module allows to ensure presence and absence of pwpolicies.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
* Pwpolicy management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipapwpolicy module.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.8+
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Example inventory file
|
||||
|
||||
```ini
|
||||
[ipaserver]
|
||||
ipaserver.test.local
|
||||
```
|
||||
|
||||
|
||||
Example playbook to ensure presence of pwpolicies for exisiting group ops:
|
||||
|
||||
```yaml
|
||||
tasks:
|
||||
- name: Ensure presence of pwpolicies for group ops
|
||||
ipapwpolicy:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: ops
|
||||
minlife: 7
|
||||
maxlife: 49
|
||||
history: 5
|
||||
priority: 1
|
||||
lockouttime: 300
|
||||
minlength: 8
|
||||
maxfail: 3
|
||||
```
|
||||
|
||||
Example playbook to ensure absence of pwpolicies for group ops
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle pwpolicies
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure absence of pwpolicies for group ops
|
||||
- ipapwpolicy:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: ops
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
=========
|
||||
|
||||
ipapwpolicy
|
||||
-------
|
||||
|
||||
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 pwpolicy name strings. | no
|
||||
`maxlife` \| `krbmaxpwdlife` | Maximum password lifetime in days. (int) | no
|
||||
`minlife` \| `krbminpwdlife` | Minimum password lifetime in hours. (int) | no
|
||||
`history` \| `krbpwdhistorylength` | Password history size. (int) | no
|
||||
`minclasses` \| `krbpwdmindiffchars` | Minimum number of character classes. (int) | no
|
||||
`minlength` \| `krbpwdminlength` | Minimum length of password. (int) | no
|
||||
`priority` \| `cospriority` | Priority of the policy, higher number means lower priority. (int) | no
|
||||
`maxfail` \| `krbpwdmaxfailure` | Consecutive failures before lockout. (int) | no
|
||||
`failinterval` \| `krbpwdfailurecountinterval` | Period after which failure count will be reset in seconds. (int) | no
|
||||
`lockouttime` \| `krbpwdlockoutduration` | Period for which lockout is enforced in seconds. (int) | no
|
||||
`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | yes
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
95
README-sudocmd.md
Normal file
95
README-sudocmd.md
Normal file
@@ -0,0 +1,95 @@
|
||||
Sudocmd module
|
||||
================
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The sudocmd module allows to ensure presence and absence of sudo command.
|
||||
|
||||
The sudocmd module is as compatible as possible to the Ansible upstream `ipa_sudocmd` module.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
* Sudo command management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipa_sudocmd 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 sudocmd exists:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle sudocmd
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudocmd is present
|
||||
- ipasudocmd:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: /usr/bin/su
|
||||
state: present
|
||||
```
|
||||
|
||||
Example playbook to make sure sudocmd is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle sudocmd
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudocmd are absent
|
||||
- ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: /usr/bin/su
|
||||
state: absent
|
||||
```
|
||||
|
||||
Variables
|
||||
=========
|
||||
|
||||
ipasudocmd
|
||||
-------
|
||||
|
||||
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` \| `sudocmd` | The sudo command strings. | yes
|
||||
`description` | The command description string. | no
|
||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||
`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | no
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Rafael Guterres Jeffman
|
||||
137
README-sudocmdgroup.md
Normal file
137
README-sudocmdgroup.md
Normal file
@@ -0,0 +1,137 @@
|
||||
Sudocmdgroup module
|
||||
===================
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The sudocmdgroup module allows to ensure presence and absence of sudocmdgroups and members of sudocmdgroups.
|
||||
|
||||
The sudocmdgroup module is as compatible as possible to the Ansible upstream `ipa_sudocmdgroup` module, but additionally offers to make sure that sudocmds are present or absent in a sudocmdgroup.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
* Sudocmdgroup management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipasudocmdgroup 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 sudocmdgroup is present:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle sudocmdgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudocmdgroup is present
|
||||
- ipasudocmdgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: group01
|
||||
description: Group of important commands
|
||||
```
|
||||
|
||||
Example playbook to make sure that a sudo command and sudocmdgroups are present in existing sudocmdgroup:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle sudocmdgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudo commands are present in existing sudocmdgroup
|
||||
- ipasudocmdgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: group01
|
||||
sudocmd:
|
||||
- /usr/bin/su
|
||||
- /usr/bin/less
|
||||
action: member
|
||||
```
|
||||
`action` controls if the sudocmdgroup or member will be handled. To add or remove members, set `action` to `member`.
|
||||
|
||||
Example playbook to make sure that a sudo command and sudocmdgroups are absent in sudocmdgroup:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle sudocmdgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudocmds are absent in existing sudocmdgroup
|
||||
- ipasudocmdgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: group01
|
||||
sudocmd:
|
||||
- /usr/bin/su
|
||||
- /usr/bin/less
|
||||
action: member
|
||||
state: absent
|
||||
```
|
||||
|
||||
Example playbook to make sure sudocmdgroup is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle sudocmdgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudocmdgroup is absent
|
||||
- ipasudocmdgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: group01
|
||||
state: absent
|
||||
```
|
||||
|
||||
Variables
|
||||
=========
|
||||
|
||||
ipasudocmdgroup
|
||||
-------
|
||||
|
||||
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 sudocmdgroup name strings. | no
|
||||
`description` | The sudocmdgroup description string. | no
|
||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||
`sudocmd` | List of sudocmdgroup name strings assigned to this sudocmdgroup. | no
|
||||
`action` | Work on sudocmdgroup or member level. It can be on of `member` or `sudocmdgroup` and defaults to `sudocmdgroup`. | no
|
||||
`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | no
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Rafael Guterres Jeffman
|
||||
141
README-sudorule.md
Normal file
141
README-sudorule.md
Normal file
@@ -0,0 +1,141 @@
|
||||
Sudorule module
|
||||
===============
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The sudorule (Sudo Rule) module allows to ensure presence and absence of Sudo Rules and host, hostgroups, users, and user groups as members of Sudo Rule.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
* Sudo Rule management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipasudorule 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 Sudo Rule is present:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle sudorules
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure Sudo Rule is present
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure sudocmds are present in Sudo Rule:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle sudorules
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure Sudo Rule is present
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
cmd:
|
||||
- /sbin/ifconfig
|
||||
action: member
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure sudocmds are not present in Sudo Rule:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle sudorules
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure Sudo Rule is present
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
cmd:
|
||||
- /sbin/ifconfig
|
||||
action: member
|
||||
state: absent
|
||||
```
|
||||
|
||||
Example playbook to make sure Sudo Rule is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle sudorules
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure Sudo Rule is present
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
=========
|
||||
|
||||
ipasudorule
|
||||
---------------
|
||||
|
||||
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 sudorule name strings. | yes
|
||||
`description` | The sudorule description string. | no
|
||||
`usercategory` | User category the rule applies to. Choices: ["all"] | no
|
||||
`hostcategory` | Host category the rule applies to. Choices: ["all"] | no
|
||||
`cmdcategory` | Command category the rule applies to. Choices: ["all"] | no
|
||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||
`host` | List of host name strings assigned to this sudorule. | no
|
||||
`hostgroup` | List of host group name strings assigned to this sudorule. | no
|
||||
`user` | List of user name strings assigned to this sudorule. | no
|
||||
`group` | List of user group name strings assigned to this sudorule. | no
|
||||
`cmd` | List of sudocmd name strings assigned to this sudorule. | no
|
||||
`cmdgroup` | List of sudocmd group name strings assigned wto this sudorule. | no
|
||||
`action` | Work on sudorule or member level. It can be on of `member` or `sudorule` and defaults to `sudorule`. | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, `enabled` or `disabled`, default: `present`. | no
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Rafael Jeffman
|
||||
@@ -4,7 +4,7 @@ Topology modules
|
||||
Description
|
||||
-----------
|
||||
|
||||
These modules allow to manage the topology. That means that topology segments can be added, removed and reinitialized. Also it is possible to verify topology suffixes.
|
||||
These modules allow to manage the topology. That means that it can made sure that topology segments are present, absent or reinitialized. Also it is possible to verify topology suffixes.
|
||||
|
||||
|
||||
Features
|
||||
@@ -39,7 +39,7 @@ ipaserver.test.local
|
||||
```
|
||||
|
||||
|
||||
Example playbook to add a topology segment wiht default name (cn):
|
||||
Example playbook to add a topology segment with default name (cn):
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -56,7 +56,7 @@ Example playbook to add a topology segment wiht default name (cn):
|
||||
right: ipareplica2.test.local
|
||||
state: present
|
||||
```
|
||||
The name (cn) can also be set if it should not be the default `{left}-to-{rkight}`.
|
||||
The name (cn) can also be set if it should not be the default `{left}-to-{right}`.
|
||||
|
||||
|
||||
Example playbook to delete a topology segment:
|
||||
|
||||
263
README-user.md
263
README-user.md
@@ -4,9 +4,9 @@ User module
|
||||
Description
|
||||
-----------
|
||||
|
||||
The user module allows to add, remove, enable, disable, unlock und undelete users.
|
||||
The user module allows to ensure presence, absence, disablement, unlocking and undeletion of users.
|
||||
|
||||
The user module is as compatible as possible to the Ansible upstream `ipa_user` module, but addtionally offers to preserve delete, enable, disable, unlock and undelete users.
|
||||
The user module is as compatible as possible to the Ansible upstream `ipa_user` module, but additionally offers to preserve delete, enable, disable, unlock and undelete users.
|
||||
|
||||
|
||||
Features
|
||||
@@ -41,7 +41,7 @@ ipaserver.test.local
|
||||
```
|
||||
|
||||
|
||||
Example playbook to add users:
|
||||
Example playbook to ensure a user is present:
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -50,7 +50,7 @@ Example playbook to add users:
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Create user pinky
|
||||
# Ensure user pinky is present
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
@@ -64,7 +64,7 @@ Example playbook to add users:
|
||||
password: "no-brain"
|
||||
update_password: on_create
|
||||
|
||||
# Create user brain
|
||||
# Ensure user brain is present
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: brain
|
||||
@@ -74,6 +74,133 @@ Example playbook to add users:
|
||||
`update_password` controls if a password for a user will be set in present state only on creation or every time (always).
|
||||
|
||||
|
||||
These two `ipauser` module calls can be combined into one with the `users` variable:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure users pinky and brain are present
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
users:
|
||||
- name: pinky
|
||||
first: pinky
|
||||
last: Acme
|
||||
uid: 10001
|
||||
gid: 100
|
||||
phone: "+555123457"
|
||||
email: pinky@acme.com
|
||||
passwordexpiration: "2023-01-19 23:59:59"
|
||||
password: "no-brain"
|
||||
- name: brain
|
||||
first: brain
|
||||
last: Acme
|
||||
update_password: on_create
|
||||
```
|
||||
|
||||
You can also alternatively use a json file containing the users, here `users_present.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"users": [
|
||||
{
|
||||
"name": "user1",
|
||||
"first": "First 1",
|
||||
"last": "Last 1"
|
||||
},
|
||||
{
|
||||
"name": "user2",
|
||||
"first": "First 2",
|
||||
"last": "Last 2"
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
And ensure the presence of the users with this example playbook:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Include users_present.json
|
||||
include_vars:
|
||||
file: users_present.json
|
||||
|
||||
- name: Users present
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users: "{{ users }}"
|
||||
```
|
||||
|
||||
Ensure user pinky is present with a generated random password and print the random password:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure user pinky is present with a random password
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: brain
|
||||
first: brain
|
||||
last: Acme
|
||||
random: yes
|
||||
register: ipauser
|
||||
|
||||
- name: Print generated random password
|
||||
debug:
|
||||
var: ipauser.user.randompassword
|
||||
```
|
||||
|
||||
Ensure users pinky and brain are present with a generated random password and print the random passwords:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure users pinky and brain are present with random password
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
users:
|
||||
- name: pinky
|
||||
first: pinky
|
||||
last: Acme
|
||||
uid: 10001
|
||||
gid: 100
|
||||
phone: "+555123457"
|
||||
email: pinky@acme.com
|
||||
passwordexpiration: "2023-01-19 23:59:59"
|
||||
password: "no-brain"
|
||||
- name: brain
|
||||
first: brain
|
||||
last: Acme
|
||||
register: ipauser
|
||||
|
||||
- name: Print generated random password of pinky
|
||||
debug:
|
||||
var: ipauser.user.pinky.randompassword
|
||||
|
||||
- name: Print generated random password of brain
|
||||
debug:
|
||||
var: ipauser.user.brain.randompassword
|
||||
```
|
||||
|
||||
Example playbook to delete a user, but preserve it:
|
||||
|
||||
```yaml
|
||||
@@ -91,6 +218,28 @@ Example playbook to delete a user, but preserve it:
|
||||
state: absent
|
||||
```
|
||||
|
||||
This can also be done with the `users` variable containing only names, this can be combined into one module call:
|
||||
|
||||
Example playbook to delete a user, but preserve it using the `users` variable:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Remove but preserve user pinky
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
users:
|
||||
- name: pinky
|
||||
preserve: yes
|
||||
state: absent
|
||||
```
|
||||
|
||||
This can also be done as an alternative with the `users` variable containing only names.
|
||||
|
||||
|
||||
Example playbook to undelete a preserved user.
|
||||
|
||||
@@ -108,6 +257,8 @@ Example playbook to undelete a preserved user.
|
||||
state: undeleted
|
||||
```
|
||||
|
||||
This can also be done as an alternative with the `users` variable containing only names.
|
||||
|
||||
|
||||
Example playbook to disable a user:
|
||||
|
||||
@@ -125,6 +276,8 @@ Example playbook to disable a user:
|
||||
state: disabled
|
||||
```
|
||||
|
||||
This can also be done as an alternative with the `users` variable containing only names.
|
||||
|
||||
|
||||
Example playbook to enable users:
|
||||
|
||||
@@ -142,6 +295,8 @@ Example playbook to enable users:
|
||||
state: enabled
|
||||
```
|
||||
|
||||
This can also be done as an alternative with the `users` variable containing only names.
|
||||
|
||||
|
||||
Example playbook to unlock users:
|
||||
|
||||
@@ -160,7 +315,7 @@ Example playbook to unlock users:
|
||||
```
|
||||
|
||||
|
||||
Example playbook to delete users:
|
||||
Example playbook to ensure users are absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -169,13 +324,34 @@ Example playbook to delete users:
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Remove user pinky and brain
|
||||
# Ensure users pinky and brain are absent
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky,brain
|
||||
state: absent
|
||||
```
|
||||
|
||||
This can also be done as an alternative with the `users` variable containing only names.
|
||||
|
||||
|
||||
Example playbook to ensure users are absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure users pinky and brain are absent
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
users:
|
||||
- name: pinky
|
||||
- name: brain
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
=========
|
||||
@@ -183,29 +359,86 @@ Variables
|
||||
ipauser
|
||||
-------
|
||||
|
||||
**General Variables:**
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`name` | The list of user name strings. | no
|
||||
`name` | The list of user name strings. `name` with *user variables* or `users` containing *user variables* need to be used. | no
|
||||
**User variables** | Only used with `name` variable in the first level. | no
|
||||
`users` | The list of user dicts. Each `users` dict entry can contain **user variables**.<br>There is one required option in the `users` dict:| no
|
||||
| `name` - The user name string of the entry. | yes
|
||||
| **User variables** | no
|
||||
`preserve` | Delete a user, keeping the entry available for future use. (bool) | no
|
||||
`update_password` | Set password for a user in present state only on creation or always. It can be one of `always` or `on_create` and defaults to `always`. | no
|
||||
`preserve` | Delete a user, keeping the entry available for future use. (bool) | no
|
||||
`action` | Work on user or member level. It can be on of `member` or `user` and defaults to `user`. | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, `enabled`, `disabled`, `unlocked` or `undeleted`, default: `present`. Only `names` or `users` with only `name` set are allowed if state is not `present`. | yes
|
||||
|
||||
|
||||
|
||||
**User Variables:**
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`first` \| `givenname` | The first name string. | no
|
||||
`last` | The last name | no
|
||||
`last` \| `sn` | The last name string. | no
|
||||
`fullname` \| `cn` | The full name string. | no
|
||||
`displayname` | The display name string. | no
|
||||
`homedir` | The home directory string. | no
|
||||
`shell` \| `loginshell` | The login shell string. | no
|
||||
`email` | List of email address strings. | no
|
||||
`principalname` \| `krbprincipalname` | The kerberos principal sptring. | no
|
||||
`passwordexpiration` \| `krbpasswordexpiration` | The kerberos password expiration date. Possible formats: `YYYYMMddHHmmssZ`, `YYYY-MM-ddTHH:mm:ssZ`, `YYYY-MM-ddTHH:mmZ`, `YYYY-MM-ddZ`, `YYYY-MM-dd HH:mm:ssZ` or `YYYY-MM-dd HH:mmZ`. The trailing 'Z' can be skipped. | no
|
||||
`principal` \| `principalnam` \| `krbprincipalname` | The kerberos principal sptring. | no
|
||||
`principalexpiration` \| `krbprincipalexpiration` | The kerberos principal expiration date. Possible formats: `YYYYMMddHHmmssZ`, `YYYY-MM-ddTHH:mm:ssZ`, `YYYY-MM-ddTHH:mmZ`, `YYYY-MM-ddZ`, `YYYY-MM-dd HH:mm:ssZ` or `YYYY-MM-dd HH:mmZ`. The trailing 'Z' can be skipped. | no
|
||||
`passwordexpiration` \| `krbpasswordexpiration` | The kerberos password expiration date. Possible formats: `YYYYMMddHHmmssZ`, `YYYY-MM-ddTHH:mm:ssZ`, `YYYY-MM-ddTHH:mmZ`, `YYYY-MM-ddZ`, `YYYY-MM-dd HH:mm:ssZ` or `YYYY-MM-dd HH:mmZ`. The trailing 'Z' can be skipped. Only usable with IPA versions 4.7 and up. | no
|
||||
`password` | The user password string. | no
|
||||
`random` | Generate a random user password | no
|
||||
`uid` \| `uidnumber` | The UID integer. | no
|
||||
`gid` \| `gidnumber` | The GID integer. | no
|
||||
`city` | City | no
|
||||
`userstate` \| `st` | State/Province | no
|
||||
`postalcode` \| `zip` | Postalcode/ZIP | no
|
||||
`phone` \| `telephonenumber` | List of telephone number strings, | no
|
||||
`mobile` | List of mobile telephone number strings. | no
|
||||
`pager` | List of pager number strings. | no
|
||||
`fax` \| `facsimiletelephonenumber` | List of fax number strings. | no
|
||||
`orgunit` | The Organisation unit. | no
|
||||
`title` | The job title string. | no
|
||||
~~`sshpubkey` \| `ipasshpubkey`~~ | ~~List of SSH public keys.~~ | ~~no~~
|
||||
`update_password` | Set password for a user in present state only on creation or always. It can be one of `always` or `on_create` and defaults to `always`. | no
|
||||
`preserve` | Delete a user, keeping the entry available for future use. (bool) | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, `enabled`, `disabled`, `unlocked` or `undeleted`, default: `present`. | yes
|
||||
`manager` | List of manager user names. | no
|
||||
`carlicense` | List of car licenses. | no
|
||||
`sshpubkey` \| `ipasshpubkey` | List of SSH public keys. | no
|
||||
`userauthtype` | List of supported user authentication types. Choices: `password`, `radius` and `otp` | no
|
||||
`userclass` | User category. (semantics placed on this attribute are for local interpretation). | no
|
||||
`radius` | RADIUS proxy configuration | no
|
||||
`radiususer` | RADIUS proxy username | no
|
||||
`departmentnumber` | Department Number | no
|
||||
`employeenumber` | Employee Number | no
|
||||
`employeetype` | Employee Type | no
|
||||
`preferredlanguage` | Preferred Language | no
|
||||
`certificate` | List of base-64 encoded user certificates. | no
|
||||
`certmapdata` | List of certificate mappings. Either `certificate` or `issuer` together with `subject` need to be specified. <br>Options: | no
|
||||
| `certificate` - Base-64 encoded user certificate | no
|
||||
| `issuer` - Issuer of the certificate | no
|
||||
| `subject` - Subject of the certificate | no
|
||||
`noprivate` | Do not create user private group. (bool) | no
|
||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
=============
|
||||
|
||||
ipauser
|
||||
-------
|
||||
|
||||
There are only return values if one or more random passwords have been generated.
|
||||
|
||||
Variable | Description | Returned When
|
||||
-------- | ----------- | -------------
|
||||
`host` | Host dict with random password. (dict) <br>Options: | If random is yes and user did not exist or update_password is yes
|
||||
| `randompassword` - The generated random password | If only one user is handled by the module
|
||||
| `name` - The user name of the user that got a new random password. (dict) <br> Options: <br> `randompassword` - The generated random password | If several users are handled by the module
|
||||
|
||||
|
||||
Authors
|
||||
|
||||
39
README.md
39
README.md
@@ -1,7 +1,7 @@
|
||||
FreeIPA Ansible collection
|
||||
==========================
|
||||
|
||||
This repository contains [Ansible](https://www.ansible.com/) roles and playbooks to install and uninstall [FreeIPA](https://www.freeipa.org/) `servers`, `replicas` and `clients`. Also modules for group, topology and user management.
|
||||
This repository contains [Ansible](https://www.ansible.com/) roles and playbooks to install and uninstall [FreeIPA](https://www.freeipa.org/) `servers`, `replicas` and `clients`. Also modules for group, host, topology and user management.
|
||||
|
||||
**Note**: The ansible playbooks and roles require a configured ansible environment where the ansible nodes are reachable and are properly set up to have an IP address and a working package manager.
|
||||
|
||||
@@ -12,6 +12,15 @@ Features
|
||||
* One-time-password (OTP) support for client installation
|
||||
* Repair mode for clients
|
||||
* Modules for group management
|
||||
* Modules for hbacrule management
|
||||
* Modules for hbacsvc management
|
||||
* Modules for hbacsvcgroup management
|
||||
* Modules for host management
|
||||
* Modules for hostgroup management
|
||||
* Modules for pwpolicy management
|
||||
* Modules for sudocmd management
|
||||
* Modules for sudocmdgroup management
|
||||
* Modules for sudorule management
|
||||
* Modules for topology management
|
||||
* Modules for user management
|
||||
|
||||
@@ -28,6 +37,7 @@ Supported Distributions
|
||||
* RHEL/CentOS 7.4+
|
||||
* Fedora 26+
|
||||
* Ubuntu
|
||||
* Debian 10+ (ipaclient only, no server or replica!)
|
||||
|
||||
Requirements
|
||||
------------
|
||||
@@ -59,17 +69,18 @@ How to use ansible-freeipa
|
||||
|
||||
**GIT repo**
|
||||
|
||||
The simplest method for now is to clone this repository on the contoller from github directly and to start the deployment from the ansible-freeipa directory:
|
||||
The simplest method for now is to clone this repository on the controller from github directly and to start the deployment from the ansible-freeipa directory:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/freeipa/ansible-freeipa.git
|
||||
cd ansible-freeipa
|
||||
```
|
||||
You can use the roles directly within the top directory of the git repo, but to be able to use the management modules in the plugins subdirectory, you have to either adapt `anisble.cfg` or create links for the modules or directories.
|
||||
You can use the roles directly within the top directory of the git repo, but to be able to use the management modules in the plugins subdirectory, you have to either adapt `ansible.cfg` or create links for the roles, modules or directories.
|
||||
|
||||
You can either adapt ansible.cfg:
|
||||
|
||||
```
|
||||
roles_path = /my/dir/ansible-freeipa/roles
|
||||
library = /my/dir/ansible-freeipa/plugins/modules
|
||||
module_utils = /my/dir/ansible-freeipa/plugins/module_utils
|
||||
```
|
||||
@@ -77,18 +88,27 @@ module_utils = /my/dir/ansible-freeipa/plugins/module_utils
|
||||
Or you can link the directories:
|
||||
|
||||
```
|
||||
ansible-freeipa/roles to ~/.ansible/
|
||||
ansible-freeipa/plugins/modules to ~/.ansible/plugins/
|
||||
ansible-freeipa/plugins/module_utils to ~/.ansible/plugins/
|
||||
```
|
||||
|
||||
**RPM package**
|
||||
|
||||
There are RPM packages available for Fedora 29+. These are installing the roles and modules into the global Ansible directories for `roles`, `plugins/modules` and `plugings/module_utils` in the `/usr/share/ansible` directory. Therefore is it possible to use the roles and modules without adapting the names like it is done in the example playbooks.
|
||||
There are RPM packages available for Fedora 29+. These are installing the roles and modules into the global Ansible directories for `roles`, `plugins/modules` and `plugins/module_utils` in the `/usr/share/ansible` directory. Therefore is it possible to use the roles and modules without adapting the names like it is done in the example playbooks.
|
||||
|
||||
**Ansible galaxy**
|
||||
|
||||
This command will get the whole collection from galaxy:
|
||||
|
||||
```bash
|
||||
ansible-galaxy collection install freeipa.ansible_freeipa
|
||||
```
|
||||
|
||||
Installing collections using the ansible-galaxy command is only supported with ansible 2.9+.
|
||||
|
||||
The mazer tool can be used for to install the collection for ansible 2.8:
|
||||
|
||||
```bash
|
||||
mazer install freeipa.ansible_freeipa
|
||||
```
|
||||
@@ -343,7 +363,7 @@ If Ansible vault is used for passwords, then it is needed to adapt the playbooks
|
||||
state: present
|
||||
```
|
||||
|
||||
It is also needed to provide the vault passowrd file on the ansible-playbook command line:
|
||||
It is also needed to provide the vault password file on the ansible-playbook command line:
|
||||
```bash
|
||||
ansible-playbook -v -i inventory/hosts --vault-password-file .vaul_pass.txt install-server.yml
|
||||
```
|
||||
@@ -384,6 +404,15 @@ Modules in plugin/modules
|
||||
=========================
|
||||
|
||||
* [ipagroup](README-group.md)
|
||||
* [ipahbacrule](README-hbacrule.md)
|
||||
* [ipahbacsvc](README-hbacsvc.md)
|
||||
* [ipahbacsvcgroup](README-hbacsvc.md)
|
||||
* [ipahost](README-host.md)
|
||||
* [ipahostgroup](README-hostgroup.md)
|
||||
* [ipapwpolicy](README-pwpolicy.md)
|
||||
* [ipasudocmd](README-sudocmd.md)
|
||||
* [ipasudocmdgroup](README-sudocmdgroup.md)
|
||||
* [ipasudorule](README-sudorule.md)
|
||||
* [ipatopologysegment](README-topology.md)
|
||||
* [ipatopologysuffix](README-topology.md)
|
||||
* [ipauser](README-user.md)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace: "freeipa"
|
||||
name: "ansible_freeipa"
|
||||
version: "A.B.C"
|
||||
description: ""
|
||||
description: "Ansible roles and modules for FreeIPA"
|
||||
|
||||
authors:
|
||||
- "Thomas Woerner <twoerner@redhat.com>"
|
||||
@@ -11,8 +11,6 @@ documentation: "https://github.com/freeipa/ansible-freeipa/blob/master/README.md
|
||||
homepage: "https://github.com/freeipa/ansible-freeipa"
|
||||
issues: "https://github.com/freeipa/ansible-freeipa/issues"
|
||||
|
||||
dependencies: {}
|
||||
|
||||
readme: "README.md"
|
||||
license: "GPL-3.0-or-later"
|
||||
license_file: "COPYING"
|
||||
|
||||
12
playbooks/hbacrule/ensure-hbarule-allhosts-absent.yml
Normal file
12
playbooks/hbacrule/ensure-hbarule-allhosts-absent.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure HBAC Rule allhosts is absent
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: allhosts
|
||||
state: absent
|
||||
12
playbooks/hbacrule/ensure-hbarule-allhosts-disabled.yml
Normal file
12
playbooks/hbacrule/ensure-hbarule-allhosts-disabled.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure HBAC Rule allhosts is disabled
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: allhosts
|
||||
state: disabled
|
||||
12
playbooks/hbacrule/ensure-hbarule-allhosts-enabled.yml
Normal file
12
playbooks/hbacrule/ensure-hbarule-allhosts-enabled.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure HBAC Rule allhosts is enabled
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: allhosts
|
||||
state: enabled
|
||||
12
playbooks/hbacrule/ensure-hbarule-allhosts-present.yml
Normal file
12
playbooks/hbacrule/ensure-hbarule-allhosts-present.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure HBAC Rule allhosts is present
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: allhosts
|
||||
usercategory: all
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure host server is absent in HBAC Rule allhosts
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: allhosts
|
||||
host: server
|
||||
action: member
|
||||
state: absent
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure host server is present in HBAC Rule allhosts
|
||||
ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: allhosts
|
||||
host: server
|
||||
action: member
|
||||
12
playbooks/hbacsvc/ensure-hbacsvc-absent.yml
Normal file
12
playbooks/hbacsvc/ensure-hbacsvc-absent.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure HBAC Services for http and tftp are absent
|
||||
ipahbacsvc:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: http,tftp
|
||||
state: absent
|
||||
18
playbooks/hbacsvc/ensure-hbacsvc-present.yml
Normal file
18
playbooks/hbacsvc/ensure-hbacsvc-present.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure HBAC Service for http is present
|
||||
ipahbacsvc:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: http
|
||||
description: Web service
|
||||
|
||||
- name: Ensure HBAC Service for tftp is present
|
||||
ipahbacsvc:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: tftp
|
||||
description: TFTP service
|
||||
14
playbooks/hbacsvcgroup/ensure-hbacsvcgroup-absent.yml
Normal file
14
playbooks/hbacsvcgroup/ensure-hbacsvcgroup-absent.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure HBAC Service Group login is absent
|
||||
ipahbacsvcgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
hbacsvc:
|
||||
- sshd
|
||||
state: absent
|
||||
15
playbooks/hbacsvcgroup/ensure-hbacsvcgroup-member-absent.yml
Normal file
15
playbooks/hbacsvcgroup/ensure-hbacsvcgroup-member-absent.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure HBAC Services sshd is absent in HBAC Service Group login
|
||||
ipahbacsvcgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
hbacsvc:
|
||||
- sshd
|
||||
action: member
|
||||
state: absent
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure HBAC Service sshd is present in HBAC Service Group login
|
||||
ipahbacsvcgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
hbacsvc:
|
||||
- sshd
|
||||
action: member
|
||||
14
playbooks/hbacsvcgroup/ensure-hbacsvcgroup-present.yml
Normal file
14
playbooks/hbacsvcgroup/ensure-hbacsvcgroup-present.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure HBAC Service sshd is present in HBAC Service Group login
|
||||
ipahbacsvcgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
hbacsvc:
|
||||
- sshd
|
||||
action: member
|
||||
1
playbooks/host/add-host.yml
Symbolic link
1
playbooks/host/add-host.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
host-present.yml
|
||||
11
playbooks/host/delete-host.yml
Normal file
11
playbooks/host/delete-host.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Playbook to handle hosts
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Ensure host host01.example.com is absent
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
state: absent
|
||||
11
playbooks/host/disable-host.yml
Normal file
11
playbooks/host/disable-host.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Playbook to handle hosts
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Disable host host01.example.com
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
state: disabled
|
||||
18
playbooks/host/ensure_host_with_randompassword.yml
Normal file
18
playbooks/host/ensure_host_with_randompassword.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
- name: Ensure host with random password
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host "{{ 'host1.' + ipaserver_domain }}" present with random password
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: "{{ 'host1.' + ipaserver_domain }}"
|
||||
random: yes
|
||||
force: yes
|
||||
update_password: on_create
|
||||
register: ipahost
|
||||
|
||||
- name: Print generated random password
|
||||
debug:
|
||||
var: ipahost.host.randompassword
|
||||
24
playbooks/host/host-member-allow_create_keytab-absent.yml
Normal file
24
playbooks/host/host-member-allow_create_keytab-absent.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
- name: Host member allow_create_keytab absent
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host1.example.com members allow_create_keytab absent for users, groups, hosts and hostgroups
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.exmaple.com
|
||||
allow_create_keytab_user:
|
||||
- user01
|
||||
- user02
|
||||
allow_create_keytab_group:
|
||||
- group01
|
||||
- group02
|
||||
allow_create_keytab_host:
|
||||
- host02.exmaple.com
|
||||
- host03.exmaple.com
|
||||
allow_create_keytab_hostgroup:
|
||||
- hostgroup01
|
||||
- hostgroup02
|
||||
action: member
|
||||
state: absent
|
||||
23
playbooks/host/host-member-allow_create_keytab-present.yml
Normal file
23
playbooks/host/host-member-allow_create_keytab-present.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
- name: Host member allow_create_keytab present
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host1.example.com members allow_create_keytab present for users, groups, hosts and hostgroups
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.exmaple.com
|
||||
allow_create_keytab_user:
|
||||
- user01
|
||||
- user02
|
||||
allow_create_keytab_group:
|
||||
- group01
|
||||
- group02
|
||||
allow_create_keytab_host:
|
||||
- host02.exmaple.com
|
||||
- host03.exmaple.com
|
||||
allow_create_keytab_hostgroup:
|
||||
- hostgroup01
|
||||
- hostgroup02
|
||||
action: member
|
||||
24
playbooks/host/host-member-allow_retrieve_keytab-absent.yml
Normal file
24
playbooks/host/host-member-allow_retrieve_keytab-absent.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
- name: Host member allow_retrieve_keytab absent
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host1.example.com members allow_retrieve_keytab absent for users, groups, hosts and hostgroups
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.exmaple.com
|
||||
allow_retrieve_keytab_user:
|
||||
- user01
|
||||
- user02
|
||||
allow_retrieve_keytab_group:
|
||||
- group01
|
||||
- group02
|
||||
allow_retrieve_keytab_host:
|
||||
- host02.exmaple.com
|
||||
- host03.exmaple.com
|
||||
allow_retrieve_keytab_hostgroup:
|
||||
- hostgroup01
|
||||
- hostgroup02
|
||||
action: member
|
||||
state: absent
|
||||
23
playbooks/host/host-member-allow_retrieve_keytab-present.yml
Normal file
23
playbooks/host/host-member-allow_retrieve_keytab-present.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
- name: Host member allow_retrieve_keytab present
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host1.example.com members allow_retrieve_keytab present for users, groups, hosts and hostgroups
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.exmaple.com
|
||||
allow_retrieve_keytab_user:
|
||||
- user01
|
||||
- user02
|
||||
allow_retrieve_keytab_group:
|
||||
- group01
|
||||
- group02
|
||||
allow_retrieve_keytab_host:
|
||||
- host02.exmaple.com
|
||||
- host03.exmaple.com
|
||||
allow_retrieve_keytab_hostgroup:
|
||||
- hostgroup01
|
||||
- hostgroup02
|
||||
action: member
|
||||
13
playbooks/host/host-member-certificate-absent.yml
Normal file
13
playbooks/host/host-member-certificate-absent.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
- name: Host member certificate absent
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host01.example.com member certificate absent
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
certificate:
|
||||
- MIIC/zCCAeegAwIBAgIUZGHLaSYg1myp6EI4VGWSC27vOrswDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4MzVaFw0yMDEwMTMxNjI4MzVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDER/lB8wUAmPTSwSc/NOXNlzdpPOQDSwrhKH6XsqZF4KpQoSY/nmCjAhJmOVpOUo4K2fGRZ0yAH9fkGv6yJP6c7IAFjLeec7GPHVwN4bZrP1DXfTAmfmXhcRQbCYkV+wmq8Puzw/+xA9EJrrodnJPPsE6E8HnSVLF6Ys9+cJMJ7HuwOI+wYt3gkmspsir1tccmf4x1PP+yHJWdcXyetlFRcmZ8gspjqOR2jb89xSQsh8gcyDW6rPNlSTzYZ2FmNtjES6ZhCsYL31fQbF2QglidlLGpAlvHUUS+xCigW73cvhFPMWXcfO51Mr15RcgYTckY+7QZ2nYqplRBoDlQl6DnAgMBAAGjUzBRMB0GA1UdDgQWBBTPG99XVRdxpOXMZo3Nhy+ldnf13TAfBgNVHSMEGDAWgBTPG99XVRdxpOXMZo3Nhy+ldnf13TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAjWTcnIl2mpNbfHAN8DB4Kk+RNRmhsH0y+r/47MXVTMMMToCfofeNY3Jeohu+2lIXMPQfTvXUbDTkNAGsGLv6LtQEUfSREqgk1eY7bT9BFfpH1uV2ZFhCO9jBA+E4bf55Kx7bgUNG31ykBshOsOblOJM1lS/0q4TWHAxrsU2PNwPi8X0ten+eGeB8aRshxS17Ij2cH0fdAMmSA+jMAvTIZl853Bxe0HuozauKwOFWL4qHm61c4O/j1mQCLqJKYfJ9mBDWFQLszd/tF+ePKiNhZCQly60F8Lumn2CDZj5UIkl8wk9Wls5n1BIQs+M8AN65NAdv7+js8jKUKCuyji8r3
|
||||
action: member
|
||||
state: absent
|
||||
12
playbooks/host/host-member-certificate-present.yml
Normal file
12
playbooks/host/host-member-certificate-present.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
- name: Host member certificate present
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host01.example.com member certificate present
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
certificate:
|
||||
- MIIC/zCCAeegAwIBAgIUZGHLaSYg1myp6EI4VGWSC27vOrswDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4MzVaFw0yMDEwMTMxNjI4MzVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDER/lB8wUAmPTSwSc/NOXNlzdpPOQDSwrhKH6XsqZF4KpQoSY/nmCjAhJmOVpOUo4K2fGRZ0yAH9fkGv6yJP6c7IAFjLeec7GPHVwN4bZrP1DXfTAmfmXhcRQbCYkV+wmq8Puzw/+xA9EJrrodnJPPsE6E8HnSVLF6Ys9+cJMJ7HuwOI+wYt3gkmspsir1tccmf4x1PP+yHJWdcXyetlFRcmZ8gspjqOR2jb89xSQsh8gcyDW6rPNlSTzYZ2FmNtjES6ZhCsYL31fQbF2QglidlLGpAlvHUUS+xCigW73cvhFPMWXcfO51Mr15RcgYTckY+7QZ2nYqplRBoDlQl6DnAgMBAAGjUzBRMB0GA1UdDgQWBBTPG99XVRdxpOXMZo3Nhy+ldnf13TAfBgNVHSMEGDAWgBTPG99XVRdxpOXMZo3Nhy+ldnf13TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAjWTcnIl2mpNbfHAN8DB4Kk+RNRmhsH0y+r/47MXVTMMMToCfofeNY3Jeohu+2lIXMPQfTvXUbDTkNAGsGLv6LtQEUfSREqgk1eY7bT9BFfpH1uV2ZFhCO9jBA+E4bf55Kx7bgUNG31ykBshOsOblOJM1lS/0q4TWHAxrsU2PNwPi8X0ten+eGeB8aRshxS17Ij2cH0fdAMmSA+jMAvTIZl853Bxe0HuozauKwOFWL4qHm61c4O/j1mQCLqJKYfJ9mBDWFQLszd/tF+ePKiNhZCQly60F8Lumn2CDZj5UIkl8wk9Wls5n1BIQs+M8AN65NAdv7+js8jKUKCuyji8r3
|
||||
action: member
|
||||
12
playbooks/host/host-member-managedby_host-absent.yml
Normal file
12
playbooks/host/host-member-managedby_host-absent.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Host member managedby_host absent
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.exmaple.com
|
||||
managedby_host: server.exmaple.com
|
||||
action: member
|
||||
state: absent
|
||||
11
playbooks/host/host-member-managedby_host-present.yml
Normal file
11
playbooks/host/host-member-managedby_host-present.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Host member managedby_host present
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.exmaple.com
|
||||
managedby_host: server.exmaple.com
|
||||
action: member
|
||||
15
playbooks/host/host-member-principal-absent.yml
Normal file
15
playbooks/host/host-member-principal-absent.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: Host member principal absent
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host01.example.com principals host/testhost01.example.com and host/myhost01.example.com absent
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
principal:
|
||||
- host/testhost01.example.com
|
||||
- host/myhost01.example.com
|
||||
action: member
|
||||
state: absent
|
||||
14
playbooks/host/host-member-principal-present.yml
Normal file
14
playbooks/host/host-member-principal-present.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Host member principal present
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host01.example.com principals host/testhost01.example.com and host/myhost01.example.com present
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
principal:
|
||||
- host/testhost01.example.com
|
||||
- host/myhost01.example.com
|
||||
action: member
|
||||
23
playbooks/host/host-present-with-allow_create_keytab.yml
Normal file
23
playbooks/host/host-present-with-allow_create_keytab.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
- name: Host present with allow_create_keytab
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host1.example.com present with allow_create_keytab for users, groups, hosts and hostgroups
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.exmaple.com
|
||||
allow_create_keytab_user:
|
||||
- user01
|
||||
- user02
|
||||
allow_create_keytab_group:
|
||||
- group01
|
||||
- group02
|
||||
allow_create_keytab_host:
|
||||
- host02.exmaple.com
|
||||
- host03.exmaple.com
|
||||
allow_create_keytab_hostgroup:
|
||||
- hostgroup01
|
||||
- hostgroup02
|
||||
ip_address: 192.168.0.123
|
||||
23
playbooks/host/host-present-with-allow_retrieve_keytab.yml
Normal file
23
playbooks/host/host-present-with-allow_retrieve_keytab.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
- name: Host present with allow_retrieve_keytab
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host1.example.com present with allow_retrieve_keytab for users, groups, hosts and hostgroups
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.exmaple.com
|
||||
allow_retrieve_keytab_user:
|
||||
- user01
|
||||
- user02
|
||||
allow_retrieve_keytab_group:
|
||||
- group01
|
||||
- group02
|
||||
allow_retrieve_keytab_host:
|
||||
- host02.exmaple.com
|
||||
- host03.exmaple.com
|
||||
allow_retrieve_keytab_hostgroup:
|
||||
- hostgroup01
|
||||
- hostgroup02
|
||||
ip_address: 192.168.0.123
|
||||
12
playbooks/host/host-present-with-certificate.yml
Normal file
12
playbooks/host/host-present-with-certificate.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
- name: Host present with certificate
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host01.example.com present with certificate
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
certificate:
|
||||
- MIIC/zCCAeegAwIBAgIUZGHLaSYg1myp6EI4VGWSC27vOrswDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4MzVaFw0yMDEwMTMxNjI4MzVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDER/lB8wUAmPTSwSc/NOXNlzdpPOQDSwrhKH6XsqZF4KpQoSY/nmCjAhJmOVpOUo4K2fGRZ0yAH9fkGv6yJP6c7IAFjLeec7GPHVwN4bZrP1DXfTAmfmXhcRQbCYkV+wmq8Puzw/+xA9EJrrodnJPPsE6E8HnSVLF6Ys9+cJMJ7HuwOI+wYt3gkmspsir1tccmf4x1PP+yHJWdcXyetlFRcmZ8gspjqOR2jb89xSQsh8gcyDW6rPNlSTzYZ2FmNtjES6ZhCsYL31fQbF2QglidlLGpAlvHUUS+xCigW73cvhFPMWXcfO51Mr15RcgYTckY+7QZ2nYqplRBoDlQl6DnAgMBAAGjUzBRMB0GA1UdDgQWBBTPG99XVRdxpOXMZo3Nhy+ldnf13TAfBgNVHSMEGDAWgBTPG99XVRdxpOXMZo3Nhy+ldnf13TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAjWTcnIl2mpNbfHAN8DB4Kk+RNRmhsH0y+r/47MXVTMMMToCfofeNY3Jeohu+2lIXMPQfTvXUbDTkNAGsGLv6LtQEUfSREqgk1eY7bT9BFfpH1uV2ZFhCO9jBA+E4bf55Kx7bgUNG31ykBshOsOblOJM1lS/0q4TWHAxrsU2PNwPi8X0ten+eGeB8aRshxS17Ij2cH0fdAMmSA+jMAvTIZl853Bxe0HuozauKwOFWL4qHm61c4O/j1mQCLqJKYfJ9mBDWFQLszd/tF+ePKiNhZCQly60F8Lumn2CDZj5UIkl8wk9Wls5n1BIQs+M8AN65NAdv7+js8jKUKCuyji8r3
|
||||
force: yes
|
||||
11
playbooks/host/host-present-with-managedby_host.yml
Normal file
11
playbooks/host/host-present-with-managedby_host.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Host present with managedby_host
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.exmaple.com
|
||||
managedby_host: server.exmaple.com
|
||||
force: yes
|
||||
14
playbooks/host/host-present-with-principal.yml
Normal file
14
playbooks/host/host-present-with-principal.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Host present with principal
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host01.example.com present with principals host/testhost01.example.com and host/myhost01.example.com
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
principal:
|
||||
- host/testhost01.example.com
|
||||
- host/myhost01.example.com
|
||||
force: yes
|
||||
17
playbooks/host/host-present-with-randompassword.yml
Normal file
17
playbooks/host/host-present-with-randompassword.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
- name: Host present with random password
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Host host01.example.com present with random password
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
random: yes
|
||||
force: yes
|
||||
register: ipahost
|
||||
|
||||
- name: Print generated random password
|
||||
debug:
|
||||
var: ipahost.host.randompassword
|
||||
20
playbooks/host/host-present.yml
Normal file
20
playbooks/host/host-present.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
- name: Host present
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Ensure host is present
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: host01.example.com
|
||||
description: Example host
|
||||
ip_address: 192.168.0.123
|
||||
locality: Lab
|
||||
ns_host_location: Lab
|
||||
ns_os_version: CentOS 7
|
||||
ns_hardware_platform: Lenovo T61
|
||||
mac_address:
|
||||
- "08:00:27:E3:B1:2D"
|
||||
- "52:54:00:BD:97:1E"
|
||||
state: present
|
||||
18
playbooks/host/hosts-member-certificate-absent.yml
Normal file
18
playbooks/host/hosts-member-certificate-absent.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
- name: Hosts member certificate absent
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Hosts host01.example.com and host01.exmaple.com member certificate absent
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
hosts:
|
||||
- name: host01.example.com
|
||||
certificate:
|
||||
- MIIC/zCCAeegAwIBAgIUZGHLaSYg1myp6EI4VGWSC27vOrswDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4MzVaFw0yMDEwMTMxNjI4MzVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDER/lB8wUAmPTSwSc/NOXNlzdpPOQDSwrhKH6XsqZF4KpQoSY/nmCjAhJmOVpOUo4K2fGRZ0yAH9fkGv6yJP6c7IAFjLeec7GPHVwN4bZrP1DXfTAmfmXhcRQbCYkV+wmq8Puzw/+xA9EJrrodnJPPsE6E8HnSVLF6Ys9+cJMJ7HuwOI+wYt3gkmspsir1tccmf4x1PP+yHJWdcXyetlFRcmZ8gspjqOR2jb89xSQsh8gcyDW6rPNlSTzYZ2FmNtjES6ZhCsYL31fQbF2QglidlLGpAlvHUUS+xCigW73cvhFPMWXcfO51Mr15RcgYTckY+7QZ2nYqplRBoDlQl6DnAgMBAAGjUzBRMB0GA1UdDgQWBBTPG99XVRdxpOXMZo3Nhy+ldnf13TAfBgNVHSMEGDAWgBTPG99XVRdxpOXMZo3Nhy+ldnf13TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAjWTcnIl2mpNbfHAN8DB4Kk+RNRmhsH0y+r/47MXVTMMMToCfofeNY3Jeohu+2lIXMPQfTvXUbDTkNAGsGLv6LtQEUfSREqgk1eY7bT9BFfpH1uV2ZFhCO9jBA+E4bf55Kx7bgUNG31ykBshOsOblOJM1lS/0q4TWHAxrsU2PNwPi8X0ten+eGeB8aRshxS17Ij2cH0fdAMmSA+jMAvTIZl853Bxe0HuozauKwOFWL4qHm61c4O/j1mQCLqJKYfJ9mBDWFQLszd/tF+ePKiNhZCQly60F8Lumn2CDZj5UIkl8wk9Wls5n1BIQs+M8AN65NAdv7+js8jKUKCuyji8r3
|
||||
- name: host02.example.com
|
||||
certificate:
|
||||
- MIIC/zCCAeegAwIBAgIUAWE1vaA+mZd3nwZqwWH64EbHvR0wDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4NDVaFw0yMDEwMTMxNjI4NDVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWzJibKtN8Zf7LgandINhFonx99AKi44iaZkrlMKEObE6Faf8NTUbUgK3VfJNYmCbA1baLVJ0YZJijJ7S/4o7h7eeqcJVXJkEhWNTimWXNW/YCzTHe3SSapnSYOKmdHHRClplysL8OyyEG7pbX/aB9iAfFb/+vUFCX5sMwFFrYxOimKJ9Pc/NRFtdv1wNw1rqWKF1ZzagWRlG4QgzRGwQ4quc7yO98TKikj2OPiIt7Zd46hbqQxmgGBtCkVOZIhxu77OmNrFsXmM4rZZpmqh0UdqcpwkRojVnGXmNqeMCd6dNTnLhr9wukUYw0KgE57zCDVr9Ix+p/dA5R1mG4RJ2XAgMBAAGjUzBRMB0GA1UdDgQWBBSbuiH2lNVrID3yt1SsFwtOFKOnpTAfBgNVHSMEGDAWgBSbuiH2lNVrID3yt1SsFwtOFKOnpTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBCVWd293wWyohFqMFMHRBBg97T2Uc1yeT0dMH4BpuOaCqQp4q5ep+uLcXEI6+3mEwm8pa/ULQCD8yLLdotIWlG3+h/4boFpdiPFcBDgT8kGe+0KOzB8Nt7E13QYOu12MNi10qwGrjKhdhu1xBe4fpY5VCetVU1OLyuTsUyucQsFrtZI0SR83h+blbyoMZ7IhMngCfGUe1bnYeWnLbpFbigKfPuVDWsMH2kgj05EAd5EgHkWbX8QA8hmcmDKfNT3YZM8kiGQwmFrnQdq8bN0uHR8Nz+24cbmdbHcD65wlDW6GmYxi8mW+V6bAqn9pir/J14r4YFnqMGgjmdt81tscJV
|
||||
action: member
|
||||
state: absent
|
||||
17
playbooks/host/hosts-member-certificate-present.yml
Normal file
17
playbooks/host/hosts-member-certificate-present.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
- name: Hosts member certificate present
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Hosts host01.example.com and host01.exmaple.com member certificate present
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
hosts:
|
||||
- name: host01.example.com
|
||||
certificate:
|
||||
- MIIC/zCCAeegAwIBAgIUZGHLaSYg1myp6EI4VGWSC27vOrswDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4MzVaFw0yMDEwMTMxNjI4MzVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDER/lB8wUAmPTSwSc/NOXNlzdpPOQDSwrhKH6XsqZF4KpQoSY/nmCjAhJmOVpOUo4K2fGRZ0yAH9fkGv6yJP6c7IAFjLeec7GPHVwN4bZrP1DXfTAmfmXhcRQbCYkV+wmq8Puzw/+xA9EJrrodnJPPsE6E8HnSVLF6Ys9+cJMJ7HuwOI+wYt3gkmspsir1tccmf4x1PP+yHJWdcXyetlFRcmZ8gspjqOR2jb89xSQsh8gcyDW6rPNlSTzYZ2FmNtjES6ZhCsYL31fQbF2QglidlLGpAlvHUUS+xCigW73cvhFPMWXcfO51Mr15RcgYTckY+7QZ2nYqplRBoDlQl6DnAgMBAAGjUzBRMB0GA1UdDgQWBBTPG99XVRdxpOXMZo3Nhy+ldnf13TAfBgNVHSMEGDAWgBTPG99XVRdxpOXMZo3Nhy+ldnf13TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAjWTcnIl2mpNbfHAN8DB4Kk+RNRmhsH0y+r/47MXVTMMMToCfofeNY3Jeohu+2lIXMPQfTvXUbDTkNAGsGLv6LtQEUfSREqgk1eY7bT9BFfpH1uV2ZFhCO9jBA+E4bf55Kx7bgUNG31ykBshOsOblOJM1lS/0q4TWHAxrsU2PNwPi8X0ten+eGeB8aRshxS17Ij2cH0fdAMmSA+jMAvTIZl853Bxe0HuozauKwOFWL4qHm61c4O/j1mQCLqJKYfJ9mBDWFQLszd/tF+ePKiNhZCQly60F8Lumn2CDZj5UIkl8wk9Wls5n1BIQs+M8AN65NAdv7+js8jKUKCuyji8r3
|
||||
- name: host02.example.com
|
||||
certificate:
|
||||
- MIIC/zCCAeegAwIBAgIUAWE1vaA+mZd3nwZqwWH64EbHvR0wDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4NDVaFw0yMDEwMTMxNjI4NDVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWzJibKtN8Zf7LgandINhFonx99AKi44iaZkrlMKEObE6Faf8NTUbUgK3VfJNYmCbA1baLVJ0YZJijJ7S/4o7h7eeqcJVXJkEhWNTimWXNW/YCzTHe3SSapnSYOKmdHHRClplysL8OyyEG7pbX/aB9iAfFb/+vUFCX5sMwFFrYxOimKJ9Pc/NRFtdv1wNw1rqWKF1ZzagWRlG4QgzRGwQ4quc7yO98TKikj2OPiIt7Zd46hbqQxmgGBtCkVOZIhxu77OmNrFsXmM4rZZpmqh0UdqcpwkRojVnGXmNqeMCd6dNTnLhr9wukUYw0KgE57zCDVr9Ix+p/dA5R1mG4RJ2XAgMBAAGjUzBRMB0GA1UdDgQWBBSbuiH2lNVrID3yt1SsFwtOFKOnpTAfBgNVHSMEGDAWgBSbuiH2lNVrID3yt1SsFwtOFKOnpTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBCVWd293wWyohFqMFMHRBBg97T2Uc1yeT0dMH4BpuOaCqQp4q5ep+uLcXEI6+3mEwm8pa/ULQCD8yLLdotIWlG3+h/4boFpdiPFcBDgT8kGe+0KOzB8Nt7E13QYOu12MNi10qwGrjKhdhu1xBe4fpY5VCetVU1OLyuTsUyucQsFrtZI0SR83h+blbyoMZ7IhMngCfGUe1bnYeWnLbpFbigKfPuVDWsMH2kgj05EAd5EgHkWbX8QA8hmcmDKfNT3YZM8kiGQwmFrnQdq8bN0uHR8Nz+24cbmdbHcD65wlDW6GmYxi8mW+V6bAqn9pir/J14r4YFnqMGgjmdt81tscJV
|
||||
action: member
|
||||
15
playbooks/host/hosts-member-managedby_host-absent.yml
Normal file
15
playbooks/host/hosts-member-managedby_host-absent.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: Hosts member managedby_host absent
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
hosts:
|
||||
- name: host01.exmaple.com
|
||||
managedby_host: server.exmaple.com
|
||||
- name: host02.exmaple.com
|
||||
managedby_host: server.exmaple.com
|
||||
action: member
|
||||
state: absent
|
||||
14
playbooks/host/hosts-member-managedby_host-present.yml
Normal file
14
playbooks/host/hosts-member-managedby_host-present.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Hosts member managedby_host present
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
hosts:
|
||||
- name: host01.exmaple.com
|
||||
managedby_host: server.exmaple.com
|
||||
- name: host02.exmaple.com
|
||||
managedby_host: server.exmaple.com
|
||||
action: member
|
||||
18
playbooks/host/hosts-member-principal-absent.yml
Normal file
18
playbooks/host/hosts-member-principal-absent.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
- name: Host member principal absent
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Hosts host01.exmaple.com and host02.exmaple.com member principals host/testhost0X.exmaple.com absent
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
hosts:
|
||||
- name: host01.exmaple.com
|
||||
principal:
|
||||
- host/testhost01.exmaple.com
|
||||
- name: host02.exmaple.com
|
||||
principal:
|
||||
- host/testhost02.exmaple.com
|
||||
action: member
|
||||
state: absent
|
||||
17
playbooks/host/hosts-member-principal-present.yml
Normal file
17
playbooks/host/hosts-member-principal-present.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
- name: Hosts member principal present
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Hosts host01.exmaple.com and host02.exmaple.com member principals host/testhost0X.exmaple.com present
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
hosts:
|
||||
- name: host01.exmaple.com
|
||||
principal:
|
||||
- host/testhost01.exmaple.com
|
||||
- name: host02.exmaple.com
|
||||
principal:
|
||||
- host/testhost02.exmaple.com
|
||||
action: member
|
||||
17
playbooks/host/hosts-present-with-certificate.yml
Normal file
17
playbooks/host/hosts-present-with-certificate.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
- name: Hosts present with certificate
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Hosts host01.example.com and host01.exmaple.com present with certificate
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
hosts:
|
||||
- name: host01.example.com
|
||||
certificate:
|
||||
- MIIC/zCCAeegAwIBAgIUZGHLaSYg1myp6EI4VGWSC27vOrswDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4MzVaFw0yMDEwMTMxNjI4MzVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDER/lB8wUAmPTSwSc/NOXNlzdpPOQDSwrhKH6XsqZF4KpQoSY/nmCjAhJmOVpOUo4K2fGRZ0yAH9fkGv6yJP6c7IAFjLeec7GPHVwN4bZrP1DXfTAmfmXhcRQbCYkV+wmq8Puzw/+xA9EJrrodnJPPsE6E8HnSVLF6Ys9+cJMJ7HuwOI+wYt3gkmspsir1tccmf4x1PP+yHJWdcXyetlFRcmZ8gspjqOR2jb89xSQsh8gcyDW6rPNlSTzYZ2FmNtjES6ZhCsYL31fQbF2QglidlLGpAlvHUUS+xCigW73cvhFPMWXcfO51Mr15RcgYTckY+7QZ2nYqplRBoDlQl6DnAgMBAAGjUzBRMB0GA1UdDgQWBBTPG99XVRdxpOXMZo3Nhy+ldnf13TAfBgNVHSMEGDAWgBTPG99XVRdxpOXMZo3Nhy+ldnf13TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAjWTcnIl2mpNbfHAN8DB4Kk+RNRmhsH0y+r/47MXVTMMMToCfofeNY3Jeohu+2lIXMPQfTvXUbDTkNAGsGLv6LtQEUfSREqgk1eY7bT9BFfpH1uV2ZFhCO9jBA+E4bf55Kx7bgUNG31ykBshOsOblOJM1lS/0q4TWHAxrsU2PNwPi8X0ten+eGeB8aRshxS17Ij2cH0fdAMmSA+jMAvTIZl853Bxe0HuozauKwOFWL4qHm61c4O/j1mQCLqJKYfJ9mBDWFQLszd/tF+ePKiNhZCQly60F8Lumn2CDZj5UIkl8wk9Wls5n1BIQs+M8AN65NAdv7+js8jKUKCuyji8r3
|
||||
- name: host02.example.com
|
||||
certificate:
|
||||
- MIIC/zCCAeegAwIBAgIUAWE1vaA+mZd3nwZqwWH64EbHvR0wDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4NDVaFw0yMDEwMTMxNjI4NDVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWzJibKtN8Zf7LgandINhFonx99AKi44iaZkrlMKEObE6Faf8NTUbUgK3VfJNYmCbA1baLVJ0YZJijJ7S/4o7h7eeqcJVXJkEhWNTimWXNW/YCzTHe3SSapnSYOKmdHHRClplysL8OyyEG7pbX/aB9iAfFb/+vUFCX5sMwFFrYxOimKJ9Pc/NRFtdv1wNw1rqWKF1ZzagWRlG4QgzRGwQ4quc7yO98TKikj2OPiIt7Zd46hbqQxmgGBtCkVOZIhxu77OmNrFsXmM4rZZpmqh0UdqcpwkRojVnGXmNqeMCd6dNTnLhr9wukUYw0KgE57zCDVr9Ix+p/dA5R1mG4RJ2XAgMBAAGjUzBRMB0GA1UdDgQWBBSbuiH2lNVrID3yt1SsFwtOFKOnpTAfBgNVHSMEGDAWgBSbuiH2lNVrID3yt1SsFwtOFKOnpTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBCVWd293wWyohFqMFMHRBBg97T2Uc1yeT0dMH4BpuOaCqQp4q5ep+uLcXEI6+3mEwm8pa/ULQCD8yLLdotIWlG3+h/4boFpdiPFcBDgT8kGe+0KOzB8Nt7E13QYOu12MNi10qwGrjKhdhu1xBe4fpY5VCetVU1OLyuTsUyucQsFrtZI0SR83h+blbyoMZ7IhMngCfGUe1bnYeWnLbpFbigKfPuVDWsMH2kgj05EAd5EgHkWbX8QA8hmcmDKfNT3YZM8kiGQwmFrnQdq8bN0uHR8Nz+24cbmdbHcD65wlDW6GmYxi8mW+V6bAqn9pir/J14r4YFnqMGgjmdt81tscJV
|
||||
force: yes
|
||||
15
playbooks/host/hosts-present-with-managedby_host.yml
Normal file
15
playbooks/host/hosts-present-with-managedby_host.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: Host present with managedby_host
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
hosts:
|
||||
- name: host01.exmaple.com
|
||||
managedby_host: server.exmaple.com
|
||||
force: yes
|
||||
- name: host02.exmaple.com
|
||||
managedby_host: server.exmaple.com
|
||||
force: yes
|
||||
26
playbooks/host/hosts-present-with-randompasswords.yml
Normal file
26
playbooks/host/hosts-present-with-randompasswords.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
- name: Hosts present with random passwords
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Hosts host01.example.com and host01.example.com present with random passwords
|
||||
ipahost:
|
||||
ipaadmin_password: MyPassword123
|
||||
hosts:
|
||||
- name: host01.example.com
|
||||
random: yes
|
||||
force: yes
|
||||
- name: host02.example.com
|
||||
random: yes
|
||||
force: yes
|
||||
register: ipahost
|
||||
|
||||
- name: Print generated random password for host01.example.com
|
||||
debug:
|
||||
var: ipahost.host["host01.example.com"].randompassword
|
||||
|
||||
- name: Print generated random password for host02.example.com
|
||||
debug:
|
||||
var: ipahost.host["host02.example.com"].randompassword
|
||||
|
||||
11
playbooks/hostgroup/ensure-hostgroup-is-absent.yml
Normal file
11
playbooks/hostgroup/ensure-hostgroup-is-absent.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Playbook to handle hostgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure host-group databases is present
|
||||
- ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
state: absent
|
||||
15
playbooks/hostgroup/ensure-hostgroup-is-present.yml
Normal file
15
playbooks/hostgroup/ensure-hostgroup-is-present.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: Playbook to handle hostgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure host-group databases is present
|
||||
- ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
host:
|
||||
- db.example.com
|
||||
hostgroup:
|
||||
- mysql-server
|
||||
- oracle-server
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
- name: Playbook to handle hostgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure hosts and hostgroups are present in existing databases hostgroup
|
||||
- ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
host:
|
||||
- db.example.com
|
||||
hostgroup:
|
||||
- mysql-server
|
||||
- oracle-server
|
||||
action: member
|
||||
state: absent
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
- name: Playbook to handle hostgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure hosts and hostgroups are present in existing databases hostgroup
|
||||
- ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
host:
|
||||
- db.example.com
|
||||
hostgroup:
|
||||
- mysql-server
|
||||
- oracle-server
|
||||
action: member
|
||||
12
playbooks/pwpolicy/pwpolicy_absent.yml
Normal file
12
playbooks/pwpolicy/pwpolicy_absent.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure absence of pwpolicies for group ops
|
||||
ipapwpolicy:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: ops
|
||||
state: absent
|
||||
20
playbooks/pwpolicy/pwpolicy_present.yml
Normal file
20
playbooks/pwpolicy/pwpolicy_present.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure presence of pwpolicies for group ops
|
||||
ipapwpolicy:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: ops
|
||||
minlife: 7
|
||||
maxlife: 49
|
||||
history: 5
|
||||
priority: 1
|
||||
lockouttime: 300
|
||||
minlength: 8
|
||||
minclasses: 5
|
||||
maxfail: 3
|
||||
failinterval: 5
|
||||
11
playbooks/sudocmd/ensure-sudocmd-is-absent.yml
Normal file
11
playbooks/sudocmd/ensure-sudocmd-is-absent.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Playbook to manage sudo command
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudo command is absent
|
||||
- ipasudocmd:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: /usr/bin/su
|
||||
state: absent
|
||||
11
playbooks/sudocmd/ensure-sudocmd-is-present.yml
Normal file
11
playbooks/sudocmd/ensure-sudocmd-is-present.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Playbook to manage sudo command
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudo command is present
|
||||
- ipasudocmd:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: /usr/bin/su
|
||||
state: present
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: Playbook to handle sudocmdgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudocmds are absent in sudocmdgroup
|
||||
- ipasudocmdgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: network
|
||||
sudocmd:
|
||||
- /usr/sbin/ifconfig
|
||||
- /usr/sbin/iwlist
|
||||
action: member
|
||||
state: absent
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
- name: Playbook to handle sudocmdgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudo commands are present
|
||||
- ipasudocmd:
|
||||
ipaadmin_password: MyPassword123
|
||||
name:
|
||||
- /usr/sbin/ifconfig
|
||||
- /usr/sbin/iwlist
|
||||
state: present
|
||||
|
||||
# Ensure sudo commands are present in existing sudocmdgroup
|
||||
- ipasudocmdgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: network
|
||||
sudocmd:
|
||||
- /usr/sbin/ifconfig
|
||||
- /usr/sbin/iwlist
|
||||
action: member
|
||||
12
playbooks/sudocmdgroup/ensure-sudocmdgroup-is-absent.yml
Normal file
12
playbooks/sudocmdgroup/ensure-sudocmdgroup-is-absent.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Playbook to handle sudocmdgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudocmdgroup is absent
|
||||
- ipasudocmdgroup:
|
||||
ipaadmin_password: pass1234
|
||||
name: network
|
||||
state: absent
|
||||
action: sudocmdgroup
|
||||
15
playbooks/sudocmdgroup/ensure-sudocmdgroup-is-present.yml
Normal file
15
playbooks/sudocmdgroup/ensure-sudocmdgroup-is-present.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: Playbook to handle sudocmdgroups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudocmdgroup sudocmds are present
|
||||
- ipasudocmdgroup:
|
||||
ipaadmin_password: pass1234
|
||||
name: network
|
||||
description: Group of important commands.
|
||||
sudocmd:
|
||||
- /usr/sbin/ifconfig
|
||||
- /usr/sbin/iwlist
|
||||
state: present
|
||||
14
playbooks/sudorule/ensure-sudorule-host-member-is-absent.yml
Normal file
14
playbooks/sudorule/ensure-sudorule-host-member-is-absent.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
# Ensure host server is absent in Sudo Rule
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
host: server
|
||||
action: member
|
||||
state: absent
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
# Ensure host server is present in Sudo Rule
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
host: server
|
||||
action: member
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
# Ensure hostgroup cluster is absent in Sudo Rule
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
hostgroup: cluster
|
||||
action: member
|
||||
state: absent
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
# Ensure hostgrep cluster is present in Sudo Rule
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
hostgroup: cluster
|
||||
action: member
|
||||
11
playbooks/sudorule/ensure-sudorule-is-absent.yml
Normal file
11
playbooks/sudorule/ensure-sudorule-is-absent.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudorule command is absent
|
||||
- ipasudorule:
|
||||
ipaadmin_password: pass1234
|
||||
name: testrule1
|
||||
state: absent
|
||||
11
playbooks/sudorule/ensure-sudorule-is-disabled.yml
Normal file
11
playbooks/sudorule/ensure-sudorule-is-disabled.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudorule command is disabled
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
state: disabled
|
||||
11
playbooks/sudorule/ensure-sudorule-is-enabled.yml
Normal file
11
playbooks/sudorule/ensure-sudorule-is-enabled.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudorule command is enabled
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
state: enabled
|
||||
12
playbooks/sudorule/ensure-sudorule-is-present.yml
Normal file
12
playbooks/sudorule/ensure-sudorule-is-present.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure sudorule command is present
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
description: A test sudo rule.
|
||||
state: present
|
||||
15
playbooks/sudorule/ensure-sudorule-sudocmd-is-absent.yml
Normal file
15
playbooks/sudorule/ensure-sudorule-sudocmd-is-absent.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
cmd:
|
||||
- /sbin/ifconfig
|
||||
- /usr/bin/vim
|
||||
action: member
|
||||
state: absent
|
||||
14
playbooks/sudorule/ensure-sudorule-sudocmd-is-present.yml
Normal file
14
playbooks/sudorule/ensure-sudorule-sudocmd-is-present.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
cmd:
|
||||
- /sbin/ifconfig
|
||||
- /usr/bin/vim
|
||||
action: member
|
||||
19
playbooks/user/ensure_user_with_randompassword.yml
Normal file
19
playbooks/user/ensure_user_with_randompassword.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
- name: Ensure user with random password
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: User user1 present with random password
|
||||
ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: user1
|
||||
first: first1
|
||||
last: last1
|
||||
random: yes
|
||||
update_password: on_create
|
||||
register: ipauser
|
||||
|
||||
- name: Print generated random password
|
||||
debug:
|
||||
var: ipauser.user.randompassword
|
||||
28
playbooks/user/ensure_users_with_randompasswords.yml
Normal file
28
playbooks/user/ensure_users_with_randompasswords.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Users user1 and user1 present with random password
|
||||
ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
users:
|
||||
- name: user1
|
||||
first: first1
|
||||
last: last1
|
||||
random: yes
|
||||
- name: user2
|
||||
first: first2
|
||||
last: last2
|
||||
random: yes
|
||||
update_password: on_create
|
||||
register: ipauser
|
||||
|
||||
- name: Print generated random password for user1
|
||||
debug:
|
||||
var: ipauser.user.user1.randompassword
|
||||
|
||||
- name: Print generated random password for user2
|
||||
debug:
|
||||
var: ipauser.user.user2.randompassword
|
||||
16
playbooks/user/user_certificate_absent.yml
Normal file
16
playbooks/user/user_certificate_absent.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
- name: Test user certificates
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: User test cert absent
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: test
|
||||
certificate:
|
||||
- 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
- MIIC/zCCAeegAwIBAgIUAWE1vaA+mZd3nwZqwWH64EbHvR0wDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4NDVaFw0yMDEwMTMxNjI4NDVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWzJibKtN8Zf7LgandINhFonx99AKi44iaZkrlMKEObE6Faf8NTUbUgK3VfJNYmCbA1baLVJ0YZJijJ7S/4o7h7eeqcJVXJkEhWNTimWXNW/YCzTHe3SSapnSYOKmdHHRClplysL8OyyEG7pbX/aB9iAfFb/+vUFCX5sMwFFrYxOimKJ9Pc/NRFtdv1wNw1rqWKF1ZzagWRlG4QgzRGwQ4quc7yO98TKikj2OPiIt7Zd46hbqQxmgGBtCkVOZIhxu77OmNrFsXmM4rZZpmqh0UdqcpwkRojVnGXmNqeMCd6dNTnLhr9wukUYw0KgE57zCDVr9Ix+p/dA5R1mG4RJ2XAgMBAAGjUzBRMB0GA1UdDgQWBBSbuiH2lNVrID3yt1SsFwtOFKOnpTAfBgNVHSMEGDAWgBSbuiH2lNVrID3yt1SsFwtOFKOnpTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBCVWd293wWyohFqMFMHRBBg97T2Uc1yeT0dMH4BpuOaCqQp4q5ep+uLcXEI6+3mEwm8pa/ULQCD8yLLdotIWlG3+h/4boFpdiPFcBDgT8kGe+0KOzB8Nt7E13QYOu12MNi10qwGrjKhdhu1xBe4fpY5VCetVU1OLyuTsUyucQsFrtZI0SR83h+blbyoMZ7IhMngCfGUe1bnYeWnLbpFbigKfPuVDWsMH2kgj05EAd5EgHkWbX8QA8hmcmDKfNT3YZM8kiGQwmFrnQdq8bN0uHR8Nz+24cbmdbHcD65wlDW6GmYxi8mW+V6bAqn9pir/J14r4YFnqMGgjmdt81tscJV
|
||||
- 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
|
||||
state: absent
|
||||
15
playbooks/user/user_certificate_present.yml
Normal file
15
playbooks/user/user_certificate_present.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: Test user certificates
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: User test cert present
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: test
|
||||
certificate:
|
||||
- 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
- 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
- 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
|
||||
40
playbooks/user/user_present.yml
Normal file
40
playbooks/user/user_present.yml
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: User pinky present
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: pinky
|
||||
uid: 10001
|
||||
gid: 100
|
||||
phone: "+555123457"
|
||||
email: pinky@acme.com
|
||||
principalexpiration: "20220119235959"
|
||||
passwordexpiration: "2022-01-19 23:59:59"
|
||||
first: pinky
|
||||
last: Acme
|
||||
initials: pa
|
||||
principal: pa
|
||||
random: yes
|
||||
city: PinkyCity
|
||||
userstate: PinkyState
|
||||
postalcode: 321
|
||||
mobile: "+555123458,+555123459"
|
||||
pager: "+555123450,+555123451"
|
||||
fax: "+555123452,+555123453"
|
||||
orgunit: PinkyOrgUnit
|
||||
manager: manager1,manager2
|
||||
update_password: on_create
|
||||
carlicense: PinkyCarLicense1,PinkyCarLicense2
|
||||
userauthtype: password,radius,otp
|
||||
userclass: PinkyUserClass
|
||||
departmentnumber: "1234"
|
||||
employeenumber: "0815"
|
||||
employeetype: "PinkyExmployeeType"
|
||||
preferredlanguage: "en"
|
||||
noprivate: yes
|
||||
nomembers: false
|
||||
42
playbooks/user/users_absent.yml
Normal file
42
playbooks/user/users_absent.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Users user1..10 absent
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users:
|
||||
- name: user1
|
||||
givenname: user1
|
||||
last: Last
|
||||
- name: user2
|
||||
first: user2
|
||||
last: Last
|
||||
- name: user3
|
||||
first: user3
|
||||
last: Last
|
||||
- name: user4
|
||||
first: user4
|
||||
last: Last
|
||||
- name: user5
|
||||
first: user5
|
||||
last: Last
|
||||
- name: user6
|
||||
first: user6
|
||||
last: Last
|
||||
- name: user7
|
||||
first: user7
|
||||
last: Last
|
||||
- name: user8
|
||||
first: user8
|
||||
last: Last
|
||||
- name: user9
|
||||
first: user9
|
||||
last: Last
|
||||
- name: user10
|
||||
first: user10
|
||||
last: Last
|
||||
state: absent
|
||||
17
playbooks/user/users_certificate_absent.yml
Normal file
17
playbooks/user/users_certificate_absent.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
- name: Test user certificates
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: User test cert absent
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users:
|
||||
- name: test
|
||||
certificate:
|
||||
- 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
- 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
- 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
|
||||
state: absent
|
||||
16
playbooks/user/users_certificate_present.yml
Normal file
16
playbooks/user/users_certificate_present.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
- name: Test user certificates
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: User test cert present
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users:
|
||||
- name: test
|
||||
certificate:
|
||||
- MIIC/zCCAeegAwIBAgIUZGHLaSYg1myp6EI4VGWSC27vOrswDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEdGVzdDAeFw0xOTEwMTQxNjI4MzVaFw0yMDEwMTMxNjI4MzVaMA8xDTALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDER/lB8wUAmPTSwSc/NOXNlzdpPOQDSwrhKH6XsqZF4KpQoSY/nmCjAhJmOVpOUo4K2fGRZ0yAH9fkGv6yJP6c7IAFjLeec7GPHVwN4bZrP1DXfTAmfmXhcRQbCYkV+wmq8Puzw/+xA9EJrrodnJPPsE6E8HnSVLF6Ys9+cJMJ7HuwOI+wYt3gkmspsir1tccmf4x1PP+yHJWdcXyetlFRcmZ8gspjqOR2jb89xSQsh8gcyDW6rPNlSTzYZ2FmNtjES6ZhCsYL31fQbF2QglidlLGpAlvHUUS+xCigW73cvhFPMWXcfO51Mr15RcgYTckY+7QZ2nYqplRBoDlQl6DnAgMBAAGjUzBRMB0GA1UdDgQWBBTPG99XVRdxpOXMZo3Nhy+ldnf13TAfBgNVHSMEGDAWgBTPG99XVRdxpOXMZo3Nhy+ldnf13TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAjWTcnIl2mpNbfHAN8DB4Kk+RNRmhsH0y+r/47MXVTMMMToCfofeNY3Jeohu+2lIXMPQfTvXUbDTkNAGsGLv6LtQEUfSREqgk1eY7bT9BFfpH1uV2ZFhCO9jBA+E4bf55Kx7bgUNG31ykBshOsOblOJM1lS/0q4TWHAxrsU2PNwPi8X0ten+eGeB8aRshxS17Ij2cH0fdAMmSA+jMAvTIZl853Bxe0HuozauKwOFWL4qHm61c4O/j1mQCLqJKYfJ9mBDWFQLszd/tF+ePKiNhZCQly60F8Lumn2CDZj5UIkl8wk9Wls5n1BIQs+M8AN65NAdv7+js8jKUKCuyji8r3
|
||||
- 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
- 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
|
||||
41
playbooks/user/users_present.yml
Normal file
41
playbooks/user/users_present.yml
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
- name: Tests
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Users user1..10 present
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users:
|
||||
- name: user1
|
||||
first: user1
|
||||
last: Last
|
||||
- name: user2
|
||||
first: user2
|
||||
last: Last
|
||||
- name: user3
|
||||
first: user3
|
||||
last: Last
|
||||
- name: user4
|
||||
first: user4
|
||||
last: Last
|
||||
- name: user5
|
||||
first: user5
|
||||
last: Last
|
||||
- name: user6
|
||||
first: user6
|
||||
last: Last
|
||||
- name: user7
|
||||
first: user7
|
||||
last: Last
|
||||
- name: user8
|
||||
first: user8
|
||||
last: Last
|
||||
- name: user9
|
||||
first: user9
|
||||
last: Last
|
||||
- name: user10
|
||||
first: user10
|
||||
last: Last
|
||||
@@ -22,25 +22,66 @@
|
||||
|
||||
|
||||
import os
|
||||
import uuid
|
||||
import tempfile
|
||||
import shutil
|
||||
import gssapi
|
||||
from datetime import datetime
|
||||
from ipalib import api
|
||||
from ipalib.config import Env
|
||||
from ipalib.constants import DEFAULT_CONFIG, LDAP_GENERALIZED_TIME_FORMAT
|
||||
try:
|
||||
from ipalib.install.kinit import kinit_password
|
||||
from ipalib.install.kinit import kinit_password, kinit_keytab
|
||||
except ImportError:
|
||||
from ipapython.ipautil import kinit_password
|
||||
from ipapython.ipautil import kinit_password, kinit_keytab
|
||||
from ipapython.ipautil import run
|
||||
from ipaplatform.paths import paths
|
||||
from ipalib.krb_utils import get_credentials_if_valid
|
||||
from ansible.module_utils._text import to_text
|
||||
try:
|
||||
from ipalib.x509 import Encoding
|
||||
except ImportError:
|
||||
from cryptography.hazmat.primitives.serialization import Encoding
|
||||
import base64
|
||||
import six
|
||||
|
||||
|
||||
def valid_creds(principal):
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
|
||||
|
||||
def valid_creds(module, principal):
|
||||
"""
|
||||
Get valid credintials matching the princial
|
||||
Get valid credintials matching the princial, try GSSAPI first
|
||||
"""
|
||||
if "KRB5CCNAME" in os.environ:
|
||||
ccache = os.environ["KRB5CCNAME"]
|
||||
module.debug('KRB5CCNAME set to %s' % ccache)
|
||||
|
||||
try:
|
||||
cred = gssapi.Credentials(usage='initiate',
|
||||
store={'ccache': ccache})
|
||||
except gssapi.raw.misc.GSSError as e:
|
||||
module.fail_json(msg='Failed to find default ccache: %s' % e)
|
||||
else:
|
||||
module.debug("Using principal %s" % str(cred.name))
|
||||
return True
|
||||
|
||||
elif "KRB5_CLIENT_KTNAME" in os.environ:
|
||||
keytab = os.environ.get('KRB5_CLIENT_KTNAME', None)
|
||||
module.debug('KRB5_CLIENT_KTNAME set to %s' % keytab)
|
||||
|
||||
ccache_name = "MEMORY:%s" % str(uuid.uuid4())
|
||||
os.environ["KRB5CCNAME"] = ccache_name
|
||||
|
||||
try:
|
||||
cred = kinit_keytab(principal, keytab, ccache_name)
|
||||
except gssapi.raw.misc.GSSError as e:
|
||||
module.fail_json(msg='Kerberos authentication failed : %s' % e)
|
||||
else:
|
||||
module.debug("Using principal %s" % str(cred.name))
|
||||
return True
|
||||
|
||||
creds = get_credentials_if_valid()
|
||||
if creds and \
|
||||
creds.lifetime > 0 and \
|
||||
@@ -79,7 +120,7 @@ def temp_kdestroy(ccache_dir, ccache_name):
|
||||
shutil.rmtree(ccache_dir, ignore_errors=True)
|
||||
|
||||
|
||||
def api_connect():
|
||||
def api_connect(context=None):
|
||||
"""
|
||||
Create environment, initialize api and connect to ldap2
|
||||
"""
|
||||
@@ -87,19 +128,34 @@ def api_connect():
|
||||
env._bootstrap()
|
||||
env._finalize_core(**dict(DEFAULT_CONFIG))
|
||||
|
||||
api.bootstrap(context='server', debug=env.debug, log=None)
|
||||
# available contexts are 'server', 'ansible-freeipa' and 'cli_installer'
|
||||
if context is None:
|
||||
context = 'server'
|
||||
|
||||
api.bootstrap(context=context, debug=env.debug, log=None)
|
||||
api.finalize()
|
||||
api.Backend.ldap2.connect()
|
||||
|
||||
if api.env.in_server:
|
||||
backend = api.Backend.ldap2
|
||||
else:
|
||||
backend = api.Backend.rpcclient
|
||||
|
||||
if not backend.isconnected():
|
||||
backend.connect()
|
||||
|
||||
|
||||
def api_command(module, command, name, args):
|
||||
"""
|
||||
Call ipa.Command, use AnsibleModule.fail_json for error handling
|
||||
Call ipa.Command
|
||||
"""
|
||||
try:
|
||||
return api.Command[command](name, **args)
|
||||
except Exception as e:
|
||||
module.fail_json(msg="%s: %s" % (command, e))
|
||||
return api.Command[command](name, **args)
|
||||
|
||||
|
||||
def api_check_param(command, name):
|
||||
"""
|
||||
Return if param exists in command param list
|
||||
"""
|
||||
return name in api.Command[command].params
|
||||
|
||||
|
||||
def execute_api_command(module, principal, password, command, name, args):
|
||||
@@ -110,7 +166,7 @@ def execute_api_command(module, principal, password, command, name, args):
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(principal):
|
||||
if not valid_creds(module, principal):
|
||||
ccache_dir, ccache_name = temp_kinit(principal, password)
|
||||
api_connect()
|
||||
|
||||
@@ -150,10 +206,65 @@ def compare_args_ipa(module, args, ipa):
|
||||
# If ipa_arg is a list and arg is not, replace arg
|
||||
# with list containing arg. Most args in a find result
|
||||
# are lists, but not all.
|
||||
if isinstance(ipa_arg, list) and not isinstance(arg, list):
|
||||
arg = [arg]
|
||||
if isinstance(ipa_arg, tuple):
|
||||
ipa_arg = list(ipa_arg)
|
||||
if isinstance(ipa_arg, list):
|
||||
if not isinstance(arg, list):
|
||||
arg = [arg]
|
||||
if isinstance(ipa_arg[0], str) and isinstance(arg[0], int):
|
||||
arg = [to_text(_arg) for _arg in arg]
|
||||
if isinstance(ipa_arg[0], unicode) and isinstance(arg[0], int):
|
||||
arg = [to_text(_arg) for _arg in arg]
|
||||
# module.warn("%s <=> %s" % (arg, ipa_arg))
|
||||
if arg != ipa_arg:
|
||||
if set(arg) != set(ipa_arg):
|
||||
# module.warn("DIFFERENT")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def _afm_convert(value):
|
||||
if value is not None:
|
||||
if isinstance(value, list):
|
||||
return [_afm_convert(x) for x in value]
|
||||
elif isinstance(value, dict):
|
||||
return {_afm_convert(k): _afm_convert(v) for k, v in value.items()}
|
||||
elif isinstance(value, str):
|
||||
return to_text(value)
|
||||
else:
|
||||
return value
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
def module_params_get(module, name):
|
||||
return _afm_convert(module.params.get(name))
|
||||
|
||||
|
||||
def api_get_realm():
|
||||
return api.env.realm
|
||||
|
||||
|
||||
def gen_add_del_lists(user_list, res_list):
|
||||
"""
|
||||
Generate the lists for the addition and removal of members using the
|
||||
provided user and ipa settings
|
||||
"""
|
||||
add_list = list(set(user_list or []) - set(res_list or []))
|
||||
del_list = list(set(res_list or []) - set(user_list or []))
|
||||
|
||||
return add_list, del_list
|
||||
|
||||
|
||||
def encode_certificate(cert):
|
||||
"""
|
||||
Encode a certificate using base64 with also taking FreeIPA and Python
|
||||
versions into account
|
||||
"""
|
||||
if isinstance(cert, str) or isinstance(cert, unicode):
|
||||
encoded = base64.b64encode(cert)
|
||||
else:
|
||||
encoded = base64.b64encode(cert.public_bytes(Encoding.DER))
|
||||
if not six.PY2:
|
||||
encoded = encoded.decode('ascii')
|
||||
return encoded
|
||||
|
||||
@@ -70,7 +70,9 @@ options:
|
||||
required: false
|
||||
type: list
|
||||
service:
|
||||
description: List of service names assigned to this group.
|
||||
description:
|
||||
- List of service names assigned to this group.
|
||||
- Only usable with IPA versions 4.7 and up.
|
||||
required: false
|
||||
type: list
|
||||
action:
|
||||
@@ -137,18 +139,18 @@ RETURN = """
|
||||
"""
|
||||
|
||||
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, compare_args_ipa
|
||||
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
|
||||
api_check_param, module_params_get
|
||||
|
||||
|
||||
def find_group(module, name):
|
||||
_args = {
|
||||
"all": True,
|
||||
"cn": to_text(name),
|
||||
"cn": name,
|
||||
}
|
||||
|
||||
_result = api_command(module, "group_find", to_text(name), _args)
|
||||
_result = api_command(module, "group_find", name, _args)
|
||||
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
@@ -164,7 +166,7 @@ def gen_args(description, gid, nonposix, external, nomembers):
|
||||
if description is not None:
|
||||
_args["description"] = description
|
||||
if gid is not None:
|
||||
_args["gidnumber"] = str(gid)
|
||||
_args["gidnumber"] = gid
|
||||
if nonposix is not None:
|
||||
_args["nonposix"] = nonposix
|
||||
if external is not None:
|
||||
@@ -209,8 +211,7 @@ def main():
|
||||
choices=["member", "group"]),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent",
|
||||
"member_present", "member_absent"]),
|
||||
choices=["present", "absent"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
@@ -220,29 +221,29 @@ def main():
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
ipaadmin_principal = ansible_module.params.get("ipaadmin_principal")
|
||||
ipaadmin_password = ansible_module.params.get("ipaadmin_password")
|
||||
names = ansible_module.params.get("name")
|
||||
ipaadmin_principal = module_params_get(ansible_module, "ipaadmin_principal")
|
||||
ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password")
|
||||
names = module_params_get(ansible_module, "name")
|
||||
|
||||
# present
|
||||
description = ansible_module.params.get("description")
|
||||
gid = ansible_module.params.get("gid")
|
||||
nonposix = ansible_module.params.get("nonposix")
|
||||
external = ansible_module.params.get("external")
|
||||
nomembers = ansible_module.params.get("nomembers")
|
||||
user = ansible_module.params.get("user")
|
||||
group = ansible_module.params.get("group")
|
||||
service = ansible_module.params.get("service")
|
||||
action = ansible_module.params.get("action")
|
||||
description = module_params_get(ansible_module, "description")
|
||||
gid = module_params_get(ansible_module, "gid")
|
||||
nonposix = module_params_get(ansible_module, "nonposix")
|
||||
external = module_params_get(ansible_module, "external")
|
||||
nomembers = module_params_get(ansible_module, "nomembers")
|
||||
user = module_params_get(ansible_module, "user")
|
||||
group = module_params_get(ansible_module, "group")
|
||||
service = module_params_get(ansible_module, "service")
|
||||
action = module_params_get(ansible_module, "action")
|
||||
# state
|
||||
state = ansible_module.params.get("state")
|
||||
state = module_params_get(ansible_module, "state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Onle one group can be added at a time.")
|
||||
msg="Only one group can be added at a time.")
|
||||
if action == "member":
|
||||
invalid = ["description", "gid", "nonposix", "external",
|
||||
"nomembers"]
|
||||
@@ -272,11 +273,17 @@ def main():
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(ipaadmin_principal):
|
||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
|
||||
has_add_member_service = api_check_param("group_add_member", "service")
|
||||
if service is not None and not has_add_member_service:
|
||||
ansible_module.fail_json(
|
||||
msg="Managing a service as part of a group is not supported "
|
||||
"by your IPA version")
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
@@ -326,47 +333,56 @@ def main():
|
||||
set(res_find.get("member_service", [])) -
|
||||
set(service or []))
|
||||
|
||||
# Add members
|
||||
if len(user_add) > 0 or len(group_add) > 0 or \
|
||||
len(service_add) > 0:
|
||||
commands.append([name, "group_add_member",
|
||||
{
|
||||
"user": user_add,
|
||||
"group": group_add,
|
||||
"service": service_add,
|
||||
}])
|
||||
# Remove members
|
||||
if len(user_del) > 0 or len(group_del) > 0 or \
|
||||
len(service_del) > 0:
|
||||
commands.append([name, "group_remove_member",
|
||||
{
|
||||
"user": user_del,
|
||||
"group": group_del,
|
||||
"service": service_del,
|
||||
}])
|
||||
if has_add_member_service:
|
||||
# Add members
|
||||
if len(user_add) > 0 or len(group_add) > 0 or \
|
||||
len(service_add) > 0:
|
||||
commands.append([name, "group_add_member",
|
||||
{
|
||||
"user": user_add,
|
||||
"group": group_add,
|
||||
"service": service_add,
|
||||
}])
|
||||
# Remove members
|
||||
if len(user_del) > 0 or len(group_del) > 0 or \
|
||||
len(service_del) > 0:
|
||||
commands.append([name, "group_remove_member",
|
||||
{
|
||||
"user": user_del,
|
||||
"group": group_del,
|
||||
"service": service_del,
|
||||
}])
|
||||
else:
|
||||
# Add members
|
||||
if len(user_add) > 0 or len(group_add) > 0:
|
||||
commands.append([name, "group_add_member",
|
||||
{
|
||||
"user": user_add,
|
||||
"group": group_add,
|
||||
}])
|
||||
# Remove members
|
||||
if len(user_del) > 0 or len(group_del) > 0:
|
||||
commands.append([name, "group_remove_member",
|
||||
{
|
||||
"user": user_del,
|
||||
"group": group_del,
|
||||
}])
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No group '%s'" % name)
|
||||
|
||||
user_add = list(
|
||||
set(user or []) -
|
||||
set(res_find.get("member_user", [])))
|
||||
group_add = list(
|
||||
set(group or []) -
|
||||
set(res_find.get("member_group", [])))
|
||||
service_add = list(
|
||||
set(service or []) -
|
||||
set(res_find.get("member_service", [])))
|
||||
|
||||
# Add members
|
||||
if len(user_add) > 0 or len(group_add) > 0 or \
|
||||
len(service_add) > 0:
|
||||
if has_add_member_service:
|
||||
commands.append([name, "group_add_member",
|
||||
{
|
||||
"user": user,
|
||||
"group": group,
|
||||
"service": service,
|
||||
}])
|
||||
else:
|
||||
commands.append([name, "group_add_member",
|
||||
{
|
||||
"user": user,
|
||||
"group": group,
|
||||
}])
|
||||
|
||||
elif state == "absent":
|
||||
if action == "group":
|
||||
@@ -377,26 +393,12 @@ def main():
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No group '%s'" % name)
|
||||
|
||||
# Remove intersection member
|
||||
user_del = list(
|
||||
set(user or []) &
|
||||
set(res_find.get("member_user", [])))
|
||||
group_del = list(
|
||||
set(group or []) &
|
||||
set(res_find.get("member_group", [])))
|
||||
service_del = list(
|
||||
set(service or []) &
|
||||
set(res_find.get("member_service", [])))
|
||||
|
||||
# Remove members
|
||||
if len(user_del) > 0 or len(group_del) > 0 or \
|
||||
len(service_del) > 0:
|
||||
commands.append([name, "group_remove_member",
|
||||
{
|
||||
"user": user,
|
||||
"group": group,
|
||||
"service": service,
|
||||
}])
|
||||
commands.append([name, "group_remove_member",
|
||||
{
|
||||
"user": user,
|
||||
"group": group,
|
||||
"service": service,
|
||||
}])
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
@@ -404,11 +406,32 @@ def main():
|
||||
|
||||
for name, command, args in commands:
|
||||
try:
|
||||
api_command(ansible_module, command, to_text(name), args)
|
||||
changed = True
|
||||
result = api_command(ansible_module, command, name,
|
||||
args)
|
||||
if "completed" in result:
|
||||
if result["completed"] > 0:
|
||||
changed = True
|
||||
else:
|
||||
changed = True
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
|
||||
str(e)))
|
||||
# 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))
|
||||
if len(errors) > 0:
|
||||
ansible_module.fail_json(msg=", ".join(errors))
|
||||
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
556
plugins/modules/ipahbacrule.py
Normal file
556
plugins/modules/ipahbacrule.py
Normal file
@@ -0,0 +1,556 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 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: ipahbacrule
|
||||
short description: Manage FreeIPA HBAC rules
|
||||
description: Manage FreeIPA HBAC rules
|
||||
options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: false
|
||||
name:
|
||||
description: The hbacrule name
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: The hbacrule description
|
||||
required: false
|
||||
usercategory:
|
||||
description: User category the rule applies to
|
||||
required: false
|
||||
aliases: ["usercat"]
|
||||
choices: ["all"]
|
||||
hostcategory:
|
||||
description: Host category the rule applies to
|
||||
required: false
|
||||
aliases: ["hostcat"]
|
||||
choices: ["all"]
|
||||
servicecategory:
|
||||
description: Service category the rule applies to
|
||||
required: false
|
||||
aliases: ["servicecat"]
|
||||
choices: ["all"]
|
||||
nomembers:
|
||||
description: Suppress processing of membership attributes
|
||||
required: false
|
||||
type: bool
|
||||
host:
|
||||
description: List of host names assigned to this hbacrule.
|
||||
required: false
|
||||
type: list
|
||||
hostgroup:
|
||||
description: List of host groups assigned to this hbacrule.
|
||||
required: false
|
||||
type: list
|
||||
hbacsvc:
|
||||
description: List of HBAC service names assigned to this hbacrule.
|
||||
required: false
|
||||
type: list
|
||||
hbacsvcgroup:
|
||||
description: List of HBAC service names assigned to this hbacrule.
|
||||
required: false
|
||||
type: list
|
||||
user:
|
||||
description: List of user names assigned to this hbacrule.
|
||||
required: false
|
||||
type: list
|
||||
group:
|
||||
description: List of user groups assigned to this hbacrule.
|
||||
required: false
|
||||
type: list
|
||||
action:
|
||||
description: Work on hbacrule or member level
|
||||
default: hbacrule
|
||||
choices: ["member", "hbacrule"]
|
||||
state:
|
||||
description: State to ensure
|
||||
default: present
|
||||
choices: ["present", "absent", "enabled", "disabled"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Ensure HBAC Rule allhosts is present
|
||||
- ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: allhosts
|
||||
usercategory: all
|
||||
|
||||
# Ensure host server is present in HBAC Rule allhosts
|
||||
- ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: allhosts
|
||||
host: server
|
||||
action: member
|
||||
|
||||
# Ensure HBAC Rule sshd-pinky is present
|
||||
- ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sshd-pinky
|
||||
hostcategory: all
|
||||
|
||||
# Ensure user pinky is present in HBAC Rule sshd-pinky
|
||||
- ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sshd-pinky
|
||||
user: pinky
|
||||
action: member
|
||||
|
||||
# Ensure HBAC service sshd is present in HBAC Rule sshd-pinky
|
||||
- ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sshd-pinky
|
||||
hbacsvc: sshd
|
||||
action: member
|
||||
|
||||
# Ensure HBAC Rule sshd-pinky is disabled
|
||||
- ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sshd-pinky
|
||||
state: disabled
|
||||
|
||||
# Ensure HBAC Rule sshd-pinky is enabled
|
||||
- ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sshd-pinky
|
||||
state: enabled
|
||||
|
||||
# Ensure HBAC Rule sshd-pinky is absent
|
||||
- ipahbacrule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sshd-pinky
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
||||
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
|
||||
module_params_get
|
||||
|
||||
|
||||
def find_hbacrule(module, name):
|
||||
_args = {
|
||||
"all": True,
|
||||
"cn": name,
|
||||
}
|
||||
|
||||
_result = api_command(module, "hbacrule_find", name, _args)
|
||||
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
msg="There is more than one hbacrule '%s'" % (name))
|
||||
elif len(_result["result"]) == 1:
|
||||
return _result["result"][0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def gen_args(description, usercategory, hostcategory, servicecategory,
|
||||
nomembers):
|
||||
_args = {}
|
||||
if description is not None:
|
||||
_args["description"] = description
|
||||
if usercategory is not None:
|
||||
_args["usercategory"] = usercategory
|
||||
if hostcategory is not None:
|
||||
_args["hostcategory"] = hostcategory
|
||||
if servicecategory is not None:
|
||||
_args["servicecategory"] = servicecategory
|
||||
if nomembers is not None:
|
||||
_args["nomembers"] = nomembers
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
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="list", aliases=["cn"], default=None,
|
||||
required=True),
|
||||
# present
|
||||
description=dict(type="str", default=None),
|
||||
usercategory=dict(type="str", default=None,
|
||||
aliases=["usercat"], choices=["all"]),
|
||||
hostcategory=dict(type="str", default=None,
|
||||
aliases=["hostcat"], choices=["all"]),
|
||||
servicecategory=dict(type="str", default=None,
|
||||
aliases=["servicecat"], choices=["all"]),
|
||||
nomembers=dict(required=False, type='bool', default=None),
|
||||
host=dict(required=False, type='list', default=None),
|
||||
hostgroup=dict(required=False, type='list', default=None),
|
||||
hbacsvc=dict(required=False, type='list', default=None),
|
||||
hbacsvcgroup=dict(required=False, type='list', default=None),
|
||||
user=dict(required=False, type='list', default=None),
|
||||
group=dict(required=False, type='list', default=None),
|
||||
action=dict(type="str", default="hbacrule",
|
||||
choices=["member", "hbacrule"]),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent",
|
||||
"enabled", "disabled"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
ipaadmin_principal = module_params_get(ansible_module,
|
||||
"ipaadmin_principal")
|
||||
ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password")
|
||||
names = module_params_get(ansible_module, "name")
|
||||
|
||||
# present
|
||||
description = module_params_get(ansible_module, "description")
|
||||
usercategory = module_params_get(ansible_module, "usercategory")
|
||||
hostcategory = module_params_get(ansible_module, "hostcategory")
|
||||
servicecategory = module_params_get(ansible_module, "servicecategory")
|
||||
nomembers = module_params_get(ansible_module, "nomembers")
|
||||
host = module_params_get(ansible_module, "host")
|
||||
hostgroup = module_params_get(ansible_module, "hostgroup")
|
||||
hbacsvc = module_params_get(ansible_module, "hbacsvc")
|
||||
hbacsvcgroup = module_params_get(ansible_module, "hbacsvcgroup")
|
||||
user = module_params_get(ansible_module, "user")
|
||||
group = module_params_get(ansible_module, "group")
|
||||
action = module_params_get(ansible_module, "action")
|
||||
# state
|
||||
state = module_params_get(ansible_module, "state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Only one hbacrule can be added at a time.")
|
||||
if action == "member":
|
||||
invalid = ["description", "usercategory", "hostcategory",
|
||||
"servicecategory", "nomembers"]
|
||||
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))
|
||||
|
||||
elif state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(msg="No name given.")
|
||||
invalid = ["description", "usercategory", "hostcategory",
|
||||
"servicecategory", "nomembers"]
|
||||
if action == "hbacrule":
|
||||
invalid.extend(["host", "hostgroup", "hbacsvc", "hbacsvcgroup",
|
||||
"user", "group"])
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with state '%s'" %
|
||||
(x, state))
|
||||
|
||||
elif state in ["enabled", "disabled"]:
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(msg="No name given.")
|
||||
if action == "member":
|
||||
ansible_module.fail_json(
|
||||
msg="Action member can not be used with states enabled and "
|
||||
"disabled")
|
||||
invalid = ["description", "usercategory", "hostcategory",
|
||||
"servicecategory", "nomembers", "host", "hostgroup",
|
||||
"hbacsvc", "hbacsvcgroup", "user", "group"]
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with state '%s'" %
|
||||
(x, state))
|
||||
else:
|
||||
ansible_module.fail_json(msg="Invalid state '%s'" % state)
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
# Make sure hbacrule exists
|
||||
res_find = find_hbacrule(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
# Generate args
|
||||
args = gen_args(description, usercategory, hostcategory,
|
||||
servicecategory, nomembers)
|
||||
|
||||
if action == "hbacrule":
|
||||
# Found the hbacrule
|
||||
if res_find is not None:
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
if not compare_args_ipa(ansible_module, args,
|
||||
res_find):
|
||||
commands.append([name, "hbacrule_mod", args])
|
||||
else:
|
||||
commands.append([name, "hbacrule_add", args])
|
||||
# Set res_find to empty dict for next step
|
||||
res_find = {}
|
||||
|
||||
# Generate addition and removal lists
|
||||
host_add = list(
|
||||
set(host or []) -
|
||||
set(res_find.get("member_host", [])))
|
||||
host_del = list(
|
||||
set(res_find.get("member_host", [])) -
|
||||
set(host or []))
|
||||
hostgroup_add = list(
|
||||
set(hostgroup or []) -
|
||||
set(res_find.get("member_hostgroup", [])))
|
||||
hostgroup_del = list(
|
||||
set(res_find.get("member_hostgroup", [])) -
|
||||
set(hostgroup or []))
|
||||
|
||||
hbacsvc_add = list(
|
||||
set(hbacsvc or []) -
|
||||
set(res_find.get("member_hbacsvc", [])))
|
||||
hbacsvc_del = list(
|
||||
set(res_find.get("member_hbacsvc", [])) -
|
||||
set(hbacsvc or []))
|
||||
hbacsvcgroup_add = list(
|
||||
set(hbacsvcgroup or []) -
|
||||
set(res_find.get("member_hbacsvcgroup", [])))
|
||||
hbacsvcgroup_del = list(
|
||||
set(res_find.get("member_hbacsvcgroup", [])) -
|
||||
set(hbacsvcgroup or []))
|
||||
|
||||
user_add = list(
|
||||
set(user or []) -
|
||||
set(res_find.get("member_user", [])))
|
||||
user_del = list(
|
||||
set(res_find.get("member_user", [])) -
|
||||
set(user or []))
|
||||
group_add = list(
|
||||
set(group or []) -
|
||||
set(res_find.get("member_group", [])))
|
||||
group_del = list(
|
||||
set(res_find.get("member_group", [])) -
|
||||
set(group or []))
|
||||
|
||||
# Add hosts and hostgroups
|
||||
if len(host_add) > 0 or len(hostgroup_add) > 0:
|
||||
commands.append([name, "hbacrule_add_host",
|
||||
{
|
||||
"host": host_add,
|
||||
"hostgroup": hostgroup_add,
|
||||
}])
|
||||
# Remove hosts and hostgroups
|
||||
if len(host_del) > 0 or len(hostgroup_del) > 0:
|
||||
commands.append([name, "hbacrule_remove_host",
|
||||
{
|
||||
"host": host_del,
|
||||
"hostgroup": hostgroup_del,
|
||||
}])
|
||||
|
||||
# Add hbacsvcs and hbacsvcgroups
|
||||
if len(hbacsvc_add) > 0 or len(hbacsvcgroup_add) > 0:
|
||||
commands.append([name, "hbacrule_add_service",
|
||||
{
|
||||
"hbacsvc": hbacsvc_add,
|
||||
"hbacsvcgroup": hbacsvcgroup_add,
|
||||
}])
|
||||
# Remove hbacsvcs and hbacsvcgroups
|
||||
if len(hbacsvc_del) > 0 or len(hbacsvcgroup_del) > 0:
|
||||
commands.append([name, "hbacrule_remove_service",
|
||||
{
|
||||
"hbacsvc": hbacsvc_del,
|
||||
"hbacsvcgroup": hbacsvcgroup_del,
|
||||
}])
|
||||
|
||||
# Add users and groups
|
||||
if len(user_add) > 0 or len(group_add) > 0:
|
||||
commands.append([name, "hbacrule_add_user",
|
||||
{
|
||||
"user": user_add,
|
||||
"group": group_add,
|
||||
}])
|
||||
# Remove users and groups
|
||||
if len(user_del) > 0 or len(group_del) > 0:
|
||||
commands.append([name, "hbacrule_remove_user",
|
||||
{
|
||||
"user": user_del,
|
||||
"group": group_del,
|
||||
}])
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No hbacrule '%s'" % name)
|
||||
|
||||
# Add hosts and hostgroups
|
||||
if host is not None or hostgroup is not None:
|
||||
commands.append([name, "hbacrule_add_host",
|
||||
{
|
||||
"host": host,
|
||||
"hostgroup": hostgroup,
|
||||
}])
|
||||
|
||||
# Add hbacsvcs and hbacsvcgroups
|
||||
if hbacsvc is not None or hbacsvcgroup is not None:
|
||||
commands.append([name, "hbacrule_add_service",
|
||||
{
|
||||
"hbacsvc": hbacsvc,
|
||||
"hbacsvcgroup": hbacsvcgroup,
|
||||
}])
|
||||
|
||||
# Add users and groups
|
||||
if user is not None or group is not None:
|
||||
commands.append([name, "hbacrule_add_user",
|
||||
{
|
||||
"user": user,
|
||||
"group": group,
|
||||
}])
|
||||
|
||||
elif state == "absent":
|
||||
if action == "hbacrule":
|
||||
if res_find is not None:
|
||||
commands.append([name, "hbacrule_del", {}])
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No hbacrule '%s'" % name)
|
||||
|
||||
# Remove hosts and hostgroups
|
||||
if host is not None or hostgroup is not None:
|
||||
commands.append([name, "hbacrule_remove_host",
|
||||
{
|
||||
"host": host,
|
||||
"hostgroup": hostgroup,
|
||||
}])
|
||||
|
||||
# Remove hbacsvcs and hbacsvcgroups
|
||||
if hbacsvc is not None or hbacsvcgroup is not None:
|
||||
commands.append([name, "hbacrule_remove_service",
|
||||
{
|
||||
"hbacsvc": hbacsvc,
|
||||
"hbacsvcgroup": hbacsvcgroup,
|
||||
}])
|
||||
|
||||
# Remove users and groups
|
||||
if user is not None or group is not None:
|
||||
commands.append([name, "hbacrule_remove_user",
|
||||
{
|
||||
"user": user,
|
||||
"group": group,
|
||||
}])
|
||||
|
||||
elif state == "enabled":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No hbacrule '%s'" % name)
|
||||
# hbacrule_enable is not failing on an enabled hbacrule
|
||||
# Therefore it is needed to have a look at the ipaenabledflag
|
||||
# in res_find.
|
||||
if "ipaenabledflag" not in res_find or \
|
||||
res_find["ipaenabledflag"][0] != "TRUE":
|
||||
commands.append([name, "hbacrule_enable", {}])
|
||||
|
||||
elif state == "disabled":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No hbacrule '%s'" % name)
|
||||
# hbacrule_disable is not failing on an disabled hbacrule
|
||||
# Therefore it is needed to have a look at the ipaenabledflag
|
||||
# in res_find.
|
||||
if "ipaenabledflag" not in res_find or \
|
||||
res_find["ipaenabledflag"][0] != "FALSE":
|
||||
commands.append([name, "hbacrule_disable", {}])
|
||||
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute commands
|
||||
|
||||
errors = []
|
||||
for name, command, args in commands:
|
||||
try:
|
||||
result = api_command(ansible_module, command, name,
|
||||
args)
|
||||
if "completed" in result:
|
||||
if result["completed"] > 0:
|
||||
changed = True
|
||||
else:
|
||||
changed = True
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
|
||||
str(e)))
|
||||
# Get all errors
|
||||
# All "already a member" and "not a member" failures in the
|
||||
# result are ignored. All others are reported.
|
||||
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))
|
||||
if len(errors) > 0:
|
||||
ansible_module.fail_json(msg=", ".join(errors))
|
||||
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
220
plugins/modules/ipahbacsvc.py
Normal file
220
plugins/modules/ipahbacsvc.py
Normal file
@@ -0,0 +1,220 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 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: ipahbacsvc
|
||||
short description: Manage FreeIPA HBAC Services
|
||||
description: Manage FreeIPA HBAC Services
|
||||
options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: false
|
||||
name:
|
||||
description: The group name
|
||||
required: false
|
||||
aliases: ["cn", "service"]
|
||||
description:
|
||||
description: The HBAC Service description
|
||||
required: false
|
||||
state:
|
||||
description: State to ensure
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Ensure HBAC Service for http is present
|
||||
- ipahbacsvc:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: http
|
||||
description: Web service
|
||||
|
||||
# Ensure HBAC Service for tftp is absent
|
||||
- ipahbacsvc:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: tftp
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
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, compare_args_ipa
|
||||
|
||||
|
||||
def find_hbacsvc(module, name):
|
||||
_args = {
|
||||
"all": True,
|
||||
"cn": to_text(name),
|
||||
}
|
||||
|
||||
_result = api_command(module, "hbacsvc_find", to_text(name), _args)
|
||||
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
msg="There is more than one hbacsvc '%s'" % (name))
|
||||
elif len(_result["result"]) == 1:
|
||||
return _result["result"][0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def gen_args(description):
|
||||
_args = {}
|
||||
if description is not None:
|
||||
_args["description"] = to_text(description)
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
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="list", aliases=["cn", "service"], default=None,
|
||||
required=True),
|
||||
# present
|
||||
|
||||
description=dict(type="str", default=None),
|
||||
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
ipaadmin_principal = ansible_module.params.get("ipaadmin_principal")
|
||||
ipaadmin_password = ansible_module.params.get("ipaadmin_password")
|
||||
names = ansible_module.params.get("name")
|
||||
|
||||
# present
|
||||
description = ansible_module.params.get("description")
|
||||
|
||||
# state
|
||||
state = ansible_module.params.get("state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Only one hbacsvc can be set at a time.")
|
||||
|
||||
if state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(
|
||||
msg="No name given.")
|
||||
invalid = ["description"]
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with state '%s'" %
|
||||
(x, state))
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
# Try to find hbacsvc
|
||||
res_find = find_hbacsvc(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
# Generate args
|
||||
args = gen_args(description)
|
||||
|
||||
# Found the hbacsvc
|
||||
if res_find is not None:
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
if not compare_args_ipa(ansible_module, args,
|
||||
res_find):
|
||||
commands.append([name, "hbacsvc_mod", args])
|
||||
else:
|
||||
commands.append([name, "hbacsvc_add", args])
|
||||
|
||||
elif state == "absent":
|
||||
if res_find is not None:
|
||||
commands.append([name, "hbacsvc_del", {}])
|
||||
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute commands
|
||||
|
||||
for name, command, args in commands:
|
||||
try:
|
||||
api_command(ansible_module, command, to_text(name), args)
|
||||
changed = True
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
|
||||
str(e)))
|
||||
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
346
plugins/modules/ipahbacsvcgroup.py
Normal file
346
plugins/modules/ipahbacsvcgroup.py
Normal file
@@ -0,0 +1,346 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 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: ipahbacsvcgroup
|
||||
short description: Manage FreeIPA hbacsvcgroups
|
||||
description: Manage FreeIPA hbacsvcgroups
|
||||
options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: false
|
||||
name:
|
||||
description: The hbacsvcgroup name
|
||||
required: false
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: The hbacsvcgroup description
|
||||
required: false
|
||||
hbacsvc:
|
||||
description: List of hbacsvc names assigned to this hbacsvcgroup.
|
||||
required: false
|
||||
type: list
|
||||
nomembers:
|
||||
description: Suppress processing of membership attributes
|
||||
required: false
|
||||
type: bool
|
||||
action:
|
||||
description: Work on hbacsvcgroup or member level
|
||||
default: hbacsvcgroup
|
||||
choices: ["member", "hbacsvcgroup"]
|
||||
state:
|
||||
description: State to ensure
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Ensure hbacsvcgroup login is present
|
||||
- ipahbacsvcgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
hbacsvc:
|
||||
- sshd
|
||||
|
||||
# Ensure hbacsvc sshd is present in existing login hbacsvcgroup
|
||||
- ipahbacsvcgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
hbacsvc:
|
||||
- sshd
|
||||
action: member
|
||||
|
||||
# Ensure hbacsvc sshd is abdsent in existing login hbacsvcgroup
|
||||
- ipahbacsvcgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
hbacsvc:
|
||||
- sshd
|
||||
action: member
|
||||
state: absent
|
||||
|
||||
# Ensure hbacsvcgroup login is absent
|
||||
- ipahbacsvcgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: login
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
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, compare_args_ipa
|
||||
|
||||
|
||||
def find_hbacsvcgroup(module, name):
|
||||
_args = {
|
||||
"all": True,
|
||||
"cn": to_text(name),
|
||||
}
|
||||
|
||||
_result = api_command(module, "hbacsvcgroup_find", to_text(name), _args)
|
||||
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
msg="There is more than one hbacsvcgroup '%s'" % (name))
|
||||
elif len(_result["result"]) == 1:
|
||||
return _result["result"][0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def gen_args(description, nomembers):
|
||||
_args = {}
|
||||
if description is not None:
|
||||
_args["description"] = to_text(description)
|
||||
if nomembers is not None:
|
||||
_args["nomembers"] = nomembers
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
def gen_member_args(hbacsvc):
|
||||
_args = {}
|
||||
if hbacsvc is not None:
|
||||
_args["member_hbacsvc"] = [to_text(svc) for svc in hbacsvc]
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
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="list", aliases=["cn"], default=None,
|
||||
required=True),
|
||||
# present
|
||||
description=dict(type="str", default=None),
|
||||
nomembers=dict(required=False, type='bool', default=None),
|
||||
hbacsvc=dict(required=False, type='list', default=None),
|
||||
action=dict(type="str", default="hbacsvcgroup",
|
||||
choices=["member", "hbacsvcgroup"]),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
ipaadmin_principal = ansible_module.params.get("ipaadmin_principal")
|
||||
ipaadmin_password = ansible_module.params.get("ipaadmin_password")
|
||||
names = ansible_module.params.get("name")
|
||||
|
||||
# present
|
||||
description = ansible_module.params.get("description")
|
||||
nomembers = ansible_module.params.get("nomembers")
|
||||
hbacsvc = ansible_module.params.get("hbacsvc")
|
||||
action = ansible_module.params.get("action")
|
||||
# state
|
||||
state = ansible_module.params.get("state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Only one hbacsvcgroup can be added at a time.")
|
||||
if action == "member":
|
||||
invalid = ["description", "nomembers"]
|
||||
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))
|
||||
|
||||
if state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(
|
||||
msg="No name given.")
|
||||
invalid = ["description", "nomembers"]
|
||||
if action == "hbacsvcgroup":
|
||||
invalid.extend(["hbacsvc"])
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with state '%s'" %
|
||||
(x, state))
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
# Make sure hbacsvcgroup exists
|
||||
res_find = find_hbacsvcgroup(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
# Generate args
|
||||
args = gen_args(description, nomembers)
|
||||
|
||||
if action == "hbacsvcgroup":
|
||||
# Found the hbacsvcgroup
|
||||
if res_find is not None:
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
if not compare_args_ipa(ansible_module, args,
|
||||
res_find):
|
||||
commands.append([name, "hbacsvcgroup_mod", args])
|
||||
else:
|
||||
commands.append([name, "hbacsvcgroup_add", args])
|
||||
# Set res_find to empty dict for next step
|
||||
res_find = {}
|
||||
|
||||
member_args = gen_member_args(hbacsvc)
|
||||
if not compare_args_ipa(ansible_module, member_args,
|
||||
res_find):
|
||||
# Generate addition and removal lists
|
||||
hbacsvc_add = list(
|
||||
set(hbacsvc or []) -
|
||||
set(res_find.get("member_hbacsvc", [])))
|
||||
hbacsvc_del = list(
|
||||
set(res_find.get("member_hbacsvc", [])) -
|
||||
set(hbacsvc or []))
|
||||
|
||||
# Add members
|
||||
if len(hbacsvc_add) > 0:
|
||||
commands.append([name, "hbacsvcgroup_add_member",
|
||||
{
|
||||
"hbacsvc":
|
||||
[to_text(svc)
|
||||
for svc in hbacsvc_add],
|
||||
}])
|
||||
# Remove members
|
||||
if len(hbacsvc_del) > 0:
|
||||
commands.append([name,
|
||||
"hbacsvcgroup_remove_member",
|
||||
{
|
||||
"hbacsvc":
|
||||
[to_text(svc)
|
||||
for svc in hbacsvc_del],
|
||||
}])
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(
|
||||
msg="No hbacsvcgroup '%s'" % name)
|
||||
|
||||
# Ensure members are present
|
||||
commands.append([name, "hbacsvcgroup_add_member",
|
||||
{
|
||||
"hbacsvc": [to_text(svc)
|
||||
for svc in hbacsvc],
|
||||
}])
|
||||
elif state == "absent":
|
||||
if action == "hbacsvcgroup":
|
||||
if res_find is not None:
|
||||
commands.append([name, "hbacsvcgroup_del", {}])
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(
|
||||
msg="No hbacsvcgroup '%s'" % name)
|
||||
|
||||
# Ensure members are absent
|
||||
commands.append([name, "hbacsvcgroup_remove_member",
|
||||
{
|
||||
"hbacsvc": [to_text(svc)
|
||||
for svc in hbacsvc],
|
||||
}])
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute commands
|
||||
errors = []
|
||||
for name, command, args in commands:
|
||||
try:
|
||||
result = api_command(ansible_module, command, to_text(name),
|
||||
args)
|
||||
if "completed" in result:
|
||||
if result["completed"] > 0:
|
||||
changed = True
|
||||
else:
|
||||
changed = True
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
|
||||
str(e)))
|
||||
# Get all errors
|
||||
# All "already a member" and "not a member" failures in the
|
||||
# result are ignored. All others are reported.
|
||||
if "failed" in result and "member" in result["failed"]:
|
||||
failed = result["failed"]["member"]
|
||||
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 len(errors) > 0:
|
||||
ansible_module.fail_json(msg=", ".join(errors))
|
||||
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
1279
plugins/modules/ipahost.py
Normal file
1279
plugins/modules/ipahost.py
Normal file
File diff suppressed because it is too large
Load Diff
367
plugins/modules/ipahostgroup.py
Normal file
367
plugins/modules/ipahostgroup.py
Normal file
@@ -0,0 +1,367 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 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: ipahostgroup
|
||||
short description: Manage FreeIPA hostgroups
|
||||
description: Manage FreeIPA hostgroups
|
||||
options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: false
|
||||
name:
|
||||
description: The hostgroup name
|
||||
required: false
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: The hostgroup description
|
||||
required: false
|
||||
nomembers:
|
||||
description: Suppress processing of membership attributes
|
||||
required: false
|
||||
type: bool
|
||||
host:
|
||||
description: List of host names assigned to this hostgroup.
|
||||
required: false
|
||||
type: list
|
||||
hostgroup:
|
||||
description: List of hostgroup names assigned to this hostgroup.
|
||||
required: false
|
||||
type: list
|
||||
action:
|
||||
description: Work on hostgroup or member level
|
||||
default: hostgroup
|
||||
choices: ["member", "hostgroup"]
|
||||
state:
|
||||
description: State to ensure
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Ensure host-group databases is present
|
||||
- ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
host:
|
||||
- db.example.com
|
||||
hostgroup:
|
||||
- mysql-server
|
||||
- oracle-server
|
||||
|
||||
# Ensure hosts and hostgroups are present in existing databases hostgroup
|
||||
- ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
host:
|
||||
- db.example.com
|
||||
hostgroup:
|
||||
- mysql-server
|
||||
- oracle-server
|
||||
action: member
|
||||
|
||||
# Ensure hosts and hostgroups are absent in databases hostgroup
|
||||
- ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
host:
|
||||
- db.example.com
|
||||
hostgroup:
|
||||
- mysql-server
|
||||
- oracle-server
|
||||
action: member
|
||||
state: absent
|
||||
|
||||
# Ensure host-group databases is absent
|
||||
- ipahostgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: databases
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
||||
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
|
||||
module_params_get
|
||||
|
||||
|
||||
def find_hostgroup(module, name):
|
||||
_args = {
|
||||
"all": True,
|
||||
"cn": name,
|
||||
}
|
||||
|
||||
_result = api_command(module, "hostgroup_find", name, _args)
|
||||
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
msg="There is more than one hostgroup '%s'" % (name))
|
||||
elif len(_result["result"]) == 1:
|
||||
return _result["result"][0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def gen_args(description, nomembers):
|
||||
_args = {}
|
||||
if description is not None:
|
||||
_args["description"] = description
|
||||
if nomembers is not None:
|
||||
_args["nomembers"] = nomembers
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
def gen_member_args(host, hostgroup):
|
||||
_args = {}
|
||||
if host is not None:
|
||||
_args["member_host"] = host
|
||||
if hostgroup is not None:
|
||||
_args["member_hostgroup"] = hostgroup
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = 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="list", aliases=["cn"], default=None,
|
||||
required=True),
|
||||
# present
|
||||
description=dict(type="str", default=None),
|
||||
nomembers=dict(required=False, type='bool', default=None),
|
||||
host=dict(required=False, type='list', default=None),
|
||||
hostgroup=dict(required=False, type='list', default=None),
|
||||
action=dict(type="str", default="hostgroup",
|
||||
choices=["member", "hostgroup"]),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
ipaadmin_principal = module_params_get(ansible_module,
|
||||
"ipaadmin_principal")
|
||||
ipaadmin_password = module_params_get(ansible_module,
|
||||
"ipaadmin_password")
|
||||
names = module_params_get(ansible_module, "name")
|
||||
|
||||
# present
|
||||
description = module_params_get(ansible_module, "description")
|
||||
nomembers = module_params_get(ansible_module, "nomembers")
|
||||
host = module_params_get(ansible_module, "host")
|
||||
hostgroup = module_params_get(ansible_module, "hostgroup")
|
||||
action = module_params_get(ansible_module, "action")
|
||||
# state
|
||||
state = module_params_get(ansible_module, "state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Only one hostgroup can be added at a time.")
|
||||
if action == "member":
|
||||
invalid = ["description", "nomembers"]
|
||||
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))
|
||||
|
||||
if state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(
|
||||
msg="No name given.")
|
||||
invalid = ["description", "nomembers"]
|
||||
if action == "hostgroup":
|
||||
invalid.extend(["host", "hostgroup"])
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with state '%s'" %
|
||||
(x, state))
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
# Make sure hostgroup exists
|
||||
res_find = find_hostgroup(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
# Generate args
|
||||
args = gen_args(description, nomembers)
|
||||
|
||||
if action == "hostgroup":
|
||||
# Found the hostgroup
|
||||
if res_find is not None:
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
if not compare_args_ipa(ansible_module, args,
|
||||
res_find):
|
||||
commands.append([name, "hostgroup_mod", args])
|
||||
else:
|
||||
commands.append([name, "hostgroup_add", args])
|
||||
# Set res_find to empty dict for next step
|
||||
res_find = {}
|
||||
|
||||
member_args = gen_member_args(host, hostgroup)
|
||||
if not compare_args_ipa(ansible_module, member_args,
|
||||
res_find):
|
||||
# Generate addition and removal lists
|
||||
host_add = list(
|
||||
set(host or []) -
|
||||
set(res_find.get("member_host", [])))
|
||||
host_del = list(
|
||||
set(res_find.get("member_host", [])) -
|
||||
set(host or []))
|
||||
hostgroup_add = list(
|
||||
set(hostgroup or []) -
|
||||
set(res_find.get("member_hostgroup", [])))
|
||||
hostgroup_del = list(
|
||||
set(res_find.get("member_hostgroup", [])) -
|
||||
set(hostgroup or []))
|
||||
|
||||
# Add members
|
||||
if len(host_add) > 0 or len(hostgroup_add) > 0:
|
||||
commands.append([name, "hostgroup_add_member",
|
||||
{
|
||||
"host": host_add,
|
||||
"hostgroup": hostgroup_add,
|
||||
}])
|
||||
# Remove members
|
||||
if len(host_del) > 0 or len(hostgroup_del) > 0:
|
||||
commands.append([name, "hostgroup_remove_member",
|
||||
{
|
||||
"host": host_del,
|
||||
"hostgroup": hostgroup_del,
|
||||
}])
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(
|
||||
msg="No hostgroup '%s'" % name)
|
||||
|
||||
# Ensure members are present
|
||||
commands.append([name, "hostgroup_add_member",
|
||||
{
|
||||
"host": host,
|
||||
"hostgroup": hostgroup,
|
||||
}])
|
||||
elif state == "absent":
|
||||
if action == "hostgroup":
|
||||
if res_find is not None:
|
||||
commands.append([name, "hostgroup_del", {}])
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(
|
||||
msg="No hostgroup '%s'" % name)
|
||||
|
||||
# Ensure members are absent
|
||||
commands.append([name, "hostgroup_remove_member",
|
||||
{
|
||||
"host": host,
|
||||
"hostgroup": hostgroup,
|
||||
}])
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute commands
|
||||
for name, command, args in commands:
|
||||
try:
|
||||
result = api_command(ansible_module, command, name, args)
|
||||
if "completed" in result:
|
||||
if result["completed"] > 0:
|
||||
changed = True
|
||||
else:
|
||||
changed = True
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
|
||||
str(e)))
|
||||
# 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 "member" in result["failed"]:
|
||||
failed = result["failed"]["member"]
|
||||
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 len(errors) > 0:
|
||||
ansible_module.fail_json(msg=", ".join(errors))
|
||||
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
304
plugins/modules/ipapwpolicy.py
Normal file
304
plugins/modules/ipapwpolicy.py
Normal file
@@ -0,0 +1,304 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 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: ipapwpolicy
|
||||
short description: Manage FreeIPA pwpolicies
|
||||
description: Manage FreeIPA pwpolicies
|
||||
options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: false
|
||||
name:
|
||||
description: The group name
|
||||
required: false
|
||||
aliases: ["cn"]
|
||||
maxlife:
|
||||
description: Maximum password lifetime (in days)
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["krbmaxpwdlife"]
|
||||
minlife:
|
||||
description: Minimum password lifetime (in hours)
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["krbminpwdlife"]
|
||||
history:
|
||||
description: Password history size
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["krbpwdhistorylength"]
|
||||
minclasses:
|
||||
description: Minimum number of character classes
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["krbpwdmindiffchars"]
|
||||
minlength:
|
||||
description: Minimum length of password
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["krbpwdminlength"]
|
||||
priority:
|
||||
description: Priority of the policy (higher number means lower priority)
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["cospriority"]
|
||||
maxfail:
|
||||
description: Consecutive failures before lockout
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["krbpwdmaxfailure"]
|
||||
failinterval:
|
||||
description: Period after which failure count will be reset (seconds)
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["krbpwdfailurecountinterval"]
|
||||
lockouttime:
|
||||
description: Period for which lockout is enforced (seconds)
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["krbpwdlockoutduration"]
|
||||
state:
|
||||
description: State to ensure
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Ensure pwpolicy is set for ops
|
||||
- ipapwpolicy:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: ops
|
||||
minlife: 7
|
||||
maxlife: 49
|
||||
history: 5
|
||||
priority: 1
|
||||
lockouttime: 300
|
||||
minlength: 8
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
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, compare_args_ipa
|
||||
|
||||
|
||||
def find_pwpolicy(module, name):
|
||||
_args = {
|
||||
"all": True,
|
||||
"cn": to_text(name),
|
||||
}
|
||||
|
||||
_result = api_command(module, "pwpolicy_find", to_text(name), _args)
|
||||
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
msg="There is more than one pwpolicy '%s'" % (name))
|
||||
elif len(_result["result"]) == 1:
|
||||
return _result["result"][0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def gen_args(maxlife, minlife, history, minclasses, minlength, priority,
|
||||
maxfail, failinterval, lockouttime):
|
||||
_args = {}
|
||||
if maxlife is not None:
|
||||
_args["krbmaxpwdlife"] = maxlife
|
||||
if minlife is not None:
|
||||
_args["krbminpwdlife"] = minlife
|
||||
if history is not None:
|
||||
_args["krbpwdhistorylength"] = history
|
||||
if minclasses is not None:
|
||||
_args["krbpwdmindiffchars"] = minclasses
|
||||
if minlength is not None:
|
||||
_args["krbpwdminlength"] = minlength
|
||||
if priority is not None:
|
||||
_args["cospriority"] = priority
|
||||
if maxfail is not None:
|
||||
_args["krbpwdmaxfailure"] = maxfail
|
||||
if failinterval is not None:
|
||||
_args["krbpwdfailurecountinterval"] = failinterval
|
||||
if lockouttime is not None:
|
||||
_args["krbpwdlockoutduration"] = lockouttime
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
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="list", aliases=["cn"], default=None,
|
||||
required=True),
|
||||
# present
|
||||
|
||||
maxlife=dict(type="int", aliases=["krbmaxpwdlife"], default=None),
|
||||
minlife=dict(type="int", aliases=["krbminpwdlife"], default=None),
|
||||
history=dict(type="int", aliases=["krbpwdhistorylength"],
|
||||
default=None),
|
||||
minclasses=dict(type="int", aliases=["krbpwdmindiffchars"],
|
||||
default=None),
|
||||
minlength=dict(type="int", aliases=["krbpwdminlength"],
|
||||
default=None),
|
||||
priority=dict(type="int", aliases=["cospriority"], default=None),
|
||||
maxfail=dict(type="int", aliases=["krbpwdmaxfailure"],
|
||||
default=None),
|
||||
failinterval=dict(type="int",
|
||||
aliases=["krbpwdfailurecountinterval"],
|
||||
default=None),
|
||||
lockouttime=dict(type="int", aliases=["krbpwdlockoutduration"],
|
||||
default=None),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
ipaadmin_principal = ansible_module.params.get("ipaadmin_principal")
|
||||
ipaadmin_password = ansible_module.params.get("ipaadmin_password")
|
||||
names = ansible_module.params.get("name")
|
||||
|
||||
# present
|
||||
maxlife = ansible_module.params.get("maxlife")
|
||||
minlife = ansible_module.params.get("minlife")
|
||||
history = ansible_module.params.get("history")
|
||||
minclasses = ansible_module.params.get("minclasses")
|
||||
minlength = ansible_module.params.get("minlength")
|
||||
priority = ansible_module.params.get("priority")
|
||||
maxfail = ansible_module.params.get("maxfail")
|
||||
failinterval = ansible_module.params.get("failinterval")
|
||||
lockouttime = ansible_module.params.get("lockouttime")
|
||||
|
||||
# state
|
||||
state = ansible_module.params.get("state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Only one pwpolicy can be set at a time.")
|
||||
|
||||
if state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(
|
||||
msg="No name given.")
|
||||
invalid = ["maxlife", "minlife", "history", "minclasses",
|
||||
"minlength", "priority", "maxfail", "failinterval",
|
||||
"lockouttime"]
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with state '%s'" %
|
||||
(x, state))
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
# Try to find pwpolicy
|
||||
res_find = find_pwpolicy(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
# Generate args
|
||||
args = gen_args(maxlife, minlife, history, minclasses,
|
||||
minlength, priority, maxfail, failinterval,
|
||||
lockouttime)
|
||||
|
||||
# Found the pwpolicy
|
||||
if res_find is not None:
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
if not compare_args_ipa(ansible_module, args,
|
||||
res_find):
|
||||
commands.append([name, "pwpolicy_mod", args])
|
||||
else:
|
||||
commands.append([name, "pwpolicy_add", args])
|
||||
|
||||
elif state == "absent":
|
||||
if res_find is not None:
|
||||
commands.append([name, "pwpolicy_del", {}])
|
||||
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute commands
|
||||
|
||||
for name, command, args in commands:
|
||||
try:
|
||||
api_command(ansible_module, command, to_text(name), args)
|
||||
changed = True
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
|
||||
str(e)))
|
||||
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
211
plugins/modules/ipasudocmd.py
Normal file
211
plugins/modules/ipasudocmd.py
Normal file
@@ -0,0 +1,211 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 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: ipasudocmd
|
||||
short description: Manage FreeIPA sudo command
|
||||
description: Manage FreeIPA sudo command
|
||||
options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: false
|
||||
name:
|
||||
description: The sudo command
|
||||
required: true
|
||||
aliases: ["sudocmd"]
|
||||
description:
|
||||
description: The command description
|
||||
required: false
|
||||
state:
|
||||
description: State to ensure
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Rafael Jeffman
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Ensure sudocmd is present
|
||||
- ipacommand:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: su
|
||||
state: present
|
||||
|
||||
# Ensure sudocmd is absent
|
||||
- ipacommand:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: su
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
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, compare_args_ipa
|
||||
|
||||
|
||||
def find_sudocmd(module, name):
|
||||
_args = {
|
||||
"all": True,
|
||||
"sudocmd": to_text(name),
|
||||
}
|
||||
|
||||
_result = api_command(module, "sudocmd_find", to_text(name), _args)
|
||||
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
msg="There is more than one sudocmd '%s'" % (name))
|
||||
elif len(_result["result"]) == 1:
|
||||
return _result["result"][0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def gen_args(description):
|
||||
_args = {}
|
||||
if description is not None:
|
||||
_args["description"] = description
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
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="list", aliases=["sudocmd"], default=None,
|
||||
required=True),
|
||||
# present
|
||||
description=dict(type="str", default=None),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
ipaadmin_principal = ansible_module.params.get("ipaadmin_principal")
|
||||
ipaadmin_password = ansible_module.params.get("ipaadmin_password")
|
||||
names = ansible_module.params.get("name")
|
||||
|
||||
# present
|
||||
description = ansible_module.params.get("description")
|
||||
# state
|
||||
state = ansible_module.params.get("state")
|
||||
|
||||
# Check parameters
|
||||
if state == "absent":
|
||||
invalid = ["description"]
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with state '%s'" %
|
||||
(x, state))
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
# Make sure hostgroup exists
|
||||
res_find = find_sudocmd(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
# Generate args
|
||||
args = gen_args(description)
|
||||
if res_find is not None:
|
||||
# For all settings in args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
if not compare_args_ipa(ansible_module, args,
|
||||
res_find):
|
||||
commands.append([name, "sudocmd_mod", args])
|
||||
else:
|
||||
commands.append([name, "sudocmd_add", args])
|
||||
# Set res_find to empty dict for next step
|
||||
res_find = {}
|
||||
elif state == "absent":
|
||||
if res_find is not None:
|
||||
commands.append([name, "sudocmd_del", {}])
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute commands
|
||||
for name, command, args in commands:
|
||||
try:
|
||||
result = api_command(ansible_module, command, to_text(name),
|
||||
args)
|
||||
# Check if any changes were made by any command
|
||||
if command == 'sudocmd_del':
|
||||
changed |= "Deleted" in result['summary']
|
||||
elif command == 'sudocmd_add':
|
||||
changed |= "Added" in result['summary']
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
|
||||
str(e)))
|
||||
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
355
plugins/modules/ipasudocmdgroup.py
Normal file
355
plugins/modules/ipasudocmdgroup.py
Normal file
@@ -0,0 +1,355 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 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: ipasudocmdgroup
|
||||
short description: Manage FreeIPA sudocmd groups
|
||||
description: Manage FreeIPA sudocmd groups
|
||||
options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: false
|
||||
name:
|
||||
description: The sudocmodgroup name
|
||||
required: false
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: The sudocmdgroup description
|
||||
required: false
|
||||
nomembers:
|
||||
description: Suppress processing of membership attributes
|
||||
required: false
|
||||
type: bool
|
||||
sudocmdgroup:
|
||||
description: List of sudocmdgroup names assigned to this sudocmdgroup.
|
||||
required: false
|
||||
type: list
|
||||
sudocmd:
|
||||
description: List of sudocmds assigned to this sudocmdgroup.
|
||||
required: false
|
||||
type: list
|
||||
action:
|
||||
description: Work on sudocmdgroup or member level
|
||||
default: hostgroup
|
||||
choices: ["member", "sudocmdgroup"]
|
||||
state:
|
||||
description: State to ensure
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Rafael Guterres Jeffman
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Ensure sudocmd-group 'network' is present
|
||||
- ipasudocmdgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: network
|
||||
state: present
|
||||
|
||||
# Ensure sudocmdgroup and sudocmd are present in 'network' sudocmdgroup
|
||||
- ipasudocmdgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: network
|
||||
sudocmd:
|
||||
- /usr/sbin/ifconfig
|
||||
- /usr/sbin/iwlist
|
||||
action: member
|
||||
|
||||
# Ensure sudocmdgroup and sudocmd are absent in 'network' sudocmdgroup
|
||||
- ipasudocmdgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: network
|
||||
sudocmd:
|
||||
- /usr/sbin/ifconfig
|
||||
- /usr/sbin/iwlist
|
||||
action: member
|
||||
state: absent
|
||||
|
||||
# Ensure sudocmd-group 'network' is absent
|
||||
- ipasudocmdgroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: network
|
||||
action: member
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
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, compare_args_ipa
|
||||
|
||||
|
||||
def find_sudocmdgroup(module, name):
|
||||
_args = {
|
||||
"all": True,
|
||||
"cn": to_text(name),
|
||||
}
|
||||
|
||||
_result = api_command(module, "sudocmdgroup_find", to_text(name), _args)
|
||||
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
msg="There is more than one sudocmdgroup '%s'" % (name))
|
||||
elif len(_result["result"]) == 1:
|
||||
return _result["result"][0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def gen_args(description, nomembers):
|
||||
_args = {}
|
||||
if description is not None:
|
||||
_args["description"] = to_text(description)
|
||||
if nomembers is not None:
|
||||
_args["nomembers"] = nomembers
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
def gen_member_args(sudocmdgroup):
|
||||
_args = {}
|
||||
if sudocmdgroup is not None:
|
||||
_args["member_sudocmdgroup"] = sudocmdgroup
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
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="list", aliases=["cn"], default=None,
|
||||
required=True),
|
||||
# present
|
||||
description=dict(type="str", default=None),
|
||||
nomembers=dict(required=False, type='bool', default=None),
|
||||
sudocmdgroup=dict(required=False, type='list', default=None),
|
||||
sudocmd=dict(required=False, type='list', default=None),
|
||||
action=dict(type="str", default="sudocmdgroup",
|
||||
choices=["member", "sudocmdgroup"]),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
ipaadmin_principal = ansible_module.params.get("ipaadmin_principal")
|
||||
ipaadmin_password = ansible_module.params.get("ipaadmin_password")
|
||||
names = ansible_module.params.get("name")
|
||||
|
||||
# present
|
||||
description = ansible_module.params.get("description")
|
||||
nomembers = ansible_module.params.get("nomembers")
|
||||
sudocmdgroup = ansible_module.params.get("sudocmdgroup")
|
||||
sudocmd = ansible_module.params.get("sudocmd")
|
||||
action = ansible_module.params.get("action")
|
||||
# state
|
||||
state = ansible_module.params.get("state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Only one sudocmdgroup can be added at a time.")
|
||||
if action == "member":
|
||||
invalid = ["description", "nomembers"]
|
||||
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))
|
||||
|
||||
if state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(
|
||||
msg="No name given.")
|
||||
invalid = ["description", "nomembers"]
|
||||
if action == "sudocmdgroup":
|
||||
invalid.extend(["sudocmd"])
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with state '%s'" %
|
||||
(x, state))
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
# Make sure hostgroup exists
|
||||
res_find = find_sudocmdgroup(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
# Generate args
|
||||
args = gen_args(description, nomembers)
|
||||
|
||||
if action == "sudocmdgroup":
|
||||
# Found the hostgroup
|
||||
if res_find is not None:
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
if not compare_args_ipa(ansible_module, args,
|
||||
res_find):
|
||||
commands.append([name, "sudocmdgroup_mod", args])
|
||||
else:
|
||||
commands.append([name, "sudocmdgroup_add", args])
|
||||
# Set res_find to empty dict for next step
|
||||
res_find = {}
|
||||
|
||||
member_args = gen_member_args(sudocmd)
|
||||
if not compare_args_ipa(ansible_module, member_args,
|
||||
res_find):
|
||||
# Generate addition and removal lists
|
||||
sudocmdgroup_add = list(
|
||||
set(sudocmdgroup or []) -
|
||||
set(res_find.get("member_sudocmdgroup", [])))
|
||||
sudocmdgroup_del = list(
|
||||
set(res_find.get("member_sudocmdgroup", [])) -
|
||||
set(sudocmdgroup or []))
|
||||
|
||||
# Add members
|
||||
if len(sudocmdgroup_add) > 0:
|
||||
commands.append([name, "sudocmdgroup_add_member",
|
||||
{
|
||||
"sudocmd": [to_text(c)
|
||||
for c in
|
||||
sudocmdgroup_add]
|
||||
}
|
||||
])
|
||||
# Remove members
|
||||
if len(sudocmdgroup_del) > 0:
|
||||
commands.append([name,
|
||||
"sudocmdgroup_remove_member",
|
||||
{
|
||||
"sudocmd": [to_text(c)
|
||||
for c in
|
||||
sudocmdgroup_del]
|
||||
}
|
||||
])
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(
|
||||
msg="No sudocmdgroup '%s'" % name)
|
||||
|
||||
# Ensure members are present
|
||||
commands.append([name, "sudocmdgroup_add_member",
|
||||
{"sudocmd": [to_text(c) for c in sudocmd]}
|
||||
])
|
||||
elif state == "absent":
|
||||
if action == "sudocmdgroup":
|
||||
if res_find is not None:
|
||||
commands.append([name, "sudocmdgroup_del", {}])
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(
|
||||
msg="No sudocmdgroup '%s'" % name)
|
||||
|
||||
# Ensure members are absent
|
||||
commands.append([name, "sudocmdgroup_remove_member",
|
||||
{"sudocmd": [to_text(c) for c in sudocmd]}
|
||||
])
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute commands
|
||||
for name, command, args in commands:
|
||||
try:
|
||||
result = api_command(ansible_module, command, to_text(name),
|
||||
args)
|
||||
if action == "member":
|
||||
if "completed" in result and result["completed"] > 0:
|
||||
changed = True
|
||||
else:
|
||||
if command == "sudocmdgroup_del":
|
||||
changed |= "Deleted" in result['summary']
|
||||
elif command == "sudocmdgroup_add":
|
||||
changed |= "Added" in result['summary']
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
|
||||
str(e)))
|
||||
# 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 "member" in result["failed"]:
|
||||
failed = result["failed"]["member"]
|
||||
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 len(errors) > 0:
|
||||
ansible_module.fail_json(msg=", ".join(errors))
|
||||
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
564
plugins/modules/ipasudorule.py
Normal file
564
plugins/modules/ipasudorule.py
Normal file
@@ -0,0 +1,564 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 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: ipasudorule
|
||||
short description: Manage FreeIPA sudo rules
|
||||
description: Manage FreeIPA sudo rules
|
||||
options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: false
|
||||
name:
|
||||
description: The sudorule name
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: The sudorule description
|
||||
required: false
|
||||
user:
|
||||
description: List of users assigned to the sudo rule.
|
||||
required: false
|
||||
usercategory:
|
||||
description: User category the sudo rule applies to
|
||||
required: false
|
||||
choices: ["all"]
|
||||
usergroup:
|
||||
description: List of user groups assigned to the sudo rule.
|
||||
required: false
|
||||
runasgroupcategory:
|
||||
description: RunAs Group category applied to the sudo rule.
|
||||
required: false
|
||||
choices: ["all"]
|
||||
runasusercategory:
|
||||
description: RunAs User category applied to the sudorule.
|
||||
required: false
|
||||
choices: ["all"]
|
||||
nomembers:
|
||||
description: Suppress processing of membership attributes
|
||||
required: false
|
||||
type: bool
|
||||
host:
|
||||
description: List of host names assigned to this sudorule.
|
||||
required: false
|
||||
type: list
|
||||
hostgroup:
|
||||
description: List of host groups assigned to this sudorule.
|
||||
required: false
|
||||
type: list
|
||||
hostcategory:
|
||||
description: Host category the sudo rule applies to.
|
||||
required: false
|
||||
choices: ["all"]
|
||||
cmd:
|
||||
description: List of sudocmds assigned to this sudorule.
|
||||
required: false
|
||||
type: list
|
||||
cmdgroup:
|
||||
description: List of sudocmd groups assigned to this sudorule.
|
||||
required: false
|
||||
type: list
|
||||
cmdcategory:
|
||||
description: Cammand category the sudo rule applies to
|
||||
required: false
|
||||
choices: ["all"]
|
||||
action:
|
||||
description: Work on sudorule or member level
|
||||
default: sudorule
|
||||
choices: ["member", "sudorule"]
|
||||
state:
|
||||
description: State to ensure
|
||||
default: present
|
||||
choices: ["present", "absent", "enabled", "disabled"]
|
||||
author:
|
||||
- Rafael Jeffman
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Ensure Sudo Rule tesrule1 is present
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
|
||||
# Ensure sudocmd is present in Sudo Rule
|
||||
- ipasudorule:
|
||||
ipaadmin_password: pass1234
|
||||
name: testrule1
|
||||
cmd:
|
||||
- /sbin/ifconfig
|
||||
- /usr/bin/vim
|
||||
action: member
|
||||
state: absent
|
||||
|
||||
# Ensure host server is present in Sudo Rule
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
host: server
|
||||
action: member
|
||||
|
||||
# Ensure hostgroup cluster is present in Sudo Rule
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
hostgroup: cluster
|
||||
action: member
|
||||
|
||||
# Ensure sudo rule for usercategory "all"
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: allusers
|
||||
usercategory: all
|
||||
action: enabled
|
||||
|
||||
# Ensure sudo rule for hostcategory "all"
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: allhosts
|
||||
hostcategory: all
|
||||
action: enabled
|
||||
|
||||
# Ensure Sudo Rule tesrule1 is absent
|
||||
- ipasudorule:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: testrule1
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
||||
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
|
||||
module_params_get
|
||||
|
||||
|
||||
def find_sudorule(module, name):
|
||||
_args = {
|
||||
"all": True,
|
||||
"cn": name,
|
||||
}
|
||||
|
||||
_result = api_command(module, "sudorule_find", name, _args)
|
||||
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
msg="There is more than one sudorule '%s'" % (name))
|
||||
elif len(_result["result"]) == 1:
|
||||
return _result["result"][0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def gen_args(ansible_module):
|
||||
arglist = ['description', 'usercategory', 'hostcategory', 'cmdcategory',
|
||||
'runasusercategory', 'runasgroupcategory', 'nomembers']
|
||||
_args = {}
|
||||
for arg in arglist:
|
||||
value = module_params_get(ansible_module, arg)
|
||||
if value is not None:
|
||||
_args[arg] = value
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
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="list", aliases=["cn"], default=None,
|
||||
required=True),
|
||||
# present
|
||||
description=dict(required=False, type="str", default=None),
|
||||
usercategory=dict(required=False, type="str", default=None,
|
||||
choices=["all"]),
|
||||
hostcategory=dict(required=False, type="str", default=None,
|
||||
choices=["all"]),
|
||||
nomembers=dict(required=False, type='bool', default=None),
|
||||
host=dict(required=False, type='list', default=None),
|
||||
hostgroup=dict(required=False, type='list', default=None),
|
||||
user=dict(required=False, type='list', default=None),
|
||||
group=dict(required=False, type='list', default=None),
|
||||
cmd=dict(required=False, type="list", default=None),
|
||||
cmdcategory=dict(required=False, type="str", default=None,
|
||||
choices=["all"]),
|
||||
runasusercategory=dict(required=False, type="str", default=None,
|
||||
choices=["all"]),
|
||||
runasgroupcategory=dict(required=False, type="str", default=None,
|
||||
choices=["all"]),
|
||||
action=dict(type="str", default="sudorule",
|
||||
choices=["member", "sudorule"]),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent",
|
||||
"enabled", "disabled"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
ipaadmin_principal = module_params_get(ansible_module,
|
||||
"ipaadmin_principal")
|
||||
ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password")
|
||||
names = module_params_get(ansible_module, "name")
|
||||
|
||||
# present
|
||||
# The 'noqa' variables are not used here, but required for vars().
|
||||
# The use of 'noqa' ensures flake8 does not complain about them.
|
||||
description = module_params_get(ansible_module, "description") # noqa
|
||||
cmdcategory = module_params_get(ansible_module, 'cmdcategory') # noqa
|
||||
usercategory = module_params_get(ansible_module, "usercategory") # noqa
|
||||
hostcategory = module_params_get(ansible_module, "hostcategory") # noqa
|
||||
runasusercategory = module_params_get(ansible_module, # noqa
|
||||
"runasusercategory")
|
||||
runasgroupcategory = module_params_get(ansible_module, # noqa
|
||||
"runasgroupcategory")
|
||||
hostcategory = module_params_get(ansible_module, "hostcategory") # noqa
|
||||
nomembers = module_params_get(ansible_module, "nomembers") # noqa
|
||||
host = module_params_get(ansible_module, "host")
|
||||
hostgroup = module_params_get(ansible_module, "hostgroup")
|
||||
user = module_params_get(ansible_module, "user")
|
||||
group = module_params_get(ansible_module, "group")
|
||||
cmd = module_params_get(ansible_module, 'cmd')
|
||||
cmdgroup = module_params_get(ansible_module, 'cmdgroup')
|
||||
action = module_params_get(ansible_module, "action")
|
||||
|
||||
# state
|
||||
state = module_params_get(ansible_module, "state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Only one sudorule can be added at a time.")
|
||||
if action == "member":
|
||||
invalid = ["description", "usercategory", "hostcategory",
|
||||
"cmdcategory", "runasusercategory",
|
||||
"runasgroupcategory", "nomembers"]
|
||||
|
||||
for x in invalid:
|
||||
if x in vars() and vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with action "
|
||||
"'%s'" % (x, action))
|
||||
|
||||
elif state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(msg="No name given.")
|
||||
invalid = ["description", "usercategory", "hostcategory",
|
||||
"cmdcategory", "runasusercategory",
|
||||
"runasgroupcategory", "nomembers"]
|
||||
if action == "sudorule":
|
||||
invalid.extend(["host", "hostgroup", "user", "group",
|
||||
"cmd", "cmdgroup"])
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with state '%s'" %
|
||||
(x, state))
|
||||
|
||||
elif state in ["enabled", "disabled"]:
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(msg="No name given.")
|
||||
if action == "member":
|
||||
ansible_module.fail_json(
|
||||
msg="Action member can not be used with states enabled and "
|
||||
"disabled")
|
||||
invalid = ["description", "usercategory", "hostcategory",
|
||||
"cmdcategory", "runasusercategory", "runasgroupcategory",
|
||||
"nomembers", "nomembers", "host", "hostgroup",
|
||||
"user", "group", "cmd", "cmdgroup"]
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with state '%s'" %
|
||||
(x, state))
|
||||
else:
|
||||
ansible_module.fail_json(msg="Invalid state '%s'" % state)
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
# Make sure sudorule exists
|
||||
res_find = find_sudorule(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
# Generate args
|
||||
args = gen_args(ansible_module)
|
||||
if action == "sudorule":
|
||||
# Found the sudorule
|
||||
if res_find is not None:
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
if not compare_args_ipa(ansible_module, args,
|
||||
res_find):
|
||||
commands.append([name, "sudorule_mod", args])
|
||||
else:
|
||||
commands.append([name, "sudorule_add", args])
|
||||
# Set res_find to empty dict for next step
|
||||
res_find = {}
|
||||
|
||||
# Generate addition and removal lists
|
||||
host_add = list(
|
||||
set(host or []) -
|
||||
set(res_find.get("member_host", [])))
|
||||
host_del = list(
|
||||
set(res_find.get("member_host", [])) -
|
||||
set(host or []))
|
||||
hostgroup_add = list(
|
||||
set(hostgroup or []) -
|
||||
set(res_find.get("member_hostgroup", [])))
|
||||
hostgroup_del = list(
|
||||
set(res_find.get("member_hostgroup", [])) -
|
||||
set(hostgroup or []))
|
||||
|
||||
user_add = list(
|
||||
set(user or []) -
|
||||
set(res_find.get("member_user", [])))
|
||||
user_del = list(
|
||||
set(res_find.get("member_user", [])) -
|
||||
set(user or []))
|
||||
group_add = list(
|
||||
set(group or []) -
|
||||
set(res_find.get("member_group", [])))
|
||||
group_del = list(
|
||||
set(res_find.get("member_group", [])) -
|
||||
set(group or []))
|
||||
|
||||
cmd_add = list(
|
||||
set(cmd or []) -
|
||||
set(res_find.get("member_cmd", [])))
|
||||
cmd_del = list(
|
||||
set(res_find.get("member_cmd", [])) -
|
||||
set(cmd or []))
|
||||
cmdgroup_add = list(
|
||||
set(cmdgroup or []) -
|
||||
set(res_find.get("member_cmdgroup", [])))
|
||||
cmdgroup_del = list(
|
||||
set(res_find.get("member_cmdgroup", [])) -
|
||||
set(cmdgroup or []))
|
||||
|
||||
# Add hosts and hostgroups
|
||||
if len(host_add) > 0 or len(hostgroup_add) > 0:
|
||||
commands.append([name, "sudorule_add_host",
|
||||
{
|
||||
"host": host_add,
|
||||
"hostgroup": hostgroup_add,
|
||||
}])
|
||||
# Remove hosts and hostgroups
|
||||
if len(host_del) > 0 or len(hostgroup_del) > 0:
|
||||
commands.append([name, "sudorule_remove_host",
|
||||
{
|
||||
"host": host_del,
|
||||
"hostgroup": hostgroup_del,
|
||||
}])
|
||||
|
||||
# Add users and groups
|
||||
if len(user_add) > 0 or len(group_add) > 0:
|
||||
commands.append([name, "sudorule_add_user",
|
||||
{
|
||||
"user": user_add,
|
||||
"group": group_add,
|
||||
}])
|
||||
# Remove users and groups
|
||||
if len(user_del) > 0 or len(group_del) > 0:
|
||||
commands.append([name, "sudorule_remove_user",
|
||||
{
|
||||
"user": user_del,
|
||||
"group": group_del,
|
||||
}])
|
||||
|
||||
# Add commands
|
||||
if len(cmd_add) > 0 or len(cmdgroup_add) > 0:
|
||||
commands.append([name, "sudorule_add_allow_command",
|
||||
{
|
||||
"sudocmd": cmd_add,
|
||||
"sudocmdgroup": cmdgroup_add,
|
||||
}])
|
||||
|
||||
if len(cmd_del) > 0 or len(cmdgroup_del) > 0:
|
||||
commands.append([name, "sudorule_add_deny_command",
|
||||
{
|
||||
"sudocmd": cmd_del,
|
||||
"sudocmdgroup": cmdgroup_del
|
||||
}])
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No sudorule '%s'" % name)
|
||||
|
||||
# Add hosts and hostgroups
|
||||
if host is not None or hostgroup is not None:
|
||||
commands.append([name, "sudorule_add_host",
|
||||
{
|
||||
"host": host,
|
||||
"hostgroup": hostgroup,
|
||||
}])
|
||||
|
||||
# Add users and groups
|
||||
if user is not None or group is not None:
|
||||
commands.append([name, "sudorule_add_user",
|
||||
{
|
||||
"user": user,
|
||||
"group": group,
|
||||
}])
|
||||
|
||||
# Add commands
|
||||
if cmd is not None:
|
||||
commands.append([name, "sudorule_add_allow_command",
|
||||
{
|
||||
"sudocmd": cmd,
|
||||
}])
|
||||
|
||||
elif state == "absent":
|
||||
if action == "sudorule":
|
||||
if res_find is not None:
|
||||
commands.append([name, "sudorule_del", {}])
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No sudorule '%s'" % name)
|
||||
|
||||
# Remove hosts and hostgroups
|
||||
if host is not None or hostgroup is not None:
|
||||
commands.append([name, "sudorule_remove_host",
|
||||
{
|
||||
"host": host,
|
||||
"hostgroup": hostgroup,
|
||||
}])
|
||||
|
||||
# Remove users and groups
|
||||
if user is not None or group is not None:
|
||||
commands.append([name, "sudorule_remove_user",
|
||||
{
|
||||
"user": user,
|
||||
"group": group,
|
||||
}])
|
||||
|
||||
# Remove commands
|
||||
if cmd is not None:
|
||||
commands.append([name, "sudorule_add_deny_command",
|
||||
{
|
||||
"sudocmd": cmd,
|
||||
}])
|
||||
|
||||
elif state == "enabled":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No sudorule '%s'" % name)
|
||||
# sudorule_enable is not failing on an enabled sudorule
|
||||
# Therefore it is needed to have a look at the ipaenabledflag
|
||||
# in res_find.
|
||||
if "ipaenabledflag" not in res_find or \
|
||||
res_find["ipaenabledflag"][0] != "TRUE":
|
||||
commands.append([name, "sudorule_enable", {}])
|
||||
|
||||
elif state == "disabled":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No sudorule '%s'" % name)
|
||||
# sudorule_disable is not failing on an disabled sudorule
|
||||
# Therefore it is needed to have a look at the ipaenabledflag
|
||||
# in res_find.
|
||||
if "ipaenabledflag" not in res_find or \
|
||||
res_find["ipaenabledflag"][0] != "FALSE":
|
||||
commands.append([name, "sudorule_disable", {}])
|
||||
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute commands
|
||||
|
||||
errors = []
|
||||
for name, command, args in commands:
|
||||
try:
|
||||
result = api_command(ansible_module, command, name,
|
||||
args)
|
||||
|
||||
if "completed" in result:
|
||||
if result["completed"] > 0:
|
||||
changed = True
|
||||
else:
|
||||
changed = True
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
|
||||
str(e)))
|
||||
# Get all errors
|
||||
# All "already a member" and "not a member" failures in the
|
||||
# result are ignored. All others are reported.
|
||||
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))
|
||||
if len(errors) > 0:
|
||||
ansible_module.fail_json(msg=", ".join(errors))
|
||||
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -217,7 +217,7 @@ def main():
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(ipaadmin_principal):
|
||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
@@ -256,12 +256,12 @@ def main():
|
||||
del args[key]
|
||||
if len(args) > 1:
|
||||
# cn needs to be in args always
|
||||
commands.append(["topologysegment_mod", args])
|
||||
commands.append(["topologysegment_mod", args, suffix])
|
||||
# else: Nothing to change
|
||||
else:
|
||||
if name is None:
|
||||
args["cn"] = to_text("%s-to-%s" % (left, right))
|
||||
commands.append(["topologysegment_add", args])
|
||||
commands.append(["topologysegment_add", args, suffix])
|
||||
|
||||
elif state in ["absent", "disabled"]:
|
||||
# Make sure topology segment does not exist
|
||||
@@ -274,7 +274,7 @@ def main():
|
||||
args = {
|
||||
"cn": res_find["cn"][0]
|
||||
}
|
||||
commands.append(["topologysegment_del", args])
|
||||
commands.append(["topologysegment_del", args, suffix])
|
||||
|
||||
elif state == "checked":
|
||||
# Check if topology segment does exists
|
||||
@@ -309,14 +309,27 @@ def main():
|
||||
elif direction == "right-to-left":
|
||||
args["right"] = True
|
||||
|
||||
commands.append(["topologysegment_reinitialize", args])
|
||||
commands.append(["topologysegment_reinitialize", args,
|
||||
suffix])
|
||||
else:
|
||||
params = []
|
||||
if name is not None:
|
||||
params.append("name=%s" % name)
|
||||
if left is not None:
|
||||
params.append("left=%s" % left)
|
||||
if right is not None:
|
||||
params.append("right=%s" % right)
|
||||
ansible_module.fail_json(
|
||||
msg="No entry '%s' for suffix '%s'" %
|
||||
(",".join(params), suffix))
|
||||
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute command
|
||||
|
||||
for command, args in commands:
|
||||
api_command(ansible_module, command, to_text(suffix), args)
|
||||
for command, args, _suffix in commands:
|
||||
api_command(ansible_module, command, to_text(_suffix), args)
|
||||
changed = True
|
||||
|
||||
except Exception as e:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user