mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-03-27 05:43:05 +00:00
Compare commits
260 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5ba88d725 | ||
|
|
1a5c62fe9c | ||
|
|
67d6455db6 | ||
|
|
a4b71700f7 | ||
|
|
5f5807b49c | ||
|
|
b670d29d30 | ||
|
|
9de235474b | ||
|
|
a55b4a241a | ||
|
|
c68348b5d3 | ||
|
|
76aad71974 | ||
|
|
3b73ad6b27 | ||
|
|
789d6eea14 | ||
|
|
422651e6ff | ||
|
|
8459e1c454 | ||
|
|
0bb0d99aa4 | ||
|
|
d859ddc7fe | ||
|
|
460adff1ba | ||
|
|
a823c0b09c | ||
|
|
624e0d3435 | ||
|
|
1c17f426ac | ||
|
|
01287288a7 | ||
|
|
58725364c1 | ||
|
|
9423eb81b7 | ||
|
|
ef11e75944 | ||
|
|
932856df67 | ||
|
|
118d754d69 | ||
|
|
ef5ae121c8 | ||
|
|
9007cffdd9 | ||
|
|
6601ee3af5 | ||
|
|
b34062cabd | ||
|
|
2cfa9af586 | ||
|
|
f2632d8c90 | ||
|
|
f82b93a801 | ||
|
|
57c303d816 | ||
|
|
165c3f06b7 | ||
|
|
300292c050 | ||
|
|
15454c3a48 | ||
|
|
d962939a61 | ||
|
|
66dbfce0f7 | ||
|
|
b22207d6ee | ||
|
|
1062e0fe99 | ||
|
|
1148476cf5 | ||
|
|
9eb07f7024 | ||
|
|
0faf8c86ca | ||
|
|
9f3a2d42d0 | ||
|
|
c2475304ec | ||
|
|
2a817a989d | ||
|
|
03e9dd3f00 | ||
|
|
62d49e4e9e | ||
|
|
446107f1cb | ||
|
|
7627c57c4a | ||
|
|
4cfa28eea7 | ||
|
|
e42f1c118b | ||
|
|
78e94864b0 | ||
|
|
ea3142ba44 | ||
|
|
b3f85d49df | ||
|
|
12ee8a9201 | ||
|
|
72d9fea37a | ||
|
|
99289fc33e | ||
|
|
d12c3748a7 | ||
|
|
8906cfc81b | ||
|
|
3f91a53b2e | ||
|
|
d1e518385e | ||
|
|
b4aa4a2af8 | ||
|
|
732133a460 | ||
|
|
4a342685af | ||
|
|
1a80954475 | ||
|
|
55393307b8 | ||
|
|
88645e5c4a | ||
|
|
ae4aaf51f0 | ||
|
|
32f681dba2 | ||
|
|
bd04171a56 | ||
|
|
065db1b359 | ||
|
|
8c81ac0f5f | ||
|
|
d4c34a28df | ||
|
|
f1d2d63f2b | ||
|
|
b89dd0d036 | ||
|
|
aa43583149 | ||
|
|
e152259757 | ||
|
|
a65b24c172 | ||
|
|
a1667babf4 | ||
|
|
08ffa7c466 | ||
|
|
0f724598a8 | ||
|
|
1239109e43 | ||
|
|
4baeaa1e68 | ||
|
|
923cd9f5b1 | ||
|
|
c3f48d2851 | ||
|
|
3c413cfdfd | ||
|
|
e932f65b7c | ||
|
|
c633b2dc88 | ||
|
|
c37be7416c | ||
|
|
97a7232bdc | ||
|
|
e3ba5c75cb | ||
|
|
b2dfd11058 | ||
|
|
0f0c098fa2 | ||
|
|
29dccf3d8a | ||
|
|
9b6fd8cce0 | ||
|
|
10b3f4610c | ||
|
|
b7e39ce7e9 | ||
|
|
07b9c7dc40 | ||
|
|
3773e300f0 | ||
|
|
68c52b564a | ||
|
|
5a07782cbe | ||
|
|
1ba397e783 | ||
|
|
767b4d36a6 | ||
|
|
2e6041d0a7 | ||
|
|
a4c890ab3b | ||
|
|
903e002e85 | ||
|
|
0dc49d0706 | ||
|
|
18008d3ff2 | ||
|
|
aba9add595 | ||
|
|
4353ad72e4 | ||
|
|
4ad3c84cae | ||
|
|
7e92fec884 | ||
|
|
1a8df6e955 | ||
|
|
77c6770bfc | ||
|
|
169e772f29 | ||
|
|
44e2718aa1 | ||
|
|
c1827807c6 | ||
|
|
5c1c4d83c2 | ||
|
|
38e874fddb | ||
|
|
495677df38 | ||
|
|
6e44b4d034 | ||
|
|
9c71d91a2e | ||
|
|
9271b84df8 | ||
|
|
2621b311f9 | ||
|
|
9480841b12 | ||
|
|
461a9ec092 | ||
|
|
706eb15291 | ||
|
|
f8ca8a7b87 | ||
|
|
c808ad6e34 | ||
|
|
17606651eb | ||
|
|
320168071f | ||
|
|
aa4cc3bf45 | ||
|
|
fa86cd2944 | ||
|
|
49dbf9fd6c | ||
|
|
f194e919a0 | ||
|
|
69a2be7b51 | ||
|
|
684dfd9cf3 | ||
|
|
aebb4456ab | ||
|
|
3877fb689f | ||
|
|
9a8d756ad6 | ||
|
|
1bf7fb7233 | ||
|
|
5382c625b2 | ||
|
|
61277c0898 | ||
|
|
cd36d32fea | ||
|
|
0411b12bbb | ||
|
|
b2ea0d79be | ||
|
|
b7c0954553 | ||
|
|
87d0812396 | ||
|
|
49ad4cbfe1 | ||
|
|
2f8911eba5 | ||
|
|
031b6f2f16 | ||
|
|
35210b3646 | ||
|
|
d1ce1526d2 | ||
|
|
0161fea4df | ||
|
|
757c0a142b | ||
|
|
f4fcf1b578 | ||
|
|
4da89de1d4 | ||
|
|
0ad7635332 | ||
|
|
0ba404733d | ||
|
|
3c1c3ebe55 | ||
|
|
95d961ccf6 | ||
|
|
1c1d26c404 | ||
|
|
43e548a25d | ||
|
|
58c936a189 | ||
|
|
af87a2d923 | ||
|
|
87aae5b396 | ||
|
|
97a0aa8d1a | ||
|
|
3850c6a0e0 | ||
|
|
d4d714dcf4 | ||
|
|
9cb4a51592 | ||
|
|
f64663519e | ||
|
|
ca036d424a | ||
|
|
40dc47ec72 | ||
|
|
8f2e96cb2c | ||
|
|
d2d04615b4 | ||
|
|
4ac5d820fc | ||
|
|
57bedd84a3 | ||
|
|
bf2eb2200d | ||
|
|
65732f33c1 | ||
|
|
bb31fbd67e | ||
|
|
187d7e73ab | ||
|
|
9920c7604c | ||
|
|
5e935eb85b | ||
|
|
c8ca316474 | ||
|
|
93c134b68b | ||
|
|
19758959e4 | ||
|
|
0fa28ba1fa | ||
|
|
44e19ada63 | ||
|
|
daa007c0d5 | ||
|
|
9836f83589 | ||
|
|
3f9acecaf3 | ||
|
|
e7e6572e02 | ||
|
|
489eb5780f | ||
|
|
5978033427 | ||
|
|
07c8bb1efb | ||
|
|
f03ad35563 | ||
|
|
e62089ed70 | ||
|
|
973319b44c | ||
|
|
83117a204b | ||
|
|
75d481c6ff | ||
|
|
fe364cc2db | ||
|
|
71f3f11031 | ||
|
|
5865d41dc4 | ||
|
|
98ba88214f | ||
|
|
5a2675e375 | ||
|
|
3c6e15aa37 | ||
|
|
f2d698b8d2 | ||
|
|
8d90c74b28 | ||
|
|
70030fd3e5 | ||
|
|
fb0b19ed01 | ||
|
|
64ee210c91 | ||
|
|
433d1096f8 | ||
|
|
6a2d007b41 | ||
|
|
b0f58ef3a8 | ||
|
|
3c8d6c7c7a | ||
|
|
3b28050f1e | ||
|
|
2973c80975 | ||
|
|
0f8f55dfd9 | ||
|
|
777f25d91c | ||
|
|
727861cb85 | ||
|
|
e6da214bfb | ||
|
|
68a99ba5f9 | ||
|
|
d936a3794e | ||
|
|
bb0ba1ef2c | ||
|
|
1eb83548fa | ||
|
|
5d7afb5f85 | ||
|
|
f7c45c4f46 | ||
|
|
38a4bf804f | ||
|
|
7077776de3 | ||
|
|
2514158498 | ||
|
|
c6cc4df77b | ||
|
|
b3ee4f9bed | ||
|
|
401d5d5acc | ||
|
|
b971c6c5eb | ||
|
|
de8911af50 | ||
|
|
7e6e6c2dc2 | ||
|
|
668d89cdb2 | ||
|
|
0c1d4efc03 | ||
|
|
eefe91b852 | ||
|
|
bed8bf6661 | ||
|
|
577aeea3f3 | ||
|
|
4775ad9a53 | ||
|
|
81143be96a | ||
|
|
7debaa23ac | ||
|
|
e05dc41e0f | ||
|
|
8bab7d365b | ||
|
|
018337a19b | ||
|
|
bb08884221 | ||
|
|
abef329b8a | ||
|
|
3216f8df37 | ||
|
|
edccf70bf6 | ||
|
|
fd79f95f9b | ||
|
|
e2fcd7767e | ||
|
|
5a14f78d44 | ||
|
|
a3a7ecd817 | ||
|
|
63f016226c | ||
|
|
a58f61792b | ||
|
|
641c550cc3 |
@@ -10,6 +10,8 @@ exclude_paths:
|
||||
- molecule/
|
||||
- tests/azure/
|
||||
- meta/runtime.yml
|
||||
- requirements-docker.yml
|
||||
- requirements-podman.yml
|
||||
|
||||
kinds:
|
||||
- playbook: '**/tests/**/test_*.yml'
|
||||
|
||||
2
.github/workflows/ansible-test.yml
vendored
2
.github/workflows/ansible-test.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
name: Verify ansible-test sanity
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install virtualenv using pip
|
||||
|
||||
24
.github/workflows/docs.yml
vendored
24
.github/workflows/docs.yml
vendored
@@ -8,8 +8,10 @@ jobs:
|
||||
name: Check Ansible Documentation with Ansible 2.9.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4.3.0
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install Ansible 2.9
|
||||
@@ -23,8 +25,10 @@ jobs:
|
||||
name: Check Ansible Documentation with ansible-core 2.11.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4.3.0
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install Ansible 2.11
|
||||
@@ -38,8 +42,10 @@ jobs:
|
||||
name: Check Ansible Documentation with ansible-core 2.12.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4.3.0
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install Ansible 2.12
|
||||
@@ -54,8 +60,10 @@ jobs:
|
||||
name: Check Ansible Documentation with latest Ansible version.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4.3.0
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install Ansible-latest
|
||||
|
||||
38
.github/workflows/lint.yml
vendored
38
.github/workflows/lint.yml
vendored
@@ -8,8 +8,10 @@ jobs:
|
||||
name: Verify ansible-lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4.3.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Run ansible-lint
|
||||
@@ -25,8 +27,10 @@ jobs:
|
||||
name: Verify yamllint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4.3.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Run yaml-lint
|
||||
@@ -36,8 +40,10 @@ jobs:
|
||||
name: Verify pydocstyle
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4.3.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Run pydocstyle
|
||||
@@ -49,8 +55,10 @@ jobs:
|
||||
name: Verify flake8
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4.3.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Run flake8
|
||||
@@ -62,19 +70,23 @@ jobs:
|
||||
name: Verify pylint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v4.3.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Run pylint
|
||||
run: |
|
||||
pip install pylint==2.12.2
|
||||
pip install pylint==2.13.7 wrapt==1.14.0
|
||||
pylint plugins roles --disable=import-error
|
||||
|
||||
shellcheck:
|
||||
name: Shellcheck
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Run ShellCheck
|
||||
uses: ludeeus/action-shellcheck@1.1.0
|
||||
uses: ludeeus/action-shellcheck@master
|
||||
|
||||
4
.github/workflows/readme.yml
vendored
4
.github/workflows/readme.yml
vendored
@@ -8,7 +8,9 @@ jobs:
|
||||
name: Verify readme
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3.1.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Run readme test
|
||||
run: |
|
||||
error=0
|
||||
|
||||
@@ -15,11 +15,11 @@ repos:
|
||||
hooks:
|
||||
- id: yamllint
|
||||
files: \.(yaml|yml)$
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
- repo: https://github.com/pycqa/flake8
|
||||
rev: 3.9.2
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://gitlab.com/pycqa/pydocstyle
|
||||
- repo: https://github.com/pycqa/pydocstyle
|
||||
rev: 6.1.1
|
||||
hooks:
|
||||
- id: pydocstyle
|
||||
|
||||
@@ -65,6 +65,9 @@ Example playbook to read config options:
|
||||
maxusername: 64
|
||||
```
|
||||
|
||||
|
||||
Example playbook to set global configuration options:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to ensure some config options are set
|
||||
@@ -79,6 +82,40 @@ Example playbook to read config options:
|
||||
```
|
||||
|
||||
|
||||
Example playbook to enable SID and generate users and groups SIDs:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to ensure SIDs are enabled and users and groups have SIDs
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Enable SID and generate users and groups SIDS
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
enable_sid: yes
|
||||
add_sids: yes
|
||||
```
|
||||
|
||||
Example playbook to change IPA domain NetBIOS name:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to change IPA domain netbios name
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Set IPA domain netbios name
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
enable_sid: yes
|
||||
netbios_name: IPADOM
|
||||
```
|
||||
|
||||
Variables
|
||||
=========
|
||||
|
||||
@@ -111,6 +148,9 @@ Variable | Description | Required
|
||||
`user_auth_type` \| `ipauserauthtype` | set default types of supported user authentication (choices: `password`, `radius`, `otp`, `disabled`). Use `""` to clear this variable. | no
|
||||
`domain_resolution_order` \| `ipadomainresolutionorder` | Set list of domains used for short name qualification | no
|
||||
`ca_renewal_master_server` \| `ipacarenewalmasterserver`| Renewal master for IPA certificate authority. | no
|
||||
`enable_sid` | New users and groups automatically get a SID assigned. Cannot be deactivated once activated. Requires IPA 4.9.8+. (bool) | no
|
||||
`netbios_name` | NetBIOS name of the IPA domain. Requires IPA 4.9.8+ and SID generation to be activated. | no
|
||||
`add_sids` | Add SIDs for existing users and groups. Requires IPA 4.9.8+ and SID generation to be activated. (bool) | no
|
||||
|
||||
|
||||
Return Values
|
||||
@@ -140,6 +180,8 @@ Variable | Description | Returned When
|
||||
| `user_auth_type` |
|
||||
| `domain_resolution_order` |
|
||||
| `ca_renewal_master_server` |
|
||||
| `enable_sid` |
|
||||
| `netbios_name` |
|
||||
|
||||
All returned fields take the same form as their namesake input parameters
|
||||
|
||||
|
||||
179
README-netgroup.md
Normal file
179
README-netgroup.md
Normal file
@@ -0,0 +1,179 @@
|
||||
Netgroup module
|
||||
============
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The netgroup module allows to ensure presence and absence of netgroups.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Netgroup management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipanetgroup 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 netgroup "my_netgroup1" is present:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA netgroup.
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure netgroup my_netgroup1 is present
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my_netgroup1
|
||||
description: My netgroup 1
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure netgroup "my_netgroup1" is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA netgroup.
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure netgroup my_netgroup1 is absent
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my_netgroup1
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure netgroup is present with user "user1"
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA netgroup.
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure netgroup is present with user "user1"
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: TestNetgroup1
|
||||
user: user1
|
||||
action: member
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure netgroup user, "user1", is absent
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA netgroup.
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure netgroup user, "user1", is absent
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: TestNetgroup1
|
||||
user: "user1"
|
||||
action: member
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure netgroup is present with members
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA netgroup.
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure netgroup members are present
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: TestNetgroup1
|
||||
user: user1,user2
|
||||
group: group1
|
||||
host: host1
|
||||
hostgroup: ipaservers
|
||||
netgroup: admins
|
||||
action: member
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure 2 netgroups TestNetgroup1, admins are absent
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA netgroup.
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure netgroups are absent
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name:
|
||||
- TestNetgroup1
|
||||
- admins
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
---------
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`ipaapi_context` | The context in which the module will execute. Executing in a server context is preferred. If not provided context will be determined by the execution environment. Valid values are `server` and `client`. | no
|
||||
`ipaapi_ldap_cache` | Use LDAP cache for IPA connection. The bool setting defaults to yes. (bool) | no
|
||||
`name` \| `cn` | The list of netgroup name strings. | yes
|
||||
`description` | Netgroup description | no
|
||||
`nisdomain` | NIS domain name | no
|
||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||
`user` | List of user name strings assigned to this netgroup. | no
|
||||
`group` | List of group name strings assigned to this netgroup. | no
|
||||
`host` | List of host name strings assigned to this netgroup. | no
|
||||
`hostgroup` | List of hostgroup name strings assigned to this netgroup. | no
|
||||
`netgroup` | List of netgroup name strings assigned to this netgroup. | no
|
||||
`action` | Work on group or member level. It can be on of `member` or `netgroup` and defaults to `netgroup`. | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, default: `present`. | no
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Denis Karpelevich
|
||||
@@ -87,6 +87,36 @@ Example playbook to ensure maxlife is set to 49 in global policy:
|
||||
maxlife: 49
|
||||
```
|
||||
|
||||
Example playbook to ensure password grace period is set to 3 in global policy:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle pwpolicies
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure maxlife is set to 49 in global policy
|
||||
- ipapwpolicy:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
gracelimit: 3
|
||||
```
|
||||
|
||||
Example playbook to ensure password grace period is set to unlimited in global policy:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle pwpolicies
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Ensure maxlife is set to 49 in global policy
|
||||
- ipapwpolicy:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
gracelimit: -1
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
=========
|
||||
@@ -107,6 +137,11 @@ Variable | Description | Required
|
||||
`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
|
||||
`maxrepeat` \| `ipapwdmaxrepeat` | Maximum number of same consecutive characters. Requires IPA 4.9+ (int) | no
|
||||
`maxsequence` \| `ipapwdmaxsequence` | The maximum length of monotonic character sequences (abcd). Requires IPA 4.9+ (int) | no
|
||||
`dictcheck` \| `ipapwdictcheck` | Check if the password is a dictionary word. Requires IPA 4.9+ (int) | no
|
||||
`usercheck` \| `ipapwdusercheck` | Check if the password contains the username. Requires IPA 4.9+ (int) | no
|
||||
`gracelimit` \| `passwordgracelimit` | Number of LDAP authentications allowed after expiration. Requires IPA 4.9.10 (int) | no
|
||||
`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | yes
|
||||
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ Variable | Description | Required
|
||||
`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
|
||||
`hostmask` | List of host masks of allowed hosts | no
|
||||
`user` | List of user name strings assigned to this sudorule. | no
|
||||
`group` | List of user group name strings assigned to this sudorule. | no
|
||||
`allow_sudocmd` | List of sudocmd name strings assigned to the allow group of this sudorule. | no
|
||||
|
||||
@@ -381,8 +381,8 @@ Variable | Description | Required
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`first` \| `givenname` | The first name string. | no
|
||||
`last` \| `sn` | The last name string. | no
|
||||
`first` \| `givenname` | The first name string. Required if user does not exist. | no
|
||||
`last` \| `sn` | The last name string. Required if user does not exist. | no
|
||||
`fullname` \| `cn` | The full name string. | no
|
||||
`displayname` | The display name string. | no
|
||||
`homedir` | The home directory string. | no
|
||||
|
||||
@@ -222,8 +222,8 @@ Variable | Description | Required
|
||||
`password_file` \| `vault_password_file` \| `old_password_file`| File containing Base64 encoded Vault password. | no
|
||||
`new_password` | Vault new password. | no
|
||||
`new_password_file` | File containing Base64 encoded new Vault password. | no
|
||||
`public_key ` \| `vault_public_key` \| `ipavaultpublickey` | Base64 encoded vault public key. | no
|
||||
`public_key_file` \| `vault_public_key_file` | Path to file with public key. | no
|
||||
`public_key ` \| `vault_public_key` \| `ipavaultpublickey` \| `new_public_key` | Base64 encoded vault public key. | no
|
||||
`public_key_file` \| `vault_public_key_file` \| `new_public_key_file` | Path to file with public key. | no
|
||||
`private_key `\| `vault_private_key` \| `ipavaultprivatekey` | Base64 encoded vault private key. Used only to retrieve data. | no
|
||||
`private_key_file` \| `vault_private_key_file` | Path to file with private key. Used only to retrieve data. | no
|
||||
`salt` \| `vault_salt` \| `ipavaultsalt` | Vault salt. | no
|
||||
|
||||
@@ -31,6 +31,7 @@ Features
|
||||
* Modules for hostgroup management
|
||||
* Modules for idrange management
|
||||
* Modules for location management
|
||||
* Modules for netgroup management
|
||||
* Modules for permission management
|
||||
* Modules for privilege management
|
||||
* Modules for pwpolicy management
|
||||
@@ -68,7 +69,6 @@ Requirements
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.8+ (ansible-freeipa is an Ansible Collection)
|
||||
* /usr/bin/kinit is required on the controller if a one time password (OTP) is used
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
@@ -288,7 +288,7 @@ ipaserver_domain=test.local
|
||||
ipaserver_realm=TEST.LOCAL
|
||||
```
|
||||
|
||||
For enhanced security it is possible to use a auto-generated one-time-password (OTP). This will be generated on the controller using the (first) server.
|
||||
For enhanced security it is possible to use a auto-generated one-time-password (OTP). This will be generated on the (first) server.
|
||||
|
||||
To enable the generation of the one-time-password:
|
||||
```yaml
|
||||
@@ -450,6 +450,7 @@ Modules in plugin/modules
|
||||
* [ipahostgroup](README-hostgroup.md)
|
||||
* [idrange](README-idrange.md)
|
||||
* [ipalocation](README-location.md)
|
||||
* [ipanetgroup](README-netgroup.md)
|
||||
* [ipapermission](README-permission.md)
|
||||
* [ipaprivilege](README-privilege.md)
|
||||
* [ipapwpolicy](README-pwpolicy.md)
|
||||
|
||||
12
playbooks/config/change-ipa-domain-netbios-name.yml
Normal file
12
playbooks/config/change-ipa-domain-netbios-name.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Playbook to change IPA domain netbios name
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Set IPA domain netbios name
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
enable_sid: yes
|
||||
netbios_name: IPADOM
|
||||
12
playbooks/config/generate-users-groups-sids.yml
Normal file
12
playbooks/config/generate-users-groups-sids.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Playbook to ensure SIDs are enabled and users and groups have SIDs
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Enable SID and generate users and groups SIDS
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
enable_sid: yes
|
||||
add_sids: yes
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: Playbook to handle global DNS configuration
|
||||
- name: Playbook to handle global IPA configuration
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: Playbook to handle global DNS configuration
|
||||
- name: Playbook to handle global IPA configuration
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
12
playbooks/netgroup/netgroup-absent.yml
Normal file
12
playbooks/netgroup/netgroup-absent.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Netgroup absent example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure netgroup my_netgroup1 is absent
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my_netgroup1
|
||||
state: absent
|
||||
14
playbooks/netgroup/netgroup-member-absent.yml
Normal file
14
playbooks/netgroup/netgroup-member-absent.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Netgroup absent example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure netgroup user, "user1", is absent
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: TestNetgroup1
|
||||
user: "user1"
|
||||
action: member
|
||||
state: absent
|
||||
13
playbooks/netgroup/netgroup-member-present.yml
Normal file
13
playbooks/netgroup/netgroup-member-present.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Netgroup member present example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure netgroup is present with user "user1"
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: TestNetgroup1
|
||||
user: user1
|
||||
action: member
|
||||
12
playbooks/netgroup/netgroup-present.yml
Normal file
12
playbooks/netgroup/netgroup-present.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Netgroup present example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure netgroup my_netgroup1 is present
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my_netgroup1
|
||||
description: My netgroup 1
|
||||
11
playbooks/pwpolicy/pwpolicy_grace_limit.yml
Normal file
11
playbooks/pwpolicy/pwpolicy_grace_limit.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Playbook to manage password policy
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Set password policy grace limit.
|
||||
ipapwpolicy:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
gracelimit: 3
|
||||
14
playbooks/pwpolicy/pwpolicy_password_check.yml
Normal file
14
playbooks/pwpolicy/pwpolicy_password_check.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Playbook to manage password policy
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Set password checking parameters.
|
||||
ipapwpolicy:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
maxrepeat: 2
|
||||
maxsequence: 3
|
||||
dictcheck: yes
|
||||
usercheck: yes
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Playbook to manage sudorule
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure hostmask network is absent in sudorule
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: testrule1
|
||||
hostmask: 192.168.122.37/24
|
||||
action: member
|
||||
state: absent
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Playbook to manage sudorule
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure hostmask network is present in sudorule
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: testrule1
|
||||
hostmask: 192.168.122.37/24
|
||||
action: member
|
||||
@@ -30,15 +30,18 @@ options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal.
|
||||
default: admin
|
||||
type: str
|
||||
ipaadmin_password:
|
||||
description: The admin password.
|
||||
required: false
|
||||
type: str
|
||||
ipaapi_context:
|
||||
description: |
|
||||
The context in which the module will execute. Executing in a
|
||||
server context is preferred. If not provided context will be
|
||||
determined by the execution environment.
|
||||
choices: ["server", "client"]
|
||||
type: str
|
||||
required: false
|
||||
ipaapi_ldap_cache:
|
||||
description: Use LDAP cache for IPA connection.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,9 @@
|
||||
# Authors:
|
||||
# Mark Hahl <mhahl@redhat.com>
|
||||
# Jake Reynolds <jakealexis@gmail.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2021 Red Hat
|
||||
# Copyright (C) 2021-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,21 +35,24 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaautomember
|
||||
short description: Add and delete FreeIPA Auto Membership Rules.
|
||||
short_description: Add and delete FreeIPA Auto Membership Rules.
|
||||
description: Add, modify and delete an IPA Auto Membership Rules.
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The automember rule
|
||||
required: true
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: A description of this auto member rule
|
||||
required: false
|
||||
type: str
|
||||
automember_type:
|
||||
description: Grouping to which the rule applies
|
||||
required: true
|
||||
required: false
|
||||
type: str
|
||||
choices: ["group", "hostgroup"]
|
||||
exclusive:
|
||||
@@ -56,7 +60,7 @@ options:
|
||||
type: list
|
||||
elements: dict
|
||||
aliases: ["automemberexclusiveregex"]
|
||||
options:
|
||||
suboptions:
|
||||
key:
|
||||
description: The attribute of the regex
|
||||
type: str
|
||||
@@ -70,7 +74,7 @@ options:
|
||||
type: list
|
||||
elements: dict
|
||||
aliases: ["automemberinclusiveregex"]
|
||||
options:
|
||||
suboptions:
|
||||
key:
|
||||
description: The attribute of the regex
|
||||
type: str
|
||||
@@ -82,10 +86,12 @@ options:
|
||||
users:
|
||||
description: Users to rebuild membership for.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
hosts:
|
||||
description: Hosts to rebuild membership for.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
no_wait:
|
||||
description: Don't wait for rebuilding membership.
|
||||
@@ -95,16 +101,18 @@ options:
|
||||
type: str
|
||||
action:
|
||||
description: Work on automember or member level
|
||||
type: str
|
||||
default: automember
|
||||
choices: ["member", "automember"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent", "rebuilt", "orphans_removed"]
|
||||
author:
|
||||
- Mark Hahl
|
||||
- Jake Reynolds
|
||||
- Thomas Woerner
|
||||
- Mark Hahl (@mhahl)
|
||||
- Jake Reynolds (@jake2184)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -208,7 +216,6 @@ EXAMPLES = """
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
|
||||
from ansible.module_utils.ansible_freeipa_module import (
|
||||
IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, ipalib_errors, DN
|
||||
)
|
||||
@@ -315,7 +322,8 @@ def main():
|
||||
aliases=["automemberinclusiveregex"],
|
||||
default=None,
|
||||
options=dict(
|
||||
key=dict(type="str", required=True),
|
||||
key=dict(type="str", required=True,
|
||||
no_log=False),
|
||||
expression=dict(type="str", required=True)
|
||||
),
|
||||
elements="dict",
|
||||
@@ -324,12 +332,13 @@ def main():
|
||||
aliases=["automemberexclusiveregex"],
|
||||
default=None,
|
||||
options=dict(
|
||||
key=dict(type="str", required=True),
|
||||
key=dict(type="str", required=True,
|
||||
no_log=False),
|
||||
expression=dict(type="str", required=True)
|
||||
),
|
||||
elements="dict",
|
||||
required=False),
|
||||
name=dict(type="list", aliases=["cn"],
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
default=None, required=False),
|
||||
description=dict(type="str", default=None),
|
||||
automember_type=dict(type='str', required=False,
|
||||
@@ -341,8 +350,8 @@ def main():
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent", "rebuilt",
|
||||
"orphans_removed"]),
|
||||
users=dict(type="list", default=None),
|
||||
hosts=dict(type="list", default=None),
|
||||
users=dict(type="list", elements="str", default=None),
|
||||
hosts=dict(type="list", elements="str", default=None),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
|
||||
# Authors:
|
||||
# Chris Procter <cprocter@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2021 Red Hat
|
||||
# Copyright (C) 2021-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,39 +35,43 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaautomountkey
|
||||
author: chris procter
|
||||
author:
|
||||
- Chris Procter (@chr15p))
|
||||
- Thomas Woerner (@t-woerner)
|
||||
short_description: Manage FreeIPA autommount map
|
||||
description:
|
||||
- Add, delete, and modify an IPA automount map
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: False
|
||||
location:
|
||||
description: automount location map is in
|
||||
type: str
|
||||
required: True
|
||||
choices: ["automountlocationcn", "automountlocation"]
|
||||
aliases: ["automountlocationcn", "automountlocation"]
|
||||
mapname:
|
||||
description: automount map to be managed
|
||||
choices: ["map", "automountmapname", "automountmap"]
|
||||
type: str
|
||||
aliases: ["map", "automountmapname", "automountmap"]
|
||||
required: True
|
||||
key:
|
||||
description: automount key to be managed
|
||||
type: str
|
||||
required: True
|
||||
choices: ["name", "automountkey"]
|
||||
newkey:
|
||||
aliases: ["name", "automountkey"]
|
||||
rename:
|
||||
description: key to change to if state is 'renamed'
|
||||
required: True
|
||||
choices: ["newname", "newautomountkey"]
|
||||
type: str
|
||||
required: False
|
||||
aliases: ["new_name", "newautomountkey"]
|
||||
info:
|
||||
description: Mount information for the key
|
||||
required: True
|
||||
choices: ["information", "automountinformation"]
|
||||
type: str
|
||||
required: False
|
||||
aliases: ["information", "automountinformation"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
required: False
|
||||
default: present
|
||||
choices: ["present", "absent", "renamed"]
|
||||
@@ -193,7 +198,7 @@ def main():
|
||||
state=dict(
|
||||
type='str',
|
||||
choices=['present', 'absent', 'renamed'],
|
||||
required=None,
|
||||
required=False,
|
||||
default='present',
|
||||
),
|
||||
location=dict(
|
||||
@@ -215,6 +220,7 @@ def main():
|
||||
type="str",
|
||||
aliases=["name", "automountkey"],
|
||||
required=True,
|
||||
no_log=False,
|
||||
),
|
||||
info=dict(
|
||||
type="str",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Authors:
|
||||
# Chris Procter <cprocter@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2021 Red Hat
|
||||
# Copyright (C) 2021-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,7 +33,9 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaautomountlocation
|
||||
author: chris procter
|
||||
author:
|
||||
- Chris Procter (@chr15p)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
short_description: Manage FreeIPA autommount locations
|
||||
description:
|
||||
- Add and delete an IPA automount location
|
||||
@@ -42,10 +45,13 @@ options:
|
||||
name:
|
||||
description: The automount location to be managed
|
||||
required: true
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["cn","location"]
|
||||
state:
|
||||
description: State to ensure
|
||||
required: false
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
'''
|
||||
@@ -116,9 +122,8 @@ def main():
|
||||
default='present',
|
||||
choices=['present', 'absent']
|
||||
),
|
||||
name=dict(type="list",
|
||||
name=dict(type="list", elements="str",
|
||||
aliases=["cn", "location"],
|
||||
default=None,
|
||||
required=True
|
||||
),
|
||||
),
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Authors:
|
||||
# Chris Procter <cprocter@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2021 Red Hat
|
||||
# Copyright (C) 2021-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -33,31 +34,34 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaautomountmap
|
||||
author: Chris Procter
|
||||
author:
|
||||
- Chris Procter (@chr15p)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
short_description: Manage FreeIPA autommount map
|
||||
description:
|
||||
- Add, delete, and modify an IPA automount map
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal.
|
||||
default: admin
|
||||
ipaadmin_password:
|
||||
description: The admin password.
|
||||
required: false
|
||||
automountlocation:
|
||||
description: automount location map is anchored to
|
||||
choices: ["location", "automountlocationcn"]
|
||||
type: str
|
||||
aliases: ["location", "automountlocationcn"]
|
||||
required: True
|
||||
name:
|
||||
description: automount map to be managed.
|
||||
choices: ["mapname", "map", "automountmapname"]
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["mapname", "map", "automountmapname"]
|
||||
required: True
|
||||
desc:
|
||||
description: description of automount map.
|
||||
choices: ["description"]
|
||||
type: str
|
||||
aliases: ["description"]
|
||||
required: false
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
required: false
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
@@ -169,12 +173,10 @@ def main():
|
||||
),
|
||||
location=dict(type="str",
|
||||
aliases=["automountlocation", "automountlocationcn"],
|
||||
default=None,
|
||||
required=True
|
||||
),
|
||||
name=dict(type="list",
|
||||
name=dict(type="list", elements="str",
|
||||
aliases=["mapname", "map", "automountmapname"],
|
||||
default=None,
|
||||
required=True
|
||||
),
|
||||
desc=dict(type="str",
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Chris Procter <cprocter@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2020 Red Hat
|
||||
# Copyright (C) 2020-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,8 +33,10 @@ ANSIBLE_METADATA = {
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipa_config
|
||||
author: chris procter
|
||||
module: ipaconfig
|
||||
author:
|
||||
- Chris Procter (@chr15p)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
short_description: Modify IPA global config options
|
||||
description:
|
||||
- Modify IPA global config options
|
||||
@@ -43,48 +46,60 @@ options:
|
||||
maxusername:
|
||||
description: Set the maximum username length between 1-255
|
||||
required: false
|
||||
type: int
|
||||
aliases: ['ipamaxusernamelength']
|
||||
maxhostname:
|
||||
description: Set the maximum hostname length between 64-255
|
||||
required: false
|
||||
type: int
|
||||
aliases: ['ipamaxhostnamelength']
|
||||
homedirectory:
|
||||
description: Set the default location of home directories
|
||||
required: false
|
||||
type: str
|
||||
aliases: ['ipahomesrootdir']
|
||||
defaultshell:
|
||||
description: Set the default shell for new users
|
||||
required: false
|
||||
type: str
|
||||
aliases: ['ipadefaultloginshell', 'loginshell']
|
||||
defaultgroup:
|
||||
description: Set the default group for new users
|
||||
required: false
|
||||
type: str
|
||||
aliases: ['ipadefaultprimarygroup']
|
||||
emaildomain:
|
||||
description: Set the default e-mail domain
|
||||
required: false
|
||||
type: str
|
||||
aliases: ['ipadefaultemaildomain']
|
||||
searchtimelimit:
|
||||
description:
|
||||
- Set maximum amount of time (seconds) for a search
|
||||
- values -1 to 2147483647 (-1 or 0 is unlimited)
|
||||
required: false
|
||||
type: int
|
||||
aliases: ['ipasearchtimelimit']
|
||||
searchrecordslimit:
|
||||
description:
|
||||
- Set maximum number of records to search
|
||||
- values -1 to 2147483647 (-1 or 0 is unlimited)
|
||||
required: false
|
||||
type: int
|
||||
aliases: ['ipasearchrecordslimit']
|
||||
usersearch:
|
||||
description:
|
||||
- Set comma-separated list of fields to search for user search
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ['ipausersearchfields']
|
||||
groupsearch:
|
||||
description:
|
||||
- Set comma-separated list of fields to search for group search
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ['ipagroupsearchfields']
|
||||
enable_migration:
|
||||
description: Enable migration mode
|
||||
@@ -95,22 +110,26 @@ options:
|
||||
description: Set default group objectclasses (comma-separated list)
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ['ipagroupobjectclasses']
|
||||
userobjectclasses:
|
||||
description: Set default user objectclasses (comma-separated list)
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ['ipauserobjectclasses']
|
||||
pwdexpnotify:
|
||||
description:
|
||||
- Set number of days's notice of impending password expiration
|
||||
- values 0 to 2147483647
|
||||
required: false
|
||||
type: int
|
||||
aliases: ['ipapwdexpadvnotify']
|
||||
configstring:
|
||||
description: Set extra hashes to generate in password plug-in
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
choices:
|
||||
- "AllowNThash"
|
||||
- "KDC:Disable Last Success"
|
||||
@@ -122,32 +141,55 @@ options:
|
||||
description: Set order in increasing priority of SELinux users
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ['ipaselinuxusermaporder']
|
||||
selinuxusermapdefault:
|
||||
description: Set default SELinux user when no match found in map rule
|
||||
required: false
|
||||
type: str
|
||||
aliases: ['ipaselinuxusermapdefault']
|
||||
pac_type:
|
||||
description: set default types of PAC supported for services
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
choices: ["MS-PAC", "PAD", "nfs:NONE", ""]
|
||||
aliases: ["ipakrbauthzdata"]
|
||||
user_auth_type:
|
||||
description: set default types of supported user authentication
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
choices: ["password", "radius", "otp", "disabled", ""]
|
||||
aliases: ["ipauserauthtype"]
|
||||
ca_renewal_master_server:
|
||||
description: Renewal master for IPA certificate authority.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
domain_resolution_order:
|
||||
description: set list of domains used for short name qualification
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipadomainresolutionorder"]
|
||||
enable_sid:
|
||||
description: >
|
||||
New users and groups automatically get a SID assigned.
|
||||
Cannot be deactivated once activated. Requires IPA 4.9.8+.
|
||||
required: false
|
||||
type: bool
|
||||
netbios_name:
|
||||
description: >
|
||||
NetBIOS name of the IPA domain. Requires IPA 4.9.8+
|
||||
and SID generation to be activated.
|
||||
required: false
|
||||
type: str
|
||||
add_sids:
|
||||
description: >
|
||||
Add SIDs for existing users and groups. Requires IPA 4.9.8+
|
||||
and SID generation to be activated.
|
||||
required: false
|
||||
type: bool
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -169,6 +211,24 @@ EXAMPLES = '''
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
defaultshell: /bin/bash
|
||||
maxusername: 64
|
||||
|
||||
- name: Playbook to enable SID and generate users and groups SIDs
|
||||
hosts: ipaserver
|
||||
tasks:
|
||||
- name: Enable SID and generate users and groups SIDS
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
enable_sid: yes
|
||||
add_sids: yes
|
||||
|
||||
- name: Playbook to change IPA domain netbios name
|
||||
hosts: ipaserver
|
||||
tasks:
|
||||
- name: Enable SID and generate users and groups SIDS
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
enable_sid: yes
|
||||
netbios_name: IPADOM
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
@@ -176,38 +236,48 @@ config:
|
||||
description: Dict of all global config options
|
||||
returned: When no options are set
|
||||
type: dict
|
||||
options:
|
||||
contains:
|
||||
maxusername:
|
||||
description: maximum username length
|
||||
type: int
|
||||
returned: always
|
||||
maxhostname:
|
||||
description: maximum hostname length
|
||||
type: int
|
||||
returned: always
|
||||
homedirectory:
|
||||
description: default location of home directories
|
||||
type: str
|
||||
returned: always
|
||||
defaultshell:
|
||||
description: default shell for new users
|
||||
type: str
|
||||
returned: always
|
||||
defaultgroup:
|
||||
description: default group for new users
|
||||
type: str
|
||||
returned: always
|
||||
emaildomain:
|
||||
description: default e-mail domain
|
||||
type: str
|
||||
returned: always
|
||||
searchtimelimit:
|
||||
description: maximum amount of time (seconds) for a search
|
||||
type: int
|
||||
returned: always
|
||||
searchrecordslimit:
|
||||
description: maximum number of records to search
|
||||
type: int
|
||||
returned: always
|
||||
usersearch:
|
||||
description: comma-separated list of fields to search in user search
|
||||
description: list of fields to search in user search
|
||||
type: list
|
||||
elements: str
|
||||
returned: always
|
||||
groupsearch:
|
||||
description: comma-separated list of fields to search in group search
|
||||
description: list of fields to search in group search
|
||||
type: list
|
||||
elements: str
|
||||
returned: always
|
||||
enable_migration:
|
||||
description: Enable migration mode
|
||||
@@ -216,37 +286,59 @@ config:
|
||||
groupobjectclasses:
|
||||
description: default group objectclasses (comma-separated list)
|
||||
type: list
|
||||
elements: str
|
||||
returned: always
|
||||
userobjectclasses:
|
||||
description: default user objectclasses (comma-separated list)
|
||||
type: list
|
||||
elements: str
|
||||
returned: always
|
||||
pwdexpnotify:
|
||||
description: number of days's notice of impending password expiration
|
||||
type: str
|
||||
returned: always
|
||||
configstring:
|
||||
description: extra hashes to generate in password plug-in
|
||||
type: list
|
||||
elements: str
|
||||
returned: always
|
||||
selinuxusermaporder:
|
||||
description: order in increasing priority of SELinux users
|
||||
type: list
|
||||
elements: str
|
||||
returned: always
|
||||
selinuxusermapdefault:
|
||||
description: default SELinux user when no match is found in map rule
|
||||
type: str
|
||||
returned: always
|
||||
pac_type:
|
||||
description: default types of PAC supported for services
|
||||
type: list
|
||||
elements: str
|
||||
returned: always
|
||||
user_auth_type:
|
||||
description: default types of supported user authentication
|
||||
type: str
|
||||
returned: always
|
||||
ca_renewal_master_server:
|
||||
description: master for IPA certificate authority.
|
||||
type: str
|
||||
returned: always
|
||||
domain_resolution_order:
|
||||
description: list of domains used for short name qualification
|
||||
type: list
|
||||
elements: str
|
||||
returned: always
|
||||
enable_sid:
|
||||
description: >
|
||||
new users and groups automatically get a SID assigned.
|
||||
Requires IPA 4.9.8+.
|
||||
type: str
|
||||
returned: always
|
||||
netbios_name:
|
||||
description: NetBIOS name of the IPA domain. Requires IPA 4.9.8+.
|
||||
type: str
|
||||
returned: if enable_sid is True
|
||||
'''
|
||||
|
||||
|
||||
@@ -260,6 +352,28 @@ def config_show(module):
|
||||
return _result["result"]
|
||||
|
||||
|
||||
def get_netbios_name(module):
|
||||
try:
|
||||
_result = module.ipa_command_no_name("trustconfig_show", {"all": True})
|
||||
except Exception: # pylint: disable=broad-except
|
||||
return None
|
||||
else:
|
||||
return _result["result"]["ipantflatname"][0]
|
||||
|
||||
|
||||
def is_enable_sid(module):
|
||||
"""When 'enable_sid' is true admin user and admins group have SID set."""
|
||||
_result = module.ipa_command("user_show", "admin", {"all": True})
|
||||
sid = _result["result"].get("ipantsecurityidentifier", [""])
|
||||
if not sid[0].endswith("-500"):
|
||||
return False
|
||||
_result = module.ipa_command("group_show", "admins", {"all": True})
|
||||
sid = _result["result"].get("ipantsecurityidentifier", [""])
|
||||
if not sid[0].endswith("-512"):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
@@ -281,39 +395,45 @@ def main():
|
||||
aliases=['ipasearchtimelimit']),
|
||||
searchrecordslimit=dict(type="int", required=False,
|
||||
aliases=['ipasearchrecordslimit']),
|
||||
usersearch=dict(type="list", required=False,
|
||||
usersearch=dict(type="list", elements="str", required=False,
|
||||
aliases=['ipausersearchfields']),
|
||||
groupsearch=dict(type="list", required=False,
|
||||
groupsearch=dict(type="list", elements="str", required=False,
|
||||
aliases=['ipagroupsearchfields']),
|
||||
enable_migration=dict(type="bool", required=False,
|
||||
aliases=['ipamigrationenabled']),
|
||||
groupobjectclasses=dict(type="list", required=False,
|
||||
groupobjectclasses=dict(type="list", elements="str",
|
||||
required=False,
|
||||
aliases=['ipagroupobjectclasses']),
|
||||
userobjectclasses=dict(type="list", required=False,
|
||||
userobjectclasses=dict(type="list", elements="str", required=False,
|
||||
aliases=['ipauserobjectclasses']),
|
||||
pwdexpnotify=dict(type="int", required=False,
|
||||
aliases=['ipapwdexpadvnotify']),
|
||||
configstring=dict(type="list", required=False,
|
||||
configstring=dict(type="list", elements="str", required=False,
|
||||
aliases=['ipaconfigstring'],
|
||||
choices=["AllowNThash",
|
||||
"KDC:Disable Last Success",
|
||||
"KDC:Disable Lockout",
|
||||
"KDC:Disable Default Preauth for SPNs",
|
||||
""]), # noqa E128
|
||||
selinuxusermaporder=dict(type="list", required=False,
|
||||
selinuxusermaporder=dict(type="list", elements="str",
|
||||
required=False,
|
||||
aliases=['ipaselinuxusermaporder']),
|
||||
selinuxusermapdefault=dict(type="str", required=False,
|
||||
aliases=['ipaselinuxusermapdefault']),
|
||||
pac_type=dict(type="list", required=False,
|
||||
pac_type=dict(type="list", elements="str", required=False,
|
||||
aliases=["ipakrbauthzdata"],
|
||||
choices=["MS-PAC", "PAD", "nfs:NONE", ""]),
|
||||
user_auth_type=dict(type="list", required=False,
|
||||
user_auth_type=dict(type="list", elements="str", required=False,
|
||||
choices=["password", "radius", "otp",
|
||||
"disabled", ""],
|
||||
aliases=["ipauserauthtype"]),
|
||||
ca_renewal_master_server=dict(type="str", required=False),
|
||||
domain_resolution_order=dict(type="list", required=False,
|
||||
aliases=["ipadomainresolutionorder"])
|
||||
domain_resolution_order=dict(type="list", elements="str",
|
||||
required=False,
|
||||
aliases=["ipadomainresolutionorder"]),
|
||||
enable_sid=dict(type="bool", required=False),
|
||||
add_sids=dict(type="bool", required=False),
|
||||
netbios_name=dict(type="str", required=False),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
@@ -344,7 +464,10 @@ def main():
|
||||
"pac_type": "ipakrbauthzdata",
|
||||
"user_auth_type": "ipauserauthtype",
|
||||
"ca_renewal_master_server": "ca_renewal_master_server",
|
||||
"domain_resolution_order": "ipadomainresolutionorder"
|
||||
"domain_resolution_order": "ipadomainresolutionorder",
|
||||
"enable_sid": "enable_sid",
|
||||
"netbios_name": "netbios_name",
|
||||
"add_sids": "add_sids",
|
||||
}
|
||||
allow_empty_string = ["pac_type", "user_auth_type", "configstring"]
|
||||
reverse_field_map = {v: k for k, v in field_map.items()}
|
||||
@@ -394,11 +517,52 @@ def main():
|
||||
changed = False
|
||||
exit_args = {}
|
||||
|
||||
# Connect to IPA API
|
||||
with ansible_module.ipa_connect():
|
||||
# Connect to IPA API (enable_sid requires context == 'client')
|
||||
with ansible_module.ipa_connect(context="client"):
|
||||
has_enable_sid = ansible_module.ipa_command_param_exists(
|
||||
"config_mod", "enable_sid")
|
||||
|
||||
result = config_show(ansible_module)
|
||||
|
||||
if params:
|
||||
enable_sid = params.get("enable_sid")
|
||||
sid_is_enabled = has_enable_sid and is_enable_sid(ansible_module)
|
||||
|
||||
if sid_is_enabled and enable_sid is False:
|
||||
ansible_module.fail_json(msg="SID cannot be disabled.")
|
||||
|
||||
netbios_name = params.get("netbios_name")
|
||||
add_sids = params.get("add_sids")
|
||||
if has_enable_sid:
|
||||
if (
|
||||
netbios_name
|
||||
and netbios_name == get_netbios_name(ansible_module)
|
||||
):
|
||||
del params["netbios_name"]
|
||||
netbios_name = None
|
||||
if not add_sids and "add_sids" in params:
|
||||
del params["add_sids"]
|
||||
if any([netbios_name, add_sids]):
|
||||
if sid_is_enabled:
|
||||
params["enable_sid"] = True
|
||||
else:
|
||||
if not enable_sid:
|
||||
ansible_module.fail_json(
|
||||
msg="SID generation must be enabled for "
|
||||
"'netbios_name' and 'add_sids'. Use "
|
||||
"'enable_sid: yes'."
|
||||
)
|
||||
else:
|
||||
if sid_is_enabled and "enable_sid" in params:
|
||||
del params["enable_sid"]
|
||||
|
||||
else:
|
||||
if any([enable_sid, netbios_name, add_sids is not None]):
|
||||
ansible_module.fail_json(
|
||||
msg="This version of IPA does not support enable_sid, "
|
||||
"add_sids or netbios_name setting through the "
|
||||
"config module"
|
||||
)
|
||||
params = {
|
||||
k: v for k, v in params.items()
|
||||
if k not in result or result[k] != v
|
||||
@@ -458,6 +622,10 @@ def main():
|
||||
# Add empty domain_resolution_order if it is not set
|
||||
if "domain_resolution_order" not in exit_args:
|
||||
exit_args["domain_resolution_order"] = []
|
||||
# Set enable_sid
|
||||
if has_enable_sid:
|
||||
exit_args["enable_sid"] = is_enable_sid(ansible_module)
|
||||
exit_args["netbios_name"] = get_netbios_name(ansible_module)
|
||||
|
||||
# Done
|
||||
ansible_module.exit_json(changed=changed, config=exit_args)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2020 Red Hat
|
||||
# Copyright (C) 2020-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,40 +32,52 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipadelegation
|
||||
short description: Manage FreeIPA delegations
|
||||
short_description: Manage FreeIPA delegations
|
||||
description: Manage FreeIPA delegations and delegation attributes
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The list of delegation name strings.
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["aciname"]
|
||||
permission:
|
||||
description: Permissions to grant (read, write). Default is write.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["permissions"]
|
||||
attribute:
|
||||
description: Attribute list to which the delegation applies
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["attrs"]
|
||||
membergroup:
|
||||
description: User group to apply delegation to
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["memberof"]
|
||||
group:
|
||||
description: User group ACI grants access to
|
||||
type: str
|
||||
required: false
|
||||
action:
|
||||
description: Work on delegation or member level.
|
||||
type: str
|
||||
choices: ["delegation", "member"]
|
||||
default: delegation
|
||||
required: false
|
||||
state:
|
||||
description: The state to ensure.
|
||||
type: str
|
||||
choices: ["present", "absent"]
|
||||
default: present
|
||||
required: true
|
||||
required: false
|
||||
author:
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -143,13 +155,13 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["aciname"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["aciname"],
|
||||
required=True),
|
||||
# present
|
||||
permission=dict(required=False, type='list',
|
||||
permission=dict(required=False, type='list', elements="str",
|
||||
aliases=["permissions"], default=None),
|
||||
attribute=dict(required=False, type='list', aliases=["attrs"],
|
||||
default=None),
|
||||
attribute=dict(required=False, type='list', elements="str",
|
||||
aliases=["attrs"], default=None),
|
||||
membergroup=dict(type="str", aliases=["memberof"], default=None),
|
||||
group=dict(type="str", default=None),
|
||||
action=dict(type="str", default="delegation",
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -33,7 +34,7 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipadnsconfig
|
||||
short description: Manage FreeIPA dnsconfig
|
||||
short_description: Manage FreeIPA dnsconfig
|
||||
description: Manage FreeIPA dnsconfig
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
@@ -41,20 +42,25 @@ options:
|
||||
forwarders:
|
||||
description: The list of global DNS forwarders.
|
||||
required: false
|
||||
options:
|
||||
type: list
|
||||
elements: dict
|
||||
suboptions:
|
||||
ip_address:
|
||||
description: The forwarder nameserver IP address list (IPv4 and IPv6).
|
||||
type: str
|
||||
required: true
|
||||
port:
|
||||
description: The port to forward requests to.
|
||||
type: int
|
||||
required: false
|
||||
forward_policy:
|
||||
description:
|
||||
Global forwarding policy. Set to "none" to disable any configured
|
||||
global forwarders.
|
||||
type: str
|
||||
required: false
|
||||
choices: ['only', 'first', 'none']
|
||||
alias: ["forwardpolicy"]
|
||||
aliases: ["forwardpolicy"]
|
||||
allow_sync_ptr:
|
||||
description:
|
||||
Allow synchronization of forward (A, AAAA) and reverse (PTR) records.
|
||||
@@ -64,14 +70,19 @@ options:
|
||||
description: |
|
||||
Work on dnsconfig or member level. It can be one of `member` or
|
||||
`dnsconfig`. Only `forwarders` can be managed with `action: member`.
|
||||
type: str
|
||||
default: "dnsconfig"
|
||||
choices: ["member", "dnsconfig"]
|
||||
state:
|
||||
description: |
|
||||
The state to ensure. It can be one of `present` or `absent`.
|
||||
`absent` can only be used with `action: member` and `forwarders`.
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Rafael Guterres Jeffman (@rjeffman)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -183,14 +194,15 @@ def gen_args(module, state, action, dnsconfig, forwarders, forward_policy,
|
||||
|
||||
def main():
|
||||
forwarder_spec = dict(
|
||||
ip_address=dict(type=str, required=True),
|
||||
port=dict(type=int, required=False, default=None)
|
||||
ip_address=dict(type="str", required=True),
|
||||
port=dict(type="int", required=False, default=None)
|
||||
)
|
||||
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# dnsconfig
|
||||
forwarders=dict(type='list', default=None, required=False,
|
||||
forwarders=dict(type='list', elements="dict", default=None,
|
||||
required=False,
|
||||
options=dict(**forwarder_spec)),
|
||||
forward_policy=dict(type='str', required=False, default=None,
|
||||
choices=['only', 'first', 'none'],
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Chris Procter <cprocter@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,53 +33,68 @@ ANSIBLE_METADATA = {
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipa_dnsforwardzone
|
||||
author: chris procter
|
||||
module: ipadnsforwardzone
|
||||
author:
|
||||
- Chris Procter (@chr15p)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
short_description: Manage FreeIPA DNS Forwarder Zones
|
||||
description:
|
||||
- Add and delete an IPA DNS Forwarder Zones using IPA API
|
||||
- Add and delete an IPA DNS Forwarder Zones using IPA API
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- The DNS zone name which needs to be managed.
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
action:
|
||||
description: |
|
||||
Work on dnsforwardzone or member level. It can be one of `member` or
|
||||
`dnsforwardzone`.
|
||||
type: str
|
||||
default: "dnsforwardzone"
|
||||
choices: ["member", "dnsforwardzone"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
required: false
|
||||
default: present
|
||||
choices: ["present", "absent", "enabled", "disabled"]
|
||||
forwarders:
|
||||
description:
|
||||
- List of the DNS servers to forward to
|
||||
type: list
|
||||
elements: dict
|
||||
aliases: ["idnsforwarders"]
|
||||
options:
|
||||
suboptions:
|
||||
ip_address:
|
||||
description: Forwarder IP address (either IPv4 or IPv6).
|
||||
required: false
|
||||
type: string
|
||||
required: true
|
||||
type: str
|
||||
port:
|
||||
description: Forwarder port.
|
||||
required: false
|
||||
type: int
|
||||
forwardpolicy:
|
||||
description: Per-zone conditional forwarding policy
|
||||
type: str
|
||||
required: false
|
||||
default: only
|
||||
choices: ["only", "first", "none"]
|
||||
aliases: ["idnsforwarders", "forward_policy"]
|
||||
aliases: ["idnsforwardpolicy", "forward_policy"]
|
||||
skip_overlap_check:
|
||||
description:
|
||||
- Force DNS zone creation even if it will overlap with an existing zone.
|
||||
type: bool
|
||||
required: false
|
||||
default: false
|
||||
permission:
|
||||
description:
|
||||
- Allow DNS Forward Zone to be managed.
|
||||
required: false
|
||||
type: bool
|
||||
aliases: ["managedby"]
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -180,7 +196,7 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
forwarders=dict(type="list", default=None, required=False,
|
||||
aliases=["idnsforwarders"], elements='dict',
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2020 Red Hat
|
||||
# Copyright (C) 2020-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,7 +35,7 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipadnsrecord
|
||||
short description: Manage FreeIPA DNS records
|
||||
short_description: Manage FreeIPA DNS records
|
||||
description: Manage FreeIPA DNS records
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
@@ -42,19 +43,24 @@ options:
|
||||
records:
|
||||
description: The list of user dns records dicts
|
||||
required: false
|
||||
options:
|
||||
type: list
|
||||
elements: dict
|
||||
suboptions:
|
||||
name:
|
||||
description: The DNS record name to manage.
|
||||
type: str
|
||||
aliases: ["record_name"]
|
||||
required: true
|
||||
zone_name:
|
||||
description: |
|
||||
The DNS zone name to which DNS record needs to be managed.
|
||||
Required if not provided globally.
|
||||
type: str
|
||||
aliases: ["dnszone"]
|
||||
required: false
|
||||
record_type:
|
||||
description: The type of DNS record.
|
||||
type: str
|
||||
choices: ["A", "AAAA", "A6", "AFSDB", "CERT", "CNAME", "DLV", "DNAME",
|
||||
"DS", "KX", "LOC", "MX", "NAPTR", "NS", "PTR", "SRV",
|
||||
"SSHFP", "TLSA", "TXT", "URI"]
|
||||
@@ -63,6 +69,7 @@ options:
|
||||
description: Manage DNS record name with these values.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
record_ttl:
|
||||
description: Set the TTL for the record.
|
||||
required: false
|
||||
@@ -73,92 +80,132 @@ options:
|
||||
type: bool
|
||||
a_rec:
|
||||
description: Raw A record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["a_record"]
|
||||
aaaa_rec:
|
||||
description: Raw AAAA record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["aaaa_record"]
|
||||
a6_rec:
|
||||
description: Raw A6 record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["a6_record"]
|
||||
afsdb_rec:
|
||||
description: Raw AFSDB record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["afsdb_record"]
|
||||
cert_rec:
|
||||
description: Raw CERT record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["cert_record"]
|
||||
cname_rec:
|
||||
description: Raw CNAME record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["cname_record"]
|
||||
dlv_rec:
|
||||
description: Raw DLV record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["dlv_record"]
|
||||
dname_rec:
|
||||
description: Raw DNAM record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["dname_record"]
|
||||
ds_rec:
|
||||
description: Raw DS record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["ds_record"]
|
||||
kx_rec:
|
||||
description: Raw KX record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["kx_record"]
|
||||
loc_rec:
|
||||
description: Raw LOC record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["loc_record"]
|
||||
mx_rec:
|
||||
description: Raw MX record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["mx_record"]
|
||||
naptr_rec:
|
||||
description: Raw NAPTR record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["naptr_record"]
|
||||
ns_rec:
|
||||
description: Raw NS record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["ns_record"]
|
||||
ptr_rec:
|
||||
description: Raw PTR record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["ptr_record"]
|
||||
srv_rec:
|
||||
description: Raw SRV record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["srv_record"]
|
||||
sshfp_rec:
|
||||
description: Raw SSHFP record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["sshfp_record"]
|
||||
tlsa_rec:
|
||||
description: Raw TLSA record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["tlsa_record"]
|
||||
txt_rec:
|
||||
description: Raw TXT record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["txt_record"]
|
||||
uri_rec:
|
||||
description: Raw URI record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["uri_record"]
|
||||
ip_address:
|
||||
description: IP adresses for A or AAAA records.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
a_ip_address:
|
||||
description: IP adresses for A records.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
a_create_reverse:
|
||||
description: |
|
||||
Create reverse record for A records.
|
||||
@@ -168,7 +215,7 @@ options:
|
||||
aaaa_ip_address:
|
||||
description: IP adresses for AAAA records.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
aaaa_create_reverse:
|
||||
description: |
|
||||
Create reverse record for AAAA records.
|
||||
@@ -185,6 +232,7 @@ options:
|
||||
a6_data:
|
||||
description: A6 record data.
|
||||
required: false
|
||||
type: str
|
||||
afsdb_subtype:
|
||||
description: AFSDB Subtype
|
||||
required: false
|
||||
@@ -192,7 +240,7 @@ options:
|
||||
afsdb_hostname:
|
||||
description: AFSDB Hostname
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
cert_type:
|
||||
description: CERT Certificate Type
|
||||
required: false
|
||||
@@ -208,13 +256,13 @@ options:
|
||||
cert_certificate_or_crl:
|
||||
description: CERT Certificate or Certificate Revocation List (CRL).
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
cname_hostname:
|
||||
description: A hostname which this alias hostname points to.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
dlv_key_tag:
|
||||
description: DS Key Tag
|
||||
description: DLV Key Tag
|
||||
required: false
|
||||
type: int
|
||||
dlv_algorithm:
|
||||
@@ -228,11 +276,11 @@ options:
|
||||
dlv_digest:
|
||||
description: DLV Digest
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
dname_target:
|
||||
description: DNAME Target
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
ds_key_tag:
|
||||
description: DS Key Tag
|
||||
required: false
|
||||
@@ -248,7 +296,7 @@ options:
|
||||
ds_digest:
|
||||
description: DS Digest
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
kx_preference:
|
||||
description: |
|
||||
Preference given to this exchanger. Lower values are more preferred.
|
||||
@@ -257,7 +305,7 @@ options:
|
||||
kx_exchanger:
|
||||
description: A host willing to act as a key exchanger.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
loc_lat_deg:
|
||||
description: LOC Degrees Latitude
|
||||
required: false
|
||||
@@ -274,6 +322,7 @@ options:
|
||||
description: LOC Direction Latitude
|
||||
required: false
|
||||
choices: ["N", "S"]
|
||||
type: str
|
||||
loc_lon_deg:
|
||||
description: LOC Degrees Longitude
|
||||
required: false
|
||||
@@ -290,6 +339,7 @@ options:
|
||||
description: LOC Direction Longitude
|
||||
required: false
|
||||
choices: ["E", "W"]
|
||||
type: str
|
||||
loc_altitude:
|
||||
description: LOC Altitude
|
||||
required: false
|
||||
@@ -314,7 +364,7 @@ options:
|
||||
mx_exchanger:
|
||||
description: A host willing to act as a mail exchanger.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
naptr_order:
|
||||
description: NAPTR Order
|
||||
required: false
|
||||
@@ -326,27 +376,27 @@ options:
|
||||
naptr_flags:
|
||||
description: NAPTR Flags
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
naptr_service:
|
||||
description: NAPTR Service
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
naptr_regexp:
|
||||
description: NAPTR Regular Expression
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
naptr_replacement:
|
||||
description: NAPTR Replacement
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
ns_hostname:
|
||||
description: NS Hostname
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
ptr_hostname:
|
||||
description: The hostname this reverse record points to.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
srv_priority:
|
||||
description: |
|
||||
Lower number means higher priority. Clients will attempt to contact
|
||||
@@ -366,7 +416,7 @@ options:
|
||||
The domain name of the target host or '.' if the service is decidedly
|
||||
not available at this domain.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
sshfp_algorithm:
|
||||
description: SSHFP Algorithm
|
||||
required: False
|
||||
@@ -378,11 +428,11 @@ options:
|
||||
sshfp_fingerprint:
|
||||
description: SSHFP Fingerprint
|
||||
required: False
|
||||
type: string
|
||||
type: str
|
||||
txt_data:
|
||||
description: TXT Text Data
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
tlsa_cert_usage:
|
||||
description: TLSA Certificate Usage
|
||||
required: false
|
||||
@@ -398,11 +448,11 @@ options:
|
||||
tlsa_cert_association_data:
|
||||
description: TLSA Certificate Association Data
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
uri_target:
|
||||
description: Target Uniform Resource Identifier according to RFC 3986.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
uri_priority:
|
||||
description: |
|
||||
Lower number means higher priority. Clients will attempt to contact
|
||||
@@ -413,27 +463,31 @@ options:
|
||||
description: Relative weight for entries with the same priority.
|
||||
required: false
|
||||
type: int
|
||||
name:
|
||||
description: The DNS record name to manage.
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["record_name"]
|
||||
required: false
|
||||
zone_name:
|
||||
description: |
|
||||
The DNS zone name to which DNS record needs to be managed.
|
||||
Required if not provided globally.
|
||||
type: str
|
||||
aliases: ["dnszone"]
|
||||
required: false
|
||||
name:
|
||||
description: The DNS record name to manage.
|
||||
aliases: ["record_name"]
|
||||
required: true
|
||||
record_type:
|
||||
description: The type of DNS record.
|
||||
required: false
|
||||
type: str
|
||||
choices: ["A", "AAAA", "A6", "AFSDB", "CERT", "CNAME", "DLV", "DNAME",
|
||||
"DS", "KX", "LOC", "MX", "NAPTR", "NS", "PTR", "SRV", "SSHFP",
|
||||
"TLSA", "TXT", "URI"]
|
||||
"DS", "KX", "LOC", "MX", "NAPTR", "NS", "PTR", "SRV",
|
||||
"SSHFP", "TLSA", "TXT", "URI"]
|
||||
default: "A"
|
||||
record_value:
|
||||
description: Manage DNS record name with this values.
|
||||
description: Manage DNS record name with these values.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
record_ttl:
|
||||
description: Set the TTL for the record.
|
||||
required: false
|
||||
@@ -444,99 +498,132 @@ options:
|
||||
type: bool
|
||||
a_rec:
|
||||
description: Raw A record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["a_record"]
|
||||
aaaa_rec:
|
||||
description: Raw AAAA record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["aaaa_record"]
|
||||
a6_rec:
|
||||
description: Raw A6 record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["a6_record"]
|
||||
afsdb_rec:
|
||||
description: Raw AFSDB record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["afsdb_record"]
|
||||
cert_rec:
|
||||
description: Raw CERT record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["cert_record"]
|
||||
cname_rec:
|
||||
description: Raw CNAME record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["cname_record"]
|
||||
dlv_rec:
|
||||
description: Raw DLV record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["dlv_record"]
|
||||
dname_rec:
|
||||
description: Raw DNAM record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["dname_record"]
|
||||
ds_rec:
|
||||
description: Raw DS record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["ds_record"]
|
||||
kx_rec:
|
||||
description: Raw KX record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["kx_record"]
|
||||
loc_rec:
|
||||
description: Raw LOC record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["loc_record"]
|
||||
mx_rec:
|
||||
description: Raw MX record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["mx_record"]
|
||||
naptr_rec:
|
||||
description: Raw NAPTR record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["naptr_record"]
|
||||
ns_rec:
|
||||
description: Raw NS record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["ns_record"]
|
||||
ptr_rec:
|
||||
description: Raw PTR record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["ptr_record"]
|
||||
srv_rec:
|
||||
description: Raw SRV record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["srv_record"]
|
||||
sshfp_rec:
|
||||
description: Raw SSHFP record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["sshfp_record"]
|
||||
tlsa_rec:
|
||||
description: Raw TLSA record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["tlsa_record"]
|
||||
txt_rec:
|
||||
description: Raw TXT record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["txt_record"]
|
||||
uri_rec:
|
||||
description: Raw URI record.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["uri_record"]
|
||||
ip_address:
|
||||
description: IP adresses for A ar AAAA.
|
||||
description: IP adresses for A or AAAA records.
|
||||
required: false
|
||||
type: string
|
||||
create_reverse:
|
||||
description: |
|
||||
Create reverse record for A or AAAA record types.
|
||||
There is no equivalent to remove reverse records.
|
||||
type: bool
|
||||
required: false
|
||||
aliases: ["reverse"]
|
||||
type: str
|
||||
a_ip_address:
|
||||
description: IP adresses for A records.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
a_create_reverse:
|
||||
description: |
|
||||
Create reverse record for A records.
|
||||
@@ -546,13 +633,24 @@ options:
|
||||
aaaa_ip_address:
|
||||
description: IP adresses for AAAA records.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
aaaa_create_reverse:
|
||||
description: |
|
||||
Create reverse record for AAAA records.
|
||||
There is no equivalent to remove reverse records.
|
||||
type: bool
|
||||
required: false
|
||||
create_reverse:
|
||||
description: |
|
||||
Create reverse record for A or AAAA record types.
|
||||
There is no equivalent to remove reverse records.
|
||||
type: bool
|
||||
required: false
|
||||
aliases: ["reverse"]
|
||||
a6_data:
|
||||
description: A6 record data.
|
||||
required: false
|
||||
type: str
|
||||
afsdb_subtype:
|
||||
description: AFSDB Subtype
|
||||
required: false
|
||||
@@ -560,7 +658,7 @@ options:
|
||||
afsdb_hostname:
|
||||
description: AFSDB Hostname
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
cert_type:
|
||||
description: CERT Certificate Type
|
||||
required: false
|
||||
@@ -574,13 +672,13 @@ options:
|
||||
required: false
|
||||
type: int
|
||||
cert_certificate_or_crl:
|
||||
description: CERT Certificate/CRL
|
||||
description: CERT Certificate or Certificate Revocation List (CRL).
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
cname_hostname:
|
||||
description: A hostname which this alias hostname points to.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
dlv_key_tag:
|
||||
description: DS Key Tag
|
||||
required: false
|
||||
@@ -596,11 +694,11 @@ options:
|
||||
dlv_digest:
|
||||
description: DLV Digest
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
dname_target:
|
||||
description: DNAME Target
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
ds_key_tag:
|
||||
description: DS Key Tag
|
||||
required: false
|
||||
@@ -616,7 +714,7 @@ options:
|
||||
ds_digest:
|
||||
description: DS Digest
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
kx_preference:
|
||||
description: |
|
||||
Preference given to this exchanger. Lower values are more preferred.
|
||||
@@ -625,7 +723,7 @@ options:
|
||||
kx_exchanger:
|
||||
description: A host willing to act as a key exchanger.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
loc_lat_deg:
|
||||
description: LOC Degrees Latitude
|
||||
required: false
|
||||
@@ -642,6 +740,7 @@ options:
|
||||
description: LOC Direction Latitude
|
||||
required: false
|
||||
choices: ["N", "S"]
|
||||
type: str
|
||||
loc_lon_deg:
|
||||
description: LOC Degrees Longitude
|
||||
required: false
|
||||
@@ -658,6 +757,7 @@ options:
|
||||
description: LOC Direction Longitude
|
||||
required: false
|
||||
choices: ["E", "W"]
|
||||
type: str
|
||||
loc_altitude:
|
||||
description: LOC Altitude
|
||||
required: false
|
||||
@@ -682,7 +782,7 @@ options:
|
||||
mx_exchanger:
|
||||
description: A host willing to act as a mail exchanger.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
naptr_order:
|
||||
description: NAPTR Order
|
||||
required: false
|
||||
@@ -694,31 +794,31 @@ options:
|
||||
naptr_flags:
|
||||
description: NAPTR Flags
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
naptr_service:
|
||||
description: NAPTR Service
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
naptr_regexp:
|
||||
description: NAPTR Regular Expression
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
naptr_replacement:
|
||||
description: NAPTR Replacement
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
ns_hostname:
|
||||
description: NS Hostname
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
ptr_hostname:
|
||||
description: The hostname this reverse record points to.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
srv_priority:
|
||||
description: |
|
||||
Lower number means higher priority. Clients will attempt to contact the
|
||||
server with the lowest-numbered priority they can reach.
|
||||
Lower number means higher priority. Clients will attempt to contact
|
||||
the server with the lowest-numbered priority they can reach.
|
||||
required: false
|
||||
type: int
|
||||
srv_weight:
|
||||
@@ -731,26 +831,26 @@ options:
|
||||
type: int
|
||||
srv_target:
|
||||
description: |
|
||||
The domain name of the target host or '.' if the service is decidedly not
|
||||
available at this domain.
|
||||
The domain name of the target host or '.' if the service is decidedly
|
||||
not available at this domain.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
sshfp_algorithm:
|
||||
description: SSHFP Algorithm
|
||||
required: false
|
||||
required: False
|
||||
type: int
|
||||
sshfp_fp_type:
|
||||
description: SSHFP Fingerprint Type
|
||||
required: false
|
||||
required: False
|
||||
type: int
|
||||
sshfp_fingerprint:
|
||||
description: SSHFP Fingerprint
|
||||
required: false
|
||||
type: string
|
||||
required: False
|
||||
type: str
|
||||
txt_data:
|
||||
description: TXT Text Data
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
tlsa_cert_usage:
|
||||
description: TLSA Certificate Usage
|
||||
required: false
|
||||
@@ -766,15 +866,15 @@ options:
|
||||
tlsa_cert_association_data:
|
||||
description: TLSA Certificate Association Data
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
uri_target:
|
||||
description: Target Uniform Resource Identifier according to RFC 3986.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
uri_priority:
|
||||
description: |
|
||||
Lower number means higher priority. Clients will attempt to contact the
|
||||
URI with the lowest-numbered priority they can reach.
|
||||
Lower number means higher priority. Clients will attempt to contact
|
||||
the URI with the lowest-numbered priority they can reach.
|
||||
required: false
|
||||
type: int
|
||||
uri_weight:
|
||||
@@ -783,11 +883,12 @@ options:
|
||||
type: int
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
|
||||
choices: ["present", "absent", "disabled"]
|
||||
author:
|
||||
- Rafael Guterres Jeffman
|
||||
- Rafael Guterres Jeffman (@rjeffman)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -866,8 +967,13 @@ RETURN = """
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, is_ipv4_addr, is_ipv6_addr, ipalib_errors
|
||||
import dns.reversename
|
||||
import dns.resolver
|
||||
try:
|
||||
import dns.reversename
|
||||
import dns.resolver
|
||||
except ImportError as _err:
|
||||
MODULE_IMPORT_ERROR = str(_err)
|
||||
else:
|
||||
MODULE_IMPORT_ERROR = None
|
||||
|
||||
from ansible.module_utils import six
|
||||
|
||||
@@ -1015,29 +1121,49 @@ def configure_module():
|
||||
"DLV", "DNAME", "DS", "KX", "LOC", "MX",
|
||||
"NAPTR", "NS", "PTR", "SRV", "SSHFP", "TLSA",
|
||||
"TXT", "URI"]),
|
||||
record_value=dict(type='list', required=False),
|
||||
record_value=dict(type='list', elements='str', required=False),
|
||||
record_ttl=dict(type='int', required=False),
|
||||
del_all=dict(type='bool', required=False),
|
||||
a_rec=dict(type='list', required=False, aliases=['a_record']),
|
||||
aaaa_rec=dict(type='list', required=False, aliases=['aaaa_record']),
|
||||
a6_rec=dict(type='list', required=False, aliases=['a6_record']),
|
||||
afsdb_rec=dict(type='list', required=False, aliases=['afsdb_record']),
|
||||
cert_rec=dict(type='list', required=False, aliases=['cert_record']),
|
||||
cname_rec=dict(type='list', required=False, aliases=['cname_record']),
|
||||
dlv_rec=dict(type='list', required=False, aliases=['dlv_record']),
|
||||
dname_rec=dict(type='list', required=False, aliases=['dname_record']),
|
||||
ds_rec=dict(type='list', required=False, aliases=['ds_record']),
|
||||
kx_rec=dict(type='list', required=False, aliases=['kx_record']),
|
||||
loc_rec=dict(type='list', required=False, aliases=['loc_record']),
|
||||
mx_rec=dict(type='list', required=False, aliases=['mx_record']),
|
||||
naptr_rec=dict(type='list', required=False, aliases=['naptr_record']),
|
||||
ns_rec=dict(type='list', required=False, aliases=['ns_record']),
|
||||
ptr_rec=dict(type='list', required=False, aliases=['ptr_record']),
|
||||
srv_rec=dict(type='list', required=False, aliases=['srv_record']),
|
||||
sshfp_rec=dict(type='list', required=False, aliases=['sshfp_record']),
|
||||
tlsa_rec=dict(type='list', required=False, aliases=['tlsa_record']),
|
||||
txt_rec=dict(type='list', required=False, aliases=['txt_record']),
|
||||
uri_rec=dict(type='list', required=False, aliases=['uri_record']),
|
||||
a_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['a_record']),
|
||||
aaaa_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['aaaa_record']),
|
||||
a6_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['a6_record']),
|
||||
afsdb_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['afsdb_record']),
|
||||
cert_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['cert_record']),
|
||||
cname_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['cname_record']),
|
||||
dlv_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['dlv_record']),
|
||||
dname_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['dname_record']),
|
||||
ds_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['ds_record']),
|
||||
kx_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['kx_record']),
|
||||
loc_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['loc_record']),
|
||||
mx_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['mx_record']),
|
||||
naptr_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['naptr_record']),
|
||||
ns_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['ns_record']),
|
||||
ptr_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['ptr_record']),
|
||||
srv_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['srv_record']),
|
||||
sshfp_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['sshfp_record']),
|
||||
tlsa_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['tlsa_record']),
|
||||
txt_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['txt_record']),
|
||||
uri_rec=dict(type='list', elements='str', required=False,
|
||||
aliases=['uri_record']),
|
||||
ip_address=dict(type='str', required=False),
|
||||
create_reverse=dict(type='bool', required=False, aliases=['reverse']),
|
||||
a_ip_address=dict(type='str', required=False),
|
||||
@@ -1048,16 +1174,16 @@ def configure_module():
|
||||
afsdb_subtype=dict(type='int', required=False),
|
||||
afsdb_hostname=dict(type='str', required=False),
|
||||
cert_type=dict(type='int', required=False),
|
||||
cert_key_tag=dict(type='int', required=False),
|
||||
cert_key_tag=dict(type='int', required=False, no_log=True),
|
||||
cert_algorithm=dict(type='int', required=False),
|
||||
cert_certificate_or_crl=dict(type='str', required=False),
|
||||
cname_hostname=dict(type='str', required=False),
|
||||
dlv_key_tag=dict(type='int', required=False),
|
||||
dlv_key_tag=dict(type='int', required=False, no_log=True),
|
||||
dlv_algorithm=dict(type='int', required=False),
|
||||
dlv_digest_type=dict(type='int', required=False),
|
||||
dlv_digest=dict(type='str', required=False),
|
||||
dname_target=dict(type='str', required=False),
|
||||
ds_key_tag=dict(type='int', required=False),
|
||||
ds_key_tag=dict(type='int', required=False, no_log=True),
|
||||
ds_algorithm=dict(type='int', required=False),
|
||||
ds_digest_type=dict(type='int', required=False),
|
||||
ds_digest=dict(type='str', required=False),
|
||||
@@ -1066,11 +1192,11 @@ def configure_module():
|
||||
loc_lat_deg=dict(type='int', required=False),
|
||||
loc_lat_min=dict(type='int', required=False),
|
||||
loc_lat_sec=dict(type='float', required=False),
|
||||
loc_lat_dir=dict(type='str', required=False),
|
||||
loc_lat_dir=dict(type='str', required=False, choices=["N", "S"]),
|
||||
loc_lon_deg=dict(type='int', required=False),
|
||||
loc_lon_min=dict(type='int', required=False),
|
||||
loc_lon_sec=dict(type='float', required=False),
|
||||
loc_lon_dir=dict(type='str', required=False),
|
||||
loc_lon_dir=dict(type='str', required=False, choices=["E", "W"]),
|
||||
loc_altitude=dict(type='float', required=False),
|
||||
loc_size=dict(type='float', required=False),
|
||||
loc_h_precision=dict(type='float', required=False),
|
||||
@@ -1105,10 +1231,14 @@ def configure_module():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["record_name"], default=None,
|
||||
required=False),
|
||||
name=dict(type="list", elements="str", aliases=["record_name"],
|
||||
default=None, required=False),
|
||||
|
||||
# Use elements="str" and not elements="dict" for records:
|
||||
# elements="dict" will create dicts with all unused parameters
|
||||
# set to None. This breaks the module logic.
|
||||
records=dict(type="list",
|
||||
elements="dict",
|
||||
default=None,
|
||||
options=dict(
|
||||
# Here name is a simple string
|
||||
@@ -1131,6 +1261,9 @@ def configure_module():
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
if MODULE_IMPORT_ERROR is not None:
|
||||
ansible_module.fail_json(msg=MODULE_IMPORT_ERROR)
|
||||
|
||||
return ansible_module
|
||||
|
||||
|
||||
@@ -1436,6 +1569,14 @@ def main():
|
||||
msg="Only one record can be added at a time.")
|
||||
|
||||
if records is not None:
|
||||
# Remove all keys that have a None value from the dicts in records
|
||||
# list.
|
||||
# This is needed after setting elements="dict" for records and makes
|
||||
# it behave like before with elements=None.
|
||||
for record in records:
|
||||
for key in list(record):
|
||||
if record[key] is None:
|
||||
del record[key]
|
||||
names = records
|
||||
|
||||
# Init
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Sergio Oliveira Campos <seocam@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2020 Red Hat
|
||||
# Copyright (C) 2020-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,16 +33,17 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipadnszone
|
||||
short description: Manage FreeIPA dnszone
|
||||
short_description: Manage FreeIPA dnszone
|
||||
description: Manage FreeIPA dnszone
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The zone name string.
|
||||
required: true
|
||||
required: false
|
||||
type: list
|
||||
alises: ["zone_name"]
|
||||
elements: str
|
||||
aliases: ["zone_name"]
|
||||
name_from_ip:
|
||||
description: |
|
||||
Derive zone name from reverse of IP (PTR).
|
||||
@@ -51,17 +53,22 @@ options:
|
||||
forwarders:
|
||||
description: The list of global DNS forwarders.
|
||||
required: false
|
||||
options:
|
||||
type: list
|
||||
elements: dict
|
||||
suboptions:
|
||||
ip_address:
|
||||
description: The forwarder nameserver IP address list (IPv4 and IPv6).
|
||||
type: str
|
||||
required: true
|
||||
port:
|
||||
description: The port to forward requests to.
|
||||
type: int
|
||||
required: false
|
||||
forward_policy:
|
||||
description:
|
||||
Global forwarding policy. Set to "none" to disable any configured
|
||||
global forwarders.
|
||||
type: str
|
||||
required: false
|
||||
choices: ['only', 'first', 'none']
|
||||
allow_sync_ptr:
|
||||
@@ -71,6 +78,7 @@ options:
|
||||
type: bool
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent", "enabled", "disabled"]
|
||||
name_server:
|
||||
@@ -89,7 +97,7 @@ options:
|
||||
description: Allow dynamic updates
|
||||
required: false
|
||||
type: bool
|
||||
alises: ["dynamicupdate"]
|
||||
aliases: ["dynamicupdate"]
|
||||
dnssec:
|
||||
description: Allow inline DNSSEC signing of records in the zone
|
||||
required: false
|
||||
@@ -97,11 +105,13 @@ options:
|
||||
allow_transfer:
|
||||
description: List of IP addresses or networks which are allowed to transfer the zone
|
||||
required: false
|
||||
type: bool
|
||||
type: list
|
||||
elements: str
|
||||
allow_query:
|
||||
description: List of IP addresses or networks which are allowed to issue queries
|
||||
required: false
|
||||
type: bool
|
||||
type: list
|
||||
elements: str
|
||||
refresh:
|
||||
description: SOA record refresh time
|
||||
required: false
|
||||
@@ -141,6 +151,9 @@ options:
|
||||
description: Force DNS zone creation even if nameserver is not resolvable
|
||||
required: false
|
||||
type: bool
|
||||
author:
|
||||
- Sergio Oliveira Campos (@seocam)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
""" # noqa: E501
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -195,13 +208,14 @@ dnszone:
|
||||
description: DNS Zone dict with zone name infered from `name_from_ip`.
|
||||
returned:
|
||||
If `state` is `present`, `name_from_ip` is used, and a zone was created.
|
||||
options:
|
||||
type: dict
|
||||
contains:
|
||||
name:
|
||||
description: The name of the zone created, inferred from `name_from_ip`.
|
||||
type: str
|
||||
returned: always
|
||||
"""
|
||||
|
||||
from ipapython.dnsutil import DNSName # noqa: E402
|
||||
from ansible.module_utils.ansible_freeipa_module import (
|
||||
IPAAnsibleModule,
|
||||
is_ip_address,
|
||||
@@ -210,8 +224,9 @@ from ansible.module_utils.ansible_freeipa_module import (
|
||||
ipalib_errors,
|
||||
compare_args_ipa,
|
||||
IPAParamMapping,
|
||||
DNSName,
|
||||
netaddr
|
||||
) # noqa: E402
|
||||
import netaddr
|
||||
from ansible.module_utils import six
|
||||
|
||||
|
||||
@@ -487,8 +502,8 @@ class DNSZoneModule(IPAAnsibleModule):
|
||||
|
||||
def get_argument_spec():
|
||||
forwarder_spec = dict(
|
||||
ip_address=dict(type=str, required=True),
|
||||
port=dict(type=int, required=False, default=None),
|
||||
ip_address=dict(type="str", required=True),
|
||||
port=dict(type="int", required=False, default=None),
|
||||
)
|
||||
|
||||
return dict(
|
||||
@@ -500,11 +515,13 @@ def get_argument_spec():
|
||||
ipaadmin_principal=dict(type="str", default="admin"),
|
||||
ipaadmin_password=dict(type="str", required=False, no_log=True),
|
||||
name=dict(
|
||||
type="list", default=None, required=False, aliases=["zone_name"]
|
||||
type="list", elements="str", default=None, required=False,
|
||||
aliases=["zone_name"]
|
||||
),
|
||||
name_from_ip=dict(type="str", default=None, required=False),
|
||||
forwarders=dict(
|
||||
type="list",
|
||||
elements="dict",
|
||||
default=None,
|
||||
required=False,
|
||||
options=dict(**forwarder_spec),
|
||||
@@ -526,8 +543,10 @@ def get_argument_spec():
|
||||
aliases=["dynamicupdate"],
|
||||
),
|
||||
dnssec=dict(type="bool", required=False, default=None),
|
||||
allow_transfer=dict(type="list", required=False, default=None),
|
||||
allow_query=dict(type="list", required=False, default=None),
|
||||
allow_transfer=dict(type="list", elements="str", required=False,
|
||||
default=None),
|
||||
allow_query=dict(type="list", elements="str", required=False,
|
||||
default=None),
|
||||
refresh=dict(type="int", required=False, default=None),
|
||||
retry=dict(type="int", required=False, default=None),
|
||||
expire=dict(type="int", required=False, default=None),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,20 +32,24 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipagroup
|
||||
short description: Manage FreeIPA groups
|
||||
short_description: Manage FreeIPA groups
|
||||
description: Manage FreeIPA groups
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The group name
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: The group description
|
||||
type: str
|
||||
required: false
|
||||
gid:
|
||||
description: The GID
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["gidnumber"]
|
||||
nonposix:
|
||||
@@ -69,49 +73,58 @@ options:
|
||||
description: List of user names assigned to this group.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
group:
|
||||
description: List of group names assigned to this group.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
service:
|
||||
description:
|
||||
- List of service names assigned to this group.
|
||||
- Only usable with IPA versions 4.7 and up.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
membermanager_user:
|
||||
description:
|
||||
- List of member manager users assigned to this group.
|
||||
- Only usable with IPA versions 4.8.4 and up.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
membermanager_group:
|
||||
description:
|
||||
- List of member manager groups assigned to this group.
|
||||
- Only usable with IPA versions 4.8.4 and up.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
externalmember:
|
||||
description:
|
||||
- List of members of a trusted domain in DOM\\name or name@domain form.
|
||||
required: false
|
||||
type: list
|
||||
ailases: ["ipaexternalmember", "external_member"]
|
||||
elements: str
|
||||
aliases: ["ipaexternalmember", "external_member"]
|
||||
idoverrideuser:
|
||||
description:
|
||||
- User ID overrides to add
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
action:
|
||||
description: Work on group or member level
|
||||
type: str
|
||||
default: group
|
||||
choices: ["member", "group"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -275,7 +288,7 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
# present
|
||||
description=dict(type="str", default=None),
|
||||
@@ -284,14 +297,20 @@ def main():
|
||||
external=dict(required=False, type='bool', default=None),
|
||||
posix=dict(required=False, type='bool', default=None),
|
||||
nomembers=dict(required=False, type='bool', default=None),
|
||||
user=dict(required=False, type='list', default=None),
|
||||
group=dict(required=False, type='list', default=None),
|
||||
service=dict(required=False, type='list', default=None),
|
||||
idoverrideuser=dict(required=False, type='list', default=None),
|
||||
membermanager_user=dict(required=False, type='list', default=None),
|
||||
user=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
group=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
service=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
idoverrideuser=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
membermanager_user=dict(required=False, type='list',
|
||||
elements="str", default=None),
|
||||
membermanager_group=dict(required=False, type='list',
|
||||
default=None),
|
||||
externalmember=dict(required=False, type='list', default=None,
|
||||
elements="str", default=None),
|
||||
externalmember=dict(required=False, type='list', elements="str",
|
||||
default=None,
|
||||
aliases=[
|
||||
"ipaexternalmember",
|
||||
"external_member"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,30 +32,36 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipahbacrule
|
||||
short description: Manage FreeIPA HBAC rules
|
||||
short_description: Manage FreeIPA HBAC rules
|
||||
description: Manage FreeIPA HBAC rules
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The hbacrule name
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: The hbacrule description
|
||||
type: str
|
||||
required: false
|
||||
usercategory:
|
||||
description: User category the rule applies to
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["usercat"]
|
||||
choices: ["all", ""]
|
||||
hostcategory:
|
||||
description: Host category the rule applies to
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["hostcat"]
|
||||
choices: ["all", ""]
|
||||
servicecategory:
|
||||
description: Service category the rule applies to
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["servicecat"]
|
||||
choices: ["all", ""]
|
||||
@@ -67,36 +73,44 @@ options:
|
||||
description: List of host names assigned to this hbacrule.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
hostgroup:
|
||||
description: List of host groups assigned to this hbacrule.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
hbacsvc:
|
||||
description: List of HBAC service names assigned to this hbacrule.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
hbacsvcgroup:
|
||||
description: List of HBAC service names assigned to this hbacrule.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
user:
|
||||
description: List of user names assigned to this hbacrule.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
group:
|
||||
description: List of user groups assigned to this hbacrule.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
action:
|
||||
description: Work on hbacrule or member level
|
||||
type: str
|
||||
default: hbacrule
|
||||
choices: ["member", "hbacrule"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent", "enabled", "disabled"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -198,7 +212,7 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
# present
|
||||
description=dict(type="str", default=None),
|
||||
@@ -209,12 +223,18 @@ def main():
|
||||
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),
|
||||
host=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
hostgroup=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
hbacsvc=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
hbacsvcgroup=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
user=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
group=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
action=dict(type="str", default="hbacrule",
|
||||
choices=["member", "hbacrule"]),
|
||||
# state
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,24 +32,28 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipahbacsvc
|
||||
short description: Manage FreeIPA HBAC Services
|
||||
short_description: Manage FreeIPA HBAC Services
|
||||
description: Manage FreeIPA HBAC Services
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The group name
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn", "service"]
|
||||
description:
|
||||
description: The HBAC Service description
|
||||
type: str
|
||||
required: false
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -102,7 +106,7 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn", "service"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["cn", "service"],
|
||||
required=True),
|
||||
# present
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -33,36 +33,42 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipahbacsvcgroup
|
||||
short description: Manage FreeIPA hbacsvcgroups
|
||||
short_description: Manage FreeIPA hbacsvcgroups
|
||||
description: Manage FreeIPA hbacsvcgroups
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The hbacsvcgroup name
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: The hbacsvcgroup description
|
||||
type: str
|
||||
required: false
|
||||
hbacsvc:
|
||||
description: List of hbacsvc names assigned to this hbacsvcgroup.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
nomembers:
|
||||
description: Suppress processing of membership attributes
|
||||
required: false
|
||||
type: bool
|
||||
action:
|
||||
description: Work on hbacsvcgroup or member level
|
||||
type: str
|
||||
default: hbacsvcgroup
|
||||
choices: ["member", "hbacsvcgroup"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -159,12 +165,13 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
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),
|
||||
hbacsvc=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
action=dict(type="str", default="hbacsvcgroup",
|
||||
choices=["member", "hbacsvcgroup"]),
|
||||
# state
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,122 +32,157 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipahost
|
||||
short description: Manage FreeIPA hosts
|
||||
short_description: Manage FreeIPA hosts
|
||||
description: Manage FreeIPA hosts
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The full qualified domain name.
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["fqdn"]
|
||||
required: true
|
||||
|
||||
required: false
|
||||
hosts:
|
||||
description: The list of user host dicts
|
||||
required: false
|
||||
options:
|
||||
type: list
|
||||
elements: dict
|
||||
suboptions:
|
||||
name:
|
||||
description: The host (internally uid).
|
||||
type: str
|
||||
aliases: ["fqdn"]
|
||||
required: true
|
||||
description:
|
||||
description: The host description
|
||||
type: str
|
||||
required: false
|
||||
locality:
|
||||
description: Host locality (e.g. "Baltimore, MD")
|
||||
type: str
|
||||
required: false
|
||||
location:
|
||||
description: Host location (e.g. "Lab 2")
|
||||
type: str
|
||||
aliases: ["ns_host_location"]
|
||||
required: false
|
||||
platform:
|
||||
description: Host hardware platform (e.g. "Lenovo T61")
|
||||
type: str
|
||||
aliases: ["ns_hardware_platform"]
|
||||
required: false
|
||||
os:
|
||||
description: Host operating system and version (e.g. "Fedora 9")
|
||||
type: str
|
||||
aliases: ["ns_os_version"]
|
||||
required: false
|
||||
password:
|
||||
description: Password used in bulk enrollment
|
||||
type: str
|
||||
aliases: ["user_password", "userpassword"]
|
||||
required: false
|
||||
random:
|
||||
description:
|
||||
Initiate the generation of a random password to be used in bulk
|
||||
enrollment
|
||||
type: bool
|
||||
aliases: ["random_password"]
|
||||
required: false
|
||||
certificate:
|
||||
description: List of base-64 encoded host certificates
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["usercertificate"]
|
||||
required: false
|
||||
managedby_host:
|
||||
description: List of hosts that can manage this host
|
||||
type: list
|
||||
aliases: ["principalname", "krbprincipalname"]
|
||||
elements: str
|
||||
required: false
|
||||
principal:
|
||||
description: List of principal aliases for this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["principalname", "krbprincipalname"]
|
||||
required: false
|
||||
allow_create_keytab_user:
|
||||
description: Users allowed to create a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_write_keys_user"]
|
||||
required: false
|
||||
allow_create_keytab_group:
|
||||
description: Groups allowed to create a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_write_keys_group"]
|
||||
required: false
|
||||
allow_create_keytab_host:
|
||||
description: Hosts allowed to create a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_write_keys_host"]
|
||||
required: false
|
||||
allow_create_keytab_hostgroup:
|
||||
description: Hostgroups allowed to create a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_write_keys_hostgroup"]
|
||||
required: false
|
||||
allow_retrieve_keytab_user:
|
||||
description: Users allowed to retrieve a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_read_keys_user"]
|
||||
required: false
|
||||
allow_retrieve_keytab_group:
|
||||
description: Groups allowed to retrieve a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_read_keys_group"]
|
||||
required: false
|
||||
allow_retrieve_keytab_host:
|
||||
description: Hosts allowed to retrieve a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_read_keys_host"]
|
||||
required: false
|
||||
allow_retrieve_keytab_hostgroup:
|
||||
description: Hostgroups allowed to retrieve a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_read_keys_hostgroup"]
|
||||
required: false
|
||||
mac_address:
|
||||
description: List of hardware MAC addresses.
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["macaddress"]
|
||||
required: false
|
||||
sshpubkey:
|
||||
description: List of SSH public keys
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipasshpubkey"]
|
||||
required: false
|
||||
userclass:
|
||||
description:
|
||||
Host category (semantics placed on this attribute are for local
|
||||
interpretation)
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["class"]
|
||||
required: false
|
||||
auth_ind:
|
||||
description:
|
||||
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.
|
||||
Use empty string to reset auth_ind to the initial value.
|
||||
Defines an allow list 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. Use empty string to reset auth_ind
|
||||
to the initial value.
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["krbprincipalauthind"]
|
||||
choices: ["radius", "otp", "pkinit", "hardened", ""]
|
||||
required: false
|
||||
@@ -169,15 +204,18 @@ options:
|
||||
required: false
|
||||
force:
|
||||
description: Force host name even if not in DNS
|
||||
type: bool
|
||||
required: false
|
||||
reverse:
|
||||
description: Reverse DNS detection
|
||||
default: true
|
||||
type: bool
|
||||
required: false
|
||||
ip_address:
|
||||
description:
|
||||
The host IP address list (IPv4 and IPv6). No IP address conflict
|
||||
check will be done.
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaddress"]
|
||||
required: false
|
||||
update_dns:
|
||||
@@ -185,105 +223,138 @@ options:
|
||||
Controls the update of the DNS SSHFP records for existing hosts and
|
||||
the removal of all DNS entries if a host gets removed with state
|
||||
absent.
|
||||
type: bool
|
||||
aliases: ["updatedns"]
|
||||
required: false
|
||||
description:
|
||||
description: The host description
|
||||
type: str
|
||||
required: false
|
||||
locality:
|
||||
description: Host locality (e.g. "Baltimore, MD")
|
||||
type: str
|
||||
required: false
|
||||
location:
|
||||
description: Host location (e.g. "Lab 2")
|
||||
type: str
|
||||
aliases: ["ns_host_location"]
|
||||
required: false
|
||||
platform:
|
||||
description: Host hardware platform (e.g. "Lenovo T61")
|
||||
type: str
|
||||
aliases: ["ns_hardware_platform"]
|
||||
required: false
|
||||
os:
|
||||
description: Host operating system and version (e.g. "Fedora 9")
|
||||
type: str
|
||||
aliases: ["ns_os_version"]
|
||||
required: false
|
||||
password:
|
||||
description: Password used in bulk enrollment
|
||||
type: str
|
||||
aliases: ["user_password", "userpassword"]
|
||||
required: false
|
||||
random:
|
||||
description:
|
||||
Initiate the generation of a random password to be used in bulk
|
||||
enrollment
|
||||
type: bool
|
||||
aliases: ["random_password"]
|
||||
required: false
|
||||
certificate:
|
||||
description: List of base-64 encoded host certificates
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["usercertificate"]
|
||||
required: false
|
||||
managedby_host:
|
||||
description: List of hosts that can manage this host
|
||||
type: list
|
||||
aliases: ["principalname", "krbprincipalname"]
|
||||
elements: str
|
||||
required: false
|
||||
principal:
|
||||
description: List of principal aliases for this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["principalname", "krbprincipalname"]
|
||||
required: false
|
||||
allow_create_keytab_user:
|
||||
description: Users allowed to create a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_write_keys_user"]
|
||||
required: false
|
||||
allow_create_keytab_group:
|
||||
description: Groups allowed to create a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_write_keys_group"]
|
||||
required: false
|
||||
allow_create_keytab_host:
|
||||
description: Hosts allowed to create a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_write_keys_host"]
|
||||
required: false
|
||||
allow_create_keytab_hostgroup:
|
||||
description: Hostgroups allowed to create a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_write_keys_hostgroup"]
|
||||
required: false
|
||||
allow_retrieve_keytab_user:
|
||||
description: Users allowed to retrieve a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_read_keys_user"]
|
||||
required: false
|
||||
allow_retrieve_keytab_group:
|
||||
description: Groups allowed to retrieve a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_read_keys_group"]
|
||||
required: false
|
||||
allow_retrieve_keytab_host:
|
||||
description: Hosts allowed to retrieve a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_read_keys_host"]
|
||||
required: false
|
||||
allow_retrieve_keytab_hostgroup:
|
||||
description: Hostgroups allowed to retrieve a keytab of this host
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_read_keys_hostgroup"]
|
||||
required: false
|
||||
mac_address:
|
||||
description: List of hardware MAC addresses.
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["macaddress"]
|
||||
required: false
|
||||
sshpubkey:
|
||||
description: List of SSH public keys
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipasshpubkey"]
|
||||
required: false
|
||||
userclass:
|
||||
description:
|
||||
Host category (semantics placed on this attribute are for local
|
||||
interpretation)
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["class"]
|
||||
required: false
|
||||
auth_ind:
|
||||
description:
|
||||
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.
|
||||
Use empty string to reset auth_ind to the initial value.
|
||||
Defines an allow list 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. Use empty string to reset auth_ind
|
||||
to the initial value.
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["krbprincipalauthind"]
|
||||
choices: ["radius", "otp", "pkinit", "hardened", ""]
|
||||
required: false
|
||||
@@ -298,21 +369,25 @@ options:
|
||||
aliases: ["ipakrbokasdelegate"]
|
||||
required: false
|
||||
ok_to_auth_as_delegate:
|
||||
description: The service is allowed to authenticate on behalf of a client
|
||||
description:
|
||||
The service is allowed to authenticate on behalf of a client
|
||||
type: bool
|
||||
aliases: ["ipakrboktoauthasdelegate"]
|
||||
required: false
|
||||
force:
|
||||
description: Force host name even if not in DNS
|
||||
type: bool
|
||||
required: false
|
||||
reverse:
|
||||
description: Reverse DNS detection
|
||||
default: true
|
||||
type: bool
|
||||
required: false
|
||||
ip_address:
|
||||
description:
|
||||
The host IP address list (IPv4 and IPv6). No IP address conflict
|
||||
check will be done.
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaddress"]
|
||||
required: false
|
||||
update_dns:
|
||||
@@ -320,23 +395,27 @@ options:
|
||||
Controls the update of the DNS SSHFP records for existing hosts and
|
||||
the removal of all DNS entries if a host gets removed with state
|
||||
absent.
|
||||
type: bool
|
||||
aliases: ["updatedns"]
|
||||
required: false
|
||||
update_password:
|
||||
description:
|
||||
Set password for a host in present state only on creation or always
|
||||
default: 'always'
|
||||
type: str
|
||||
choices: ["always", "on_create"]
|
||||
action:
|
||||
description: Work on host or member level
|
||||
type: str
|
||||
default: "host"
|
||||
choices: ["member", "host"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent",
|
||||
"disabled"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -389,17 +468,19 @@ host:
|
||||
description: Host dict with random password
|
||||
returned: If random is yes and user did not exist or update_password is yes
|
||||
type: dict
|
||||
options:
|
||||
contains:
|
||||
randompassword:
|
||||
description: The generated random password
|
||||
type: str
|
||||
returned: If only one user is handled by the module
|
||||
name:
|
||||
description: The user name of the user that got a new random password
|
||||
returned: If several users are handled by the module
|
||||
type: dict
|
||||
options:
|
||||
contains:
|
||||
randompassword:
|
||||
description: The generated random password
|
||||
type: str
|
||||
returned: always
|
||||
"""
|
||||
|
||||
@@ -626,52 +707,52 @@ def main():
|
||||
default=None, no_log=True),
|
||||
random=dict(type="bool", aliases=["random_password"],
|
||||
default=None),
|
||||
certificate=dict(type="list", aliases=["usercertificate"],
|
||||
default=None),
|
||||
managedby_host=dict(type="list",
|
||||
default=None),
|
||||
principal=dict(type="list", aliases=["krbprincipalname"],
|
||||
certificate=dict(type="list", elements="str",
|
||||
aliases=["usercertificate"], default=None),
|
||||
managedby_host=dict(type="list", elements="str", default=None),
|
||||
principal=dict(type="list", elements="str",
|
||||
aliases=["principalname", "krbprincipalname"],
|
||||
default=None),
|
||||
allow_create_keytab_user=dict(
|
||||
type="list",
|
||||
type="list", elements="str",
|
||||
aliases=["ipaallowedtoperform_write_keys_user"],
|
||||
default=None),
|
||||
default=None, no_log=False),
|
||||
allow_create_keytab_group=dict(
|
||||
type="list",
|
||||
type="list", elements="str",
|
||||
aliases=["ipaallowedtoperform_write_keys_group"],
|
||||
default=None),
|
||||
default=None, no_log=False),
|
||||
allow_create_keytab_host=dict(
|
||||
type="list",
|
||||
type="list", elements="str",
|
||||
aliases=["ipaallowedtoperform_write_keys_host"],
|
||||
default=None),
|
||||
default=None, no_log=False),
|
||||
allow_create_keytab_hostgroup=dict(
|
||||
type="list",
|
||||
type="list", elements="str",
|
||||
aliases=["ipaallowedtoperform_write_keys_hostgroup"],
|
||||
default=None),
|
||||
default=None, no_log=False),
|
||||
allow_retrieve_keytab_user=dict(
|
||||
type="list",
|
||||
aliases=["ipaallowedtoperform_write_keys_user"],
|
||||
default=None),
|
||||
type="list", elements="str",
|
||||
aliases=["ipaallowedtoperform_read_keys_user"],
|
||||
default=None, no_log=False),
|
||||
allow_retrieve_keytab_group=dict(
|
||||
type="list",
|
||||
aliases=["ipaallowedtoperform_write_keys_group"],
|
||||
default=None),
|
||||
type="list", elements="str",
|
||||
aliases=["ipaallowedtoperform_read_keys_group"],
|
||||
default=None, no_log=False),
|
||||
allow_retrieve_keytab_host=dict(
|
||||
type="list",
|
||||
aliases=["ipaallowedtoperform_write_keys_host"],
|
||||
default=None),
|
||||
type="list", elements="str",
|
||||
aliases=["ipaallowedtoperform_read_keys_host"],
|
||||
default=None, no_log=False),
|
||||
allow_retrieve_keytab_hostgroup=dict(
|
||||
type="list",
|
||||
aliases=["ipaallowedtoperform_write_keys_hostgroup"],
|
||||
default=None),
|
||||
mac_address=dict(type="list", aliases=["macaddress"],
|
||||
type="list", elements="str",
|
||||
aliases=["ipaallowedtoperform_read_keys_hostgroup"],
|
||||
default=None, no_log=False),
|
||||
mac_address=dict(type="list", elements="str", aliases=["macaddress"],
|
||||
default=None),
|
||||
sshpubkey=dict(type="str", aliases=["ipasshpubkey"],
|
||||
sshpubkey=dict(type="list", elements="str", aliases=["ipasshpubkey"],
|
||||
default=None),
|
||||
userclass=dict(type="list", aliases=["class"],
|
||||
userclass=dict(type="list", elements="str", aliases=["class"],
|
||||
default=None),
|
||||
auth_ind=dict(type='list', aliases=["krbprincipalauthind"],
|
||||
default=None,
|
||||
auth_ind=dict(type='list', elements="str",
|
||||
aliases=["krbprincipalauthind"], default=None,
|
||||
choices=['radius', 'otp', 'pkinit', 'hardened', '']),
|
||||
requires_pre_auth=dict(type="bool", aliases=["ipakrbrequirespreauth"],
|
||||
default=None),
|
||||
@@ -682,7 +763,7 @@ def main():
|
||||
default=None),
|
||||
force=dict(type='bool', default=None),
|
||||
reverse=dict(type='bool', default=None),
|
||||
ip_address=dict(type="list", aliases=["ipaddress"],
|
||||
ip_address=dict(type="list", elements="str", aliases=["ipaddress"],
|
||||
default=None),
|
||||
update_dns=dict(type="bool", aliases=["updatedns"],
|
||||
default=None),
|
||||
@@ -695,8 +776,8 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["fqdn"], default=None,
|
||||
required=False),
|
||||
name=dict(type="list", elements="str", aliases=["fqdn"],
|
||||
default=None, required=False),
|
||||
|
||||
hosts=dict(type="list", default=None,
|
||||
options=dict(
|
||||
@@ -762,7 +843,8 @@ def main():
|
||||
allow_retrieve_keytab_hostgroup = ansible_module.params_get(
|
||||
"allow_retrieve_keytab_hostgroup")
|
||||
mac_address = ansible_module.params_get("mac_address")
|
||||
sshpubkey = ansible_module.params_get("sshpubkey")
|
||||
sshpubkey = ansible_module.params_get("sshpubkey",
|
||||
allow_empty_string=True)
|
||||
userclass = ansible_module.params_get("userclass")
|
||||
auth_ind = ansible_module.params_get("auth_ind", allow_empty_string=True)
|
||||
requires_pre_auth = ansible_module.params_get("requires_pre_auth")
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -33,17 +33,20 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipahostgroup
|
||||
short description: Manage FreeIPA hostgroups
|
||||
short_description: Manage FreeIPA hostgroups
|
||||
description: Manage FreeIPA hostgroups
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The hostgroup name
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: The hostgroup description
|
||||
type: str
|
||||
required: false
|
||||
nomembers:
|
||||
description: Suppress processing of membership attributes
|
||||
@@ -53,38 +56,45 @@ options:
|
||||
description: List of host names assigned to this hostgroup.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
hostgroup:
|
||||
description: List of hostgroup names assigned to this hostgroup.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
membermanager_user:
|
||||
description:
|
||||
- List of member manager users assigned to this hostgroup.
|
||||
- Only usable with IPA versions 4.8.4 and up.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
membermanager_group:
|
||||
description:
|
||||
- List of member manager groups assigned to this hostgroup.
|
||||
- Only usable with IPA versions 4.8.4 and up.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
rename:
|
||||
description:
|
||||
- Rename hostgroup to the given name.
|
||||
- Only usable with IPA versions 4.8.7 and up.
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["new_name"]
|
||||
action:
|
||||
description: Work on hostgroup or member level
|
||||
type: str
|
||||
default: hostgroup
|
||||
choices: ["member", "hostgroup"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent", "renamed"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -185,16 +195,19 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
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),
|
||||
membermanager_user=dict(required=False, type='list', default=None),
|
||||
host=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
hostgroup=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
membermanager_user=dict(required=False, type='list',
|
||||
elements="str", default=None),
|
||||
membermanager_group=dict(required=False, type='list',
|
||||
default=None),
|
||||
elements="str", default=None),
|
||||
rename=dict(required=False, type='str', default=None,
|
||||
aliases=["new_name"]),
|
||||
action=dict(type="str", default="hostgroup",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
@@ -32,7 +33,7 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaidrange
|
||||
short description: Manage FreeIPA idrange
|
||||
short_description: Manage FreeIPA idrange
|
||||
description: Manage FreeIPA idrange
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
@@ -40,6 +41,8 @@ extends_documentation_fragment:
|
||||
options:
|
||||
name:
|
||||
description: The list of idrange name strings.
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
base_id:
|
||||
@@ -64,33 +67,37 @@ options:
|
||||
aliases: ["ipasecondarybaserid"]
|
||||
idrange_type:
|
||||
description: ID range type.
|
||||
type: string
|
||||
type: str
|
||||
required: false
|
||||
choices: ["ipa-ad-trust", "ipa-ad-trust-posix", "ipa-local"]
|
||||
aliases: ["iparangetype"]
|
||||
dom_sid:
|
||||
description: Domain SID of the trusted domain.
|
||||
type: string
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ipanttrusteddomainsid"]
|
||||
dom_name:
|
||||
description: |
|
||||
Domain name of the trusted domain. Can only be used when
|
||||
`ipaapi_context: server`.
|
||||
type: string
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ipanttrusteddomainname"]
|
||||
auto_private_groups:
|
||||
description: Auto creation of private groups.
|
||||
type: string
|
||||
type: str
|
||||
required: false
|
||||
choices: ["true", "false", "hybrid"]
|
||||
aliases: ["ipaautoprivategroups"]
|
||||
state:
|
||||
description: The state to ensure.
|
||||
type: str
|
||||
choices: ["present", "absent"]
|
||||
default: present
|
||||
required: true
|
||||
required: false
|
||||
author:
|
||||
- Rafael Guterres Jeffman (@rjeffman)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -184,8 +191,8 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"],
|
||||
default=None, required=True),
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
# present
|
||||
base_id=dict(required=False, type='int',
|
||||
aliases=["ipabaseid"], default=None),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2020 Red Hat
|
||||
# Copyright (C) 2020-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,23 +32,29 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipalocation
|
||||
short description: Manage FreeIPA location
|
||||
short_description: Manage FreeIPA location
|
||||
description: Manage FreeIPA location
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The list of location name strings.
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["idnsname"]
|
||||
description:
|
||||
description: The IPA location string
|
||||
type: str
|
||||
required: false
|
||||
state:
|
||||
description: The state to ensure.
|
||||
type: str
|
||||
choices: ["present", "absent"]
|
||||
default: present
|
||||
required: true
|
||||
required: false
|
||||
author:
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -94,8 +100,8 @@ def gen_args(description):
|
||||
def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
name=dict(type="list", aliases=["idnsname"],
|
||||
default=None, required=True),
|
||||
name=dict(type="list", elements="str", aliases=["idnsname"],
|
||||
required=True),
|
||||
# present
|
||||
description=dict(required=False, type='str', default=None),
|
||||
# state
|
||||
|
||||
423
plugins/modules/ipanetgroup.py
Normal file
423
plugins/modules/ipanetgroup.py
Normal file
@@ -0,0 +1,423 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Denis Karpelevich <dkarpele@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
"metadata_version": "1.0",
|
||||
"supported_by": "community",
|
||||
"status": ["preview"],
|
||||
}
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipanetgroup
|
||||
short_description: NIS entities can be stored in netgroups.
|
||||
description: |
|
||||
A netgroup is a group used for permission checking.
|
||||
It can contain both user and host values.
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
- ipamodule_base_docs.delete_continue
|
||||
options:
|
||||
name:
|
||||
description: The list of netgroup name strings.
|
||||
required: true
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: Netgroup description
|
||||
required: false
|
||||
type: str
|
||||
aliases: ["desc"]
|
||||
nisdomain:
|
||||
description: NIS domain name
|
||||
required: false
|
||||
type: str
|
||||
aliases: ["nisdomainname"]
|
||||
nomembers:
|
||||
description: Suppress processing of membership attributes
|
||||
required: false
|
||||
type: bool
|
||||
user:
|
||||
description: List of user names assigned to this netgroup.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["users"]
|
||||
group:
|
||||
description: List of group names assigned to this netgroup.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["groups"]
|
||||
host:
|
||||
description: List of host names assigned to this netgroup.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["hosts"]
|
||||
hostgroup:
|
||||
description: List of host group names assigned to this netgroup.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["hostgroups"]
|
||||
netgroup:
|
||||
description: List of netgroup names assigned to this netgroup.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["netgroups"]
|
||||
action:
|
||||
description: Work on netgroup or member level
|
||||
required: false
|
||||
default: netgroup
|
||||
choices: ["member", "netgroup"]
|
||||
state:
|
||||
description: The state to ensure.
|
||||
choices: ["present", "absent"]
|
||||
default: present
|
||||
author:
|
||||
- Denis Karpelevich (@dkarpele)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
- name: Ensure netgroup my_netgroup1 is present
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my_netgroup1
|
||||
description: My netgroup 1
|
||||
|
||||
- name: Ensure netgroup my_netgroup1 is absent
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my_netgroup1
|
||||
state: absent
|
||||
|
||||
- name: Ensure netgroup is present with user "user1"
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: TestNetgroup1
|
||||
user: user1
|
||||
action: member
|
||||
|
||||
- name: Ensure netgroup user, "user1", is absent
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: TestNetgroup1
|
||||
user: "user1"
|
||||
action: member
|
||||
state: absent
|
||||
|
||||
- name: Ensure netgroup is present with members
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: TestNetgroup1
|
||||
user: user1,user2
|
||||
group: group1
|
||||
host: host1
|
||||
hostgroup: ipaservers
|
||||
netgroup: admins
|
||||
action: member
|
||||
|
||||
- name: Ensure 2 netgroups TestNetgroup1, admins are absent
|
||||
ipanetgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name:
|
||||
- TestNetgroup1
|
||||
- admins
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, \
|
||||
gen_add_list, gen_intersection_list, ipalib_errors, ensure_fqdn
|
||||
|
||||
|
||||
def find_netgroup(module, name):
|
||||
"""Find if a netgroup with the given name already exist."""
|
||||
try:
|
||||
_result = module.ipa_command("netgroup_show", name, {"all": True})
|
||||
except ipalib_errors.NotFound:
|
||||
# An exception is raised if netgroup name is not found.
|
||||
return None
|
||||
else:
|
||||
return _result["result"]
|
||||
|
||||
|
||||
def gen_args(description, nisdomain, nomembers):
|
||||
_args = {}
|
||||
if description is not None:
|
||||
_args["description"] = description
|
||||
if nisdomain is not None:
|
||||
_args["nisdomainname"] = nisdomain
|
||||
if nomembers is not None:
|
||||
_args["nomembers"] = nomembers
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
def gen_member_args(user, group, host, hostgroup, netgroup):
|
||||
_args = {}
|
||||
if user is not None:
|
||||
_args["memberuser_user"] = user
|
||||
if group is not None:
|
||||
_args["memberuser_group"] = group
|
||||
if host is not None:
|
||||
_args["memberhost_host"] = host
|
||||
if hostgroup is not None:
|
||||
_args["memberhost_hostgroup"] = hostgroup
|
||||
if netgroup is not None:
|
||||
_args["member_netgroup"] = netgroup
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
# present
|
||||
description=dict(required=False, type='str',
|
||||
aliases=["desc"], default=None),
|
||||
nisdomain=dict(required=False, type='str',
|
||||
aliases=["nisdomainname"], default=None),
|
||||
nomembers=dict(required=False, type='bool', default=None),
|
||||
user=dict(required=False, type='list', elements="str",
|
||||
aliases=["users"], default=None),
|
||||
group=dict(required=False, type='list', elements="str",
|
||||
aliases=["groups"], default=None),
|
||||
host=dict(required=False, type='list', elements="str",
|
||||
aliases=["hosts"], default=None),
|
||||
hostgroup=dict(required=False, type='list', elements="str",
|
||||
aliases=["hostgroups"], default=None),
|
||||
netgroup=dict(required=False, type='list', elements="str",
|
||||
aliases=["netgroups"], default=None),
|
||||
action=dict(required=False, type="str", default="netgroup",
|
||||
choices=["member", "netgroup"]),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
ipa_module_options=["delete_continue"],
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
names = ansible_module.params_get("name")
|
||||
|
||||
# present
|
||||
description = ansible_module.params_get("description")
|
||||
nisdomain = ansible_module.params_get("nisdomain")
|
||||
nomembers = ansible_module.params_get("nomembers")
|
||||
user = ansible_module.params_get_lowercase("user")
|
||||
group = ansible_module.params_get_lowercase("group")
|
||||
host = ansible_module.params_get_lowercase("host")
|
||||
hostgroup = ansible_module.params_get_lowercase("hostgroup")
|
||||
netgroup = ansible_module.params_get_lowercase("netgroup")
|
||||
action = ansible_module.params_get("action")
|
||||
|
||||
# state
|
||||
state = ansible_module.params_get("state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
invalid = []
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Only one netgroup can be added at a time.")
|
||||
if action == "member":
|
||||
invalid = ["description", "nisdomain", "nomembers"]
|
||||
|
||||
if state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(msg="No name given.")
|
||||
if len(names) != 1 and action == "member":
|
||||
ansible_module.fail_json(msg="Members can be removed only from one"
|
||||
" netgroup at a time.")
|
||||
invalid = ["description", "nisdomain", "nomembers"]
|
||||
if action == "netgroup":
|
||||
invalid.extend(["user", "group", "host", "hostgroup", "netgroup"])
|
||||
|
||||
ansible_module.params_fail_used_invalid(invalid, state)
|
||||
|
||||
# Init
|
||||
|
||||
exit_args = {}
|
||||
|
||||
# Connect to IPA API
|
||||
with ansible_module.ipa_connect():
|
||||
# Ensure fqdn host names, use default domain for simple names
|
||||
if host is not None:
|
||||
default_domain = ansible_module.ipa_get_domain()
|
||||
host = [ensure_fqdn(_host, default_domain).lower()
|
||||
for _host in host]
|
||||
|
||||
commands = []
|
||||
for name in names:
|
||||
# Make sure netgroup exists
|
||||
res_find = find_netgroup(ansible_module, name)
|
||||
|
||||
user_add, user_del = [], []
|
||||
group_add, group_del = [], []
|
||||
host_add, host_del = [], []
|
||||
hostgroup_add, hostgroup_del = [], []
|
||||
netgroup_add, netgroup_del = [], []
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
# Generate args
|
||||
args = gen_args(description, nisdomain, nomembers)
|
||||
|
||||
if action == "netgroup":
|
||||
# Found the netgroup
|
||||
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, "netgroup_mod", args])
|
||||
else:
|
||||
commands.append([name, "netgroup_add", args])
|
||||
res_find = {}
|
||||
|
||||
member_args = gen_member_args(
|
||||
user, group, host, hostgroup, netgroup
|
||||
)
|
||||
if not compare_args_ipa(ansible_module, member_args,
|
||||
res_find):
|
||||
# Generate addition and removal lists
|
||||
user_add, user_del = gen_add_del_lists(
|
||||
user, res_find.get("memberuser_user"))
|
||||
|
||||
group_add, group_del = gen_add_del_lists(
|
||||
group, res_find.get("memberuser_group"))
|
||||
|
||||
host_add, host_del = gen_add_del_lists(
|
||||
host, res_find.get("memberhost_host"))
|
||||
|
||||
hostgroup_add, hostgroup_del = gen_add_del_lists(
|
||||
hostgroup, res_find.get("memberhost_hostgroup"))
|
||||
|
||||
netgroup_add, netgroup_del = gen_add_del_lists(
|
||||
netgroup, res_find.get("member_netgroup"))
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No netgroup '%s'" % name)
|
||||
|
||||
# Reduce add lists for memberuser_user, memberuser_group,
|
||||
# member_service and member_external to new entries
|
||||
# only that are not in res_find.
|
||||
user_add = gen_add_list(
|
||||
user, res_find.get("memberuser_user"))
|
||||
group_add = gen_add_list(
|
||||
group, res_find.get("memberuser_group"))
|
||||
host_add = gen_add_list(
|
||||
host, res_find.get("memberhost_host"))
|
||||
hostgroup_add = gen_add_list(
|
||||
hostgroup, res_find.get("memberhost_hostgroup"))
|
||||
netgroup_add = gen_add_list(
|
||||
netgroup, res_find.get("member_netgroup"))
|
||||
|
||||
elif state == "absent":
|
||||
if action == "netgroup":
|
||||
if res_find is not None:
|
||||
commands.append([name, "netgroup_del", {}])
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No netgroup '%s'" % name)
|
||||
user_del = gen_intersection_list(
|
||||
user, res_find.get("memberuser_user"))
|
||||
group_del = gen_intersection_list(
|
||||
group, res_find.get("memberuser_group"))
|
||||
host_del = gen_intersection_list(
|
||||
host, res_find.get("memberhost_host"))
|
||||
hostgroup_del = gen_intersection_list(
|
||||
hostgroup, res_find.get("memberhost_hostgroup"))
|
||||
netgroup_del = gen_intersection_list(
|
||||
netgroup, res_find.get("member_netgroup"))
|
||||
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unknown state '%s'" % state)
|
||||
|
||||
# manage members
|
||||
# setup member args for add/remove members.
|
||||
add_member_args = {
|
||||
"user": user_add,
|
||||
"group": group_add,
|
||||
"host": host_add,
|
||||
"hostgroup": hostgroup_add,
|
||||
"netgroup": netgroup_add
|
||||
}
|
||||
|
||||
del_member_args = {
|
||||
"user": user_del,
|
||||
"group": group_del,
|
||||
"host": host_del,
|
||||
"hostgroup": hostgroup_del,
|
||||
"netgroup": netgroup_del
|
||||
}
|
||||
|
||||
# Add members
|
||||
add_members = any([user_add, group_add, host_add,
|
||||
hostgroup_add, netgroup_add])
|
||||
if add_members:
|
||||
commands.append(
|
||||
[name, "netgroup_add_member", add_member_args]
|
||||
)
|
||||
# Remove members
|
||||
remove_members = any([user_del, group_del, host_del,
|
||||
hostgroup_del, netgroup_del])
|
||||
if remove_members:
|
||||
commands.append(
|
||||
[name, "netgroup_remove_member", del_member_args]
|
||||
)
|
||||
# Execute commands
|
||||
|
||||
changed = ansible_module.execute_ipa_commands(
|
||||
commands, fail_on_member_errors=True)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Seth Kress <kresss@gmail.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2020 Red Hat
|
||||
# Copyright (C) 2020-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,13 +33,15 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipapermission
|
||||
short description: Manage FreeIPA permission
|
||||
short_description: Manage FreeIPA permission
|
||||
description: Manage FreeIPA permission and permission members
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The permission name string.
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
right:
|
||||
@@ -46,52 +49,64 @@ options:
|
||||
required: false
|
||||
choices: ["read", "search", "compare", "write", "add", "delete", "all"]
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipapermright"]
|
||||
attrs:
|
||||
description: All attributes to which the permission applies
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
bindtype:
|
||||
description: Bind rule type
|
||||
required: false
|
||||
choices: ["permission", "all", "anonymous"]
|
||||
type: str
|
||||
choices: ["permission", "all", "anonymous", "self"]
|
||||
aliases: ["ipapermbindruletype"]
|
||||
subtree:
|
||||
description: Subtree to apply permissions to
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ipapermlocation"]
|
||||
filter:
|
||||
extra_target_filter:
|
||||
description: Extra target filter
|
||||
required: false
|
||||
type: list
|
||||
aliases: ["extratargetfilter"]
|
||||
elements: str
|
||||
aliases: ["filter", "extratargetfilter"]
|
||||
rawfilter:
|
||||
description: All target filters
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipapermtargetfilter"]
|
||||
target:
|
||||
description: Optional DN to apply the permission to
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ipapermtarget"]
|
||||
targetto:
|
||||
description: Optional DN subtree where an entry can be moved to
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ipapermtargetto"]
|
||||
targetfrom:
|
||||
description: Optional DN subtree from where an entry can be moved
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ipapermtargetfrom"]
|
||||
memberof:
|
||||
description: Target members of a group (sets memberOf targetfilter)
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
targetgroup:
|
||||
description: User group to apply permissions to (sets target)
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["targetgroup"]
|
||||
object_type:
|
||||
description: Type of IPA object (sets subtree and objectClass targetfilter)
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["type"]
|
||||
no_members:
|
||||
@@ -100,18 +115,24 @@ options:
|
||||
type: bool
|
||||
rename:
|
||||
description: Rename the permission object
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["new_name"]
|
||||
action:
|
||||
description: Work on permission or member privilege level.
|
||||
type: str
|
||||
choices: ["permission", "member"]
|
||||
default: permission
|
||||
required: false
|
||||
state:
|
||||
description: The state to ensure.
|
||||
type: str
|
||||
choices: ["present", "absent", "renamed"]
|
||||
default: present
|
||||
required: true
|
||||
required: false
|
||||
author:
|
||||
- Seth Kress (@kresss)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -203,24 +224,26 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"],
|
||||
default=None, required=True),
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
# present
|
||||
right=dict(type="list", aliases=["ipapermright"], default=None,
|
||||
required=False,
|
||||
right=dict(type="list", elements="str", aliases=["ipapermright"],
|
||||
default=None, required=False,
|
||||
choices=["read", "search", "compare", "write", "add",
|
||||
"delete", "all"]),
|
||||
attrs=dict(type="list", default=None, required=False),
|
||||
attrs=dict(type="list", elements="str", default=None,
|
||||
required=False),
|
||||
# Note: bindtype has a default of permission for Adds.
|
||||
bindtype=dict(type="str", aliases=["ipapermbindruletype"],
|
||||
default=None, require=False, choices=["permission",
|
||||
default=None, required=False, choices=["permission",
|
||||
"all", "anonymous", "self"]),
|
||||
subtree=dict(type="str", aliases=["ipapermlocation"], default=None,
|
||||
required=False),
|
||||
extra_target_filter=dict(type="list", aliases=["filter",
|
||||
"extratargetfilter"], default=None,
|
||||
required=False),
|
||||
rawfilter=dict(type="list", aliases=["ipapermtargetfilter"],
|
||||
extra_target_filter=dict(type="list", elements="str",
|
||||
aliases=["filter", "extratargetfilter"],
|
||||
default=None, required=False),
|
||||
rawfilter=dict(type="list", elements="str",
|
||||
aliases=["ipapermtargetfilter"],
|
||||
default=None, required=False),
|
||||
target=dict(type="str", aliases=["ipapermtarget"], default=None,
|
||||
required=False),
|
||||
@@ -228,11 +251,12 @@ def main():
|
||||
default=None, required=False),
|
||||
targetfrom=dict(type="str", aliases=["ipapermtargetfrom"],
|
||||
default=None, required=False),
|
||||
memberof=dict(type="list", default=None, required=False),
|
||||
memberof=dict(type="list", elements="str", default=None,
|
||||
required=False),
|
||||
targetgroup=dict(type="str", default=None, required=False),
|
||||
object_type=dict(type="str", aliases=["type"], default=None,
|
||||
required=False),
|
||||
no_members=dict(type=bool, default=None, require=False),
|
||||
no_members=dict(type="bool", default=None, required=False),
|
||||
rename=dict(type="str", default=None, required=False,
|
||||
aliases=["new_name"]),
|
||||
action=dict(type="str", default="permission",
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2020 Red Hat
|
||||
# Copyright (C) 2020-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -35,35 +36,46 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaprivilege
|
||||
short description: Manage FreeIPA privilege
|
||||
short_description: Manage FreeIPA privilege
|
||||
description: Manage FreeIPA privilege and privilege members
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The list of privilege name strings.
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: Privilege description
|
||||
type: str
|
||||
required: false
|
||||
rename:
|
||||
description: Rename the privilege object.
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["new_name"]
|
||||
permission:
|
||||
description: Permissions to be added to the privilege.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
action:
|
||||
description: Work on privilege or member level.
|
||||
type: str
|
||||
choices: ["privilege", "member"]
|
||||
default: privilege
|
||||
required: false
|
||||
state:
|
||||
description: The state to ensure.
|
||||
type: str
|
||||
choices: ["present", "absent", "renamed"]
|
||||
default: present
|
||||
required: true
|
||||
required: false
|
||||
author:
|
||||
- Rafael Guterres Jeffman (@rjeffman)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -134,13 +146,14 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"],
|
||||
default=None, required=True),
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
# present
|
||||
description=dict(required=False, type='str', default=None),
|
||||
rename=dict(required=False, type='str', default=None,
|
||||
aliases=["new_name"], ),
|
||||
permission=dict(required=False, type='list', default=None),
|
||||
permission=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
action=dict(type="str", default="privilege",
|
||||
choices=["member", "privilege"]),
|
||||
# state
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,17 +33,15 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipapwpolicy
|
||||
short description: Manage FreeIPA pwpolicies
|
||||
short_description: Manage FreeIPA pwpolicies
|
||||
description: Manage FreeIPA pwpolicies
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: false
|
||||
name:
|
||||
description: The group name
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["cn"]
|
||||
maxlife:
|
||||
@@ -90,12 +89,49 @@ options:
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["krbpwdlockoutduration"]
|
||||
maxrepeat:
|
||||
description: >
|
||||
Maximum number of same consecutive characters.
|
||||
Requires IPA 4.9+
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["ipapwdmaxrepeat"]
|
||||
maxsequence:
|
||||
description: >
|
||||
The maximum length of monotonic character sequences (abcd).
|
||||
Requires IPA 4.9+
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["ipapwdmaxsequence"]
|
||||
dictcheck:
|
||||
description: >
|
||||
Check if the password is a dictionary word.
|
||||
Requires IPA 4.9+
|
||||
type: bool
|
||||
required: false
|
||||
aliases: ["ipapwdictcheck"]
|
||||
usercheck:
|
||||
description: >
|
||||
Check if the password contains the username.
|
||||
Requires IPA 4.9+
|
||||
type: bool
|
||||
required: false
|
||||
aliases: ["ipapwdusercheck"]
|
||||
gracelimit:
|
||||
description: >
|
||||
Number of LDAP authentications allowed after expiration.
|
||||
Requires IPA 4.10.1+
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["passwordgracelimit"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
- Rafael Guterres Jeffman (@rjeffman)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -136,7 +172,8 @@ def find_pwpolicy(module, name):
|
||||
|
||||
|
||||
def gen_args(maxlife, minlife, history, minclasses, minlength, priority,
|
||||
maxfail, failinterval, lockouttime):
|
||||
maxfail, failinterval, lockouttime, maxrepeat, maxsequence,
|
||||
dictcheck, usercheck, gracelimit):
|
||||
_args = {}
|
||||
if maxlife is not None:
|
||||
_args["krbmaxpwdlife"] = maxlife
|
||||
@@ -156,16 +193,53 @@ def gen_args(maxlife, minlife, history, minclasses, minlength, priority,
|
||||
_args["krbpwdfailurecountinterval"] = failinterval
|
||||
if lockouttime is not None:
|
||||
_args["krbpwdlockoutduration"] = lockouttime
|
||||
if maxrepeat is not None:
|
||||
_args["ipapwdmaxrepeat"] = maxrepeat
|
||||
if maxsequence is not None:
|
||||
_args["ipapwdmaxrsequence"] = maxsequence
|
||||
if dictcheck is not None:
|
||||
_args["ipapwddictcheck"] = dictcheck
|
||||
if usercheck is not None:
|
||||
_args["ipapwdusercheck"] = usercheck
|
||||
if gracelimit is not None:
|
||||
_args["passwordgracelimit"] = gracelimit
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
def check_supported_params(
|
||||
module, maxrepeat, maxsequence, dictcheck, usercheck, gracelimit
|
||||
):
|
||||
# All password checking parameters were added by the same commit,
|
||||
# so we only need to test one of them.
|
||||
has_password_check = module.ipa_command_param_exists(
|
||||
"pwpolicy_add", "ipapwdmaxrepeat")
|
||||
# check if gracelimit is supported
|
||||
has_gracelimit = module.ipa_command_param_exists(
|
||||
"pwpolicy_add", "passwordgracelimit")
|
||||
|
||||
# If needed, report unsupported password checking paramteres
|
||||
if not has_password_check:
|
||||
check_password_params = [maxrepeat, maxsequence, dictcheck, usercheck]
|
||||
unsupported = [
|
||||
x for x in check_password_params if x is not None
|
||||
]
|
||||
if unsupported:
|
||||
module.fail_json(
|
||||
msg="Your IPA version does not support arguments: "
|
||||
"maxrepeat, maxsequence, dictcheck, usercheck.")
|
||||
|
||||
if gracelimit is not None and not has_gracelimit:
|
||||
module.fail_json(
|
||||
msg="Your IPA version does not support 'gracelimit'.")
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
required=False),
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
default=None, required=False),
|
||||
# present
|
||||
|
||||
maxlife=dict(type="int", aliases=["krbmaxpwdlife"], default=None),
|
||||
@@ -184,6 +258,16 @@ def main():
|
||||
default=None),
|
||||
lockouttime=dict(type="int", aliases=["krbpwdlockoutduration"],
|
||||
default=None),
|
||||
maxrepeat=dict(type="int", aliases=["ipapwdmaxrepeat"],
|
||||
default=None),
|
||||
maxsequence=dict(type="int", aliases=["ipapwdmaxsequence"],
|
||||
default=None),
|
||||
dictcheck=dict(type="bool", aliases=["ipapwdictcheck"],
|
||||
default=None),
|
||||
usercheck=dict(type="bool", aliases=["ipapwusercheck"],
|
||||
default=None),
|
||||
gracelimit=dict(type="int", aliases=["passwordgracelimit"],
|
||||
default=None),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
@@ -208,6 +292,11 @@ def main():
|
||||
maxfail = ansible_module.params_get("maxfail")
|
||||
failinterval = ansible_module.params_get("failinterval")
|
||||
lockouttime = ansible_module.params_get("lockouttime")
|
||||
maxrepeat = ansible_module.params_get("maxrepeat")
|
||||
maxsequence = ansible_module.params_get("maxsequence")
|
||||
dictcheck = ansible_module.params_get("dictcheck")
|
||||
usercheck = ansible_module.params_get("usercheck")
|
||||
gracelimit = ansible_module.params_get("gracelimit")
|
||||
|
||||
# state
|
||||
state = ansible_module.params_get("state")
|
||||
@@ -231,10 +320,16 @@ def main():
|
||||
msg="'global_policy' can not be made absent.")
|
||||
invalid = ["maxlife", "minlife", "history", "minclasses",
|
||||
"minlength", "priority", "maxfail", "failinterval",
|
||||
"lockouttime"]
|
||||
"lockouttime", "maxrepeat", "maxsequence", "dictcheck",
|
||||
"usercheck", "gracelimit"]
|
||||
|
||||
ansible_module.params_fail_used_invalid(invalid, state)
|
||||
|
||||
if gracelimit is not None:
|
||||
if gracelimit < -1:
|
||||
ansible_module.fail_json(
|
||||
msg="'gracelimit' must be no less than -1")
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
@@ -242,6 +337,11 @@ def main():
|
||||
|
||||
with ansible_module.ipa_connect():
|
||||
|
||||
check_supported_params(
|
||||
ansible_module, maxrepeat, maxsequence, dictcheck, usercheck,
|
||||
gracelimit
|
||||
)
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
@@ -253,7 +353,8 @@ def main():
|
||||
# Generate args
|
||||
args = gen_args(maxlife, minlife, history, minclasses,
|
||||
minlength, priority, maxfail, failinterval,
|
||||
lockouttime)
|
||||
lockouttime, maxrepeat, maxsequence, dictcheck,
|
||||
usercheck, gracelimit)
|
||||
|
||||
# Found the pwpolicy
|
||||
if res_find is not None:
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2020 Red Hat
|
||||
# Copyright (C) 2020-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,47 +35,71 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: iparole
|
||||
short description: Manage FreeIPA role
|
||||
short_description: Manage FreeIPA role
|
||||
description: Manage FreeIPA role
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
role:
|
||||
name:
|
||||
description: The list of role name strings.
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: A description for the role.
|
||||
type: str
|
||||
required: false
|
||||
rename:
|
||||
description: Rename the role object.
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["new_name"]
|
||||
privilege:
|
||||
description: List of privileges
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
user:
|
||||
description: List of users.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
group:
|
||||
description: List of groups.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
host:
|
||||
description: List of hosts.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
hostgroup:
|
||||
description: List of hostgroups.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
service:
|
||||
description: List of services.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
action:
|
||||
description: Work on role or member level.
|
||||
type: str
|
||||
choices: ["role", "member"]
|
||||
default: role
|
||||
required: false
|
||||
state:
|
||||
description: The state to ensure.
|
||||
type: str
|
||||
choices: ["present", "absent", "renamed"]
|
||||
default: present
|
||||
required: true
|
||||
required: false
|
||||
author:
|
||||
- Rafael Guterres Jeffman (@rjeffman)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -394,19 +419,25 @@ def create_module():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# generalgroups
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
# present
|
||||
description=dict(required=False, type="str", default=None),
|
||||
rename=dict(required=False, type="str", default=None,
|
||||
aliases=["new_name"]),
|
||||
# members
|
||||
privilege=dict(required=False, type='list', default=None),
|
||||
user=dict(required=False, type='list', default=None),
|
||||
group=dict(required=False, type='list', default=None),
|
||||
host=dict(required=False, type='list', default=None),
|
||||
hostgroup=dict(required=False, type='list', default=None),
|
||||
service=dict(required=False, type='list', default=None),
|
||||
privilege=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
user=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
group=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
host=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
hostgroup=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
service=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
|
||||
# state
|
||||
action=dict(type="str", default="role",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2020 Red Hat
|
||||
# Copyright (C) 2020-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,33 +32,43 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaselfservice
|
||||
short description: Manage FreeIPA selfservices
|
||||
short_description: Manage FreeIPA selfservices
|
||||
description: Manage FreeIPA selfservices and selfservice attributes
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The list of selfservice name strings.
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["aciname"]
|
||||
permission:
|
||||
description: Permissions to grant (read, write). Default is write.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["permissions"]
|
||||
attribute:
|
||||
description: Attribute list to which the selfservice applies
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["attrs"]
|
||||
action:
|
||||
description: Work on selfservice or member level.
|
||||
type: str
|
||||
choices: ["selfservice", "member"]
|
||||
default: selfservice
|
||||
required: false
|
||||
state:
|
||||
description: The state to ensure.
|
||||
type: str
|
||||
choices: ["present", "absent"]
|
||||
default: present
|
||||
required: true
|
||||
required: false
|
||||
author:
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -130,13 +140,13 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["aciname"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["aciname"],
|
||||
required=True),
|
||||
# present
|
||||
permission=dict(required=False, type='list',
|
||||
permission=dict(required=False, type='list', elements="str",
|
||||
aliases=["permissions"], default=None),
|
||||
attribute=dict(required=False, type='list', aliases=["attrs"],
|
||||
default=None),
|
||||
attribute=dict(required=False, type='list', elements="str",
|
||||
aliases=["attrs"], default=None),
|
||||
action=dict(type="str", default="selfservice",
|
||||
choices=["member", "selfservice"]),
|
||||
# state
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2021 Red Hat
|
||||
# Copyright (C) 2021-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,13 +32,15 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaserver
|
||||
short description: Manage FreeIPA server
|
||||
short_description: Manage FreeIPA server
|
||||
description: Manage FreeIPA server
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The list of server name strings.
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
location:
|
||||
@@ -46,6 +48,7 @@ options:
|
||||
The server location string.
|
||||
"" for location reset.
|
||||
Only in state: present.
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ipalocation_location"]
|
||||
service_weight:
|
||||
@@ -96,9 +99,12 @@ options:
|
||||
type: bool
|
||||
state:
|
||||
description: The state to ensure.
|
||||
type: str
|
||||
choices: ["present", "absent"]
|
||||
default: present
|
||||
required: true
|
||||
required: false
|
||||
author:
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -244,8 +250,8 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"],
|
||||
default=None, required=True),
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
# present
|
||||
location=dict(required=False, type='str',
|
||||
aliases=["ipalocation_location"], default=None),
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -33,28 +34,34 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaservice
|
||||
short description: Manage FreeIPA service
|
||||
short_description: Manage FreeIPA service
|
||||
description: Manage FreeIPA service
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The service to manage
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["service"]
|
||||
certificate:
|
||||
description: Base-64 encoded service certificate.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["usercertificate"]
|
||||
pac_type:
|
||||
description: Supported PAC type.
|
||||
required: false
|
||||
choices: ["MS-PAC", "PAD", "NONE", ""]
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["pac_type", "ipakrbauthzdata"]
|
||||
auth_ind:
|
||||
description: Defines a whitelist for Authentication Indicators.
|
||||
description: Defines an allow list for Authentication Indicators.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
choices: ["otp", "radius", "pkinit", "hardened", ""]
|
||||
aliases: ["krbprincipalauthind"]
|
||||
@@ -70,24 +77,22 @@ options:
|
||||
description: Pre-authentication is required for the service.
|
||||
required: false
|
||||
type: bool
|
||||
default: False
|
||||
aliases: ["ipakrbrequirespreauth"]
|
||||
ok_as_delegate:
|
||||
description: Client credentials may be delegated to the service.
|
||||
required: false
|
||||
type: bool
|
||||
default: False
|
||||
aliases: ["ipakrbokasdelegate"]
|
||||
ok_to_auth_as_delegate:
|
||||
description: Allow service to authenticate on behalf of a client.
|
||||
required: false
|
||||
type: bool
|
||||
default: False
|
||||
aliases: ["ipakrboktoauthasdelegate"]
|
||||
principal:
|
||||
description: List of principal aliases for the service.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["krbprincipalname"]
|
||||
smb:
|
||||
description: Add a SMB service.
|
||||
@@ -101,63 +106,75 @@ options:
|
||||
description: Host that can manage the service.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["managedby_host"]
|
||||
allow_create_keytab_user:
|
||||
description: Users allowed to create a keytab of this host.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_write_keys_user"]
|
||||
allow_create_keytab_group:
|
||||
description: Groups allowed to create a keytab of this host.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_write_keys_group"]
|
||||
allow_create_keytab_host:
|
||||
description: Hosts allowed to create a keytab of this host.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_write_keys_host"]
|
||||
allow_create_keytab_hostgroup:
|
||||
description: Host group allowed to create a keytab of this host.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_write_keys_hostgroup"]
|
||||
allow_retrieve_keytab_user:
|
||||
description: User allowed to retrieve a keytab of this host.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_read_keys_user"]
|
||||
allow_retrieve_keytab_group:
|
||||
description: Groups allowed to retrieve a keytab of this host.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_read_keys_group"]
|
||||
allow_retrieve_keytab_host:
|
||||
description: Hosts allowed to retrieve a keytab of this host.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_read_keys_host"]
|
||||
allow_retrieve_keytab_hostgroup:
|
||||
description: Host groups allowed to retrieve a keytab of this host.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipaallowedtoperform_read_keys_hostgroup"]
|
||||
continue:
|
||||
delete_continue:
|
||||
description:
|
||||
Continuous mode. Don't stop on errors. Valid only if `state` is `absent`.
|
||||
required: false
|
||||
default: True
|
||||
type: bool
|
||||
aliases: ["continue"]
|
||||
action:
|
||||
description: Work on service or member level
|
||||
type: str
|
||||
default: service
|
||||
choices: ["member", "service"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent", "disabled"]
|
||||
author:
|
||||
- Rafael Jeffman
|
||||
- Rafael Guterres Jeffman (@rjeffman)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -346,18 +363,20 @@ def init_ansible_module():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["service"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["service"],
|
||||
required=True),
|
||||
# service attributesstr
|
||||
certificate=dict(type="list", aliases=['usercertificate'],
|
||||
certificate=dict(type="list", elements="str",
|
||||
aliases=['usercertificate'],
|
||||
default=None, required=False),
|
||||
principal=dict(type="list", aliases=["krbprincipalname"],
|
||||
default=None),
|
||||
principal=dict(type="list", elements="str",
|
||||
aliases=["krbprincipalname"], default=None),
|
||||
smb=dict(type="bool", required=False),
|
||||
netbiosname=dict(type="str", required=False),
|
||||
pac_type=dict(type="list", aliases=["ipakrbauthzdata"],
|
||||
pac_type=dict(type="list", elements="str",
|
||||
aliases=["ipakrbauthzdata"],
|
||||
choices=["MS-PAC", "PAD", "NONE", ""]),
|
||||
auth_ind=dict(type="list",
|
||||
auth_ind=dict(type="list", elements="str",
|
||||
aliases=["krbprincipalauthind"],
|
||||
choices=["otp", "radius", "pkinit", "hardened", ""]),
|
||||
skip_host_check=dict(type="bool"),
|
||||
@@ -367,30 +386,31 @@ def init_ansible_module():
|
||||
ok_as_delegate=dict(type="bool", aliases=["ipakrbokasdelegate"]),
|
||||
ok_to_auth_as_delegate=dict(type="bool",
|
||||
aliases=["ipakrboktoauthasdelegate"]),
|
||||
host=dict(type="list", aliases=["managedby_host"], required=False),
|
||||
host=dict(type="list", elements="str", aliases=["managedby_host"],
|
||||
required=False),
|
||||
allow_create_keytab_user=dict(
|
||||
type="list", required=False,
|
||||
type="list", elements="str", required=False, no_log=False,
|
||||
aliases=['ipaallowedtoperform_write_keys_user']),
|
||||
allow_retrieve_keytab_user=dict(
|
||||
type="list", required=False,
|
||||
type="list", elements="str", required=False, no_log=False,
|
||||
aliases=['ipaallowedtoperform_read_keys_user']),
|
||||
allow_create_keytab_group=dict(
|
||||
type="list", required=False,
|
||||
type="list", elements="str", required=False, no_log=False,
|
||||
aliases=['ipaallowedtoperform_write_keys_group']),
|
||||
allow_retrieve_keytab_group=dict(
|
||||
type="list", required=False,
|
||||
type="list", elements="str", required=False, no_log=False,
|
||||
aliases=['ipaallowedtoperform_read_keys_group']),
|
||||
allow_create_keytab_host=dict(
|
||||
type="list", required=False,
|
||||
type="list", elements="str", required=False, no_log=False,
|
||||
aliases=['ipaallowedtoperform_write_keys_host']),
|
||||
allow_retrieve_keytab_host=dict(
|
||||
type="list", required=False,
|
||||
type="list", elements="str", required=False, no_log=False,
|
||||
aliases=['ipaallowedtoperform_read_keys_host']),
|
||||
allow_create_keytab_hostgroup=dict(
|
||||
type="list", required=False,
|
||||
type="list", elements="str", required=False, no_log=False,
|
||||
aliases=['ipaallowedtoperform_write_keys_hostgroup']),
|
||||
allow_retrieve_keytab_hostgroup=dict(
|
||||
type="list", required=False,
|
||||
type="list", elements="str", required=False, no_log=False,
|
||||
aliases=['ipaallowedtoperform_read_keys_hostgroup']),
|
||||
delete_continue=dict(type="bool", required=False,
|
||||
aliases=['continue']),
|
||||
|
||||
@@ -32,7 +32,7 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaservicedelegationrule
|
||||
short description: Manage FreeIPA servicedelegationrule
|
||||
short_description: Manage FreeIPA servicedelegationrule
|
||||
description: |
|
||||
Manage FreeIPA servicedelegationrule and servicedelegationrule members
|
||||
extends_documentation_fragment:
|
||||
@@ -40,6 +40,8 @@ extends_documentation_fragment:
|
||||
options:
|
||||
name:
|
||||
description: The list of servicedelegationrule name strings.
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
principal:
|
||||
@@ -49,22 +51,30 @@ options:
|
||||
host/fqdn@REALM, alias$, alias$@REALM, where fqdn and fqdn@REALM
|
||||
are host principals and the same as host/fqdn and host/fqd
|
||||
Host princpals are only usable with IPA versions 4.9.0 and up.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
target:
|
||||
description: |
|
||||
The list of service delegation targets.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["servicedelegationtarget"]
|
||||
action:
|
||||
description: Work on servicedelegationrule or member level.
|
||||
type: str
|
||||
choices: ["servicedelegationrule", "member"]
|
||||
default: servicedelegationrule
|
||||
required: false
|
||||
state:
|
||||
description: The state to ensure.
|
||||
type: str
|
||||
choices: ["present", "absent"]
|
||||
default: present
|
||||
required: true
|
||||
required: false
|
||||
author:
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -161,11 +171,12 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
# present
|
||||
principal=dict(required=False, type='list', default=None),
|
||||
target=dict(required=False, type='list',
|
||||
principal=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
target=dict(required=False, type='list', elements="str",
|
||||
aliases=["servicedelegationtarget"], default=None),
|
||||
|
||||
action=dict(type="str", default="servicedelegationrule",
|
||||
|
||||
@@ -32,7 +32,7 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaservicedelegationtarget
|
||||
short description: Manage FreeIPA servicedelegationtarget
|
||||
short_description: Manage FreeIPA servicedelegationtarget
|
||||
description: |
|
||||
Manage FreeIPA servicedelegationtarget and servicedelegationtarget members
|
||||
extends_documentation_fragment:
|
||||
@@ -40,6 +40,8 @@ extends_documentation_fragment:
|
||||
options:
|
||||
name:
|
||||
description: The list of servicedelegationtarget name strings.
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
principal:
|
||||
@@ -49,17 +51,23 @@ options:
|
||||
host/fqdn@REALM, alias$, alias$@REALM, where fqdn and fqdn@REALM
|
||||
are host principals and the same as host/fqdn and host/fqdn@REALM.
|
||||
Host princpals are only usable with IPA versions 4.9.0 and up.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
action:
|
||||
description: Work on servicedelegationtarget or member level.
|
||||
type: str
|
||||
choices: ["servicedelegationtarget", "member"]
|
||||
default: servicedelegationtarget
|
||||
required: false
|
||||
state:
|
||||
description: The state to ensure.
|
||||
type: str
|
||||
choices: ["present", "absent"]
|
||||
default: present
|
||||
required: true
|
||||
required: false
|
||||
author:
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -121,10 +129,11 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
# present
|
||||
principal=dict(required=False, type='list', default=None),
|
||||
principal=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
|
||||
action=dict(type="str", default="servicedelegationtarget",
|
||||
choices=["member", "servicedelegationtarget"]),
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -33,24 +34,29 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipasudocmd
|
||||
short description: Manage FreeIPA sudo command
|
||||
short_description: Manage FreeIPA sudo command
|
||||
description: Manage FreeIPA sudo command
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The sudo command
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["sudocmd"]
|
||||
description:
|
||||
description: The command description
|
||||
type: str
|
||||
required: false
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Rafael Jeffman
|
||||
- Rafael Guterres Jeffman (@rjeffman)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -103,7 +109,7 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["sudocmd"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["sudocmd"],
|
||||
required=True),
|
||||
# present
|
||||
description=dict(type="str", default=None),
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -33,17 +34,20 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipasudocmdgroup
|
||||
short description: Manage FreeIPA sudocmd groups
|
||||
short_description: Manage FreeIPA sudocmd groups
|
||||
description: Manage FreeIPA sudocmd groups
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The sudocmodgroup name
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: The sudocmdgroup description
|
||||
type: str
|
||||
required: false
|
||||
nomembers:
|
||||
description: Suppress processing of membership attributes
|
||||
@@ -53,16 +57,20 @@ options:
|
||||
description: List of sudocmds assigned to this sudocmdgroup.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
action:
|
||||
description: Work on sudocmdgroup or member level
|
||||
default: hostgroup
|
||||
type: str
|
||||
default: sudocmdgroup
|
||||
choices: ["member", "sudocmdgroup"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Rafael Guterres Jeffman
|
||||
- Rafael Guterres Jeffman (@rjeffman)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -140,12 +148,13 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
# present
|
||||
description=dict(type="str", default=None),
|
||||
nomembers=dict(required=False, type='bool', default=None),
|
||||
sudocmd=dict(required=False, type='list', default=None),
|
||||
sudocmd=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
action=dict(type="str", default="sudocmdgroup",
|
||||
choices=["member", "sudocmdgroup"]),
|
||||
# state
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,36 +33,46 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipasudorule
|
||||
short description: Manage FreeIPA sudo rules
|
||||
short_description: Manage FreeIPA sudo rules
|
||||
description: Manage FreeIPA sudo rules
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The sudorule name
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: The sudorule description
|
||||
type: str
|
||||
required: false
|
||||
user:
|
||||
description: List of users assigned to the sudo rule.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
usercategory:
|
||||
description: User category the sudo rule applies to
|
||||
type: str
|
||||
required: false
|
||||
choices: ["all", ""]
|
||||
aliases: ["usercat"]
|
||||
group:
|
||||
description: List of user groups assigned to the sudo rule.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
runasgroupcategory:
|
||||
description: RunAs Group category applied to the sudo rule.
|
||||
type: str
|
||||
required: false
|
||||
choices: ["all", ""]
|
||||
aliases: ["runasgroupcat"]
|
||||
runasusercategory:
|
||||
description: RunAs User category applied to the sudorule.
|
||||
type: str
|
||||
required: false
|
||||
choices: ["all", ""]
|
||||
aliases: ["runasusercat"]
|
||||
@@ -73,12 +84,15 @@ options:
|
||||
description: List of host names assigned to this sudorule.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
hostgroup:
|
||||
description: List of host groups assigned to this sudorule.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
hostcategory:
|
||||
description: Host category the sudo rule applies to.
|
||||
type: str
|
||||
required: false
|
||||
choices: ["all", ""]
|
||||
aliases: ["hostcat"]
|
||||
@@ -86,20 +100,25 @@ options:
|
||||
description: List of allowed sudocmds assigned to this sudorule.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
allow_sudocmdgroup:
|
||||
description: List of allowed sudocmd groups assigned to this sudorule.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
deny_sudocmd:
|
||||
description: List of denied sudocmds assigned to this sudorule.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
deny_sudocmdgroup:
|
||||
description: List of denied sudocmd groups assigned to this sudorule.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
cmdcategory:
|
||||
description: Command category the sudo rule applies to
|
||||
type: str
|
||||
required: false
|
||||
choices: ["all", ""]
|
||||
aliases: ["cmdcat"]
|
||||
@@ -107,29 +126,41 @@ options:
|
||||
description: Order to apply this rule.
|
||||
required: false
|
||||
type: int
|
||||
aliases: ["sudoorder"]
|
||||
sudooption:
|
||||
description: List of sudo options.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["options"]
|
||||
runasuser:
|
||||
description: List of users for Sudo to execute as.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
runasgroup:
|
||||
description: List of groups for Sudo to execute as.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
hostmask:
|
||||
description: Host masks of allowed hosts.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
action:
|
||||
description: Work on sudorule or member level
|
||||
type: str
|
||||
default: sudorule
|
||||
choices: ["member", "sudorule"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent", "enabled", "disabled"]
|
||||
author:
|
||||
- Rafael Jeffman
|
||||
- Rafael Guterres Jeffman (@rjeffman)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -162,19 +193,28 @@ EXAMPLES = """
|
||||
hostgroup: cluster
|
||||
action: member
|
||||
|
||||
# Ensure sudo rule for usercategory "all"
|
||||
# Ensure sudo rule for usercategory "all" is enabled
|
||||
- ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: allusers
|
||||
usercategory: all
|
||||
action: enabled
|
||||
state: enabled
|
||||
|
||||
# Ensure sudo rule for hostcategory "all"
|
||||
# Ensure sudo rule for hostcategory "all" is enabled
|
||||
- ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: allhosts
|
||||
hostcategory: all
|
||||
action: enabled
|
||||
state: enabled
|
||||
|
||||
# Ensure sudo rule applies for hosts with hostmasks
|
||||
- ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: testrule1
|
||||
hostmask:
|
||||
- 192.168.122.1/24
|
||||
- 192.168.120.1/24
|
||||
action: member
|
||||
|
||||
# Ensure Sudo Rule tesrule1 is absent
|
||||
- ipasudorule:
|
||||
@@ -188,7 +228,7 @@ RETURN = """
|
||||
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, gen_add_list, \
|
||||
gen_intersection_list, api_get_domain, ensure_fqdn
|
||||
gen_intersection_list, api_get_domain, ensure_fqdn, netaddr, to_text
|
||||
|
||||
|
||||
def find_sudorule(module, name):
|
||||
@@ -236,7 +276,7 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
# present
|
||||
description=dict(required=False, type="str", default=None),
|
||||
@@ -245,14 +285,24 @@ def main():
|
||||
hostcategory=dict(required=False, type="str", default=None,
|
||||
choices=["all", ""], aliases=['hostcat']),
|
||||
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),
|
||||
allow_sudocmd=dict(required=False, type="list", default=None),
|
||||
deny_sudocmd=dict(required=False, type="list", default=None),
|
||||
allow_sudocmdgroup=dict(required=False, type="list", default=None),
|
||||
deny_sudocmdgroup=dict(required=False, type="list", default=None),
|
||||
host=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
hostgroup=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
hostmask=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
user=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
group=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
allow_sudocmd=dict(required=False, type="list", elements="str",
|
||||
default=None),
|
||||
deny_sudocmd=dict(required=False, type="list", elements="str",
|
||||
default=None),
|
||||
allow_sudocmdgroup=dict(required=False, type="list",
|
||||
elements="str", default=None),
|
||||
deny_sudocmdgroup=dict(required=False, type="list", elements="str",
|
||||
default=None),
|
||||
cmdcategory=dict(required=False, type="str", default=None,
|
||||
choices=["all", ""], aliases=['cmdcat']),
|
||||
runasusercategory=dict(required=False, type="str", default=None,
|
||||
@@ -261,11 +311,13 @@ def main():
|
||||
runasgroupcategory=dict(required=False, type="str", default=None,
|
||||
choices=["all", ""],
|
||||
aliases=['runasgroupcat']),
|
||||
runasuser=dict(required=False, type="list", default=None),
|
||||
runasgroup=dict(required=False, type="list", default=None),
|
||||
runasuser=dict(required=False, type="list", elements="str",
|
||||
default=None),
|
||||
runasgroup=dict(required=False, type="list", elements="str",
|
||||
default=None),
|
||||
order=dict(type="int", required=False, aliases=['sudoorder']),
|
||||
sudooption=dict(required=False, type='list', default=None,
|
||||
aliases=["options"]),
|
||||
sudooption=dict(required=False, type='list', elements="str",
|
||||
default=None, aliases=["options"]),
|
||||
action=dict(type="str", default="sudorule",
|
||||
choices=["member", "sudorule"]),
|
||||
# state
|
||||
@@ -298,6 +350,7 @@ def main():
|
||||
nomembers = ansible_module.params_get("nomembers") # noqa
|
||||
host = ansible_module.params_get("host")
|
||||
hostgroup = ansible_module.params_get_lowercase("hostgroup")
|
||||
hostmask = ansible_module.params_get("hostmask")
|
||||
user = ansible_module.params_get_lowercase("user")
|
||||
group = ansible_module.params_get_lowercase("group")
|
||||
allow_sudocmd = ansible_module.params_get('allow_sudocmd')
|
||||
@@ -315,6 +368,10 @@ def main():
|
||||
# state
|
||||
state = ansible_module.params_get("state")
|
||||
|
||||
# ensure hostmasks are network cidr
|
||||
if hostmask is not None:
|
||||
hostmask = [to_text(netaddr.IPNetwork(x).cidr) for x in hostmask]
|
||||
|
||||
# Check parameters
|
||||
invalid = []
|
||||
|
||||
@@ -346,7 +403,7 @@ def main():
|
||||
"cmdcategory", "runasusercategory",
|
||||
"runasgroupcategory", "nomembers", "order"]
|
||||
if action == "sudorule":
|
||||
invalid.extend(["host", "hostgroup", "user", "group",
|
||||
invalid.extend(["host", "hostgroup", "hostmask", "user", "group",
|
||||
"runasuser", "runasgroup", "allow_sudocmd",
|
||||
"allow_sudocmdgroup", "deny_sudocmd",
|
||||
"deny_sudocmdgroup", "sudooption"])
|
||||
@@ -360,7 +417,7 @@ def main():
|
||||
"disabled")
|
||||
invalid = ["description", "usercategory", "hostcategory",
|
||||
"cmdcategory", "runasusercategory", "runasgroupcategory",
|
||||
"nomembers", "nomembers", "host", "hostgroup",
|
||||
"nomembers", "nomembers", "host", "hostgroup", "hostmask",
|
||||
"user", "group", "allow_sudocmd", "allow_sudocmdgroup",
|
||||
"deny_sudocmd", "deny_sudocmdgroup", "runasuser",
|
||||
"runasgroup", "order", "sudooption"]
|
||||
@@ -389,6 +446,7 @@ def main():
|
||||
user_add, user_del = [], []
|
||||
group_add, group_del = [], []
|
||||
hostgroup_add, hostgroup_del = [], []
|
||||
hostmask_add, hostmask_del = [], []
|
||||
allow_cmd_add, allow_cmd_del = [], []
|
||||
allow_cmdgroup_add, allow_cmdgroup_del = [], []
|
||||
deny_cmd_add, deny_cmd_del = [], []
|
||||
@@ -454,6 +512,9 @@ def main():
|
||||
hostgroup_add, hostgroup_del = gen_add_del_lists(
|
||||
hostgroup, res_find.get('memberhost_hostgroup', []))
|
||||
|
||||
hostmask_add, hostmask_del = gen_add_del_lists(
|
||||
hostmask, res_find.get('hostmask', []))
|
||||
|
||||
user_add, user_del = gen_add_del_lists(
|
||||
user, res_find.get('memberuser_user', []))
|
||||
|
||||
@@ -520,6 +581,9 @@ def main():
|
||||
if hostgroup is not None:
|
||||
hostgroup_add = gen_add_list(
|
||||
hostgroup, res_find.get("memberhost_hostgroup"))
|
||||
if hostmask is not None:
|
||||
hostmask_add = gen_add_list(
|
||||
hostmask, res_find.get("hostmask"))
|
||||
if user is not None:
|
||||
user_add = gen_add_list(
|
||||
user, res_find.get("memberuser_user"))
|
||||
@@ -592,6 +656,10 @@ def main():
|
||||
hostgroup_del = gen_intersection_list(
|
||||
hostgroup, res_find.get("memberhost_hostgroup"))
|
||||
|
||||
if hostmask is not None:
|
||||
hostmask_del = gen_intersection_list(
|
||||
hostmask, res_find.get("hostmask"))
|
||||
|
||||
if user is not None:
|
||||
user_del = gen_intersection_list(
|
||||
user, res_find.get("memberuser_user"))
|
||||
@@ -683,18 +751,19 @@ def main():
|
||||
|
||||
# Manage members.
|
||||
# Manage hosts and hostgroups
|
||||
if host_add or hostgroup_add:
|
||||
commands.append([name, "sudorule_add_host",
|
||||
{
|
||||
"host": host_add,
|
||||
"hostgroup": hostgroup_add,
|
||||
}])
|
||||
if host_del or hostgroup_del:
|
||||
commands.append([name, "sudorule_remove_host",
|
||||
{
|
||||
"host": host_del,
|
||||
"hostgroup": hostgroup_del,
|
||||
}])
|
||||
if any([host_add, hostgroup_add, hostmask_add]):
|
||||
params = {"host": host_add, "hostgroup": hostgroup_add}
|
||||
# An empty Hostmask cannot be used, or IPA API will fail.
|
||||
if hostmask_add:
|
||||
params["hostmask"] = hostmask_add
|
||||
commands.append([name, "sudorule_add_host", params])
|
||||
|
||||
if any([host_del, hostgroup_del, hostmask_del]):
|
||||
params = {"host": host_del, "hostgroup": hostgroup_del}
|
||||
# An empty Hostmask cannot be used, or IPA API will fail.
|
||||
if hostmask_del:
|
||||
params["hostmask"] = hostmask_del
|
||||
commands.append([name, "sudorule_remove_host", params])
|
||||
|
||||
# Manage users and groups
|
||||
if user_add or group_add:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,36 +32,44 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipatopologysegment
|
||||
short description: Manage FreeIPA topology segments
|
||||
short_description: Manage FreeIPA topology segments
|
||||
description: Manage FreeIPA topology segments
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
suffix:
|
||||
description: Topology suffix
|
||||
type: str
|
||||
required: true
|
||||
choices: ["domain", "ca", "domain+ca"]
|
||||
name:
|
||||
description: Topology segment name, unique identifier.
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["cn"]
|
||||
left:
|
||||
description: Left replication node - an IPA server
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["leftnode"]
|
||||
right:
|
||||
description: Right replication node - an IPA server
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["rightnode"]
|
||||
direction:
|
||||
description: The direction a segment will be reinitialized
|
||||
type: str
|
||||
required: false
|
||||
choices: ["left-to-right", "right-to-left"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent", "enabled", "disabled", "reinitialized",
|
||||
"checked" ]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -178,7 +186,8 @@ def find_left_right_cn(module, suffix, left, right, name):
|
||||
def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
suffix=dict(choices=["domain", "ca", "domain+ca"], required=True),
|
||||
suffix=dict(type="str", choices=["domain", "ca", "domain+ca"],
|
||||
required=True),
|
||||
name=dict(type="str", aliases=["cn"], default=None),
|
||||
left=dict(type="str", aliases=["leftnode"], default=None),
|
||||
right=dict(type="str", aliases=["rightnode"], default=None),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,21 +32,23 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipatopologysuffix
|
||||
short description: Verify FreeIPA topology suffix
|
||||
short_description: Verify FreeIPA topology suffix
|
||||
description: Verify FreeIPA topology suffix
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
suffix:
|
||||
description: Topology suffix
|
||||
type: str
|
||||
required: true
|
||||
choices: ["domain", "ca"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: verified
|
||||
choices: ["verified"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -65,7 +67,7 @@ from ansible.module_utils.ansible_freeipa_module import IPAAnsibleModule
|
||||
def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
suffix=dict(choices=["domain", "ca"], required=True),
|
||||
suffix=dict(type="str", choices=["domain", "ca"], required=True),
|
||||
state=dict(type="str", default="verified",
|
||||
choices=["verified"]),
|
||||
),
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Rob Verduijn <rob.verduijn@gmail.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 By Rob Verduijn
|
||||
# Copyright (C) 2019-2022 By Rob Verduijn
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -39,62 +40,75 @@ options:
|
||||
realm:
|
||||
description:
|
||||
- Realm name
|
||||
type: str
|
||||
required: true
|
||||
trust_type:
|
||||
description:
|
||||
- Trust type (ad for Active Directory, default)
|
||||
type: str
|
||||
default: ad
|
||||
required: false
|
||||
choices: ["ad"]
|
||||
admin:
|
||||
description:
|
||||
- Active Directory domain administrator
|
||||
type: str
|
||||
required: false
|
||||
password:
|
||||
description:
|
||||
- Active Directory domain administrator's password
|
||||
type: str
|
||||
required: false
|
||||
server:
|
||||
description:
|
||||
- Domain controller for the Active Directory domain (optional)
|
||||
type: str
|
||||
required: false
|
||||
trust_secret:
|
||||
description:
|
||||
- Shared secret for the trust
|
||||
type: str
|
||||
required: false
|
||||
base_id:
|
||||
description:
|
||||
- First Posix ID of the range reserved for the trusted domain
|
||||
type: int
|
||||
required: false
|
||||
range_size:
|
||||
description:
|
||||
- Size of the ID range reserved for the trusted domain
|
||||
type: int
|
||||
default: 200000
|
||||
range_type:
|
||||
description:
|
||||
- Type of trusted domain ID range, one of ipa-ad-trust, ipa-ad-trust-posix
|
||||
type: str
|
||||
choices: ["ipa-ad-trust-posix", "ipa-ad-trust"]
|
||||
default: ipa-ad-trust
|
||||
required: false
|
||||
two_way:
|
||||
description:
|
||||
- Establish bi-directional trust. By default trust is inbound one-way only.
|
||||
type: bool
|
||||
default: false
|
||||
required: false
|
||||
choices: ["true", "false"]
|
||||
external:
|
||||
description:
|
||||
- Establish external trust to a domain in another forest.
|
||||
- The trust is not transitive beyond the domain.
|
||||
type: bool
|
||||
default: false
|
||||
required: false
|
||||
choices: ["true", "false"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
required: true
|
||||
required: false
|
||||
choices: ["present", "absent"]
|
||||
|
||||
author:
|
||||
- Rob Verduijn
|
||||
- Rob Verduijn (@RobVerduijn)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -188,7 +202,7 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
realm=dict(type="str", default=None, required=True),
|
||||
realm=dict(type="str", required=True),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,50 +32,68 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipauser
|
||||
short description: Manage FreeIPA users
|
||||
short_description: Manage FreeIPA users
|
||||
description: Manage FreeIPA users
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The list of users (internally uid).
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["login"]
|
||||
users:
|
||||
description: The list of user dicts (internally uid).
|
||||
options:
|
||||
type: list
|
||||
elements: dict
|
||||
suboptions:
|
||||
name:
|
||||
description: The user (internally uid).
|
||||
type: str
|
||||
required: true
|
||||
aliases: ["login"]
|
||||
first:
|
||||
description: The first name
|
||||
description: The first name. Required if user does not exist.
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["givenname"]
|
||||
last:
|
||||
description: The last name
|
||||
description: The last name. Required if user doesnot exst.
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["sn"]
|
||||
fullname:
|
||||
description: The full name
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["cn"]
|
||||
displayname:
|
||||
description: The display name
|
||||
type: str
|
||||
required: false
|
||||
initials:
|
||||
description: Initials
|
||||
type: str
|
||||
required: false
|
||||
homedir:
|
||||
description: The home directory
|
||||
type: str
|
||||
required: false
|
||||
shell:
|
||||
description: The login shell
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["loginshell"]
|
||||
email:
|
||||
description: List of email addresses
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
principal:
|
||||
description: The kerberos principal
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["principalname", "krbprincipalname"]
|
||||
principalexpiration:
|
||||
@@ -84,6 +102,7 @@ options:
|
||||
(possible formats: YYYYMMddHHmmssZ, YYYY-MM-ddTHH:mm:ssZ,
|
||||
YYYY-MM-ddTHH:mmZ, YYYY-MM-ddZ, YYYY-MM-dd HH:mm:ssZ,
|
||||
YYYY-MM-dd HH:mmZ) The trailing 'Z' can be skipped.
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["krbprincipalexpiration"]
|
||||
passwordexpiration:
|
||||
@@ -93,10 +112,12 @@ options:
|
||||
YYYY-MM-ddTHH:mmZ, YYYY-MM-ddZ, YYYY-MM-dd HH:mm:ssZ,
|
||||
YYYY-MM-dd HH:mmZ) The trailing 'Z' can be skipped.
|
||||
Only usable with IPA versions 4.7 and up.
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["krbpasswordexpiration"]
|
||||
password:
|
||||
description: The user password
|
||||
type: str
|
||||
required: false
|
||||
random:
|
||||
description: Generate a random user password
|
||||
@@ -104,57 +125,81 @@ options:
|
||||
type: bool
|
||||
uid:
|
||||
description: The UID
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["uidnumber"]
|
||||
gid:
|
||||
description: The GID
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["gidnumber"]
|
||||
city:
|
||||
description: City
|
||||
type: str
|
||||
required: false
|
||||
userstate:
|
||||
description: State/Province
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["st"]
|
||||
postalcode:
|
||||
description: Postalcode/ZIP
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["zip"]
|
||||
phone:
|
||||
description: List of telephone numbers
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["telephonenumber"]
|
||||
mobile:
|
||||
description: List of mobile telephone numbers
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
pager:
|
||||
description: List of pager numbers
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
fax:
|
||||
description: List of fax numbers
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["facsimiletelephonenumber"]
|
||||
orgunit:
|
||||
description: Org. Unit
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ou"]
|
||||
title:
|
||||
description: The job title
|
||||
type: str
|
||||
required: false
|
||||
manager:
|
||||
description: List of managers
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
carlicense:
|
||||
description: List of car licenses
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
sshpubkey:
|
||||
description: List of SSH public keys
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipasshpubkey"]
|
||||
userauthtype:
|
||||
description:
|
||||
List of supported user authentication types
|
||||
Use empty string to reset userauthtype to the initial value.
|
||||
type: list
|
||||
elements: str
|
||||
choices: ['password', 'radius', 'otp', '']
|
||||
required: false
|
||||
aliases: ["ipauserauthtype"]
|
||||
@@ -162,44 +207,65 @@ options:
|
||||
description:
|
||||
- User category
|
||||
- (semantics placed on this attribute are for local interpretation)
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["class"]
|
||||
radius:
|
||||
description: RADIUS proxy configuration
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ipatokenradiusconfiglink"]
|
||||
radiususer:
|
||||
description: RADIUS proxy username
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["radiususername", "ipatokenradiususername"]
|
||||
departmentnumber:
|
||||
description: Department Number
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
employeenumber:
|
||||
description: Employee Number
|
||||
type: str
|
||||
required: false
|
||||
employeetype:
|
||||
description: Employee Type
|
||||
type: str
|
||||
required: false
|
||||
preferredlanguage:
|
||||
description: Preferred Language
|
||||
type: str
|
||||
required: false
|
||||
certificate:
|
||||
description: List of base-64 encoded user certificates
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["usercertificate"]
|
||||
certmapdata:
|
||||
description:
|
||||
- List of certificate mappings
|
||||
- Only usable with IPA versions 4.5 and up.
|
||||
options:
|
||||
type: list
|
||||
elements: dict
|
||||
suboptions:
|
||||
certificate:
|
||||
description: Base-64 encoded user certificate
|
||||
type: str
|
||||
required: false
|
||||
issuer:
|
||||
description: Issuer of the certificate
|
||||
type: str
|
||||
required: false
|
||||
subject:
|
||||
description: Subject of the certificate
|
||||
type: str
|
||||
required: false
|
||||
data:
|
||||
description: Certmap data
|
||||
type: str
|
||||
required: false
|
||||
required: false
|
||||
noprivate:
|
||||
@@ -212,35 +278,46 @@ options:
|
||||
type: bool
|
||||
required: false
|
||||
first:
|
||||
description: The first name
|
||||
description: The first name. Required if user does not exist.
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["givenname"]
|
||||
last:
|
||||
description: The last name
|
||||
description: The last name. Required if user doesnot exst.
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["sn"]
|
||||
fullname:
|
||||
description: The full name
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["cn"]
|
||||
displayname:
|
||||
description: The display name
|
||||
type: str
|
||||
required: false
|
||||
initials:
|
||||
description: Initials
|
||||
type: str
|
||||
required: false
|
||||
homedir:
|
||||
description: The home directory
|
||||
type: str
|
||||
required: false
|
||||
shell:
|
||||
description: The login shell
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["loginshell"]
|
||||
email:
|
||||
description: List of email addresses
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
principal:
|
||||
description: The kerberos principal
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["principalname", "krbprincipalname"]
|
||||
principalexpiration:
|
||||
@@ -249,6 +326,7 @@ options:
|
||||
(possible formats: YYYYMMddHHmmssZ, YYYY-MM-ddTHH:mm:ssZ,
|
||||
YYYY-MM-ddTHH:mmZ, YYYY-MM-ddZ, YYYY-MM-dd HH:mm:ssZ,
|
||||
YYYY-MM-dd HH:mmZ) The trailing 'Z' can be skipped.
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["krbprincipalexpiration"]
|
||||
passwordexpiration:
|
||||
@@ -258,10 +336,12 @@ options:
|
||||
YYYY-MM-ddTHH:mmZ, YYYY-MM-ddZ, YYYY-MM-dd HH:mm:ssZ,
|
||||
YYYY-MM-dd HH:mmZ) The trailing 'Z' can be skipped.
|
||||
Only usable with IPA versions 4.7 and up.
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["krbpasswordexpiration"]
|
||||
password:
|
||||
description: The user password
|
||||
type: str
|
||||
required: false
|
||||
random:
|
||||
description: Generate a random user password
|
||||
@@ -269,57 +349,81 @@ options:
|
||||
type: bool
|
||||
uid:
|
||||
description: The UID
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["uidnumber"]
|
||||
gid:
|
||||
description: The GID
|
||||
type: int
|
||||
required: false
|
||||
aliases: ["gidnumber"]
|
||||
city:
|
||||
description: City
|
||||
type: str
|
||||
required: false
|
||||
userstate:
|
||||
description: State/Province
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["st"]
|
||||
postalcode:
|
||||
description: ZIP
|
||||
description: Postalcode/ZIP
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["zip"]
|
||||
phone:
|
||||
description: List of telephone numbers
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["telephonenumber"]
|
||||
mobile:
|
||||
description: List of mobile telephone numbers
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
pager:
|
||||
description: List of pager numbers
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
fax:
|
||||
description: List of fax numbers
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["facsimiletelephonenumber"]
|
||||
orgunit:
|
||||
description: Org. Unit
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ou"]
|
||||
title:
|
||||
description: The job title
|
||||
type: str
|
||||
required: false
|
||||
manager:
|
||||
description: List of managers
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
carlicense:
|
||||
description: List of car licenses
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
sshpubkey:
|
||||
description: List of SSH public keys
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ipasshpubkey"]
|
||||
userauthtype:
|
||||
description:
|
||||
List of supported user authentication types
|
||||
Use empty string to reset userauthtype to the initial value.
|
||||
type: list
|
||||
elements: str
|
||||
choices: ['password', 'radius', 'otp', '']
|
||||
required: false
|
||||
aliases: ["ipauserauthtype"]
|
||||
@@ -327,44 +431,65 @@ options:
|
||||
description:
|
||||
- User category
|
||||
- (semantics placed on this attribute are for local interpretation)
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["class"]
|
||||
radius:
|
||||
description: RADIUS proxy configuration
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ipatokenradiusconfiglink"]
|
||||
radiususer:
|
||||
description: RADIUS proxy username
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["radiususername", "ipatokenradiususername"]
|
||||
departmentnumber:
|
||||
description: Department Number
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
employeenumber:
|
||||
description: Employee Number
|
||||
type: str
|
||||
required: false
|
||||
employeetype:
|
||||
description: Employee Type
|
||||
type: str
|
||||
required: false
|
||||
preferredlanguage:
|
||||
description: Preferred Language
|
||||
type: str
|
||||
required: false
|
||||
certificate:
|
||||
description: List of base-64 encoded user certificates
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
aliases: ["usercertificate"]
|
||||
certmapdata:
|
||||
description:
|
||||
- List of certificate mappings
|
||||
- Only usable with IPA versions 4.5 and up.
|
||||
options:
|
||||
type: list
|
||||
elements: dict
|
||||
suboptions:
|
||||
certificate:
|
||||
description: Base-64 encoded user certificate
|
||||
type: str
|
||||
required: false
|
||||
issuer:
|
||||
description: Issuer of the certificate
|
||||
type: str
|
||||
required: false
|
||||
subject:
|
||||
description: Subject of the certificate
|
||||
type: str
|
||||
required: false
|
||||
data:
|
||||
description: Certmap data
|
||||
type: str
|
||||
required: false
|
||||
required: false
|
||||
noprivate:
|
||||
@@ -378,24 +503,27 @@ options:
|
||||
preserve:
|
||||
description: Delete a user, keeping the entry available for future use
|
||||
required: false
|
||||
type: bool
|
||||
update_password:
|
||||
description:
|
||||
Set password for a user in present state only on creation or always
|
||||
default: "always"
|
||||
type: str
|
||||
choices: ["always", "on_create"]
|
||||
required: false
|
||||
action:
|
||||
description: Work on user or member level
|
||||
type: str
|
||||
default: "user"
|
||||
choices: ["member", "user"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent",
|
||||
"enabled", "disabled",
|
||||
"unlocked", "undeleted"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -457,17 +585,19 @@ user:
|
||||
description: User dict with random password
|
||||
returned: If random is yes and user did not exist or update_password is yes
|
||||
type: dict
|
||||
options:
|
||||
contains:
|
||||
randompassword:
|
||||
description: The generated random password
|
||||
type: str
|
||||
returned: If only one user is handled by the module
|
||||
name:
|
||||
description: The user name of the user that got a new random password
|
||||
returned: If several users are handled by the module
|
||||
type: dict
|
||||
options:
|
||||
contains:
|
||||
randompassword:
|
||||
description: The generated random password
|
||||
type: str
|
||||
returned: always
|
||||
"""
|
||||
|
||||
@@ -752,16 +882,16 @@ def main():
|
||||
initials=dict(type="str", default=None),
|
||||
homedir=dict(type="str", default=None),
|
||||
shell=dict(type="str", aliases=["loginshell"], default=None),
|
||||
email=dict(type="list", default=None),
|
||||
principal=dict(type="list", aliases=["principalname",
|
||||
"krbprincipalname"],
|
||||
email=dict(type="list", elements="str", default=None),
|
||||
principal=dict(type="list", elements="str",
|
||||
aliases=["principalname", "krbprincipalname"],
|
||||
default=None),
|
||||
principalexpiration=dict(type="str",
|
||||
aliases=["krbprincipalexpiration"],
|
||||
default=None),
|
||||
passwordexpiration=dict(type="str",
|
||||
aliases=["krbpasswordexpiration"],
|
||||
default=None),
|
||||
default=None, no_log=False),
|
||||
password=dict(type="str", default=None, no_log=True),
|
||||
random=dict(type='bool', default=None),
|
||||
uid=dict(type="int", aliases=["uidnumber"], default=None),
|
||||
@@ -769,33 +899,34 @@ def main():
|
||||
city=dict(type="str", default=None),
|
||||
userstate=dict(type="str", aliases=["st"], default=None),
|
||||
postalcode=dict(type="str", aliases=["zip"], default=None),
|
||||
phone=dict(type="list", aliases=["telephonenumber"], default=None),
|
||||
mobile=dict(type="list", default=None),
|
||||
pager=dict(type="list", default=None),
|
||||
fax=dict(type="list", aliases=["facsimiletelephonenumber"],
|
||||
default=None),
|
||||
phone=dict(type="list", elements="str", aliases=["telephonenumber"],
|
||||
default=None),
|
||||
mobile=dict(type="list", elements="str", default=None),
|
||||
pager=dict(type="list", elements="str", default=None),
|
||||
fax=dict(type="list", elements="str",
|
||||
aliases=["facsimiletelephonenumber"], default=None),
|
||||
orgunit=dict(type="str", aliases=["ou"], default=None),
|
||||
title=dict(type="str", default=None),
|
||||
manager=dict(type="list", default=None),
|
||||
carlicense=dict(type="list", default=None),
|
||||
sshpubkey=dict(type="list", aliases=["ipasshpubkey"],
|
||||
manager=dict(type="list", elements="str", default=None),
|
||||
carlicense=dict(type="list", elements="str", default=None),
|
||||
sshpubkey=dict(type="list", elements="str", aliases=["ipasshpubkey"],
|
||||
default=None),
|
||||
userauthtype=dict(type='list', aliases=["ipauserauthtype"],
|
||||
default=None,
|
||||
userauthtype=dict(type='list', elements="str",
|
||||
aliases=["ipauserauthtype"], default=None,
|
||||
choices=['password', 'radius', 'otp', '']),
|
||||
userclass=dict(type="list", aliases=["class"],
|
||||
userclass=dict(type="list", elements="str", aliases=["class"],
|
||||
default=None),
|
||||
radius=dict(type="str", aliases=["ipatokenradiusconfiglink"],
|
||||
default=None),
|
||||
radiususer=dict(type="str", aliases=["radiususername",
|
||||
"ipatokenradiususername"],
|
||||
default=None),
|
||||
departmentnumber=dict(type="list", default=None),
|
||||
departmentnumber=dict(type="list", elements="str", default=None),
|
||||
employeenumber=dict(type="str", default=None),
|
||||
employeetype=dict(type="str", default=None),
|
||||
preferredlanguage=dict(type="str", default=None),
|
||||
certificate=dict(type="list", aliases=["usercertificate"],
|
||||
default=None),
|
||||
certificate=dict(type="list", elements="str",
|
||||
aliases=["usercertificate"], default=None),
|
||||
certmapdata=dict(type="list", default=None,
|
||||
options=dict(
|
||||
# Here certificate is a simple string
|
||||
@@ -812,14 +943,14 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", aliases=["login"], default=None,
|
||||
required=False),
|
||||
name=dict(type="list", elements="str", aliases=["login"],
|
||||
default=None, required=False),
|
||||
users=dict(type="list",
|
||||
aliases=["login"],
|
||||
default=None,
|
||||
options=dict(
|
||||
# Here name is a simple string
|
||||
name=dict(type="str", required=True),
|
||||
name=dict(type="str", required=True,
|
||||
aliases=["login"]),
|
||||
# Add user specific parameters
|
||||
**user_spec
|
||||
),
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,130 +33,142 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipavault
|
||||
short description: Manage vaults and secret vaults.
|
||||
short_description: Manage vaults and secret vaults.
|
||||
description: Manage vaults and secret vaults. KRA service must be enabled.
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
name:
|
||||
description: The vault name
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: The vault description
|
||||
type: str
|
||||
required: false
|
||||
public_key:
|
||||
vault_public_key:
|
||||
description: Base64 encode public key.
|
||||
required: false
|
||||
type: string
|
||||
aliases: ["ipavaultpublickey", "vault_public_key"]
|
||||
public_key_file:
|
||||
type: str
|
||||
aliases: ["ipavaultpublickey", "public_key", "new_public_key"]
|
||||
vault_public_key_file:
|
||||
description: Path to file with public key.
|
||||
required: false
|
||||
type: string
|
||||
aliases: ["vault_public_key_file"]
|
||||
type: str
|
||||
aliases: ["public_key_file", "new_public_key_file"]
|
||||
private_key:
|
||||
description: Base64 encode private key.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
aliases: ["ipavaultprivatekey", "vault_private_key"]
|
||||
private_key_file:
|
||||
description: Path to file with private key.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
aliases: ["vault_private_key_file"]
|
||||
password:
|
||||
description: password to be used on symmetric vault.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
aliases: ["ipavaultpassword", "vault_password", "old_password"]
|
||||
password_file:
|
||||
description: file with password to be used on symmetric vault.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
aliases: ["vault_password_file", "old_password_file"]
|
||||
new_password:
|
||||
description: new password to be used on symmetric vault.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
new_password_file:
|
||||
description: file with new password to be used on symmetric vault.
|
||||
required: false
|
||||
type: string
|
||||
salt:
|
||||
type: str
|
||||
vault_salt:
|
||||
description: Vault salt.
|
||||
required: false
|
||||
type: list
|
||||
aliases: ["ipavaultsalt", "vault_salt"]
|
||||
type: str
|
||||
aliases: ["ipavaultsalt", "salt"]
|
||||
vault_type:
|
||||
description: Vault types are based on security level.
|
||||
required: true
|
||||
default: symmetric
|
||||
type: str
|
||||
required: false
|
||||
choices: ["standard", "symmetric", "asymmetric"]
|
||||
aliases: ["ipavaulttype"]
|
||||
service:
|
||||
description: Any service can own one or more service vaults.
|
||||
required: false
|
||||
type: list
|
||||
type: str
|
||||
username:
|
||||
description: Any user can own one or more user vaults.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
aliases: ["user"]
|
||||
shared:
|
||||
description: Vault is shared.
|
||||
required: false
|
||||
type: boolean
|
||||
type: bool
|
||||
users:
|
||||
description: Users that are member of the vault.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
groups:
|
||||
description: Groups that are member of the vault.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
owners:
|
||||
description: Users that are owners of the vault.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["ownerusers"]
|
||||
ownergroups:
|
||||
description: Groups that are owners of the vault.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
ownerservices:
|
||||
description: Services that are owners of the vault.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
services:
|
||||
description: Services that are member of the container.
|
||||
required: false
|
||||
type: list
|
||||
elements: str
|
||||
data:
|
||||
description: Data to be stored in the vault.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
aliases: ["ipavaultdata", "vault_data"]
|
||||
in:
|
||||
description: Path to file with data to be stored in the vault.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
aliases: ["datafile_in"]
|
||||
out:
|
||||
description: Path to file to store data retrieved from the vault.
|
||||
required: false
|
||||
type: string
|
||||
type: str
|
||||
aliases: ["datafile_out"]
|
||||
action:
|
||||
description: Work on vault or member level.
|
||||
type: str
|
||||
default: vault
|
||||
choices: ["vault", "member"]
|
||||
choices: ["vault", "data", "member"]
|
||||
state:
|
||||
description: State to ensure
|
||||
type: str
|
||||
default: present
|
||||
choices: ["present", "absent", "retrieved"]
|
||||
author:
|
||||
- Rafael Jeffman
|
||||
- Rafael Guterres Jeffman (@rjeffman)
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -307,11 +320,11 @@ vault:
|
||||
description: Vault dict with archived data.
|
||||
returned: If state is `retrieved`.
|
||||
type: dict
|
||||
options:
|
||||
contains:
|
||||
data:
|
||||
description: The vault data.
|
||||
returned: always
|
||||
type: string
|
||||
type: str
|
||||
"""
|
||||
|
||||
import os
|
||||
@@ -525,7 +538,7 @@ def check_encryption_params( # pylint: disable=unused-argument
|
||||
|
||||
if (
|
||||
salt is not None
|
||||
and not(
|
||||
and not (
|
||||
any([password, password_file])
|
||||
and any([new_password, new_password_file])
|
||||
)
|
||||
@@ -587,7 +600,7 @@ def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# generalgroups
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
name=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=True),
|
||||
|
||||
description=dict(required=False, type="str", default=None),
|
||||
@@ -614,13 +627,19 @@ def main():
|
||||
service=dict(type="str", required=False, default=None),
|
||||
shared=dict(type="bool", required=False, default=None),
|
||||
|
||||
users=dict(required=False, type='list', default=None),
|
||||
groups=dict(required=False, type='list', default=None),
|
||||
services=dict(required=False, type='list', default=None),
|
||||
owners=dict(required=False, type='list', default=None,
|
||||
users=dict(required=False, type="list", elements="str",
|
||||
default=None),
|
||||
groups=dict(required=False, type="list", elements="str",
|
||||
default=None),
|
||||
services=dict(required=False, type="list", elements="str",
|
||||
default=None),
|
||||
owners=dict(required=False, type="list", elements="str",
|
||||
default=None,
|
||||
aliases=['ownerusers']),
|
||||
ownergroups=dict(required=False, type='list', default=None),
|
||||
ownerservices=dict(required=False, type='list', default=None),
|
||||
ownergroups=dict(required=False, type="list", elements="str",
|
||||
default=None),
|
||||
ownerservices=dict(required=False, type="list", elements="str",
|
||||
default=None),
|
||||
vault_data=dict(type="str", required=False, default=None,
|
||||
no_log=True, aliases=['ipavaultdata', 'data']),
|
||||
datafile_in=dict(type="str", required=False, default=None,
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
ipdb==0.13.4
|
||||
pre-commit
|
||||
flake8==4.0.1
|
||||
flake8-bugbear
|
||||
flake8-bugbear==22.10.27
|
||||
pylint==2.13.7
|
||||
wrapt >= 1.14.0
|
||||
pydocstyle==6.0.0
|
||||
yamllint==1.26.3
|
||||
ansible-lint==5.3.2
|
||||
dnspython==2.2.0
|
||||
netaddr==0.8.0
|
||||
gssapi==1.7.2
|
||||
|
||||
3
requirements-docker.yml
Normal file
3
requirements-docker.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
collections:
|
||||
- name: community.docker
|
||||
3
requirements-podman.yml
Normal file
3
requirements-podman.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
collections:
|
||||
- name: containers.podman
|
||||
@@ -1,6 +1,7 @@
|
||||
-r requirements.txt
|
||||
pytest>=2.7
|
||||
pytest-sourceorder>=0.5
|
||||
pytest-split-tests>=1.0.3
|
||||
pytest-split>=0.8.0
|
||||
pytest-custom_exit_code>=0.3.0
|
||||
pytest-testinfra>=5.0
|
||||
pyyaml>=3
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2021 Red Hat
|
||||
# Copyright (C) 2021-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,13 +32,12 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipabackup_get_backup_dir
|
||||
short description:
|
||||
short_description:
|
||||
Get IPA_BACKUP_DIR from ipaplatform
|
||||
description:
|
||||
Get IPA_BACKUP_DIR from ipaplatform
|
||||
options:
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -56,7 +55,13 @@ backup_dir:
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ipaplatform.paths import paths
|
||||
try:
|
||||
from ipaplatform.paths import paths
|
||||
except ImportError as _err:
|
||||
MODULE_IMPORT_ERROR = str(_err)
|
||||
paths = None
|
||||
else:
|
||||
MODULE_IMPORT_ERROR = None
|
||||
|
||||
|
||||
def main():
|
||||
@@ -65,6 +70,9 @@ def main():
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
if MODULE_IMPORT_ERROR is not None:
|
||||
module.fail_json(msg=MODULE_IMPORT_ERROR)
|
||||
|
||||
module.exit_json(changed=False,
|
||||
backup_dir=paths.IPA_BACKUP_DIR)
|
||||
|
||||
|
||||
@@ -26,6 +26,12 @@
|
||||
fail: msg="ipabackup_from_controller and ipabackup_to_controller are set"
|
||||
when: ipabackup_from_controller | bool and ipabackup_to_controller | bool
|
||||
|
||||
- name: Fail for given ipabackup_name if state is not copied, restored or absent
|
||||
fail: msg="ipabackup_name is given and state is not copied, restored or absent"
|
||||
when: state is not defined or
|
||||
(state != "copied" and state != "restored" and state != "absent") and
|
||||
ipabackup_name is defined
|
||||
|
||||
- name: Get ipabackup_dir from IPA installation
|
||||
include_tasks: "{{ role_path }}/tasks/get_ipabackup_dir.yml"
|
||||
|
||||
@@ -33,12 +39,6 @@
|
||||
include_tasks: "{{ role_path }}/tasks/backup.yml"
|
||||
when: state|default("present") == "present"
|
||||
|
||||
- name: Fail for given ipabackup_name if state is not copied, restored or absent
|
||||
fail: msg="ipabackup_name is given and state is not copied, restored or absent"
|
||||
when: state is not defined or
|
||||
(state != "copied" and state != "restored" and state != "absent") and
|
||||
ipabackup_name is defined
|
||||
|
||||
- name: Fail on missing ipabackup_name
|
||||
fail: msg="ipabackup_name is not set"
|
||||
when: (ipabackup_name is not defined or not ipabackup_name) and
|
||||
|
||||
@@ -11,6 +11,7 @@ Features
|
||||
* Client deployment
|
||||
* One-time-password (OTP) support
|
||||
* Repair mode
|
||||
* DNS resolver configuration support
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
@@ -32,7 +33,6 @@ Requirements
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.8+
|
||||
* /usr/bin/kinit is required on the controller if a one time password (OTP) is used
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
@@ -107,6 +107,40 @@ Example playbook to setup the IPA client(s) using principal and password from in
|
||||
state: present
|
||||
```
|
||||
|
||||
Example inventory file with configuration of dns resolvers:
|
||||
|
||||
```ini
|
||||
[ipaclients]
|
||||
ipaclient1.example.com
|
||||
ipaclient2.example.com
|
||||
|
||||
[ipaservers]
|
||||
ipaserver.example.com
|
||||
|
||||
[ipaclients:vars]
|
||||
ipaadmin_principal=admin
|
||||
ipaadmin_password=MySecretPassword123
|
||||
ipaclient_domain=example.com
|
||||
ipaclient_configure_dns_resolver=yes
|
||||
ipaclient_dns_servers=192.168.100.1
|
||||
```
|
||||
|
||||
Example inventory file with cleanup of dns resolvers:
|
||||
|
||||
```ini
|
||||
[ipaclients]
|
||||
ipaclient1.example.com
|
||||
ipaclient2.example.com
|
||||
|
||||
[ipaservers]
|
||||
ipaserver.example.com
|
||||
|
||||
[ipaclients:vars]
|
||||
ipaadmin_principal=admin
|
||||
ipaadmin_password=MySecretPassword123
|
||||
ipaclient_domain=example.com
|
||||
ipaclient_cleanup_dns_resolver=yes
|
||||
```
|
||||
|
||||
Playbooks
|
||||
=========
|
||||
@@ -172,7 +206,7 @@ Server Variables
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaservers` | This group is a list of the IPA server full qualified host names. In a topology with a chain of servers and replicas, it is important to use the right server or replica as the server for the client. If there is a need to overwrite the setting for a client in the `ipaclients` group, please use the list `ipaclient_servers` explained below. If no `ipaservers` group is defined than the installation preparation step will try to use DNS autodiscovery to identify the the IPA server using DNS txt records. | mostly
|
||||
`ipaadmin_keytab` | The string variable enables the use of an admin keytab as an alternative authentication method. The variable needs to contain the local path to the keytab file. If `ipaadmin_keytab` is used, then `ipaadmin_password` does not need to be set. If `ipaadmin_keytab` is used with `ipaclient_use_otp: yes` then the keytab needs to be available on the controller, else on the client node. The use of full path names is recommended. | no
|
||||
`ipaadmin_keytab` | The string variable enables the use of an admin keytab as an alternative authentication method. The variable needs to contain the local path to the keytab file. If `ipaadmin_keytab` is used, then `ipaadmin_password` does not need to be set. If `ipaadmin_keytab` is used with `ipaclient_use_otp: yes` then the keytab needs to be available on the controller, else on the client node. The use of full path names is recommended. | no
|
||||
`ipaadmin_principal` | The string variable only needs to be set if the name of the Kerberos admin principal is not "admin". If `ipaadmin_principal` is not set it will be set internally to "admin". | no
|
||||
`ipaadmin_password` | The string variable contains the Kerberos password of the Kerberos admin principal. If `ipaadmin_keytab` is used, then `ipaadmin_password` does not need to be set. | mostly
|
||||
|
||||
@@ -198,6 +232,9 @@ Variable | Description | Required
|
||||
`ipaclient_allow_repair` | The bool value defines if an already joined or partly set-up client can be repaired. `ipaclient_allow_repair` defaults to `no`. Contrary to `ipaclient_force_join=yes` the host entry will not be changed on the server. | no
|
||||
`ipaclient_install_packages` | The bool value defines if the needed packages are installed on the node. `ipaclient_install_packages` defaults to `yes`. | no
|
||||
`ipaclient_on_master` | The bool value is only used in the server and replica installation process to install the client part. It should not be set otherwise. `ipaclient_on_master` defaults to `no`. | no
|
||||
`ipaclient_configure_dns_resolver` | The bool value defines if the DNS resolver is configured. This is useful if the IPA server has internal DNS support. `ipaclient_dns_server` need to be set also. The installation of packages is happening before the DNS resolver is configured, therefore package installation needs to be possible without the configuration of the DNS resolver. The DNS nameservers are configured for `NetworkManager`, `systemd-resolved` (if installed and enabled) and `/etc/resolv.conf` if neither NetworkManager nor systemd-resolved is used. | no
|
||||
`ipaclient_dns_servers` | The list of DNS server IP addresses. This is only useful with `ipaclient_configure_dns_resolver`. | no
|
||||
`ipaclient_cleanup_dns_resolver` | The bool value defines if DNS resolvers that have been configured before with `ipaclient_configure_dns_resolver` will be cleaned up again. | no
|
||||
|
||||
|
||||
Authors
|
||||
|
||||
@@ -1,247 +0,0 @@
|
||||
# Authors:
|
||||
# Florence Blanc-Renaud <frenaud@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
from jinja2 import Template
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.plugins.action import ActionBase
|
||||
|
||||
|
||||
def run_cmd(args, stdin=None):
|
||||
"""Execute an external command."""
|
||||
p_in = None
|
||||
p_out = subprocess.PIPE
|
||||
p_err = subprocess.PIPE
|
||||
|
||||
if stdin:
|
||||
p_in = subprocess.PIPE
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
with subprocess.Popen(
|
||||
args, stdin=p_in, stdout=p_out, stderr=p_err, close_fds=True
|
||||
) as p:
|
||||
__temp, stderr = p.communicate(stdin)
|
||||
|
||||
if p.returncode != 0:
|
||||
raise RuntimeError(stderr)
|
||||
|
||||
|
||||
def kinit_password(principal, password, ccache_name, config):
|
||||
"""
|
||||
Perform kinit using principal/password.
|
||||
|
||||
It uses the specified config file to kinit and stores the TGT
|
||||
in ccache_name.
|
||||
"""
|
||||
args = ["/usr/bin/kinit", principal, '-c', ccache_name]
|
||||
old_config = os.environ.get('KRB5_CONFIG')
|
||||
os.environ['KRB5_CONFIG'] = config
|
||||
|
||||
try:
|
||||
return run_cmd(args, stdin=password.encode())
|
||||
finally:
|
||||
if old_config is not None:
|
||||
os.environ['KRB5_CONFIG'] = old_config
|
||||
else:
|
||||
os.environ.pop('KRB5_CONFIG', None)
|
||||
|
||||
|
||||
def kinit_keytab(principal, keytab, ccache_name, config):
|
||||
"""
|
||||
Perform kinit using principal/keytab.
|
||||
|
||||
It uses the specified config file to kinit and stores the TGT
|
||||
in ccache_name.
|
||||
"""
|
||||
args = ["/usr/bin/kinit", "-kt", keytab, "-c", ccache_name, principal]
|
||||
old_config = os.environ.get('KRB5_CONFIG')
|
||||
os.environ["KRB5_CONFIG"] = config
|
||||
|
||||
try:
|
||||
return run_cmd(args)
|
||||
finally:
|
||||
if old_config is not None:
|
||||
os.environ["KRB5_CONFIG"] = old_config
|
||||
else:
|
||||
os.environ.pop("KRB5_CONFIG", None)
|
||||
|
||||
|
||||
KRB5CONF_TEMPLATE = """
|
||||
[logging]
|
||||
default = FILE:/var/log/krb5libs.log
|
||||
kdc = FILE:/var/log/krb5kdc.log
|
||||
admin_server = FILE:/var/log/kadmind.log
|
||||
|
||||
[libdefaults]
|
||||
default_realm = {{ ipa_realm }}
|
||||
dns_lookup_realm = false
|
||||
dns_lookup_kdc = true
|
||||
rdns = false
|
||||
ticket_lifetime = {{ ipa_lifetime }}
|
||||
forwardable = true
|
||||
udp_preference_limit = 0
|
||||
default_ccache_name = KEYRING:persistent:%{uid}
|
||||
|
||||
[realms]
|
||||
{{ ipa_realm }} = {
|
||||
kdc = {{ ipa_server }}:88
|
||||
master_kdc = {{ ipa_server }}:88
|
||||
admin_server = {{ ipa_server }}:749
|
||||
default_domain = {{ ipa_domain }}
|
||||
}
|
||||
|
||||
[domain_realm]
|
||||
.{{ ipa_domain }} = {{ ipa_realm }}
|
||||
{{ ipa_domain }} = {{ ipa_realm }}
|
||||
"""
|
||||
|
||||
|
||||
class ActionModule(ActionBase): # pylint: disable=too-few-public-methods
|
||||
|
||||
# pylint: disable=too-many-return-statements
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
"""
|
||||
Handle credential cache transfer.
|
||||
|
||||
ipa* commands can either provide a password or a keytab file
|
||||
in order to authenticate on the managed node with Kerberos.
|
||||
The module is using these credentials to obtain a TGT locally on the
|
||||
control node:
|
||||
- need to create a krb5.conf Kerberos client configuration that is
|
||||
using IPA server
|
||||
- set the environment variable KRB5_CONFIG to point to this conf file
|
||||
- set the environment variable KRB5CCNAME to use a specific cache
|
||||
- perform kinit on the control node
|
||||
This command creates the credential cache file
|
||||
- copy the credential cache file on the managed node
|
||||
|
||||
Then the IPA commands can use this credential cache file.
|
||||
"""
|
||||
if task_vars is None:
|
||||
task_vars = {}
|
||||
|
||||
# pylint: disable=super-with-arguments
|
||||
result = super(ActionModule, self).run(tmp, task_vars)
|
||||
principal = self._task.args.get('principal', None)
|
||||
keytab = self._task.args.get('keytab', None)
|
||||
password = self._task.args.get('password', None)
|
||||
lifetime = self._task.args.get('lifetime', '1h')
|
||||
|
||||
if (not keytab and not password):
|
||||
result['failed'] = True
|
||||
result['msg'] = "keytab or password is required"
|
||||
return result
|
||||
|
||||
if not principal:
|
||||
result['failed'] = True
|
||||
result['msg'] = "principal is required"
|
||||
return result
|
||||
|
||||
data = self._execute_module(module_name='ipaclient_get_facts',
|
||||
module_args={}, task_vars=task_vars)
|
||||
|
||||
try:
|
||||
domain = data['ansible_facts']['ipa']['domain']
|
||||
realm = data['ansible_facts']['ipa']['realm']
|
||||
except KeyError:
|
||||
result['failed'] = True
|
||||
result['msg'] = "The host is not an IPA server"
|
||||
return result
|
||||
|
||||
items = principal.split('@')
|
||||
if len(items) < 2:
|
||||
principal = str('%s@%s' % (principal, realm))
|
||||
|
||||
# Locally create a temp directory to store krb5.conf and ccache
|
||||
local_temp_dir = tempfile.mkdtemp()
|
||||
krb5conf_name = os.path.join(local_temp_dir, 'krb5.conf')
|
||||
ccache_name = os.path.join(local_temp_dir, 'ccache')
|
||||
|
||||
# Create the krb5.conf from the template
|
||||
template = Template(KRB5CONF_TEMPLATE)
|
||||
content = template.render(dict(
|
||||
ipa_server=task_vars['ansible_host'],
|
||||
ipa_domain=domain,
|
||||
ipa_realm=realm,
|
||||
ipa_lifetime=lifetime))
|
||||
|
||||
with open(krb5conf_name, 'w') as f: # pylint: disable=invalid-name
|
||||
f.write(content)
|
||||
|
||||
if password:
|
||||
try:
|
||||
# perform kinit -c ccache_name -l 1h principal
|
||||
kinit_password(principal, password, ccache_name,
|
||||
krb5conf_name)
|
||||
except Exception as e:
|
||||
result['failed'] = True
|
||||
result['msg'] = 'kinit %s with password failed: %s' % \
|
||||
(principal, to_native(e))
|
||||
return result
|
||||
|
||||
else:
|
||||
# Password not supplied, need to use the keytab file
|
||||
# Check if the source keytab exists
|
||||
try:
|
||||
keytab = self._find_needle('files', keytab)
|
||||
except AnsibleError as e:
|
||||
result['failed'] = True
|
||||
result['msg'] = to_native(e)
|
||||
return result
|
||||
# perform kinit -kt keytab
|
||||
try:
|
||||
kinit_keytab(principal, keytab, ccache_name, krb5conf_name)
|
||||
except Exception as e:
|
||||
result['failed'] = True
|
||||
result['msg'] = 'kinit %s with keytab %s failed: %s' % \
|
||||
(principal, keytab, str(e))
|
||||
return result
|
||||
|
||||
try:
|
||||
# Create the remote tmp dir
|
||||
tmp = self._make_tmp_path()
|
||||
tmp_ccache = self._connection._shell.join_path(
|
||||
tmp, os.path.basename(ccache_name))
|
||||
|
||||
# Copy the ccache to the remote tmp dir
|
||||
self._transfer_file(ccache_name, tmp_ccache)
|
||||
self._fixup_perms2((tmp, tmp_ccache))
|
||||
|
||||
new_module_args = self._task.args.copy()
|
||||
new_module_args.pop('password', None)
|
||||
new_module_args.pop('keytab', None)
|
||||
new_module_args.pop('lifetime', None)
|
||||
new_module_args.update(ccache=tmp_ccache)
|
||||
|
||||
# Execute module
|
||||
result.update(self._execute_module(module_args=new_module_args,
|
||||
task_vars=task_vars))
|
||||
return result
|
||||
finally:
|
||||
# delete the local temp directory
|
||||
shutil.rmtree(local_temp_dir, ignore_errors=True)
|
||||
@@ -28,3 +28,6 @@ ipaclient_request_cert: no
|
||||
|
||||
### packages ###
|
||||
ipaclient_install_packages: yes
|
||||
|
||||
ipaclient_configure_dns_resolver: no
|
||||
ipaclient_cleanup_dns_resolver: no
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,25 +32,31 @@ ANSIBLE_METADATA = {'metadata_version': '1.0',
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_api
|
||||
short description:
|
||||
short_description:
|
||||
Create temporary NSS database, call IPA API for remaining enrollment parts
|
||||
description:
|
||||
Create temporary NSS database, call IPA API for remaining enrollment parts
|
||||
options:
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
type: list
|
||||
elements: str
|
||||
required: yes
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
debug:
|
||||
description: Turn on extra debugging
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -70,7 +76,7 @@ ca_enabled:
|
||||
subject_base:
|
||||
description: The subject base, needed for certmonger
|
||||
returned: always
|
||||
type: string
|
||||
type: str
|
||||
sample: O=EXAMPLE.COM
|
||||
'''
|
||||
|
||||
@@ -78,7 +84,7 @@ import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging,
|
||||
setup_logging, check_imports,
|
||||
paths, x509, NUM_VERSION, serialization, certdb, api,
|
||||
delete_persistent_client_session_data, write_tmp_file,
|
||||
ipa_generate_password, CalledProcessError, errors, disable_ra, DN,
|
||||
@@ -89,15 +95,16 @@ from ansible.module_utils.ansible_ipa_client import (
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
realm=dict(required=True),
|
||||
hostname=dict(required=True),
|
||||
servers=dict(required=True, type='list', elements='str'),
|
||||
realm=dict(required=True, type='str'),
|
||||
hostname=dict(required=True, type='str'),
|
||||
debug=dict(required=False, type='bool', default="false"),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
realm = module.params.get('realm')
|
||||
|
||||
321
roles/ipaclient/library/ipaclient_configure_dns_resolver.py
Normal file
321
roles/ipaclient/library/ipaclient_configure_dns_resolver.py
Normal file
@@ -0,0 +1,321 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Based on ipaplatform/redhat/tasks.py code from Christian Heimes
|
||||
#
|
||||
# Copyright (C) 2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
'metadata_version': '1.0',
|
||||
'supported_by': 'community',
|
||||
'status': ['preview'],
|
||||
}
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaclient_configure_dns_resolver
|
||||
short_description: Configure DNS resolver for IPA client
|
||||
description:
|
||||
Configure DNS resolver for IPA client, register files for installer
|
||||
options:
|
||||
nameservers:
|
||||
description: The nameservers, required with state:present.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
searchdomains:
|
||||
description: The searchdomains, required with state:present.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
state:
|
||||
description: The state to ensure.
|
||||
type: str
|
||||
choices: ["present", "absent"]
|
||||
default: present
|
||||
required: false
|
||||
author:
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Ensure DNS nameservers and domain are configured
|
||||
- ipaclient_configure_dns_resolver:
|
||||
nameservers: groups.ipaservers
|
||||
searchdomains: "{{ ipaserver_domain | default(ipaclient_domain) }}"
|
||||
# Ensure DNS nameservers and domain are not configured
|
||||
- ipaclient_configure_dns_resolver:
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
check_imports, services, tasks, paths, sysrestore, CheckedIPAddress
|
||||
)
|
||||
try:
|
||||
from ipalib.installdnsforwarders import detect_resolve1_resolv_conf
|
||||
except ImportError:
|
||||
def detect_resolve1_resolv_conf():
|
||||
"""
|
||||
Detect if /etc/resolv.conf is managed by systemd-resolved.
|
||||
|
||||
See man(5) NetworkManager.conf
|
||||
"""
|
||||
systemd_resolv_conf_files = {
|
||||
"/run/systemd/resolve/stub-resolv.conf",
|
||||
"/run/systemd/resolve/resolv.conf",
|
||||
"/lib/systemd/resolv.conf",
|
||||
"/usr/lib/systemd/resolv.conf",
|
||||
}
|
||||
|
||||
try:
|
||||
dest = os.readlink(paths.RESOLV_CONF)
|
||||
except OSError:
|
||||
# not a link
|
||||
return False
|
||||
# convert path relative to /etc/resolv.conf to abs path
|
||||
dest = os.path.normpath(
|
||||
os.path.join(os.path.dirname(paths.RESOLV_CONF), dest)
|
||||
)
|
||||
return dest in systemd_resolv_conf_files
|
||||
|
||||
|
||||
if hasattr(paths, "SYSTEMD_RESOLVED_IPA_CONF"):
|
||||
SYSTEMD_RESOLVED_IPA_CONF = paths.SYSTEMD_RESOLVED_IPA_CONF
|
||||
else:
|
||||
SYSTEMD_RESOLVED_IPA_CONF = "/etc/systemd/resolved.conf.d/zzz-ipa.conf"
|
||||
|
||||
|
||||
if hasattr(paths, "NETWORK_MANAGER_IPA_CONF"):
|
||||
NETWORK_MANAGER_IPA_CONF = paths.NETWORK_MANAGER_IPA_CONF
|
||||
else:
|
||||
NETWORK_MANAGER_IPA_CONF = "/etc/NetworkManager/conf.d/zzz-ipa.conf"
|
||||
|
||||
|
||||
NM_IPA_CONF = """
|
||||
# auto-generated by IPA client installer
|
||||
[main]
|
||||
dns={dnsprocessing}
|
||||
[global-dns]
|
||||
searches={searches}
|
||||
[global-dns-domain-*]
|
||||
servers={servers}
|
||||
"""
|
||||
|
||||
|
||||
RESOLVE1_IPA_CONF = """
|
||||
# auto-generated by IPA client installer
|
||||
[Resolve]
|
||||
# use DNS servers
|
||||
DNS={servers}
|
||||
# make default DNS server, add search suffixes
|
||||
Domains=~. {searchdomains}
|
||||
"""
|
||||
|
||||
|
||||
def configure_dns_resolver(nameservers, searchdomains, fstore=None):
|
||||
"""
|
||||
Configure global DNS resolver (e.g. /etc/resolv.conf).
|
||||
|
||||
:param nameservers: list of IP addresses
|
||||
:param searchdomains: list of search domaons
|
||||
:param fstore: optional file store for resolv.conf backup
|
||||
"""
|
||||
if not nameservers or not isinstance(nameservers, list):
|
||||
raise AssertionError("nameservers must be of type list")
|
||||
if not searchdomains or not isinstance(searchdomains, list):
|
||||
raise AssertionError("searchdomains must be of type list")
|
||||
|
||||
if fstore is not None and not fstore.has_file(paths.RESOLV_CONF):
|
||||
fstore.backup_file(paths.RESOLV_CONF)
|
||||
|
||||
resolve1_enabled = detect_resolve1_resolv_conf()
|
||||
if "NetworkManager" not in services.knownservices:
|
||||
# NetworkManager is not in wellknownservices for old IPA releases
|
||||
# Therefore create own service for it.
|
||||
nm_service = services.service("NetworkManager.service")
|
||||
else:
|
||||
nm_service = services.knownservices['NetworkManager']
|
||||
|
||||
# At first configure systemd-resolved
|
||||
if resolve1_enabled:
|
||||
if not os.path.exists(SYSTEMD_RESOLVED_IPA_CONF):
|
||||
confd = os.path.dirname(SYSTEMD_RESOLVED_IPA_CONF)
|
||||
if not os.path.isdir(confd):
|
||||
os.mkdir(confd)
|
||||
# owned by root, readable by systemd-resolve user
|
||||
os.chmod(confd, 0o755)
|
||||
tasks.restore_context(confd, force=True)
|
||||
|
||||
# Additionally to IPA server code also set servers
|
||||
cfg = RESOLVE1_IPA_CONF.format(
|
||||
servers=' '.join(nameservers),
|
||||
searchdomains=" ".join(searchdomains)
|
||||
)
|
||||
with open(SYSTEMD_RESOLVED_IPA_CONF, "w") as outf:
|
||||
os.fchmod(outf.fileno(), 0o644)
|
||||
outf.write(cfg)
|
||||
|
||||
tasks.restore_context(
|
||||
SYSTEMD_RESOLVED_IPA_CONF, force=True
|
||||
)
|
||||
|
||||
if "systemd-resolved" in services.knownservices:
|
||||
sdrd_service = services.knownservices["systemd-resolved"]
|
||||
else:
|
||||
sdrd_service = services.service("systemd-resolved.service")
|
||||
if sdrd_service.is_enabled():
|
||||
sdrd_service.reload_or_restart()
|
||||
|
||||
# Then configure NetworkManager or resolve.conf
|
||||
if nm_service.is_enabled():
|
||||
if not os.path.exists(NETWORK_MANAGER_IPA_CONF):
|
||||
# write DNS override and reload network manager to have it create
|
||||
# a new resolv.conf. The file is prefixed with ``zzz`` to
|
||||
# make it the last file. Global dns options do not stack and last
|
||||
# man standing wins.
|
||||
if resolve1_enabled:
|
||||
# push DNS configuration to systemd-resolved
|
||||
dnsprocessing = "systemd-resolved"
|
||||
else:
|
||||
# update /etc/resolv.conf
|
||||
dnsprocessing = "default"
|
||||
|
||||
cfg = NM_IPA_CONF.format(
|
||||
dnsprocessing=dnsprocessing,
|
||||
servers=','.join(nameservers),
|
||||
searches=','.join(searchdomains)
|
||||
)
|
||||
with open(NETWORK_MANAGER_IPA_CONF, 'w') as outf:
|
||||
os.fchmod(outf.fileno(), 0o644)
|
||||
outf.write(cfg)
|
||||
# reload NetworkManager
|
||||
nm_service.reload_or_restart()
|
||||
|
||||
# Configure resolv.conf if NetworkManager and systemd-resoled are not
|
||||
# enabled
|
||||
elif not resolve1_enabled:
|
||||
# no NM running, no systemd-resolved detected
|
||||
# fall back to /etc/resolv.conf
|
||||
cfg = [
|
||||
"# auto-generated by IPA installer",
|
||||
"search %s" % ' '.join(searchdomains),
|
||||
]
|
||||
for nameserver in nameservers:
|
||||
cfg.append("nameserver %s" % nameserver)
|
||||
with open(paths.RESOLV_CONF, 'w') as outf:
|
||||
outf.write('\n'.join(cfg))
|
||||
|
||||
|
||||
def unconfigure_dns_resolver(fstore=None):
|
||||
"""
|
||||
Unconfigure global DNS resolver (e.g. /etc/resolv.conf).
|
||||
|
||||
:param fstore: optional file store for resolv.conf restore
|
||||
"""
|
||||
if fstore is not None and fstore.has_file(paths.RESOLV_CONF):
|
||||
fstore.restore_file(paths.RESOLV_CONF)
|
||||
|
||||
if os.path.isfile(NETWORK_MANAGER_IPA_CONF):
|
||||
os.unlink(NETWORK_MANAGER_IPA_CONF)
|
||||
if "NetworkManager" not in services.knownservices:
|
||||
# NetworkManager is not in wellknownservices for old IPA releases
|
||||
# Therefore create own service for it.
|
||||
nm_service = services.service("NetworkManager.service")
|
||||
else:
|
||||
nm_service = services.knownservices['NetworkManager']
|
||||
if nm_service.is_enabled():
|
||||
nm_service.reload_or_restart()
|
||||
|
||||
if os.path.isfile(SYSTEMD_RESOLVED_IPA_CONF):
|
||||
os.unlink(SYSTEMD_RESOLVED_IPA_CONF)
|
||||
if "systemd-resolved" in services.knownservices:
|
||||
sdrd_service = services.knownservices["systemd-resolved"]
|
||||
else:
|
||||
sdrd_service = services.service("systemd-resolved.service")
|
||||
if sdrd_service.is_enabled():
|
||||
sdrd_service.reload_or_restart()
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
nameservers=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=False),
|
||||
searchdomains=dict(type="list", elements="str", aliases=["cn"],
|
||||
required=False),
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
),
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
check_imports(module)
|
||||
|
||||
nameservers = module.params.get('nameservers')
|
||||
searchdomains = module.params.get('searchdomains')
|
||||
|
||||
state = module.params.get("state")
|
||||
|
||||
if state == "present":
|
||||
required = ["nameservers", "searchdomains"]
|
||||
for param in required:
|
||||
value = module.params.get(param)
|
||||
if value is None or len(value) < 1:
|
||||
module.fail_json(
|
||||
msg="Argument '%s' is required for state:present" % param)
|
||||
else:
|
||||
invalid = ["nameservers", "searchdomains"]
|
||||
for param in invalid:
|
||||
if module.params.get(param) is not None:
|
||||
module.fail_json(
|
||||
msg="Argument '%s' can not be used with state:present" %
|
||||
param)
|
||||
|
||||
# Check nameservers to contain valid IP addresses
|
||||
if nameservers is not None:
|
||||
for value in nameservers:
|
||||
try:
|
||||
CheckedIPAddress(value)
|
||||
except Exception as e:
|
||||
module.fail_json(
|
||||
msg="Invalid IP address %s: %s" % (value, str(e)))
|
||||
|
||||
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||
|
||||
if state == "present":
|
||||
configure_dns_resolver(nameservers, searchdomains, fstore)
|
||||
else:
|
||||
unconfigure_dns_resolver(fstore)
|
||||
|
||||
module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -32,25 +32,30 @@ ANSIBLE_METADATA = {'metadata_version': '1.0',
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_fix_ca
|
||||
short description: Fix IPA ca certificate
|
||||
description: Repair Fix IPA ca certificate
|
||||
short_description: Fix IPA ca certificate
|
||||
description: Fix IPA ca certificate
|
||||
options:
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
type: list
|
||||
elements: str
|
||||
required: yes
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
basedn:
|
||||
description: The basedn of the IPA server (of the form dc=example,dc=com)
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
allow_repair:
|
||||
description: |
|
||||
Allow repair of already joined hosts. Contrary to ipaclient_force_join
|
||||
the host entry will not be changed on the server
|
||||
required: no
|
||||
type: bool
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -69,7 +74,7 @@ import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging,
|
||||
setup_logging, check_imports,
|
||||
SECURE_PATH, paths, sysrestore, options, NUM_VERSION, get_ca_cert,
|
||||
get_ca_certs, errors
|
||||
)
|
||||
@@ -78,14 +83,15 @@ from ansible.module_utils.ansible_ipa_client import (
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
realm=dict(required=True),
|
||||
basedn=dict(required=True),
|
||||
servers=dict(required=True, type='list', elements='str'),
|
||||
realm=dict(required=True, type='str'),
|
||||
basedn=dict(required=True, type='str'),
|
||||
allow_repair=dict(required=True, type='bool'),
|
||||
),
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
servers = module.params.get('servers')
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,14 +34,15 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_fstore
|
||||
short description: Backup files using IPA client sysrestore
|
||||
short_description: Backup files using IPA client sysrestore
|
||||
description: Backup files using IPA client sysrestore
|
||||
options:
|
||||
backup:
|
||||
description: File to backup
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -55,18 +56,19 @@ RETURN = '''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging, paths, sysrestore
|
||||
setup_logging, check_imports, paths, sysrestore
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
backup=dict(required=True),
|
||||
backup=dict(required=True, type='str'),
|
||||
),
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
backup = module.params.get('backup')
|
||||
|
||||
@@ -1,208 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaclient_get_facts
|
||||
short description: Get facts about IPA client and server configuration.
|
||||
description: Get facts about IPA client and server configuration.
|
||||
author:
|
||||
- Thomas Woerner
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
from ansible.module_utils import six
|
||||
try:
|
||||
from ansible.module_utils.six.moves.configparser import RawConfigParser
|
||||
except ImportError:
|
||||
from ConfigParser import RawConfigParser
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
# pylint: disable=unused-import
|
||||
try:
|
||||
from ipalib import api # noqa: F401
|
||||
except ImportError:
|
||||
HAS_IPALIB = False
|
||||
else:
|
||||
HAS_IPALIB = True
|
||||
from ipaplatform.paths import paths
|
||||
try:
|
||||
# FreeIPA >= 4.5
|
||||
from ipalib.install import sysrestore
|
||||
except ImportError:
|
||||
# FreeIPA 4.4 and older
|
||||
from ipapython import sysrestore
|
||||
|
||||
try:
|
||||
import ipaserver # noqa: F401
|
||||
except ImportError:
|
||||
HAS_IPASERVER = False
|
||||
else:
|
||||
HAS_IPASERVER = True
|
||||
|
||||
SERVER_SYSRESTORE_STATE = "/var/lib/ipa/sysrestore/sysrestore.state"
|
||||
NAMED_CONF = "/etc/named.conf"
|
||||
VAR_LIB_PKI_TOMCAT = "/var/lib/pki/pki-tomcat"
|
||||
|
||||
|
||||
def is_ntpd_configured():
|
||||
# ntpd is configured when sysrestore.state contains the line
|
||||
# [ntpd]
|
||||
ntpd_conf_section = re.compile(r'^\s*\[ntpd\]\s*$')
|
||||
|
||||
try:
|
||||
# pylint: disable=invalid-name
|
||||
with open(SERVER_SYSRESTORE_STATE) as f:
|
||||
for line in f.readlines():
|
||||
if ntpd_conf_section.match(line):
|
||||
return True
|
||||
# pylint: enable=invalid-name
|
||||
return False
|
||||
except IOError:
|
||||
return False
|
||||
|
||||
|
||||
def is_dns_configured():
|
||||
# dns is configured when /etc/named.conf contains the line
|
||||
# dyndb "ipa" "/usr/lib64/bind/ldap.so" {
|
||||
bind_conf_section = re.compile(r'^\s*dyndb\s+"ipa"\s+"[^"]+"\s+{$')
|
||||
|
||||
try:
|
||||
with open(NAMED_CONF) as f: # pylint: disable=invalid-name
|
||||
for line in f.readlines():
|
||||
if bind_conf_section.match(line):
|
||||
return True
|
||||
return False
|
||||
except IOError:
|
||||
return False
|
||||
|
||||
|
||||
def is_dogtag_configured(subsystem):
|
||||
# ca / kra is configured when the directory
|
||||
# /var/lib/pki/pki-tomcat/[ca|kra] # exists
|
||||
available_subsystems = {'ca', 'kra'}
|
||||
if subsystem not in available_subsystems:
|
||||
raise AssertionError("Subsystem '%s' not available" % subsystem)
|
||||
|
||||
return os.path.isdir(os.path.join(VAR_LIB_PKI_TOMCAT, subsystem))
|
||||
|
||||
|
||||
def is_ca_configured():
|
||||
return is_dogtag_configured('ca')
|
||||
|
||||
|
||||
def is_kra_configured():
|
||||
return is_dogtag_configured('kra')
|
||||
|
||||
|
||||
def is_client_configured():
|
||||
# IPA Client is configured when /etc/ipa/default.conf exists
|
||||
# and /var/lib/ipa-client/sysrestore/sysrestore.state exists
|
||||
|
||||
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||
return os.path.isfile(paths.IPA_DEFAULT_CONF) and fstore.has_files()
|
||||
|
||||
|
||||
def is_server_configured():
|
||||
# IPA server is configured when /etc/ipa/default.conf exists
|
||||
# and /var/lib/ipa/sysrestore/sysrestore.state exists
|
||||
return (os.path.isfile(paths.IPA_DEFAULT_CONF) and
|
||||
os.path.isfile(SERVER_SYSRESTORE_STATE))
|
||||
|
||||
|
||||
def get_ipa_conf():
|
||||
# Extract basedn, realm and domain from /etc/ipa/default.conf
|
||||
parser = RawConfigParser()
|
||||
parser.read(paths.IPA_DEFAULT_CONF)
|
||||
basedn = parser.get('global', 'basedn')
|
||||
realm = parser.get('global', 'realm')
|
||||
domain = parser.get('global', 'domain')
|
||||
return dict(
|
||||
basedn=basedn,
|
||||
realm=realm,
|
||||
domain=domain
|
||||
)
|
||||
|
||||
|
||||
def get_ipa_version():
|
||||
try:
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from ipapython import version
|
||||
# pylint: enable=import-outside-toplevel
|
||||
except ImportError:
|
||||
return None
|
||||
else:
|
||||
version_info = []
|
||||
for part in version.VERSION.split('.'):
|
||||
# DEV versions look like:
|
||||
# 4.4.90.201610191151GITd852c00
|
||||
# 4.4.90.dev201701071308+git2e43db1
|
||||
# 4.6.90.pre2
|
||||
if part.startswith('dev') or part.startswith('pre') or \
|
||||
'GIT' in part:
|
||||
version_info.append(part)
|
||||
else:
|
||||
version_info.append(int(part))
|
||||
|
||||
return dict(
|
||||
api_version=version.API_VERSION,
|
||||
num_version=version.NUM_VERSION,
|
||||
vendor_version=version.VENDOR_VERSION,
|
||||
version=version.VERSION,
|
||||
version_info=version_info
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec={},
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
# The module does not change anything, meaning that
|
||||
# check mode is supported
|
||||
|
||||
facts = dict(
|
||||
packages=dict(
|
||||
ipalib=HAS_IPALIB,
|
||||
ipaserver=HAS_IPASERVER,
|
||||
),
|
||||
configured=dict(
|
||||
client=False,
|
||||
server=False,
|
||||
dns=False,
|
||||
ca=False,
|
||||
kra=False,
|
||||
ntpd=False
|
||||
)
|
||||
)
|
||||
|
||||
if HAS_IPALIB:
|
||||
if is_client_configured():
|
||||
facts['configured']['client'] = True
|
||||
|
||||
facts['version'] = get_ipa_version()
|
||||
for key, value in six.iteritems(get_ipa_conf()):
|
||||
facts[key] = value
|
||||
|
||||
if HAS_IPASERVER:
|
||||
if is_server_configured():
|
||||
facts['configured']['server'] = True
|
||||
facts['configured']['dns'] = is_dns_configured()
|
||||
facts['configured']['ca'] = is_ca_configured()
|
||||
facts['configured']['kra'] = is_kra_configured()
|
||||
facts['configured']['ntpd'] = is_ntpd_configured()
|
||||
|
||||
module.exit_json(
|
||||
changed=False,
|
||||
ansible_facts=dict(ipa=facts)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,9 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Florence Blanc-Renaud <frenaud@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2019-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -23,307 +23,267 @@ from __future__ import (absolute_import, division, print_function)
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.0',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
ANSIBLE_METADATA = {
|
||||
"metadata_version": "1.0",
|
||||
"supported_by": "community",
|
||||
"status": ["preview"],
|
||||
}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipaclient_get_otp
|
||||
short description: Manage IPA hosts
|
||||
description:
|
||||
Manage hosts in a IPA domain.
|
||||
The operation needs to be authenticated with Kerberos either by providing
|
||||
a password or a keytab corresponding to a principal allowed to perform
|
||||
host operations.
|
||||
short_description: Get OTP for host enrollment
|
||||
description: Get OTP for host enrollment
|
||||
options:
|
||||
principal:
|
||||
description:
|
||||
User Principal allowed to promote replicas and join IPA realm
|
||||
required: yes
|
||||
ccache:
|
||||
description: The local ccache
|
||||
required: yes
|
||||
fqdn:
|
||||
description:
|
||||
The fully-qualified hostname of the host to add/modify/remove
|
||||
required: no
|
||||
certificates:
|
||||
description: A list of host certificates
|
||||
required: yes
|
||||
sshpubkey:
|
||||
description: The SSH public key for the host
|
||||
required: yes
|
||||
ipaddress:
|
||||
description: The IP address for the host
|
||||
required: yes
|
||||
random:
|
||||
description: Generate a random password to be used in bulk enrollment
|
||||
required: yes
|
||||
state:
|
||||
description: The desired host state
|
||||
required: yes
|
||||
ipaadmin_principal:
|
||||
description: The admin principal.
|
||||
default: admin
|
||||
type: str
|
||||
ipaadmin_password:
|
||||
description: |
|
||||
The admin password. Either ipaadmin_password or ipaadmin_keytab needs
|
||||
to be given.
|
||||
required: false
|
||||
type: str
|
||||
ipaadmin_keytab:
|
||||
description: |
|
||||
The admin keytab. Either ipaadmin_password or ipaadmin_keytab needs
|
||||
to be given.
|
||||
type: str
|
||||
required: false
|
||||
hostname:
|
||||
description: The FQDN hostname.
|
||||
type: str
|
||||
required: true
|
||||
author:
|
||||
- "Florence Blanc-Renaud"
|
||||
'''
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = '''
|
||||
# Example from Ansible Playbooks
|
||||
# Add a new host with a random OTP, authenticate using principal/password
|
||||
- ipaclient_get_otp:
|
||||
principal: admin
|
||||
password: MySecretPassword
|
||||
fqdn: ipaclient.ipa.domain.com
|
||||
ipaddress: 192.168.100.23
|
||||
random: True
|
||||
register: result_ipaclient_get_otp
|
||||
'''
|
||||
EXAMPLES = """
|
||||
"""
|
||||
|
||||
RETURN = '''
|
||||
RETURN = """
|
||||
host:
|
||||
description: the host structure as returned from IPA API
|
||||
description: Host dict with random password
|
||||
returned: always
|
||||
type: complex
|
||||
type: dict
|
||||
contains:
|
||||
dn:
|
||||
description: the DN of the host entry
|
||||
type: string
|
||||
returned: always
|
||||
fqdn:
|
||||
description: the fully qualified host name
|
||||
type: string
|
||||
returned: always
|
||||
has_keytab:
|
||||
description: whether the host entry contains a keytab
|
||||
type: bool
|
||||
returned: always
|
||||
has_password:
|
||||
description: whether the host entry contains a password
|
||||
type: bool
|
||||
returned: always
|
||||
managedby_host:
|
||||
description: the list of hosts managing the host
|
||||
type: list
|
||||
returned: always
|
||||
randompassword:
|
||||
description: the OneTimePassword generated for this host
|
||||
type: string
|
||||
returned: changed
|
||||
certificates:
|
||||
description: the list of host certificates
|
||||
type: list
|
||||
returned: when present
|
||||
sshpubkey:
|
||||
description: the SSH public key for the host
|
||||
type: string
|
||||
returned: when present
|
||||
ipaddress:
|
||||
description: the IP address for the host
|
||||
type: string
|
||||
returned: when present
|
||||
'''
|
||||
description: The generated random password
|
||||
type: str
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import tempfile
|
||||
import shutil
|
||||
from contextlib import contextmanager
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils import six
|
||||
|
||||
from ipalib import api, errors
|
||||
from ipaplatform.paths import paths
|
||||
from ipapython.ipautil import run
|
||||
try:
|
||||
from ipalib import api
|
||||
from ipalib import errors as ipalib_errors # noqa
|
||||
from ipalib.config import Env
|
||||
from ipaplatform.paths import paths
|
||||
from ipapython.ipautil import run
|
||||
from ipalib.constants import DEFAULT_CONFIG
|
||||
try:
|
||||
from ipalib.install.kinit import kinit_password, kinit_keytab
|
||||
except ImportError:
|
||||
from ipapython.ipautil import kinit_password, kinit_keytab
|
||||
except ImportError as _err:
|
||||
MODULE_IMPORT_ERROR = str(_err)
|
||||
else:
|
||||
MODULE_IMPORT_ERROR = None
|
||||
|
||||
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
|
||||
|
||||
def get_host_diff(ipa_host, module_host):
|
||||
"""
|
||||
Build a dict with the differences from two host dicts.
|
||||
def temp_kinit(principal, password, keytab):
|
||||
"""Kinit with password or keytab using a temporary ccache."""
|
||||
ccache_dir = tempfile.mkdtemp(prefix='krbcc')
|
||||
ccache_name = os.path.join(ccache_dir, 'ccache')
|
||||
|
||||
:param ipa_host: the host structure seen from IPA
|
||||
:param module_host: the target host structure seen from the module params
|
||||
|
||||
:return: a dict representing the host attributes to apply
|
||||
"""
|
||||
non_updateable_keys = ['ip_address']
|
||||
data = {}
|
||||
for key in non_updateable_keys:
|
||||
if key in module_host:
|
||||
del module_host[key]
|
||||
|
||||
for key in module_host.keys():
|
||||
ipa_value = ipa_host.get(key, None)
|
||||
module_value = module_host.get(key, None)
|
||||
if isinstance(ipa_value, list) and not isinstance(module_value, list):
|
||||
module_value = [module_value]
|
||||
if isinstance(ipa_value, list) and isinstance(module_value, list):
|
||||
ipa_value = sorted(ipa_value)
|
||||
module_value = sorted(module_value)
|
||||
if ipa_value != module_value:
|
||||
data[key] = unicode(module_value)
|
||||
return data
|
||||
|
||||
|
||||
def get_module_host(module):
|
||||
"""
|
||||
Create a structure representing the host information.
|
||||
|
||||
Reads the module parameters and builds the host structure as expected from
|
||||
the module
|
||||
:param module: the ansible module
|
||||
:returns: a dict representing the host attributes
|
||||
"""
|
||||
data = {}
|
||||
certificates = module.params.get('certificates')
|
||||
if certificates:
|
||||
data['usercertificate'] = certificates
|
||||
sshpubkey = module.params.get('sshpubkey')
|
||||
if sshpubkey:
|
||||
data['ipasshpubkey'] = unicode(sshpubkey)
|
||||
ipaddress = module.params.get('ipaddress')
|
||||
if ipaddress:
|
||||
data['ip_address'] = unicode(ipaddress)
|
||||
random = module.params.get('random')
|
||||
if random:
|
||||
data['random'] = random
|
||||
return data
|
||||
|
||||
|
||||
def ensure_host_present(module, _api, ipahost):
|
||||
"""
|
||||
Ensure host exists in IPA and has the same attributes.
|
||||
|
||||
:param module: the ansible module
|
||||
:param api: IPA api handle
|
||||
:param ipahost: the host information present in IPA, can be none if the
|
||||
host does not exist
|
||||
"""
|
||||
fqdn = unicode(module.params.get('fqdn'))
|
||||
if ipahost:
|
||||
# Host already present, need to compare the attributes
|
||||
module_host = get_module_host(module)
|
||||
diffs = get_host_diff(ipahost, module_host)
|
||||
|
||||
if not diffs:
|
||||
# Same attributes, success
|
||||
module.exit_json(changed=False, host=ipahost)
|
||||
|
||||
# Need to modify the host - only if not in check_mode
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=True)
|
||||
|
||||
# If we want to create a random password, and the host
|
||||
# already has Keytab: true, then we need first to run
|
||||
# ipa host-disable in order to remove OTP and keytab
|
||||
if module.params.get('random') and ipahost['has_keytab'] is True:
|
||||
_api.Command.host_disable(fqdn)
|
||||
|
||||
result = _api.Command.host_mod(fqdn, **diffs)
|
||||
# Save random password as it is not displayed by host-show
|
||||
if module.params.get('random'):
|
||||
randompassword = result['result']['randompassword']
|
||||
result = _api.Command.host_show(fqdn)
|
||||
if module.params.get('random'):
|
||||
result['result']['randompassword'] = randompassword
|
||||
module.exit_json(changed=True, host=result['result'])
|
||||
|
||||
if not ipahost:
|
||||
# Need to add the user, only if not in check_mode
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=True)
|
||||
|
||||
# Must add the user
|
||||
module_host = get_module_host(module)
|
||||
# force creation of host even if there is no DNS record
|
||||
module_host["force"] = True
|
||||
result = _api.Command.host_add(fqdn, **module_host)
|
||||
# Save random password as it is not displayed by host-show
|
||||
if module.params.get('random'):
|
||||
randompassword = result['result']['randompassword']
|
||||
result = _api.Command.host_show(fqdn)
|
||||
if module.params.get('random'):
|
||||
result['result']['randompassword'] = randompassword
|
||||
module.exit_json(changed=True, host=result['result'])
|
||||
|
||||
|
||||
def ensure_host_absent(module, _api, host):
|
||||
"""
|
||||
Ensure host does not exist in IPA.
|
||||
|
||||
:param module: the ansible module
|
||||
:param api: the IPA API handle
|
||||
:param host: the host information present in IPA, can be none if the
|
||||
host does not exist
|
||||
"""
|
||||
if not host:
|
||||
# Nothing to do, host already removed
|
||||
module.exit_json(changed=False)
|
||||
|
||||
# Need to remove the host - only if not in check_mode
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=True, host=host)
|
||||
|
||||
fqdn = unicode(module.params.get('fqdn'))
|
||||
try:
|
||||
_api.Command.host_del(fqdn)
|
||||
except Exception as e:
|
||||
module.fail_json(msg="Failed to remove host: %s" % e)
|
||||
if password:
|
||||
kinit_password(principal, password, ccache_name)
|
||||
else:
|
||||
kinit_keytab(principal, keytab, ccache_name)
|
||||
except RuntimeError as e:
|
||||
raise RuntimeError("Kerberos authentication failed: %s" % str(e))
|
||||
|
||||
module.exit_json(changed=True)
|
||||
os.environ["KRB5CCNAME"] = ccache_name
|
||||
return ccache_dir, ccache_name
|
||||
|
||||
|
||||
def temp_kdestroy(ccache_dir, ccache_name):
|
||||
"""Destroy temporary ticket and remove temporary ccache."""
|
||||
if ccache_name is not None:
|
||||
run([paths.KDESTROY, '-c', ccache_name], raiseonerr=False)
|
||||
del os.environ['KRB5CCNAME']
|
||||
if ccache_dir is not None:
|
||||
shutil.rmtree(ccache_dir, ignore_errors=True)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def ipa_connect(module, principal=None, password=None, keytab=None):
|
||||
"""
|
||||
Create a context with a connection to IPA API.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
module: AnsibleModule
|
||||
The AnsibleModule to use
|
||||
principal: string
|
||||
The optional principal name
|
||||
password: string
|
||||
The optional password. Either password or keytab needs to be given.
|
||||
keytab: string
|
||||
The optional keytab. Either password or keytab needs to be given.
|
||||
|
||||
"""
|
||||
if not password and not keytab:
|
||||
module.fail_json(msg="One of password and keytab is required.")
|
||||
if not principal:
|
||||
principal = "admin"
|
||||
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
ccache_dir, ccache_name = temp_kinit(principal, password, keytab)
|
||||
# api_connect start
|
||||
env = Env()
|
||||
env._bootstrap()
|
||||
env._finalize_core(**dict(DEFAULT_CONFIG))
|
||||
|
||||
api.bootstrap(context="server", debug=env.debug, log=None)
|
||||
api.finalize()
|
||||
|
||||
if api.env.in_server:
|
||||
backend = api.Backend.ldap2
|
||||
else:
|
||||
backend = api.Backend.rpcclient
|
||||
|
||||
if not backend.isconnected():
|
||||
backend.connect(ccache=ccache_name)
|
||||
# api_connect end
|
||||
except Exception as e:
|
||||
module.fail_json(msg=str(e))
|
||||
else:
|
||||
try:
|
||||
yield ccache_name
|
||||
except Exception as e:
|
||||
module.fail_json(msg=str(e))
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
|
||||
def ipa_command(command, name, args):
|
||||
"""
|
||||
Execute an IPA API command with a required `name` argument.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
command: string
|
||||
The IPA API command to execute.
|
||||
name: string
|
||||
The name parameter to pass to the command.
|
||||
args: dict
|
||||
The parameters to pass to the command.
|
||||
|
||||
"""
|
||||
return api.Command[command](name, **args)
|
||||
|
||||
|
||||
def _afm_convert(value):
|
||||
if value is not None:
|
||||
if isinstance(value, list):
|
||||
return [_afm_convert(x) for x in value]
|
||||
if isinstance(value, dict):
|
||||
return {_afm_convert(k): _afm_convert(v)
|
||||
for k, v in value.items()}
|
||||
if isinstance(value, str):
|
||||
return to_text(value)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def module_params_get(module, name):
|
||||
return _afm_convert(module.params.get(name))
|
||||
|
||||
|
||||
def host_show(module, name):
|
||||
_args = {
|
||||
"all": True,
|
||||
}
|
||||
|
||||
try:
|
||||
_result = ipa_command("host_show", name, _args)
|
||||
except ipalib_errors.NotFound as e:
|
||||
msg = str(e)
|
||||
if "host not found" in msg:
|
||||
return None
|
||||
module.fail_json(msg="host_show failed: %s" % msg)
|
||||
|
||||
return _result["result"]
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
principal=dict(default='admin'),
|
||||
ccache=dict(required=False, type='path'),
|
||||
fqdn=dict(required=True),
|
||||
certificates=dict(required=False, type='list'),
|
||||
sshpubkey=dict(required=False),
|
||||
ipaddress=dict(required=False),
|
||||
random=dict(default=False, type='bool'),
|
||||
state=dict(default='present', choices=['present', 'absent']),
|
||||
ipaadmin_principal=dict(type="str", default="admin"),
|
||||
ipaadmin_password=dict(type="str", required=False, no_log=True),
|
||||
ipaadmin_keytab=dict(type="str", required=False, no_log=False),
|
||||
hostname=dict(type="str", required=True),
|
||||
),
|
||||
mutually_exclusive=[["ipaadmin_password", "ipaadmin_keytab"]],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ccache = module.params.get('ccache')
|
||||
fqdn = unicode(module.params.get('fqdn'))
|
||||
state = module.params.get('state')
|
||||
if MODULE_IMPORT_ERROR is not None:
|
||||
module.fail_json(msg=MODULE_IMPORT_ERROR)
|
||||
|
||||
try:
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
# In check mode always return changed.
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=True)
|
||||
|
||||
cfg = dict(
|
||||
context='ansible_module',
|
||||
confdir=paths.ETC_IPA,
|
||||
in_server=False,
|
||||
debug=False,
|
||||
verbose=0,
|
||||
)
|
||||
api.bootstrap(**cfg)
|
||||
api.finalize()
|
||||
api.Backend.rpcclient.connect()
|
||||
ipaadmin_principal = module_params_get(module, "ipaadmin_principal")
|
||||
ipaadmin_password = module_params_get(module, "ipaadmin_password")
|
||||
ipaadmin_keytab = module_params_get(module, "ipaadmin_keytab")
|
||||
if ipaadmin_keytab:
|
||||
if not os.path.exists(ipaadmin_keytab):
|
||||
module.fail_json(msg="Unable to open ipaadmin_keytab '%s'" %
|
||||
ipaadmin_keytab)
|
||||
|
||||
try:
|
||||
result = api.Command.host_show(fqdn, all=True)
|
||||
host = result['result']
|
||||
except errors.NotFound:
|
||||
host = None
|
||||
hostname = module_params_get(module, "hostname")
|
||||
|
||||
if state in ['present', 'disabled']:
|
||||
ensure_host_present(module, api, host)
|
||||
elif state == 'absent':
|
||||
ensure_host_absent(module, api, host)
|
||||
exit_args = {}
|
||||
|
||||
except Exception as e:
|
||||
module.fail_json(msg="ipaclient_get_otp module failed : %s" % str(e))
|
||||
finally:
|
||||
run([paths.KDESTROY], raiseonerr=False, env=os.environ)
|
||||
# Connect to IPA API
|
||||
with ipa_connect(module, ipaadmin_principal, ipaadmin_password,
|
||||
ipaadmin_keytab):
|
||||
res_show = host_show(module, hostname)
|
||||
|
||||
module.exit_json(changed=False, host=host)
|
||||
args = {"random": True}
|
||||
if res_show is None:
|
||||
# Create new host, force is needed to create the host without
|
||||
# IP address.
|
||||
args["force"] = True
|
||||
result = ipa_command("host_add", hostname, args)
|
||||
else:
|
||||
# If host exists and has a keytab (is enrolled) then disable the
|
||||
# host to be able to create a new OTP.
|
||||
if res_show["has_keytab"]:
|
||||
ipa_command("host_disable", hostname, {})
|
||||
result = ipa_command("host_mod", hostname, args)
|
||||
|
||||
exit_args["randompassword"] = result['result']['randompassword']
|
||||
|
||||
module.exit_json(changed=True, host=exit_args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2018 Red Hat
|
||||
# Copyright (C) 2018-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,27 +34,33 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_ipa_conf
|
||||
short description: Configure ipa.conf
|
||||
short_description: Configure ipa.conf
|
||||
description:
|
||||
Configure ipa.conf
|
||||
options:
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
type: list
|
||||
elements: str
|
||||
required: yes
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
basedn:
|
||||
description: The basedn of the IPA server (of the form dc=example,dc=com)
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -73,23 +79,24 @@ RETURN = '''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging, paths, sysrestore, configure_ipa_conf
|
||||
setup_logging, check_imports, paths, sysrestore, configure_ipa_conf
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
domain=dict(required=True, default=None),
|
||||
servers=dict(required=True, type='list', default=None),
|
||||
realm=dict(required=True, default=None),
|
||||
hostname=dict(required=True, default=None),
|
||||
basedn=dict(required=True),
|
||||
domain=dict(required=True, type='str'),
|
||||
servers=dict(required=True, type='list', elements='str'),
|
||||
realm=dict(required=True, type='str'),
|
||||
hostname=dict(required=True, type='str'),
|
||||
basedn=dict(required=True, type='str'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
servers = module.params.get('servers')
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,7 +34,7 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_join
|
||||
short description:
|
||||
short_description:
|
||||
Join a machine to an IPA realm and get a keytab for the host service
|
||||
principal
|
||||
description:
|
||||
@@ -43,51 +43,67 @@ description:
|
||||
options:
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
type: list
|
||||
elements: str
|
||||
required: yes
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
kdc:
|
||||
description: The name or address of the host running the KDC
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
basedn:
|
||||
description: The basedn of the IPA server (of the form dc=example,dc=com)
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
principal:
|
||||
description:
|
||||
User Principal allowed to promote replicas and join IPA realm
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
password:
|
||||
description: Admin user kerberos password
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
keytab:
|
||||
description: Path to backed up keytab from previous enrollment
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
admin_keytab:
|
||||
description: The path to a local admin keytab
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
ca_cert_file:
|
||||
description:
|
||||
A CA certificate to use. Do not acquire the IPA CA certificate via
|
||||
automated means
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
force_join:
|
||||
description: Force client enrollment even if already enrolled
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
kinit_attempts:
|
||||
description: Repeat the request for host Kerberos ticket X times
|
||||
required: yes
|
||||
type: int
|
||||
required: no
|
||||
default: 5
|
||||
debug:
|
||||
description: Turn on extra debugging
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -130,7 +146,7 @@ import tempfile
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging,
|
||||
setup_logging, check_imports,
|
||||
SECURE_PATH, sysrestore, paths, options, configure_krb5_conf,
|
||||
realm_to_suffix, kinit_keytab, GSSError, kinit_password, NUM_VERSION,
|
||||
get_ca_cert, get_ca_certs, errors, run
|
||||
@@ -140,25 +156,26 @@ from ansible.module_utils.ansible_ipa_client import (
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
domain=dict(required=True),
|
||||
realm=dict(required=True),
|
||||
hostname=dict(required=True),
|
||||
kdc=dict(required=True),
|
||||
basedn=dict(required=True),
|
||||
principal=dict(required=False),
|
||||
password=dict(required=False, no_log=True),
|
||||
keytab=dict(required=False),
|
||||
admin_keytab=dict(required=False),
|
||||
ca_cert_file=dict(required=False),
|
||||
servers=dict(required=True, type='list', elements='str'),
|
||||
domain=dict(required=True, type='str'),
|
||||
realm=dict(required=True, type='str'),
|
||||
hostname=dict(required=True, type='str'),
|
||||
kdc=dict(required=True, type='str'),
|
||||
basedn=dict(required=True, type='str'),
|
||||
principal=dict(required=False, type='str'),
|
||||
password=dict(required=False, type='str', no_log=True),
|
||||
keytab=dict(required=False, type='str', no_log=False),
|
||||
admin_keytab=dict(required=False, type='str', no_log=False),
|
||||
ca_cert_file=dict(required=False, type='str'),
|
||||
force_join=dict(required=False, type='bool'),
|
||||
kinit_attempts=dict(required=False, type='int', default=5),
|
||||
debug=dict(required=False, type='bool'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
servers = module.params.get('servers')
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2018 Red Hat
|
||||
# Copyright (C) 2018-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,15 +34,16 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_set_hostname
|
||||
short description: Backup and set hostname
|
||||
short_description: Backup and set hostname
|
||||
description:
|
||||
Backup and set hostname
|
||||
options:
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -57,19 +58,20 @@ RETURN = '''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging, sysrestore, paths, tasks
|
||||
setup_logging, check_imports, sysrestore, paths, tasks
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
hostname=dict(required=True),
|
||||
hostname=dict(required=True, type='str'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
hostname = module.params.get('hostname')
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,21 +34,26 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_setup_automount
|
||||
short description: Setup automount for IPA client
|
||||
short_description: Setup automount for IPA client
|
||||
description:
|
||||
Setup automount for IPA client
|
||||
options:
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
type: list
|
||||
elements: str
|
||||
required: yes
|
||||
sssd:
|
||||
description: The installer sssd setting
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: yes
|
||||
automount_location:
|
||||
description: The automount location
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -63,23 +68,24 @@ RETURN = '''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging, options, configure_automount
|
||||
setup_logging, check_imports, options, configure_automount
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
servers=dict(required=True, type='list', elements='str'),
|
||||
sssd=dict(required=False, type='bool', default='yes'),
|
||||
automount_location=dict(required=False, default=None),
|
||||
automount_location=dict(required=False, type='str', default=None),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
# os.environ['KRB5CCNAME'] = paths.IPA_DNS_CCACHE
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
options.servers = module.params.get('servers')
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,20 +34,22 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_setup_firefox
|
||||
short description: Setup firefox for IPA client
|
||||
short_description: Setup firefox for IPA client
|
||||
description:
|
||||
Setup firefox for IPA client
|
||||
options:
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
type: str
|
||||
required: yes
|
||||
firefox_dir:
|
||||
description:
|
||||
Specify directory where Firefox is installed (for example
|
||||
'/usr/lib/firefox')
|
||||
type: str
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -63,20 +65,21 @@ RETURN = '''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging, sysrestore, paths, options, configure_firefox
|
||||
setup_logging, check_imports, sysrestore, paths, options, configure_firefox
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
domain=dict(required=True),
|
||||
firefox_dir=dict(required=False),
|
||||
domain=dict(required=True, type='str'),
|
||||
firefox_dir=dict(required=False, type='str'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
domain = module.params.get('domain')
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2018 Red Hat
|
||||
# Copyright (C) 2018-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,39 +34,52 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_setup_krb5
|
||||
short description: Setup krb5 for IPA client
|
||||
short_description: Setup krb5 for IPA client
|
||||
description:
|
||||
Setup krb5 for IPA client
|
||||
options:
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
kdc:
|
||||
description: The name or address of the host running the KDC
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
dnsok:
|
||||
description: The installer dnsok setting
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
client_domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
sssd:
|
||||
description: The installer sssd setting
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
force:
|
||||
description: Installer force parameter
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -84,28 +97,31 @@ RETURN = '''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging, sysrestore, paths, configure_krb5_conf, logger
|
||||
setup_logging, check_imports, sysrestore, paths, configure_krb5_conf,
|
||||
logger
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
domain=dict(required=False, default=None),
|
||||
servers=dict(required=False, type='list', default=None),
|
||||
realm=dict(required=False, default=None),
|
||||
hostname=dict(required=False, default=None),
|
||||
kdc=dict(required=False, default=None),
|
||||
domain=dict(required=False, type='str', default=None),
|
||||
servers=dict(required=False, type='list', elements='str',
|
||||
default=None),
|
||||
realm=dict(required=False, type='str', default=None),
|
||||
hostname=dict(required=False, type='str', default=None),
|
||||
kdc=dict(required=False, type='str', default=None),
|
||||
dnsok=dict(required=False, type='bool', default=False),
|
||||
client_domain=dict(required=False, default=None),
|
||||
client_domain=dict(required=False, type='str', default=None),
|
||||
sssd=dict(required=False, type='bool', default=False),
|
||||
force=dict(required=False, type='bool', default=False),
|
||||
# on_master=dict(required=False, type='bool', default=False),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
servers = module.params.get('servers')
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,18 +34,20 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_setup_nis
|
||||
short description: Setup NIS for IPA client
|
||||
short_description: Setup NIS for IPA client
|
||||
description:
|
||||
Setup NIS for IPA client
|
||||
options:
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
nisdomain:
|
||||
description: The NIS domain name
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -59,21 +61,22 @@ RETURN = '''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging, options, sysrestore, paths, configure_nisdomain,
|
||||
getargspec
|
||||
setup_logging, check_imports, options, sysrestore, paths,
|
||||
configure_nisdomain, getargspec
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
domain=dict(required=True),
|
||||
nisdomain=dict(required=False),
|
||||
domain=dict(required=True, type='str'),
|
||||
nisdomain=dict(required=False, type='str'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
domain = module.params.get('domain')
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,93 +34,122 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_setup_nss
|
||||
short description: Create IPA client NSS database
|
||||
short_description: Create IPA client NSS database
|
||||
description: Create IPA NSS database
|
||||
options:
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
type: list
|
||||
elements: str
|
||||
required: yes
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
basedn:
|
||||
description: The basedn of the IPA server (of the form dc=example,dc=com)
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
principal:
|
||||
description:
|
||||
User Principal allowed to promote replicas and join IPA realm
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
subject_base:
|
||||
description: |
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
ca_enabled:
|
||||
description: Whether the Certificate Authority is enabled or not
|
||||
required: no
|
||||
type: bool
|
||||
required: yes
|
||||
mkhomedir:
|
||||
description: Create home directories for users on their first login
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
on_master:
|
||||
description: Whether the configuration is done on the master or not
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
dnsok:
|
||||
description: The installer dnsok setting
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
enable_dns_updates:
|
||||
description: |
|
||||
Configures the machine to attempt dns updates when the ip address
|
||||
changes
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
all_ip_addresses:
|
||||
description: |
|
||||
All routable IP addresses configured on any interface will be added
|
||||
to DNS
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
ip_addresses:
|
||||
description: List of Master Server IP Addresses
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
request_cert:
|
||||
description: Request certificate for the machine
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
preserve_sssd:
|
||||
description: Preserve old SSSD configuration if possible
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_ssh:
|
||||
description: Do not configure OpenSSH client
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_sshd:
|
||||
description: Do not configure OpenSSH server
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_sudo:
|
||||
description: Do not configure SSSD as data source for sudo
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
fixed_primary:
|
||||
description: Configure sssd to use fixed server as primary IPA server
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
permit:
|
||||
description: Disable access rules by default, permit all access
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_krb5_offline_passwords:
|
||||
description:
|
||||
Configure SSSD not to store user password when the server is offline
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_dns_sshfp:
|
||||
description: Do not automatically create DNS SSHFP records
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
nosssd_files:
|
||||
description: >
|
||||
The dist of nss_ldap or nss-pam-ldapd files if sssd is disabled
|
||||
required: yes
|
||||
type: dict
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -144,26 +173,27 @@ import time
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging,
|
||||
setup_logging, check_imports,
|
||||
options, sysrestore, paths, ansible_module_get_parsed_ip_addresses,
|
||||
api, errors, create_ipa_nssdb, ipautil, ScriptError, CLIENT_INSTALL_ERROR,
|
||||
get_certs_from_ldap, DN, certstore, x509, logger, certdb,
|
||||
CalledProcessError, tasks, client_dns, configure_certmonger, services,
|
||||
update_ssh_keys, save_state, configure_ldap_conf, configure_nslcd_conf,
|
||||
configure_openldap_conf, hardcode_ldap_server, getargspec
|
||||
configure_openldap_conf, hardcode_ldap_server, getargspec, NUM_VERSION,
|
||||
serialization
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
domain=dict(required=True),
|
||||
realm=dict(required=True),
|
||||
hostname=dict(required=True),
|
||||
basedn=dict(required=True),
|
||||
principal=dict(required=False),
|
||||
subject_base=dict(required=True),
|
||||
servers=dict(required=True, type='list', elements='str'),
|
||||
domain=dict(required=True, type='str'),
|
||||
realm=dict(required=True, type='str'),
|
||||
hostname=dict(required=True, type='str'),
|
||||
basedn=dict(required=True, type='str'),
|
||||
principal=dict(required=False, type='str'),
|
||||
subject_base=dict(required=True, type='str'),
|
||||
ca_enabled=dict(required=True, type='bool'),
|
||||
mkhomedir=dict(required=False, type='bool'),
|
||||
on_master=dict(required=False, type='bool'),
|
||||
@@ -171,7 +201,8 @@ def main():
|
||||
|
||||
enable_dns_updates=dict(required=False, type='bool'),
|
||||
all_ip_addresses=dict(required=False, type='bool', default=False),
|
||||
ip_addresses=dict(required=False, type='list', default=None),
|
||||
ip_addresses=dict(required=False, type='list', elements='str',
|
||||
default=None),
|
||||
request_cert=dict(required=False, type='bool', default=False),
|
||||
preserve_sssd=dict(required=False, type='bool'),
|
||||
no_ssh=dict(required=False, type='bool'),
|
||||
@@ -183,10 +214,11 @@ def main():
|
||||
no_dns_sshfp=dict(required=False, type='bool', default=False),
|
||||
nosssd_files=dict(required=True, type='dict'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
cli_server = module.params.get('servers')
|
||||
@@ -271,6 +303,17 @@ def main():
|
||||
ca_subject = DN(('CN', 'Certificate Authority'), subject_base)
|
||||
else:
|
||||
ca_subject = None
|
||||
|
||||
# Set ca_certs
|
||||
# Copied from ipaclient_api
|
||||
ca_certs = x509.load_certificate_list_from_file(paths.IPA_CA_CRT)
|
||||
if 40500 <= NUM_VERSION < 40590:
|
||||
ca_certs = [cert.public_bytes(serialization.Encoding.DER)
|
||||
for cert in ca_certs]
|
||||
elif NUM_VERSION < 40500:
|
||||
ca_certs = [cert.der_data for cert in ca_certs]
|
||||
# Copied from ipaclient_api
|
||||
|
||||
ca_certs = certstore.make_compat_ca_certs(ca_certs, cli_realm,
|
||||
ca_subject)
|
||||
ca_certs_trust = [(c, n,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,30 +34,40 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_setup_ntp
|
||||
short description: Setup NTP for IPA client
|
||||
short_description: Setup NTP for IPA client
|
||||
description:
|
||||
Setup NTP for IPA client
|
||||
options:
|
||||
ntp_servers:
|
||||
description: ntp servers to use
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
ntp_pool:
|
||||
description: ntp server pool to use
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
no_ntp:
|
||||
description: Do not configure ntp
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
on_master:
|
||||
description: Whether the configuration is done on the master or not
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -68,7 +78,7 @@ RETURN = '''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging,
|
||||
setup_logging, check_imports,
|
||||
options, sysrestore, paths, sync_time, logger, ipadiscovery,
|
||||
timeconf, getargspec
|
||||
)
|
||||
@@ -78,19 +88,22 @@ def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
ntp_servers=dict(required=False, type='list', default=None),
|
||||
ntp_pool=dict(required=False, default=None),
|
||||
ntp_servers=dict(required=False, type='list', elements='str',
|
||||
default=None),
|
||||
ntp_pool=dict(required=False, type='str', default=None),
|
||||
no_ntp=dict(required=False, type='bool', default=False),
|
||||
# force_ntpd=dict(required=False, type='bool', default=False),
|
||||
on_master=dict(required=False, type='bool', default=False),
|
||||
# additional
|
||||
servers=dict(required=False, type='list', default=None),
|
||||
domain=dict(required=False, default=None),
|
||||
servers=dict(required=False, type='list', elements='str',
|
||||
default=None),
|
||||
domain=dict(required=False, type='str', default=None),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
# module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
options.ntp_servers = module.params.get('ntp_servers')
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,27 +34,37 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_setup_ssh
|
||||
short description: Configure ssh and sshd for IPA client
|
||||
short_description: Configure ssh and sshd for IPA client
|
||||
description:
|
||||
Configure ssh and sshd for IPA client
|
||||
options:
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
type: list
|
||||
elements: str
|
||||
required: yes
|
||||
no_ssh:
|
||||
description: Do not configure OpenSSH client
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
ssh_trust_dns:
|
||||
description: Configure OpenSSH client to trust DNS SSHFP records
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
no_sshd:
|
||||
description: Do not configure OpenSSH server
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
sssd:
|
||||
description: The installer sssd setting
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -71,7 +81,7 @@ RETURN = '''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging,
|
||||
setup_logging, check_imports,
|
||||
options, sysrestore, paths, configure_ssh_config, configure_sshd_config
|
||||
)
|
||||
|
||||
@@ -79,16 +89,17 @@ from ansible.module_utils.ansible_ipa_client import (
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
servers=dict(required=True, type='list', elements='str'),
|
||||
no_ssh=dict(required=False, type='bool', default='no'),
|
||||
ssh_trust_dns=dict(required=False, type='bool', default='no'),
|
||||
no_sshd=dict(required=False, type='bool', default='no'),
|
||||
sssd=dict(required=False, type='bool', default='no'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
options.servers = module.params.get('servers')
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -33,60 +33,75 @@ ANSIBLE_METADATA = {
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_setup_ssd
|
||||
short description: Setup sssd for IPA client
|
||||
module: ipaclient_setup_sssd
|
||||
short_description: Setup sssd for IPA client
|
||||
description:
|
||||
Setup sssd for IPA client
|
||||
options:
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
type: list
|
||||
elements: str
|
||||
required: yes
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
on_master:
|
||||
description: Whether the configuration is done on the master or not
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_ssh:
|
||||
description: Do not configure OpenSSH client
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_sshd:
|
||||
description: Do not configure OpenSSH server
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_sudo:
|
||||
description: Do not configure SSSD as data source for sudo
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
all_ip_addresses:
|
||||
description:
|
||||
All routable IP addresses configured on any interface will be added
|
||||
to DNS
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
fixed_primary:
|
||||
description: Configure sssd to use fixed server as primary IPA server
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
permit:
|
||||
description: Disable access rules by default, permit all access
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
enable_dns_updates:
|
||||
description:
|
||||
Configures the machine to attempt dns updates when the ip address
|
||||
changes
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
preserve_sssd:
|
||||
description: Preserve old SSSD configuration if possible
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_krb5_offline_passwords:
|
||||
description:
|
||||
Configure SSSD not to store user password when the server is offline
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -104,17 +119,18 @@ RETURN = '''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging, options, sysrestore, paths, configure_sssd_conf, logger
|
||||
setup_logging, check_imports, options, sysrestore, paths,
|
||||
configure_sssd_conf, logger
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
domain=dict(required=True),
|
||||
realm=dict(required=True),
|
||||
hostname=dict(required=True),
|
||||
servers=dict(required=True, type='list', elements='str'),
|
||||
domain=dict(required=True, type='str'),
|
||||
realm=dict(required=True, type='str'),
|
||||
hostname=dict(required=True, type='str'),
|
||||
on_master=dict(required=False, type='bool'),
|
||||
no_ssh=dict(required=False, type='bool'),
|
||||
no_sshd=dict(required=False, type='bool'),
|
||||
@@ -127,12 +143,13 @@ def main():
|
||||
preserve_sssd=dict(required=False, type='bool'),
|
||||
no_krb5_offline_passwords=dict(required=False, type='bool'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
# ansible_log = AnsibleModuleLog(module, logger)
|
||||
# options.set_logger(ansible_log)
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
cli_server = module.params.get('servers')
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,76 +34,105 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_test
|
||||
short description: Tries to discover IPA server
|
||||
short_description: Tries to discover IPA server
|
||||
description:
|
||||
Tries to discover IPA server using DNS or host name
|
||||
options:
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
ntp_servers:
|
||||
description: ntp servers to use
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
ntp_pool:
|
||||
description: ntp server pool to use
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
no_ntp:
|
||||
description: Do not configure ntp
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
force_ntpd:
|
||||
description:
|
||||
Stop and disable any time&date synchronization services besides ntpd
|
||||
Deprecated since 4.7
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
nisdomain:
|
||||
description: The NIS domain name
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
no_nisdomain:
|
||||
description: Do not configure NIS domain name
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
kinit_attempts:
|
||||
description: Repeat the request for host Kerberos ticket X times
|
||||
required: yes
|
||||
type: int
|
||||
required: no
|
||||
ca_cert_files:
|
||||
description:
|
||||
List of files containing CA certificates for the service certificate
|
||||
files
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
configure_firefox:
|
||||
description: Configure Firefox to use IPA domain credentials
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
firefox_dir:
|
||||
description:
|
||||
Specify directory where Firefox is installed (for example
|
||||
'/usr/lib/firefox')
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
ip_addresses:
|
||||
description: List of Master Server IP Addresses
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
all_ip_addresses:
|
||||
description:
|
||||
All routable IP addresses configured on any interface will be added
|
||||
to DNS
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
on_master:
|
||||
description: Whether the configuration is done on the master or not
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
enable_dns_updates:
|
||||
description:
|
||||
Configures the machine to attempt dns updates when the ip address
|
||||
changes
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -142,36 +171,37 @@ servers:
|
||||
description: The list of detected or passed in IPA servers.
|
||||
returned: always
|
||||
type: list
|
||||
elements: str
|
||||
sample: ["server1.example.com","server2.example.com"]
|
||||
domain:
|
||||
description: The DNS domain of the detected or passed in IPA deployment.
|
||||
returned: always
|
||||
type: string
|
||||
type: str
|
||||
sample: example.com
|
||||
realm:
|
||||
description: The Kerberos realm of the detected or passed in IPA deployment.
|
||||
returned: always
|
||||
type: string
|
||||
type: str
|
||||
sample: EXAMPLE.COM
|
||||
kdc:
|
||||
description: The detected KDC server name.
|
||||
returned: always
|
||||
type: string
|
||||
type: str
|
||||
sample: server1.example.com
|
||||
basedn:
|
||||
description: The basedn of the detected IPA server.
|
||||
returned: always
|
||||
type: string
|
||||
type: str
|
||||
sample: dc=example,dc=com
|
||||
hostname:
|
||||
description: The detected or passed in FQDN hostname of the client.
|
||||
returned: always
|
||||
type: string
|
||||
type: str
|
||||
sample: client1.example.com
|
||||
client_domain:
|
||||
description: The domain name of the client.
|
||||
returned: always
|
||||
type: string
|
||||
type: str
|
||||
sample: example.com
|
||||
dnsok:
|
||||
description: True if DNS discovery worked and not passed in any servers.
|
||||
@@ -181,6 +211,7 @@ ntp_servers:
|
||||
description: The list of detected NTP servers.
|
||||
returned: always
|
||||
type: list
|
||||
elements: str
|
||||
sample: ["ntp.example.com"]
|
||||
ipa_python_version:
|
||||
description: >
|
||||
@@ -192,7 +223,9 @@ ipa_python_version:
|
||||
nosssd_files:
|
||||
description: >
|
||||
The dist of nss_ldap or nss-pam-ldapd files if sssd is disabled
|
||||
returned: always
|
||||
type: list
|
||||
elements: str
|
||||
'''
|
||||
|
||||
import os
|
||||
@@ -205,7 +238,7 @@ except ImportError:
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging,
|
||||
setup_logging, check_imports,
|
||||
paths, sysrestore, options, CheckedIPAddress, validate_domain_name,
|
||||
logger, x509, normalize_hostname, installer, version, ScriptError,
|
||||
CLIENT_INSTALL_ERROR, tasks, check_ldap_conf, timeconf, constants,
|
||||
@@ -270,31 +303,36 @@ def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
domain=dict(required=False, default=None),
|
||||
servers=dict(required=False, type='list', default=None),
|
||||
realm=dict(required=False, default=None),
|
||||
hostname=dict(required=False, default=None),
|
||||
ntp_servers=dict(required=False, type='list', default=None),
|
||||
ntp_pool=dict(required=False, default=None),
|
||||
domain=dict(required=False, type='str', default=None),
|
||||
servers=dict(required=False, type='list', elements='str',
|
||||
default=None),
|
||||
realm=dict(required=False, type='str', default=None),
|
||||
hostname=dict(required=False, type='str', default=None),
|
||||
ntp_servers=dict(required=False, type='list', elements='str',
|
||||
default=None),
|
||||
ntp_pool=dict(required=False, type='str', default=None),
|
||||
no_ntp=dict(required=False, type='bool', default=False),
|
||||
force_ntpd=dict(required=False, type='bool', default=False),
|
||||
nisdomain=dict(required=False, default=None),
|
||||
nisdomain=dict(required=False, type='str', default=None),
|
||||
no_nisdomain=dict(required=False, type='bool', default='no'),
|
||||
kinit_attempts=dict(required=False, type='int'),
|
||||
ca_cert_files=dict(required=False, type='list', default=None),
|
||||
ca_cert_files=dict(required=False, type='list', elements='str',
|
||||
default=None),
|
||||
configure_firefox=dict(required=False, type='bool', default=False),
|
||||
firefox_dir=dict(required=False),
|
||||
ip_addresses=dict(required=False, type='list', default=None),
|
||||
firefox_dir=dict(required=False, type='str'),
|
||||
ip_addresses=dict(required=False, type='list', elements='str',
|
||||
default=None),
|
||||
all_ip_addresses=dict(required=False, type='bool', default=False),
|
||||
on_master=dict(required=False, type='bool', default=False),
|
||||
# sssd
|
||||
enable_dns_updates=dict(required=False, type='bool',
|
||||
default=False),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
# module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
options.domain_name = module.params.get('domain')
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,7 +34,7 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_test_keytab
|
||||
short description:
|
||||
short_description:
|
||||
Test if the krb5.keytab on the machine is valid and can be used.
|
||||
description:
|
||||
Test if the krb5.keytab on the machine is valid and can be used.
|
||||
@@ -42,24 +42,31 @@ description:
|
||||
options:
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
type: list
|
||||
elements: str
|
||||
required: yes
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
kdc:
|
||||
description: The name or address of the host running the KDC
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
kinit_attempts:
|
||||
description: Repeat the request for host Kerberos ticket X times
|
||||
required: yes
|
||||
type: int
|
||||
default: 5
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -91,6 +98,7 @@ krb5_keytab_ok:
|
||||
ca_crt_exists:
|
||||
description: The flag describes if ca.crt exists.
|
||||
returned: always
|
||||
type: str
|
||||
krb5_conf_ok:
|
||||
description: The flag describes if krb5.conf on the host is usable.
|
||||
returned: always
|
||||
@@ -106,7 +114,7 @@ import tempfile
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
setup_logging,
|
||||
setup_logging, check_imports,
|
||||
SECURE_PATH, paths, kinit_keytab, run, GSSError, configure_krb5_conf
|
||||
)
|
||||
|
||||
@@ -114,17 +122,18 @@ from ansible.module_utils.ansible_ipa_client import (
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
domain=dict(required=True),
|
||||
realm=dict(required=True),
|
||||
hostname=dict(required=True),
|
||||
kdc=dict(required=True),
|
||||
servers=dict(required=True, type='list', elements='str'),
|
||||
domain=dict(required=True, type='str'),
|
||||
realm=dict(required=True, type='str'),
|
||||
hostname=dict(required=True, type='str'),
|
||||
kdc=dict(required=True, type='str'),
|
||||
kinit_attempts=dict(required=False, type='int', default=5),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
check_imports(module)
|
||||
setup_logging()
|
||||
|
||||
servers = module.params.get('servers')
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-client-install code
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# Copyright (C) 2017-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -46,17 +46,36 @@ __all__ = ["gssapi", "version", "ipadiscovery", "api", "errors", "x509",
|
||||
"configure_nslcd_conf", "configure_ssh_config",
|
||||
"configure_sshd_config", "configure_automount",
|
||||
"configure_firefox", "sync_time", "check_ldap_conf",
|
||||
"sssd_enable_ifp", "getargspec"]
|
||||
"sssd_enable_ifp", "getargspec", "paths", "options",
|
||||
"IPA_PYTHON_VERSION", "NUM_VERSION", "certdb", "get_ca_cert",
|
||||
"ipalib", "logger", "ipautil", "installer"]
|
||||
|
||||
import sys
|
||||
|
||||
# HACK: workaround for Ansible 2.9
|
||||
# https://github.com/ansible/ansible/issues/68361
|
||||
if 'ansible.executor' in sys.modules:
|
||||
for attr in __all__:
|
||||
setattr(sys.modules[__name__], attr, None)
|
||||
# Import getargspec from inspect or provide own getargspec for
|
||||
# Python 2 compatibility with Python 3.11+.
|
||||
try:
|
||||
from inspect import getargspec
|
||||
except ImportError:
|
||||
from collections import namedtuple
|
||||
from inspect import getfullargspec
|
||||
|
||||
else:
|
||||
# The code is copied from Python 3.10 inspect.py
|
||||
# Authors: Ka-Ping Yee <ping@lfw.org>
|
||||
# Yury Selivanov <yselivanov@sprymix.com>
|
||||
ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
|
||||
|
||||
def getargspec(func):
|
||||
args, varargs, varkw, defaults, kwonlyargs, _kwonlydefaults, \
|
||||
ann = getfullargspec(func)
|
||||
if kwonlyargs or ann:
|
||||
raise ValueError(
|
||||
"Function has keyword-only parameters or annotations"
|
||||
", use inspect.signature() API which can support them")
|
||||
return ArgSpec(args, varargs, varkw, defaults)
|
||||
|
||||
|
||||
try:
|
||||
from ipapython.version import NUM_VERSION, VERSION
|
||||
|
||||
if NUM_VERSION < 30201:
|
||||
@@ -113,33 +132,12 @@ else:
|
||||
import gssapi
|
||||
import logging
|
||||
|
||||
# Import getargspec from inspect or provide own getargspec for
|
||||
# Python 2 compatibility with Python 3.11+.
|
||||
try:
|
||||
from inspect import getargspec
|
||||
except ImportError:
|
||||
from collections import namedtuple
|
||||
from inspect import getfullargspec
|
||||
|
||||
# The code is copied from Python 3.10 inspect.py
|
||||
# Authors: Ka-Ping Yee <ping@lfw.org>
|
||||
# Yury Selivanov <yselivanov@sprymix.com>
|
||||
ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
|
||||
|
||||
def getargspec(func):
|
||||
args, varargs, varkw, defaults, kwonlyargs, _kwonlydefaults, \
|
||||
ann = getfullargspec(func)
|
||||
if kwonlyargs or ann:
|
||||
raise ValueError(
|
||||
"Function has keyword-only parameters or annotations"
|
||||
", use inspect.signature() API which can support them")
|
||||
return ArgSpec(args, varargs, varkw, defaults)
|
||||
|
||||
from ipapython import version
|
||||
try:
|
||||
from ipaclient.install import ipadiscovery
|
||||
except ImportError:
|
||||
from ipaclient import ipadiscovery
|
||||
import ipalib
|
||||
from ipalib import api, errors, x509
|
||||
from ipalib import constants
|
||||
try:
|
||||
@@ -312,6 +310,15 @@ else:
|
||||
|
||||
raise Exception("freeipa version '%s' is too old" % VERSION)
|
||||
|
||||
except ImportError as _err:
|
||||
ANSIBLE_IPA_CLIENT_MODULE_IMPORT_ERROR = str(_err)
|
||||
|
||||
for attr in __all__:
|
||||
setattr(sys.modules[__name__], attr, None)
|
||||
|
||||
else:
|
||||
ANSIBLE_IPA_CLIENT_MODULE_IMPORT_ERROR = None
|
||||
|
||||
|
||||
def setup_logging():
|
||||
standard_logging_setup(
|
||||
@@ -333,3 +340,8 @@ def ansible_module_get_parsed_ip_addresses(ansible_module,
|
||||
ansible_module.fail_json(msg="Invalid IP Address %s: %s" % (ip, e))
|
||||
ip_addrs.append(ip_parsed)
|
||||
return ip_addrs
|
||||
|
||||
|
||||
def check_imports(module):
|
||||
if ANSIBLE_IPA_CLIENT_MODULE_IMPORT_ERROR is not None:
|
||||
module.fail_json(msg=ANSIBLE_IPA_CLIENT_MODULE_IMPORT_ERROR)
|
||||
|
||||
@@ -18,15 +18,35 @@
|
||||
when: ipaclient_no_dns_lookup | bool and groups.ipaserver is defined and
|
||||
ipaclient_servers is not defined
|
||||
|
||||
- name: Install - Check that either principal or keytab is set
|
||||
fail: msg="ipaadmin_principal and ipaadmin_keytab cannot be used together"
|
||||
when: ipaadmin_keytab is defined and ipaadmin_principal is defined
|
||||
- name: Install - Check that either password or keytab is set
|
||||
fail: msg="ipaadmin_password and ipaadmin_keytab cannot be used together"
|
||||
when: ipaadmin_keytab is defined and ipaadmin_password is defined
|
||||
|
||||
- name: Install - Set default principal if no keytab is given
|
||||
set_fact:
|
||||
ipaadmin_principal: admin
|
||||
when: ipaadmin_principal is undefined and ipaclient_keytab is undefined
|
||||
|
||||
- name: Install - Configure DNS resolver Block
|
||||
block:
|
||||
|
||||
- name: Install - Fail on missing ipaclient_domain and ipaserver_domain
|
||||
fail: msg="ipaclient_domain or ipaserver_domain is required for ipaclient_configure_dns_resolver"
|
||||
when: ipaserver_domain is not defined and ipaclient_domain is not defined
|
||||
|
||||
- name: Install - Fail on missing ipaclient_servers
|
||||
fail: msg="ipaclient_dns_servers is required for ipaclient_configure_dns_resolver"
|
||||
when: ipaclient_dns_servers is not defined
|
||||
|
||||
- name: Install - Configure DNS resolver
|
||||
ipaclient_configure_dns_resolver:
|
||||
nameservers: "{{ ipaclient_dns_servers }}"
|
||||
searchdomains: "{{ ipaserver_domain | default(ipaclient_domain) }}"
|
||||
state: present
|
||||
|
||||
when: ipaclient_configure_dns_resolver | bool
|
||||
and not ipaclient_on_master | bool
|
||||
|
||||
- name: Install - IPA client test
|
||||
ipaclient_test:
|
||||
### basic ###
|
||||
@@ -99,35 +119,44 @@
|
||||
not ipaclient_force_join | bool
|
||||
|
||||
# The following block is executed when using OTP to enroll IPA client and
|
||||
# the OTP isn't predefined, ie when ipaclient_use_otp is set and ipaclient_otp
|
||||
# is not set.
|
||||
# the OTP isn't predefined, ie when ipaclient_use_otp is set and
|
||||
# ipaclient_otp is not set.
|
||||
# It connects to ipaserver and add the host with --random option in order
|
||||
# to create a OneTime Password
|
||||
# If a keytab is specified in the hostent, then the hostent will be disabled
|
||||
# if ipaclient_use_otp is set.
|
||||
- block:
|
||||
- name: Install - Keytab or password is required for getting otp
|
||||
fail: msg="Keytab or password is required for getting otp"
|
||||
ansible.builtin.fail:
|
||||
msg: Keytab or password is required for getting otp
|
||||
when: ipaadmin_keytab is undefined and ipaadmin_password is undefined
|
||||
|
||||
- name: Install - Create temporary file for keytab
|
||||
ansible.builtin.tempfile:
|
||||
state: file
|
||||
prefix: ipaclient_temp_
|
||||
path: /root
|
||||
register: keytab_temp
|
||||
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
||||
when: ipaadmin_keytab is defined
|
||||
|
||||
- name: Install - Copy keytab to server temporary file
|
||||
ansible.builtin.copy:
|
||||
src: "{{ ipaadmin_keytab }}"
|
||||
dest: "{{ keytab_temp.path }}"
|
||||
mode: 0600
|
||||
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
||||
when: ipaadmin_keytab is defined
|
||||
|
||||
- name: Install - Get One-Time Password for client enrollment
|
||||
no_log: yes
|
||||
ipaclient_get_otp:
|
||||
state: present
|
||||
principal: "{{ ipaadmin_principal | default(omit) }}"
|
||||
password: "{{ ipaadmin_password | default(omit) }}"
|
||||
keytab: "{{ ipaadmin_keytab | default(omit) }}"
|
||||
fqdn: "{{ result_ipaclient_test.hostname }}"
|
||||
lifetime: "{{ ipaclient_lifetime | default(omit) }}"
|
||||
random: True
|
||||
ipaadmin_principal: "{{ ipaadmin_principal | default(omit) }}"
|
||||
ipaadmin_password: "{{ ipaadmin_password | default(omit) }}"
|
||||
ipaadmin_keytab: "{{ keytab_temp.path | default(omit) }}"
|
||||
hostname: "{{ result_ipaclient_test.hostname }}"
|
||||
register: result_ipaclient_get_otp
|
||||
# If the host is already enrolled, this command will exit on error
|
||||
# The error can be ignored
|
||||
failed_when: result_ipaclient_get_otp is failed and
|
||||
"Password cannot be set on enrolled host" not
|
||||
in result_ipaclient_get_otp.msg
|
||||
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Install - Report error for OTP generation
|
||||
debug:
|
||||
@@ -144,6 +173,14 @@
|
||||
|
||||
when: ipaclient_use_otp | bool and ipaclient_otp is not defined
|
||||
|
||||
always:
|
||||
- name: Install - Remove keytab temporary file
|
||||
ansible.builtin.file:
|
||||
path: "{{ keytab_temp.path }}"
|
||||
state: absent
|
||||
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
||||
when: keytab_temp.path is defined
|
||||
|
||||
- name: Store predefined OTP in admin_password
|
||||
no_log: yes
|
||||
set_fact:
|
||||
@@ -161,7 +198,7 @@
|
||||
# result_ipaclient_join.already_joined)))
|
||||
|
||||
- name: Install - Check if principal and keytab are set
|
||||
fail: msg="Principal and keytab cannot be used together"
|
||||
fail: msg="Admin principal and client keytab cannot be used together"
|
||||
when: ipaadmin_principal is defined and ipaclient_keytab is defined
|
||||
|
||||
- name: Install - Check if one of password or keytabs are set
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
failed_when: uninstall.rc != 0 and uninstall.rc != 2
|
||||
changed_when: uninstall.rc == 0
|
||||
|
||||
- name: Uninstall - Unconfigure DNS resolver
|
||||
ipaclient_configure_dns_resolver:
|
||||
state: absent
|
||||
when: ipaclient_cleanup_dns_resolver | bool
|
||||
|
||||
#- name: Remove IPA client package
|
||||
# package:
|
||||
# name: "{{ ipaclient_packages }}"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-replica-install code
|
||||
#
|
||||
# Copyright (C) 2018 Red Hat
|
||||
# Copyright (C) 2018-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,27 +34,32 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipareplica_add_to_ipaservers
|
||||
short description: Add to ipaservers
|
||||
short_description: Add to ipaservers
|
||||
description:
|
||||
Add to ipaservers
|
||||
options:
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: no
|
||||
type: bool
|
||||
required: yes
|
||||
config_master_host_name:
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
ccache:
|
||||
description: The local ccache
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
installer_ccache:
|
||||
description: The installer ccache setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
_top_dir:
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -67,7 +72,7 @@ import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, setup_logging, installer, paths,
|
||||
check_imports, AnsibleModuleLog, setup_logging, installer, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_remote_api, api
|
||||
)
|
||||
@@ -84,15 +89,16 @@ def main():
|
||||
# server
|
||||
setup_kra=dict(required=True, type='bool'),
|
||||
# additional
|
||||
config_master_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
installer_ccache=dict(required=True),
|
||||
_top_dir=dict(required=True),
|
||||
config_master_host_name=dict(required=True, type='str'),
|
||||
ccache=dict(required=True, type='str'),
|
||||
installer_ccache=dict(required=True, type='str'),
|
||||
_top_dir=dict(required=True, type='str'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
check_imports(ansible_module)
|
||||
setup_logging()
|
||||
ansible_log = AnsibleModuleLog(ansible_module)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-replica-install code
|
||||
#
|
||||
# Copyright (C) 2018 Red Hat
|
||||
# Copyright (C) 2018-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,98 +34,129 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipareplica_create_ipa_conf
|
||||
short description: Create ipa.conf
|
||||
short_description: Create ipa.conf
|
||||
description:
|
||||
Create ipa.conf
|
||||
options:
|
||||
dm_password:
|
||||
description: Directory Manager password
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
password:
|
||||
description: Admin user kerberos password
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
ip_addresses:
|
||||
description: List of Master Server IP Addresses
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
ca_cert_files:
|
||||
description:
|
||||
List of files containing CA certificates for the service certificate
|
||||
files
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
no_host_dns:
|
||||
description: Do not use DNS for hostname lookup during installation
|
||||
required: yes
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
setup_adtrust:
|
||||
description: Configure AD trust capability
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
setup_dns:
|
||||
description: Configure bind with our zone
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
dirsrv_cert_files:
|
||||
description:
|
||||
Files containing the Directory Server SSL certificate and private key
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
force_join:
|
||||
description: Force client enrollment even if already enrolled
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
server:
|
||||
description: Fully qualified name of IPA server to enroll to
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
config_master_host_name:
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
config_ca_host_name:
|
||||
description: The config ca_host_name setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
ccache:
|
||||
description: The local ccache
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
installer_ccache:
|
||||
description: The installer ccache setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
_ca_enabled:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
_top_dir:
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
_add_to_ipaservers:
|
||||
description: The installer _add_to_ipaservers setting
|
||||
required: no
|
||||
type: bool
|
||||
required: yes
|
||||
_ca_subject:
|
||||
description: The installer _ca_subject setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
_subject_base:
|
||||
description: The installer _subject_base setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
master:
|
||||
description: Master host name
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
dirman_password:
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -138,7 +169,7 @@ import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, setup_logging, installer, DN, paths,
|
||||
check_imports, AnsibleModuleLog, setup_logging, installer, DN, paths,
|
||||
ansible_module_get_parsed_ip_addresses, sysrestore,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, create_ipa_conf
|
||||
@@ -149,13 +180,15 @@ def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
dm_password=dict(required=False, no_log=True),
|
||||
password=dict(required=False, no_log=True),
|
||||
ip_addresses=dict(required=False, type='list', default=[]),
|
||||
domain=dict(required=False),
|
||||
realm=dict(required=False),
|
||||
hostname=dict(required=False),
|
||||
ca_cert_files=dict(required=False, type='list', default=[]),
|
||||
dm_password=dict(required=False, type='str', no_log=True),
|
||||
password=dict(required=False, type='str', no_log=True),
|
||||
ip_addresses=dict(required=False, type='list', elements='str',
|
||||
default=[]),
|
||||
domain=dict(required=False, type='str'),
|
||||
realm=dict(required=False, type='str'),
|
||||
hostname=dict(required=False, type='str'),
|
||||
ca_cert_files=dict(required=False, type='list', elements='str',
|
||||
default=[]),
|
||||
no_host_dns=dict(required=False, type='bool', default=False),
|
||||
# server
|
||||
setup_adtrust=dict(required=False, type='bool'),
|
||||
@@ -163,30 +196,32 @@ def main():
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
setup_dns=dict(required=False, type='bool'),
|
||||
# ssl certificate
|
||||
dirsrv_cert_files=dict(required=False, type='list', default=[]),
|
||||
dirsrv_cert_files=dict(required=False, type='list', elements='str',
|
||||
default=[]),
|
||||
# client
|
||||
force_join=dict(required=False, type='bool'),
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
subject_base=dict(required=True, type='str'),
|
||||
# additional
|
||||
server=dict(required=True),
|
||||
config_master_host_name=dict(required=True),
|
||||
config_ca_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
installer_ccache=dict(required=True),
|
||||
server=dict(required=True, type='str'),
|
||||
config_master_host_name=dict(required=True, type='str'),
|
||||
config_ca_host_name=dict(required=True, type='str'),
|
||||
ccache=dict(required=True, type='str'),
|
||||
installer_ccache=dict(required=True, type='str'),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_top_dir=dict(required=True),
|
||||
_top_dir=dict(required=True, type='str'),
|
||||
_add_to_ipaservers=dict(required=True, type='bool'),
|
||||
_ca_subject=dict(required=True),
|
||||
_subject_base=dict(required=True),
|
||||
master=dict(required=False, default=None),
|
||||
_ca_subject=dict(required=True, type='str'),
|
||||
_subject_base=dict(required=True, type='str'),
|
||||
master=dict(required=False, type='str', default=None),
|
||||
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
check_imports(ansible_module)
|
||||
setup_logging()
|
||||
ansible_log = AnsibleModuleLog(ansible_module)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-replica-install code
|
||||
#
|
||||
# Copyright (C) 2018 Red Hat
|
||||
# Copyright (C) 2018-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,59 +34,74 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipareplica_custodia_import_dm_password
|
||||
short description: Import dm password into custodia
|
||||
short_description: Import dm password into custodia
|
||||
description:
|
||||
Import dm password into custodia
|
||||
options:
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_pkinit:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_ui_redirect:
|
||||
description: Do not automatically redirect to the Web UI
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
ccache:
|
||||
description: The local ccache
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
_ca_enabled:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
_ca_file:
|
||||
description: The installer _ca_file setting
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
_kra_enabled:
|
||||
description: The installer _kra_enabled setting
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
_kra_host_name:
|
||||
description: The installer _kra_host_name setting
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
_top_dir:
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
dirman_password:
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
config_setup_ca:
|
||||
description: The config setup_ca setting
|
||||
required: no
|
||||
type: bool
|
||||
required: yes
|
||||
config_master_host_name:
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
config_ca_host_name:
|
||||
description: The config ca_host_name setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -99,7 +114,7 @@ import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, setup_logging, installer, DN, paths,
|
||||
check_imports, AnsibleModuleLog, setup_logging, installer, DN, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, redirect_stdout, custodiainstance,
|
||||
getargspec
|
||||
@@ -115,23 +130,24 @@ def main():
|
||||
no_pkinit=dict(required=False, type='bool'),
|
||||
no_ui_redirect=dict(required=False, type='bool'),
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
subject_base=dict(required=True, type='str'),
|
||||
# additional
|
||||
ccache=dict(required=True),
|
||||
ccache=dict(required=True, type='str'),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_ca_file=dict(required=False),
|
||||
_ca_file=dict(required=False, type='str'),
|
||||
_kra_enabled=dict(required=False, type='bool'),
|
||||
_kra_host_name=dict(required=False),
|
||||
_top_dir=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
_kra_host_name=dict(required=False, type='str'),
|
||||
_top_dir=dict(required=True, type='str'),
|
||||
dirman_password=dict(required=True, type='str', no_log=True),
|
||||
config_setup_ca=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
config_ca_host_name=dict(required=True),
|
||||
config_master_host_name=dict(required=True, type='str'),
|
||||
config_ca_host_name=dict(required=True, type='str'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
check_imports(ansible_module)
|
||||
setup_logging()
|
||||
ansible_log = AnsibleModuleLog(ansible_module)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-replica-install code
|
||||
#
|
||||
# Copyright (C) 2018 Red Hat
|
||||
# Copyright (C) 2018-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,61 +34,78 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipareplica_ds_apply_updates
|
||||
short description: DS apply updates
|
||||
short_description: DS apply updates
|
||||
description:
|
||||
DS apply updates
|
||||
options:
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_pkinit:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_ui_redirect:
|
||||
description: Do not automatically redirect to the Web UI
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
dirsrv_config_file:
|
||||
description:
|
||||
The path to LDIF file that will be used to modify configuration of
|
||||
dse.ldif during installation of the directory server instance
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
config_master_host_name:
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
ccache:
|
||||
description: The local ccache
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
_ca_enabled:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
_ca_file:
|
||||
description: The installer _ca_file setting
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
_dirsrv_pkcs12_info:
|
||||
description: The installer _dirsrv_pkcs12_info setting
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
_pkinit_pkcs12_info:
|
||||
description: The installer _pkinit_pkcs12_info setting
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
_top_dir:
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
dirman_password:
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
ds_ca_subject:
|
||||
description: The ds.ca_subject setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -101,7 +118,7 @@ import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, setup_logging, installer, DN, paths,
|
||||
check_imports, AnsibleModuleLog, setup_logging, installer, DN, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout,
|
||||
replica_ds_init_info, dsinstance, upgradeinstance, installutils
|
||||
@@ -116,24 +133,27 @@ def main():
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
no_pkinit=dict(required=False, type='bool'),
|
||||
no_ui_redirect=dict(required=False, type='bool'),
|
||||
dirsrv_config_file=dict(required=False),
|
||||
dirsrv_config_file=dict(required=False, type='str'),
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
subject_base=dict(required=True, type='str'),
|
||||
# additional
|
||||
config_master_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
config_master_host_name=dict(required=True, type='str'),
|
||||
ccache=dict(required=True, type='str'),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_ca_file=dict(required=False),
|
||||
_dirsrv_pkcs12_info=dict(required=False, type='list'),
|
||||
_pkinit_pkcs12_info=dict(required=False, type='list'),
|
||||
_top_dir=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
ds_ca_subject=dict(required=True),
|
||||
_ca_file=dict(required=False, type='str'),
|
||||
_dirsrv_pkcs12_info=dict(required=False, type='list',
|
||||
elements='str'),
|
||||
_pkinit_pkcs12_info=dict(required=False, type='list',
|
||||
elements='str'),
|
||||
_top_dir=dict(required=True, type='str'),
|
||||
dirman_password=dict(required=True, type='str', no_log=True),
|
||||
ds_ca_subject=dict(required=True, type='str'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
check_imports(ansible_module)
|
||||
setup_logging()
|
||||
ansible_log = AnsibleModuleLog(ansible_module)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-replica-install code
|
||||
#
|
||||
# Copyright (C) 2018 Red Hat
|
||||
# Copyright (C) 2018-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,58 +34,74 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipareplica_ds_enable_ssl
|
||||
short description: DS enable SSL
|
||||
short_description: DS enable SSL
|
||||
description:
|
||||
DS enable SSL
|
||||
options:
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
no_pkinit:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
dirsrv_config_file:
|
||||
description:
|
||||
The path to LDIF file that will be used to modify configuration of
|
||||
dse.ldif during installation of the directory server instance
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
config_master_host_name:
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
ccache:
|
||||
description: The local ccache
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
_ca_enabled:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
type: bool
|
||||
required: no
|
||||
_ca_file:
|
||||
description: The installer _ca_file setting
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
_dirsrv_pkcs12_info:
|
||||
description: The installer _dirsrv_pkcs12_info setting
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
_pkinit_pkcs12_info:
|
||||
description: The installer _pkinit_pkcs12_info setting
|
||||
required: yes
|
||||
type: list
|
||||
elements: str
|
||||
required: no
|
||||
_top_dir:
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
dirman_password:
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
ds_ca_subject:
|
||||
description: The ds.ca_subject setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -98,7 +114,7 @@ import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, setup_logging, installer, DN, paths,
|
||||
check_imports, AnsibleModuleLog, setup_logging, installer, DN, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout,
|
||||
replica_ds_init_info
|
||||
@@ -112,24 +128,27 @@ def main():
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
no_pkinit=dict(required=False, type='bool'),
|
||||
dirsrv_config_file=dict(required=False),
|
||||
dirsrv_config_file=dict(required=False, type='str'),
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
subject_base=dict(required=True, type='str'),
|
||||
# additional
|
||||
config_master_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
config_master_host_name=dict(required=True, type='str'),
|
||||
ccache=dict(required=True, type='str'),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_ca_file=dict(required=False),
|
||||
_dirsrv_pkcs12_info=dict(required=False, type='list'),
|
||||
_pkinit_pkcs12_info=dict(required=False, type='list'),
|
||||
_top_dir=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
ds_ca_subject=dict(required=True),
|
||||
_ca_file=dict(required=False, type='str'),
|
||||
_dirsrv_pkcs12_info=dict(required=False, type='list',
|
||||
elements='str'),
|
||||
_pkinit_pkcs12_info=dict(required=False, type='list',
|
||||
elements='str'),
|
||||
_top_dir=dict(required=True, type='str'),
|
||||
dirman_password=dict(required=True, type='str', no_log=True),
|
||||
ds_ca_subject=dict(required=True, type='str'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
check_imports(ansible_module)
|
||||
setup_logging()
|
||||
ansible_log = AnsibleModuleLog(ansible_module)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Based on ipa-replica-install code
|
||||
#
|
||||
# Copyright (C) 2018 Red Hat
|
||||
# Copyright (C) 2018-2022 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -34,38 +34,47 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipareplica_enable_ipa
|
||||
short description: Enable IPA
|
||||
short_description: Enable IPA
|
||||
description: Enable IPA
|
||||
Enable IPA
|
||||
options:
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
type: str
|
||||
required: no
|
||||
hidden_replica:
|
||||
description: Install a hidden replica
|
||||
required: yes
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
ccache:
|
||||
description: The local ccache
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
_top_dir:
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: no
|
||||
type: bool
|
||||
required: yes
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: no
|
||||
type: bool
|
||||
required: yes
|
||||
config_master_host_name:
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
type: str
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -78,7 +87,7 @@ import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, setup_logging, installer, DN, paths,
|
||||
check_imports, AnsibleModuleLog, setup_logging, installer, DN, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, service,
|
||||
find_providing_servers, services
|
||||
@@ -88,22 +97,23 @@ from ansible.module_utils.ansible_ipa_replica import (
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
hostname=dict(required=False),
|
||||
hostname=dict(required=False, type='str'),
|
||||
hidden_replica=dict(required=False, type='bool', default=False),
|
||||
# server
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
subject_base=dict(required=True, type='str'),
|
||||
# additional
|
||||
ccache=dict(required=True),
|
||||
_top_dir=dict(required=True),
|
||||
ccache=dict(required=True, type='str'),
|
||||
_top_dir=dict(required=True, type='str'),
|
||||
setup_ca=dict(required=True, type='bool'),
|
||||
setup_kra=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
config_master_host_name=dict(required=True, type='str'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
supports_check_mode=False,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
check_imports(ansible_module)
|
||||
setup_logging()
|
||||
ansible_log = AnsibleModuleLog(ansible_module)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user