mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-03-27 13:53:06 +00:00
Compare commits
410 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c23ae5b37 | ||
|
|
3b4367cf89 | ||
|
|
e96f92c36f | ||
|
|
683a894876 | ||
|
|
2761c7e8d9 | ||
|
|
7d3921e510 | ||
|
|
6000aac687 | ||
|
|
e8354932b4 | ||
|
|
a3089484b1 | ||
|
|
1469ac6058 | ||
|
|
308d970b6c | ||
|
|
7b470ceb60 | ||
|
|
77f5d8751f | ||
|
|
3292252802 | ||
|
|
414dc06c86 | ||
|
|
d2f9fe6325 | ||
|
|
d7c02d1347 | ||
|
|
cc6a80fa88 | ||
|
|
fe6edbabdb | ||
|
|
434905432d | ||
|
|
9f773ff5ac | ||
|
|
e95bec1803 | ||
|
|
ea709ebc4d | ||
|
|
add89c25ee | ||
|
|
9108065ea7 | ||
|
|
6cac891287 | ||
|
|
fc5fc9d9ef | ||
|
|
670740bdc0 | ||
|
|
529deae407 | ||
|
|
a945862540 | ||
|
|
8240d9beb6 | ||
|
|
6da6110432 | ||
|
|
1d8deb8e2d | ||
|
|
b3856a1e2c | ||
|
|
410682a01d | ||
|
|
ee59ec2142 | ||
|
|
d043a3bdd1 | ||
|
|
5062ac2b09 | ||
|
|
292e2eb60e | ||
|
|
baa7cae8bf | ||
|
|
6b7633976c | ||
|
|
9a32359a5d | ||
|
|
82e176af95 | ||
|
|
2a1ecdbd83 | ||
|
|
f8b5851610 | ||
|
|
b760863847 | ||
|
|
e3bf82d873 | ||
|
|
76ca587d76 | ||
|
|
5c630d6021 | ||
|
|
483d51b418 | ||
|
|
ba353a9b16 | ||
|
|
56560855b4 | ||
|
|
a8d44e2c52 | ||
|
|
b175c78c95 | ||
|
|
198298b2d0 | ||
|
|
d5269c83e6 | ||
|
|
9d47ffc2b9 | ||
|
|
feadbfce95 | ||
|
|
a9257e7f44 | ||
|
|
d204b6d480 | ||
|
|
c645841444 | ||
|
|
f2a0edeb25 | ||
|
|
45baf5c108 | ||
|
|
deec31c3ab | ||
|
|
fea480b348 | ||
|
|
defd1e4e92 | ||
|
|
adc262bcb0 | ||
|
|
72b4b89116 | ||
|
|
473ed03e26 | ||
|
|
d546b4614d | ||
|
|
872537f4de | ||
|
|
d6658347c9 | ||
|
|
062b53a676 | ||
|
|
470d0ddc1b | ||
|
|
2e707a48cb | ||
|
|
971d40c3a9 | ||
|
|
7d89af48b6 | ||
|
|
03ce096fbb | ||
|
|
91edff3b21 | ||
|
|
84c0188023 | ||
|
|
1f91730b17 | ||
|
|
99c7acbe5f | ||
|
|
14706cc49e | ||
|
|
dde5b06b97 | ||
|
|
c7e83685e3 | ||
|
|
882d60515d | ||
|
|
27cbd40182 | ||
|
|
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 | ||
|
|
c251632368 | ||
|
|
452d20e28d | ||
|
|
c7699472a6 | ||
|
|
eba457d5ff | ||
|
|
809e423947 | ||
|
|
e5f0ab2fe4 | ||
|
|
f85c60676c | ||
|
|
f9bf0cfec0 | ||
|
|
8f0d983845 | ||
|
|
aed5edae33 | ||
|
|
889b2a5576 | ||
|
|
e9d637c57a | ||
|
|
b3a97eacec | ||
|
|
aa745100e3 | ||
|
|
23faa83a0b | ||
|
|
12729fc2c0 | ||
|
|
31810ad7c0 | ||
|
|
9dcff9a308 | ||
|
|
e500c133c0 | ||
|
|
a5306b2db5 | ||
|
|
8ab3aa06ff | ||
|
|
87ff15a92c | ||
|
|
c8d5cb7ee2 | ||
|
|
2fa4aa60b1 | ||
|
|
4332636fd2 | ||
|
|
266f79b55f | ||
|
|
07b056ad25 | ||
|
|
7db5d59de1 | ||
|
|
e19e16c734 | ||
|
|
0ff119a2a8 | ||
|
|
90f6e14c40 | ||
|
|
e044310dad | ||
|
|
4be7a9fba0 | ||
|
|
98959807d2 | ||
|
|
a16379cfa0 | ||
|
|
672413f4dd | ||
|
|
8af4329fac | ||
|
|
9932b1dc98 | ||
|
|
1c44898e68 | ||
|
|
f44dc55b90 | ||
|
|
65b106449e | ||
|
|
7501c84844 | ||
|
|
d45e6ac399 | ||
|
|
d990832681 | ||
|
|
b998597815 | ||
|
|
d51ee9dc69 | ||
|
|
fdfea1b6fb | ||
|
|
ac92ed1408 | ||
|
|
757b89dfae | ||
|
|
914e4879f8 | ||
|
|
13cff6354b | ||
|
|
4ff5aaa172 | ||
|
|
d82abdbef9 | ||
|
|
5aa80204d5 | ||
|
|
8b8cbdd8c2 | ||
|
|
a06b16f5bc | ||
|
|
dc99b821eb | ||
|
|
796f84357a | ||
|
|
9e6c79abbb | ||
|
|
d3af87c731 | ||
|
|
7011283335 | ||
|
|
0297cbe973 | ||
|
|
1ec0d1e640 |
@@ -10,10 +10,17 @@ exclude_paths:
|
||||
- molecule/
|
||||
- tests/azure/
|
||||
- meta/runtime.yml
|
||||
- requirements-docker.yml
|
||||
- requirements-podman.yml
|
||||
|
||||
kinds:
|
||||
- playbook: '**/tests/**/test_*.yml'
|
||||
- playbook: '**/playbooks/**/*.yml'
|
||||
- playbook: '**/tests/ca-less/install_*_without_ca.yml'
|
||||
- playbook: '**/tests/ca-less/clean_up_certificates.yml'
|
||||
- playbook: '**/tests/external-signed-ca-with-automatic-copy/install-server-with-external-ca-with-automatic-copy.yml'
|
||||
- playbook: '**/tests/external-signed-ca-with-manual-copy/install-server-with-external-ca-with-manual-copy.yml'
|
||||
- playbook: '**/tests/user/create_users_json.yml'
|
||||
- tasks: '**/tasks_*.yml'
|
||||
- tasks: '**/env_*.yml'
|
||||
|
||||
@@ -26,6 +33,8 @@ skip_list:
|
||||
- '305' # Use shell only when shell functionality is required
|
||||
- '306' # risky-shell-pipe
|
||||
- yaml # yamllint should be executed separately.
|
||||
- experimental # Do not run any experimental tests
|
||||
- name[template] # Allow Jinja templating inside task names
|
||||
|
||||
use_default_rules: true
|
||||
|
||||
|
||||
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
|
||||
|
||||
81
.github/workflows/docs.yml
vendored
81
.github/workflows/docs.yml
vendored
@@ -4,42 +4,14 @@ on:
|
||||
- push
|
||||
- pull_request
|
||||
jobs:
|
||||
check_docs_29:
|
||||
name: Check Ansible Documentation with Ansible 2.9.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install Ansible 2.9
|
||||
run: |
|
||||
python -m pip install "ansible < 2.10"
|
||||
- name: Run ansible-doc-test
|
||||
run: |
|
||||
ANSIBLE_LIBRARY="." ANSIBLE_DOC_FRAGMENT_PLUGINS="." python utils/ansible-doc-test -v roles plugins
|
||||
|
||||
check_docs_2_11:
|
||||
name: Check Ansible Documentation with ansible-core 2.11.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install Ansible 2.11
|
||||
run: |
|
||||
python -m pip install "ansible-core >=2.11,<2.12"
|
||||
- name: Run ansible-doc-test
|
||||
run: |
|
||||
ANSIBLE_LIBRARY="." ANSIBLE_DOC_FRAGMENT_PLUGINS="." python utils/ansible-doc-test -v roles plugins
|
||||
|
||||
check_docs_2_12:
|
||||
check_docs_oldest_supported:
|
||||
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
|
||||
@@ -47,15 +19,50 @@ jobs:
|
||||
python -m pip install "ansible-core >=2.12,<2.13"
|
||||
- name: Run ansible-doc-test
|
||||
run: |
|
||||
python -m pip install "ansible-core >=2.12,<2.13"
|
||||
ANSIBLE_LIBRARY="." ANSIBLE_DOC_FRAGMENT_PLUGINS="." python utils/ansible-doc-test -v roles plugins
|
||||
|
||||
check_docs_latest:
|
||||
check_docs_previous:
|
||||
name: Check Ansible Documentation with ansible-core 2.13.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- 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.13
|
||||
run: |
|
||||
python -m pip install "ansible-core >=2.13,<2.14"
|
||||
- name: Run ansible-doc-test
|
||||
run: |
|
||||
ANSIBLE_LIBRARY="." ANSIBLE_DOC_FRAGMENT_PLUGINS="." python utils/ansible-doc-test -v roles plugins
|
||||
|
||||
check_docs_current:
|
||||
name: Check Ansible Documentation with ansible-core 2.14.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- 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.14
|
||||
run: |
|
||||
python -m pip install "ansible-core >=2.14,<2.15"
|
||||
- name: Run ansible-doc-test
|
||||
run: |
|
||||
ANSIBLE_LIBRARY="." ANSIBLE_DOC_FRAGMENT_PLUGINS="." python utils/ansible-doc-test -v roles plugins
|
||||
|
||||
check_docs_ansible_latest:
|
||||
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
|
||||
|
||||
52
.github/workflows/lint.yml
vendored
52
.github/workflows/lint.yml
vendored
@@ -8,36 +8,40 @@ 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
|
||||
run: |
|
||||
pip install ansible-core==2.11.6 ansible-lint
|
||||
find playbooks roles tests -name '*.yml' ! -name "env_*" ! -name "tasks_*" -exec ansible-lint --force-color {} \+
|
||||
env:
|
||||
ANSIBLE_MODULE_UTILS: plugins/module_utils
|
||||
ANSIBLE_LIBRARY: plugins/modules
|
||||
ANSIBLE_DOC_FRAGMENT_PLUGINS: plugins/doc_fragments
|
||||
pip install "ansible-core >=2.14,<2.15" ansible-lint
|
||||
utils/build-galaxy-release.sh -ki
|
||||
cd .galaxy-build
|
||||
ansible-lint
|
||||
|
||||
yamllint:
|
||||
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
|
||||
uses: ibiqlik/action-yamllint@v1
|
||||
uses: ibiqlik/action-yamllint@v3.1.1
|
||||
|
||||
pydocstyle:
|
||||
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,32 +53,38 @@ 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
|
||||
run: |
|
||||
pip install flake8
|
||||
pip install flake8 flake8-bugbear
|
||||
flake8
|
||||
|
||||
pylint:
|
||||
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.14.4 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
repos:
|
||||
- repo: https://github.com/ansible/ansible-lint.git
|
||||
rev: v5.3.2
|
||||
rev: v6.6.1
|
||||
hooks:
|
||||
- id: ansible-lint
|
||||
always_run: false
|
||||
@@ -11,20 +11,20 @@ repos:
|
||||
entry: |
|
||||
env ANSIBLE_LIBRARY=./plugins/modules ANSIBLE_MODULE_UTILS=./plugins/module_utils ANSIBLE_DOC_FRAGMENT_PLUGINS=./plugins/doc_fragments ansible-lint
|
||||
- repo: https://github.com/adrienverge/yamllint.git
|
||||
rev: v1.26.1
|
||||
rev: v1.28.0
|
||||
hooks:
|
||||
- id: yamllint
|
||||
files: \.(yaml|yml)$
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.9.2
|
||||
- repo: https://github.com/pycqa/flake8
|
||||
rev: 5.0.3
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://gitlab.com/pycqa/pydocstyle
|
||||
rev: 6.1.1
|
||||
- repo: https://github.com/pycqa/pydocstyle
|
||||
rev: 6.0.0
|
||||
hooks:
|
||||
- id: pydocstyle
|
||||
- repo: https://github.com/pycqa/pylint
|
||||
rev: v2.12.2
|
||||
rev: v2.14.4
|
||||
hooks:
|
||||
- id: pylint
|
||||
args:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -175,8 +175,8 @@ Variable | Description | Required
|
||||
`rid_base` \| `ipabaserid` | First RID of the corresponding RID range. (int) | no
|
||||
`secondary_rid_base` \| `ipasecondarybaserid` | First RID of the secondary RID range. (int) | no
|
||||
`dom_sid` \| `ipanttrusteddomainsid` | Domain SID of the trusted domain. | no
|
||||
`dom_name` \| `ipanttrusteddomainname` | Name of the trusted domain. | no
|
||||
`idrange_type` \| `iparangetype` | ID range type, one of `ipa-ad-trust`, `ipa-ad-trust-posix`, `ipa-local`. Only valid if idrange does not exist. | no
|
||||
`dom_name` \| `ipanttrusteddomainname` | Name of the trusted domain. Can only be used when `ipaapi_context: server`. | no
|
||||
`auto_private_groups` \| `ipaautoprivategroups` | Auto creation of private groups, one of `true`, `false`, `hybrid`. | no
|
||||
`delete_continue` \| `continue` | Continuous mode: don't stop on errors. Valid only if `state` is `absent`. Default: `no` (bool) | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, default: `present`. | no
|
||||
|
||||
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
|
||||
|
||||
@@ -12,6 +12,7 @@ Features
|
||||
* One-time-password (OTP) support for client installation
|
||||
* Repair mode for clients
|
||||
* Backup and restore, also to and from controller
|
||||
* Smartcard setup for servers and clients
|
||||
* Modules for automembership rule management
|
||||
* Modules for automount key management
|
||||
* Modules for automount location management
|
||||
@@ -30,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
|
||||
@@ -67,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)
|
||||
@@ -287,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
|
||||
@@ -425,6 +426,8 @@ Roles
|
||||
* [Replica](roles/ipareplica/README.md)
|
||||
* [Client](roles/ipaclient/README.md)
|
||||
* [Backup](roles/ipabackup/README.md)
|
||||
* [SmartCard server](roles/ipasmartcard_server/README.md)
|
||||
* [SmartCard client](roles/ipasmartcard_client/README.md)
|
||||
|
||||
Modules in plugin/modules
|
||||
=========================
|
||||
@@ -447,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)
|
||||
|
||||
@@ -1 +1 @@
|
||||
centos-8
|
||||
fedora-latest
|
||||
30
molecule/fedora-rawhide-build/Dockerfile
Normal file
30
molecule/fedora-rawhide-build/Dockerfile
Normal file
@@ -0,0 +1,30 @@
|
||||
FROM fedora:rawhide
|
||||
ENV container=docker
|
||||
|
||||
RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
|
||||
dnf makecache; \
|
||||
dnf --assumeyes install \
|
||||
/usr/bin/python3 \
|
||||
/usr/bin/python3-config \
|
||||
/usr/bin/dnf-3 \
|
||||
sudo \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
iproute && \
|
||||
dnf clean all; \
|
||||
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/*;\
|
||||
rm -f /etc/systemd/system/*.wants/*;\
|
||||
rm -f /lib/systemd/system/local-fs.target.wants/*; \
|
||||
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
|
||||
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
|
||||
rm -f /lib/systemd/system/basic.target.wants/*;\
|
||||
rm -f /lib/systemd/system/anaconda.target.wants/*; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
VOLUME ["/sys/fs/cgroup"]
|
||||
|
||||
CMD ["/usr/sbin/init"]
|
||||
@@ -2,9 +2,9 @@
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: centos-8-build
|
||||
image: "centos:centos8"
|
||||
pre_build_image: true
|
||||
- name: fedora-rawhide-build
|
||||
image: "fedora:rawhide"
|
||||
dockerfile: Dockerfile
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
- 8.8.8.8
|
||||
@@ -2,8 +2,8 @@
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: centos-8
|
||||
image: quay.io/ansible-freeipa/upstream-tests:centos-8
|
||||
- name: fedora-rawhide
|
||||
image: quay.io/ansible-freeipa/upstream-tests:fedora-rawhide
|
||||
pre_build_image: true
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
@@ -4,7 +4,7 @@
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: ensure map TestMap is absent
|
||||
- name: Ensure map TestMap is absent
|
||||
ipaautomountmap:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: TestMap
|
||||
@@ -4,7 +4,7 @@
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: ensure map TestMap is present
|
||||
- name: Ensure map TestMap is present
|
||||
ipaautomountmap:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: TestMap
|
||||
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
|
||||
@@ -11,5 +11,5 @@
|
||||
register: serverconfig
|
||||
|
||||
- name: Display current configuration.
|
||||
debug:
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ serverconfig }}"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
- name: Playbook to handle global DNS configuration
|
||||
- name: Playbook to handle global IPA configuration
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: set ca_renewal_master_server
|
||||
- name: Set ca_renewal_master_server
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ca_renewal_master_server: carenewal.example.com
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: dnszone present
|
||||
- name: All dnszone parameters
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: dnszone present
|
||||
- name: Dnszone present
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
register: result
|
||||
|
||||
- name: Zone name inferred from `name_from_ip`
|
||||
debug:
|
||||
ansible.builtin.debug:
|
||||
msg: "Zone created: {{ result.dnszone.name }}"
|
||||
|
||||
@@ -14,5 +14,5 @@
|
||||
register: ipahost
|
||||
|
||||
- name: Print generated random password
|
||||
debug:
|
||||
ansible.builtin.debug:
|
||||
var: ipahost.host.randompassword
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
register: ipahost
|
||||
|
||||
- name: Print generated random password
|
||||
debug:
|
||||
ansible.builtin.debug:
|
||||
var: ipahost.host.randompassword
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
register: ipahost
|
||||
|
||||
- name: Print generated random password for host01.example.com
|
||||
debug:
|
||||
ansible.builtin.debug:
|
||||
var: ipahost.host["host01.example.com"].randompassword
|
||||
|
||||
- name: Print generated random password for host02.example.com
|
||||
debug:
|
||||
ansible.builtin.debug:
|
||||
var: ipahost.host["host02.example.com"].randompassword
|
||||
|
||||
8
playbooks/install-smartcard-clients.yml
Normal file
8
playbooks/install-smartcard-clients.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: Playbook to setup smartcard for IPA clients
|
||||
hosts: ipaclients
|
||||
become: true
|
||||
|
||||
roles:
|
||||
- role: ipasmartcard_client
|
||||
state: present
|
||||
8
playbooks/install-smartcard-replicas.yml
Normal file
8
playbooks/install-smartcard-replicas.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: Playbook to setup smartcard for IPA replicas
|
||||
hosts: ipareplicas
|
||||
become: true
|
||||
|
||||
roles:
|
||||
- role: ipasmartcard_server
|
||||
state: present
|
||||
8
playbooks/install-smartcard-server.yml
Normal file
8
playbooks/install-smartcard-server.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: Playbook to setup smartcard for IPA server
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
roles:
|
||||
- role: ipasmartcard_server
|
||||
state: present
|
||||
8
playbooks/install-smartcard-servers.yml
Normal file
8
playbooks/install-smartcard-servers.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: Playbook to setup smartcard for IPA server and replicas
|
||||
hosts: ipaserver, ipareplicas
|
||||
become: true
|
||||
|
||||
roles:
|
||||
- role: ipasmartcard_server
|
||||
state: present
|
||||
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
|
||||
@@ -4,7 +4,7 @@
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: ensure the trust is present
|
||||
- name: Ensure the trust is present
|
||||
ipatrust:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
realm: windows.local
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: ensure the trust is absent
|
||||
- name: Ensure the trust is absent
|
||||
ipatrust:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
realm: windows.local
|
||||
|
||||
@@ -15,5 +15,5 @@
|
||||
register: ipauser
|
||||
|
||||
- name: Print generated random password
|
||||
debug:
|
||||
ansible.builtin.debug:
|
||||
var: ipauser.user.randompassword
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
register: ipauser
|
||||
|
||||
- name: Print generated random password for user1
|
||||
debug:
|
||||
ansible.builtin.debug:
|
||||
var: ipauser.user.user1.randompassword
|
||||
|
||||
- name: Print generated random password for user2
|
||||
debug:
|
||||
ansible.builtin.debug:
|
||||
var: ipauser.user.user2.randompassword
|
||||
|
||||
@@ -15,5 +15,5 @@
|
||||
register: result
|
||||
no_log: true
|
||||
- name: Display retrieved data.
|
||||
debug:
|
||||
ansible.builtin.debug:
|
||||
msg: "Data: {{ result.vault.data }}"
|
||||
|
||||
@@ -15,5 +15,5 @@
|
||||
register: result
|
||||
no_log: true
|
||||
- name: Display retrieved data.
|
||||
debug:
|
||||
ansible.builtin.debug:
|
||||
msg: "Data: {{ result.vault.data }}"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
tasks:
|
||||
- name: Copy file containing password to server.
|
||||
copy:
|
||||
ansible.builtin.copy:
|
||||
src: "{{ playbook_dir }}/password.txt"
|
||||
dest: "{{ ansible_facts['env'].HOME }}/password.txt"
|
||||
owner: "{{ ansible_user }}"
|
||||
@@ -20,6 +20,6 @@
|
||||
vault_type: symmetric
|
||||
vault_password_file: "{{ ansible_facts['env'].HOME }}/password.txt"
|
||||
- name: Remove file containing password from server.
|
||||
file:
|
||||
ansible.builtin.file:
|
||||
path: "{{ ansible_facts['env'].HOME }}/password.txt"
|
||||
state: absent
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
tasks:
|
||||
- name: Copy public key file to server.
|
||||
copy:
|
||||
ansible.builtin.copy:
|
||||
src: "{{ playbook_dir }}/public.pem"
|
||||
dest: "{{ ansible_facts['env'].HOME }}/public.pem"
|
||||
owner: "{{ ansible_user }}"
|
||||
@@ -25,6 +25,6 @@
|
||||
vault_type: asymmetric
|
||||
vault_public_key_file: "{{ ansible_facts['env'].HOME }}/public.pem"
|
||||
- name: Remove public key file from server.
|
||||
file:
|
||||
ansible.builtin.file:
|
||||
path: "{{ ansible_facts['env'].HOME }}/public.pem"
|
||||
state: absent
|
||||
|
||||
@@ -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"]
|
||||
@@ -122,7 +126,7 @@ class AutomountMap(IPAAnsibleModule):
|
||||
|
||||
self.params_fail_used_invalid(invalid, state)
|
||||
|
||||
def get_args(self, mapname, desc): # pylint: disable=no-self-use
|
||||
def get_args(self, mapname, desc):
|
||||
# automountmapname is required for all automountmap operations.
|
||||
if not mapname:
|
||||
self.fail_json(msg="automountmapname cannot be None or empty.")
|
||||
@@ -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
|
||||
@@ -441,7 +605,11 @@ def main():
|
||||
elif (
|
||||
isinstance(value, (tuple, list)) and arg_type == "bool"
|
||||
):
|
||||
exit_args[k] = (value[0] == "TRUE")
|
||||
# FreeIPA 4.9.10+ and 4.10 use proper mapping for
|
||||
# boolean values, so we need to convert it to str
|
||||
# for comparison.
|
||||
# See: https://github.com/freeipa/freeipa/pull/6294
|
||||
exit_args[k] = (str(value[0]).upper() == "TRUE")
|
||||
else:
|
||||
if arg_type not in type_map:
|
||||
raise ValueError(
|
||||
@@ -454,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 = """
|
||||
@@ -173,21 +184,25 @@ def gen_args(module, state, action, dnsconfig, forwarders, forward_policy,
|
||||
_args['idnsforwardpolicy'] = forward_policy
|
||||
|
||||
if allow_sync_ptr is not None:
|
||||
_args['idnsallowsyncptr'] = 'TRUE' if allow_sync_ptr else 'FALSE'
|
||||
if module.ipa_check_version("<", "4.9.10"):
|
||||
_args['idnsallowsyncptr'] = "TRUE" if allow_sync_ptr else "FALSE"
|
||||
else:
|
||||
_args['idnsallowsyncptr'] = allow_sync_ptr
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
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'],
|
||||
@@ -199,7 +214,8 @@ def main():
|
||||
choices=["member", "dnsconfig"]),
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
)
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
@@ -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',
|
||||
@@ -344,7 +360,13 @@ def main():
|
||||
|
||||
if state in ['enabled', 'disabled']:
|
||||
if existing_resource is not None:
|
||||
is_enabled = existing_resource["idnszoneactive"][0]
|
||||
# FreeIPA 4.9.10+ and 4.10 use proper mapping for
|
||||
# boolean values, so we need to convert it to str
|
||||
# for comparison.
|
||||
# See: https://github.com/freeipa/freeipa/pull/6294
|
||||
is_enabled = (
|
||||
str(existing_resource["idnszoneactive"][0]).upper()
|
||||
)
|
||||
else:
|
||||
ansible_module.fail_json(
|
||||
msg="dnsforwardzone '%s' not found." % (name))
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -265,7 +280,8 @@ class DNSZoneModule(IPAAnsibleModule):
|
||||
if any(invalid_ips):
|
||||
self.fail_json(msg=error_msg % invalid_ips)
|
||||
|
||||
def is_valid_nsec3param_rec(self, nsec3param_rec): # pylint: disable=R0201
|
||||
@staticmethod
|
||||
def is_valid_nsec3param_rec(nsec3param_rec):
|
||||
try:
|
||||
part1, part2, part3, part4 = nsec3param_rec.split(" ")
|
||||
except ValueError:
|
||||
@@ -418,7 +434,11 @@ class DNSZoneModule(IPAAnsibleModule):
|
||||
is_zone_active = False
|
||||
else:
|
||||
zone = response["result"]
|
||||
is_zone_active = "TRUE" in zone.get("idnszoneactive")
|
||||
# FreeIPA 4.9.10+ and 4.10 use proper mapping for boolean vaalues.
|
||||
# See: https://github.com/freeipa/freeipa/pull/6294
|
||||
is_zone_active = (
|
||||
str(zone.get("idnszoneactive")[0]).upper() == "TRUE"
|
||||
)
|
||||
|
||||
return zone, is_zone_active
|
||||
|
||||
@@ -483,8 +503,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(
|
||||
@@ -496,11 +516,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),
|
||||
@@ -522,8 +544,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
|
||||
@@ -472,18 +492,26 @@ def main():
|
||||
# hbacrule_enable is not failing on an enabled hbacrule
|
||||
# Therefore it is needed to have a look at the ipaenabledflag
|
||||
# in res_find.
|
||||
if "ipaenabledflag" not in res_find or \
|
||||
res_find["ipaenabledflag"][0] != "TRUE":
|
||||
# FreeIPA 4.9.10+ and 4.10 use proper mapping for
|
||||
# boolean values, so we need to convert it to str
|
||||
# for comparison.
|
||||
# See: https://github.com/freeipa/freeipa/pull/6294
|
||||
enabled_flag = str(res_find.get("ipaenabledflag", [False])[0])
|
||||
if enabled_flag.upper() != "TRUE":
|
||||
commands.append([name, "hbacrule_enable", {}])
|
||||
|
||||
elif state == "disabled":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No hbacrule '%s'" % name)
|
||||
# hbacrule_disable is not failing on an disabled hbacrule
|
||||
# hbacrule_disable is not failing on an enabled hbacrule
|
||||
# Therefore it is needed to have a look at the ipaenabledflag
|
||||
# in res_find.
|
||||
if "ipaenabledflag" not in res_find or \
|
||||
res_find["ipaenabledflag"][0] != "FALSE":
|
||||
# FreeIPA 4.9.10+ and 4.10 use proper mapping for
|
||||
# boolean values, so we need to convert it to str
|
||||
# for comparison.
|
||||
# See: https://github.com/freeipa/freeipa/pull/6294
|
||||
enabled_flag = str(res_find.get("ipaenabledflag", [False])[0])
|
||||
if enabled_flag.upper() != "FALSE":
|
||||
commands.append([name, "hbacrule_disable", {}])
|
||||
|
||||
else:
|
||||
|
||||
@@ -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,31 +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.
|
||||
type: string
|
||||
description: |
|
||||
Domain name of the trusted domain. Can only be used when
|
||||
`ipaapi_context: server`.
|
||||
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 = """
|
||||
@@ -134,7 +143,7 @@ RETURN = """
|
||||
|
||||
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, compare_args_ipa
|
||||
IPAAnsibleModule, compare_args_ipa, get_trusted_domain_sid_from_name
|
||||
from ansible.module_utils import six
|
||||
|
||||
if six.PY3:
|
||||
@@ -154,7 +163,7 @@ def find_idrange(module, name):
|
||||
|
||||
def gen_args(
|
||||
base_id, range_size, rid_base, secondary_rid_base, idrange_type, dom_sid,
|
||||
auto_private_groups
|
||||
dom_name, auto_private_groups
|
||||
):
|
||||
_args = {}
|
||||
# Integer parameters are stored as strings.
|
||||
@@ -169,6 +178,8 @@ def gen_args(
|
||||
_args["ipasecondarybaserid"] = secondary_rid_base
|
||||
if idrange_type is not None:
|
||||
_args["iparangetype"] = idrange_type
|
||||
if dom_name is not None:
|
||||
dom_sid = get_trusted_domain_sid_from_name(dom_name)
|
||||
if dom_sid is not None:
|
||||
_args["ipanttrusteddomainsid"] = dom_sid
|
||||
if auto_private_groups is not None:
|
||||
@@ -180,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),
|
||||
@@ -230,6 +241,7 @@ def main():
|
||||
secondary_rid_base = ansible_module.params_get("secondary_rid_base")
|
||||
idrange_type = ansible_module.params_get("idrange_type")
|
||||
dom_sid = ansible_module.params_get("dom_sid")
|
||||
dom_name = ansible_module.params_get("dom_name")
|
||||
auto_private_groups = \
|
||||
ansible_module.params_get_lowercase("auto_private_groups")
|
||||
|
||||
@@ -248,7 +260,10 @@ def main():
|
||||
if state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(msg="No name given.")
|
||||
invalid = ["base_id", "range_size", "idrange_type", "dom_sid"]
|
||||
invalid = [
|
||||
"base_id", "range_size", "idrange_type", "dom_sid", "dom_name",
|
||||
"rid_base", "secondary_rid_base", "auto_private_groups"
|
||||
]
|
||||
|
||||
ansible_module.params_fail_used_invalid(invalid, state)
|
||||
|
||||
@@ -278,7 +293,7 @@ def main():
|
||||
# Generate args
|
||||
args = gen_args(
|
||||
base_id, range_size, rid_base, secondary_rid_base,
|
||||
idrange_type, dom_sid, auto_private_groups
|
||||
idrange_type, dom_sid, dom_name, auto_private_groups
|
||||
)
|
||||
|
||||
# Found the idrange
|
||||
|
||||
@@ -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
|
||||
|
||||
434
plugins/modules/ipanetgroup.py
Normal file
434
plugins/modules/ipanetgroup.py
Normal file
@@ -0,0 +1,434 @@
|
||||
# -*- 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, ensure_fqdn
|
||||
|
||||
|
||||
def find_netgroup(module, name):
|
||||
"""Find if a netgroup with the given name already exist."""
|
||||
_args = {
|
||||
"all": True,
|
||||
"cn": name,
|
||||
}
|
||||
|
||||
# `netgroup_find` is used here instead of `netgroup_show` to workaround
|
||||
# FreeIPA bug https://pagure.io/freeipa/issue/9284.
|
||||
# `ipa netgroup-show hostgroup` shows hostgroup - it's a bug.
|
||||
# `ipa netgroup-find hostgroup` doesn't show hostgroup - it's correct.
|
||||
_result = module.ipa_command("netgroup_find", name, _args)
|
||||
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
msg="There is more than one netgroup '%s'" % name)
|
||||
elif len(_result["result"]) == 1:
|
||||
return _result["result"][0]
|
||||
|
||||
return None
|
||||
|
||||
|
||||
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,70 +33,105 @@ 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:
|
||||
description: Maximum password lifetime (in days)
|
||||
type: int
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["krbmaxpwdlife"]
|
||||
minlife:
|
||||
description: Minimum password lifetime (in hours)
|
||||
type: int
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["krbminpwdlife"]
|
||||
history:
|
||||
description: Password history size
|
||||
type: int
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["krbpwdhistorylength"]
|
||||
minclasses:
|
||||
description: Minimum number of character classes
|
||||
type: int
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["krbpwdmindiffchars"]
|
||||
minlength:
|
||||
description: Minimum length of password
|
||||
type: int
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["krbpwdminlength"]
|
||||
priority:
|
||||
description: Priority of the policy (higher number means lower priority)
|
||||
type: int
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["cospriority"]
|
||||
maxfail:
|
||||
description: Consecutive failures before lockout
|
||||
type: int
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["krbpwdmaxfailure"]
|
||||
failinterval:
|
||||
description: Period after which failure count will be reset (seconds)
|
||||
type: int
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["krbpwdfailurecountinterval"]
|
||||
lockouttime:
|
||||
description: Period for which lockout is enforced (seconds)
|
||||
type: int
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["krbpwdlockoutduration"]
|
||||
maxrepeat:
|
||||
description: >
|
||||
Maximum number of same consecutive characters.
|
||||
Requires IPA 4.9+
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ipapwdmaxrepeat"]
|
||||
maxsequence:
|
||||
description: >
|
||||
The maximum length of monotonic character sequences (abcd).
|
||||
Requires IPA 4.9+
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ipapwdmaxsequence"]
|
||||
dictcheck:
|
||||
description: >
|
||||
Check if the password is a dictionary word.
|
||||
Requires IPA 4.9+
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ipapwdictcheck"]
|
||||
usercheck:
|
||||
description: >
|
||||
Check if the password contains the username.
|
||||
Requires IPA 4.9+
|
||||
type: str
|
||||
required: false
|
||||
aliases: ["ipapwdusercheck"]
|
||||
gracelimit:
|
||||
description: >
|
||||
Number of LDAP authentications allowed after expiration.
|
||||
Requires IPA 4.10.1+
|
||||
type: str
|
||||
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 = """
|
||||
@@ -135,8 +171,10 @@ def find_pwpolicy(module, name):
|
||||
return None
|
||||
|
||||
|
||||
def gen_args(maxlife, minlife, history, minclasses, minlength, priority,
|
||||
maxfail, failinterval, lockouttime):
|
||||
def gen_args(module,
|
||||
maxlife, minlife, history, minclasses, minlength, priority,
|
||||
maxfail, failinterval, lockouttime, maxrepeat, maxsequence,
|
||||
dictcheck, usercheck, gracelimit):
|
||||
_args = {}
|
||||
if maxlife is not None:
|
||||
_args["krbmaxpwdlife"] = maxlife
|
||||
@@ -156,34 +194,91 @@ 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:
|
||||
if module.ipa_check_version("<", "4.9.10"):
|
||||
# Allowed values: "TRUE", "FALSE", ""
|
||||
_args["ipapwddictcheck"] = "TRUE" if dictcheck is True else \
|
||||
"FALSE" if dictcheck is False else dictcheck
|
||||
else:
|
||||
_args["ipapwddictcheck"] = dictcheck
|
||||
if usercheck is not None:
|
||||
if module.ipa_check_version("<", "4.9.10"):
|
||||
# Allowed values: "TRUE", "FALSE", ""
|
||||
_args["ipapwdusercheck"] = "TRUE" if usercheck is True else \
|
||||
"FALSE" if usercheck is False else usercheck
|
||||
else:
|
||||
_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),
|
||||
minlife=dict(type="int", aliases=["krbminpwdlife"], default=None),
|
||||
history=dict(type="int", aliases=["krbpwdhistorylength"],
|
||||
maxlife=dict(type="str", aliases=["krbmaxpwdlife"], default=None),
|
||||
minlife=dict(type="str", aliases=["krbminpwdlife"], default=None),
|
||||
history=dict(type="str", aliases=["krbpwdhistorylength"],
|
||||
default=None),
|
||||
minclasses=dict(type="int", aliases=["krbpwdmindiffchars"],
|
||||
minclasses=dict(type="str", aliases=["krbpwdmindiffchars"],
|
||||
default=None),
|
||||
minlength=dict(type="int", aliases=["krbpwdminlength"],
|
||||
minlength=dict(type="str", aliases=["krbpwdminlength"],
|
||||
default=None),
|
||||
priority=dict(type="int", aliases=["cospriority"], default=None),
|
||||
maxfail=dict(type="int", aliases=["krbpwdmaxfailure"],
|
||||
priority=dict(type="str", aliases=["cospriority"], default=None),
|
||||
maxfail=dict(type="str", aliases=["krbpwdmaxfailure"],
|
||||
default=None),
|
||||
failinterval=dict(type="int",
|
||||
failinterval=dict(type="str",
|
||||
aliases=["krbpwdfailurecountinterval"],
|
||||
default=None),
|
||||
lockouttime=dict(type="int", aliases=["krbpwdlockoutduration"],
|
||||
lockouttime=dict(type="str", aliases=["krbpwdlockoutduration"],
|
||||
default=None),
|
||||
maxrepeat=dict(type="str", aliases=["ipapwdmaxrepeat"],
|
||||
default=None),
|
||||
maxsequence=dict(type="str", aliases=["ipapwdmaxsequence"],
|
||||
default=None),
|
||||
dictcheck=dict(type="str", aliases=["ipapwdictcheck"],
|
||||
default=None),
|
||||
usercheck=dict(type="str", aliases=["ipapwusercheck"],
|
||||
default=None),
|
||||
gracelimit=dict(type="str", aliases=["passwordgracelimit"],
|
||||
default=None),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent"]),
|
||||
@@ -208,6 +303,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 +331,57 @@ 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)
|
||||
|
||||
# Ensure parameter values are valid and have proper type.
|
||||
def int_or_empty_param(value, param):
|
||||
if value is not None and value != "":
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
ansible_module.fail_json(
|
||||
msg="Invalid value '%s' for argument '%s'" % (value, param)
|
||||
)
|
||||
return value
|
||||
|
||||
maxlife = int_or_empty_param(maxlife, "maxlife")
|
||||
minlife = int_or_empty_param(minlife, "minlife")
|
||||
history = int_or_empty_param(history, "history")
|
||||
minclasses = int_or_empty_param(minclasses, "minclasses")
|
||||
minlength = int_or_empty_param(minlength, "minlength")
|
||||
priority = int_or_empty_param(priority, "priority")
|
||||
maxfail = int_or_empty_param(maxfail, "maxfail")
|
||||
failinterval = int_or_empty_param(failinterval, "failinterval")
|
||||
lockouttime = int_or_empty_param(lockouttime, "lockouttime")
|
||||
maxrepeat = int_or_empty_param(maxrepeat, "maxrepeat")
|
||||
maxsequence = int_or_empty_param(maxsequence, "maxsequence")
|
||||
gracelimit = int_or_empty_param(gracelimit, "gracelimit")
|
||||
|
||||
def bool_or_empty_param(value, param): # pylint: disable=R1710
|
||||
# As of Ansible 2.14, values True, False, Yes an No, with variable
|
||||
# capitalization are accepted by Ansible.
|
||||
if not value:
|
||||
return value
|
||||
if value in ["TRUE", "True", "true", "YES", "Yes", "yes"]:
|
||||
return True
|
||||
if value in ["FALSE", "False", "false", "NO", "No", "no"]:
|
||||
return False
|
||||
ansible_module.fail_json(
|
||||
msg="Invalid value '%s' for argument '%s'." % (value, param)
|
||||
)
|
||||
|
||||
dictcheck = bool_or_empty_param(dictcheck, "dictcheck")
|
||||
usercheck = bool_or_empty_param(usercheck, "usercheck")
|
||||
|
||||
# Ensure gracelimit has proper limit.
|
||||
if gracelimit:
|
||||
if gracelimit < -1:
|
||||
ansible_module.fail_json(
|
||||
msg="'gracelimit' must be no less than -1")
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
@@ -242,6 +389,11 @@ def main():
|
||||
|
||||
with ansible_module.ipa_connect():
|
||||
|
||||
check_supported_params(
|
||||
ansible_module, maxrepeat, maxsequence, dictcheck, usercheck,
|
||||
gracelimit
|
||||
)
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
@@ -251,9 +403,11 @@ def main():
|
||||
# Create command
|
||||
if state == "present":
|
||||
# Generate args
|
||||
args = gen_args(maxlife, minlife, history, minclasses,
|
||||
args = gen_args(ansible_module,
|
||||
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"))
|
||||
@@ -656,8 +724,12 @@ def main():
|
||||
# sudorule_enable is not failing on an enabled sudorule
|
||||
# Therefore it is needed to have a look at the ipaenabledflag
|
||||
# in res_find.
|
||||
if "ipaenabledflag" not in res_find or \
|
||||
res_find["ipaenabledflag"][0] != "TRUE":
|
||||
# FreeIPA 4.9.10+ and 4.10 use proper mapping for
|
||||
# boolean values, so we need to convert it to str
|
||||
# for comparison.
|
||||
# See: https://github.com/freeipa/freeipa/pull/6294
|
||||
enabled_flag = str(res_find.get("ipaenabledflag", [False])[0])
|
||||
if enabled_flag.upper() != "TRUE":
|
||||
commands.append([name, "sudorule_enable", {}])
|
||||
|
||||
elif state == "disabled":
|
||||
@@ -666,8 +738,12 @@ def main():
|
||||
# sudorule_disable is not failing on an disabled sudorule
|
||||
# Therefore it is needed to have a look at the ipaenabledflag
|
||||
# in res_find.
|
||||
if "ipaenabledflag" not in res_find or \
|
||||
res_find["ipaenabledflag"][0] != "FALSE":
|
||||
# FreeIPA 4.9.10+ and 4.10 use proper mapping for
|
||||
# boolean values, so we need to convert it to str
|
||||
# for comparison.
|
||||
# See: https://github.com/freeipa/freeipa/pull/6294
|
||||
enabled_flag = str(res_find.get("ipaenabledflag", [False])[0])
|
||||
if enabled_flag.upper() != "FALSE":
|
||||
commands.append([name, "sudorule_disable", {}])
|
||||
|
||||
else:
|
||||
@@ -675,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,
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
-r requirements-tests.txt
|
||||
ipdb
|
||||
pre-commit
|
||||
flake8-bugbear
|
||||
pylint==2.12.2
|
||||
ipdb==0.13.4
|
||||
pre-commit==2.20.0
|
||||
flake8==5.0.3
|
||||
flake8-bugbear==22.10.27
|
||||
pylint==2.14.4
|
||||
wrapt == 1.14.0
|
||||
pydocstyle==6.0.0
|
||||
yamllint==1.28.0
|
||||
ansible-lint==6.6.1
|
||||
|
||||
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,8 @@
|
||||
-r requirements.txt
|
||||
pytest>=2.7
|
||||
pytest-sourceorder>=0.5
|
||||
pytest-split-tests>=1.0.3
|
||||
pytest-testinfra>=5.0
|
||||
pytest==7.1.3
|
||||
pytest-sourceorder==0.6.0
|
||||
pytest-split>=0.8.0
|
||||
pytest-custom_exit_code>=0.3.0
|
||||
pytest-testinfra==6.8.0
|
||||
pytest-randomly==3.12.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)
|
||||
|
||||
|
||||
@@ -6,15 +6,15 @@ galaxy_info:
|
||||
description: A role to backup and restore an IPA server
|
||||
company: Red Hat, Inc
|
||||
license: GPLv3
|
||||
min_ansible_version: 2.8
|
||||
min_ansible_version: "2.8"
|
||||
platforms:
|
||||
- name: Fedora
|
||||
versions:
|
||||
- all
|
||||
- name: EL
|
||||
versions:
|
||||
- 7
|
||||
- 8
|
||||
- "7"
|
||||
- "8"
|
||||
galaxy_tags:
|
||||
- identity
|
||||
- ipa
|
||||
|
||||
@@ -2,20 +2,22 @@
|
||||
# tasks file for ipabackup
|
||||
|
||||
- name: Create backup
|
||||
shell: >
|
||||
ansible.builtin.shell: >
|
||||
ipa-backup
|
||||
{{ "--gpg" if ipabackup_gpg | bool else "" }}
|
||||
{{ "--gpg-keyring="+ipabackup_gpg_keyring if ipabackup_gpg_keyring is defined else "" }}
|
||||
{{ "--gpg-keyring=" + ipabackup_gpg_keyring if ipabackup_gpg_keyring is defined else "" }}
|
||||
{{ "--data" if ipabackup_data | bool else "" }}
|
||||
{{ "--logs" if ipabackup_logs | bool else "" }}
|
||||
{{ "--online" if ipabackup_online | bool else "" }}
|
||||
{{ "--disable-role-check" if ipabackup_disable_role_check | bool else "" }}
|
||||
{{ "--log-file="+ipabackup_log_file if ipabackup_log_file is defined else "" }}
|
||||
{{ "--log-file=" + ipabackup_log_file if ipabackup_log_file is defined else "" }}
|
||||
register: result_ipabackup
|
||||
|
||||
- block:
|
||||
- name: Handle backup
|
||||
when: ipabackup_to_controller
|
||||
block:
|
||||
- name: Get ipabackup_item from stderr or stdout output
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
ipabackup_item: "{{ item | regex_search('\n.*/([^\n]+)','\\1') | first }}"
|
||||
when: item.find("Backed up to "+ipabackup_dir+"/") > 0
|
||||
with_items:
|
||||
@@ -25,15 +27,14 @@
|
||||
label: ""
|
||||
|
||||
- name: Fail on missing ipabackup_item
|
||||
fail: msg="Failed to get ipabackup_item"
|
||||
ansible.builtin.fail:
|
||||
msg: "Failed to get ipabackup_item"
|
||||
when: ipabackup_item is not defined
|
||||
|
||||
- name: Copy backup to controller
|
||||
include_tasks: "{{ role_path }}/tasks/copy_backup_from_server.yml"
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/copy_backup_from_server.yml"
|
||||
when: state|default("present") == "present"
|
||||
|
||||
- name: Remove backup on server
|
||||
include_tasks: "{{ role_path }}/tasks/remove_backup_from_server.yml"
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/remove_backup_from_server.yml"
|
||||
when: not ipabackup_keep_on_server
|
||||
|
||||
when: ipabackup_to_controller
|
||||
|
||||
@@ -1,45 +1,47 @@
|
||||
---
|
||||
- name: Fail on invalid ipabackup_item
|
||||
fail: msg="ipabackup_item {{ ipabackup_item }} is not valid"
|
||||
ansible.builtin.fail:
|
||||
msg: "ipabackup_item {{ ipabackup_item }} is not valid"
|
||||
when: ipabackup_item is not defined or
|
||||
ipabackup_item | length < 1 or
|
||||
(ipabackup_item.find("ipa-full-") == -1 and
|
||||
ipabackup_item.find("ipa-data-") == -1)
|
||||
|
||||
- name: Set controller destination directory
|
||||
set_fact:
|
||||
ipabackup_controller_dir:
|
||||
"{{ ipabackup_controller_path | default(lookup('env','PWD')) }}/{{
|
||||
ansible.builtin.set_fact:
|
||||
__derived_controller_dir:
|
||||
"{{ ipabackup_controller_path | default(lookup('env', 'PWD')) }}/{{
|
||||
ipabackup_name_prefix | default(ansible_facts['fqdn']) }}_{{
|
||||
ipabackup_item }}/"
|
||||
|
||||
- name: Stat backup on server
|
||||
stat:
|
||||
ansible.builtin.stat:
|
||||
path: "{{ ipabackup_dir }}/{{ ipabackup_item }}"
|
||||
register: result_backup_stat
|
||||
|
||||
- name: Fail on missing backup directory
|
||||
fail: msg="Unable to find backup {{ ipabackup_item }}"
|
||||
ansible.builtin.fail:
|
||||
msg: "Unable to find backup {{ ipabackup_item }}"
|
||||
when: result_backup_stat.stat.isdir is not defined
|
||||
|
||||
- name: Get backup files to copy for "{{ ipabackup_item }}"
|
||||
shell:
|
||||
ansible.builtin.shell:
|
||||
find . -type f | cut -d"/" -f 2
|
||||
args:
|
||||
chdir: "{{ ipabackup_dir }}/{{ ipabackup_item }}"
|
||||
register: result_find_backup_files
|
||||
|
||||
- name: Copy server backup files to controller
|
||||
fetch:
|
||||
ansible.builtin.fetch:
|
||||
flat: yes
|
||||
src: "{{ ipabackup_dir }}/{{ ipabackup_item }}/{{ item }}"
|
||||
dest: "{{ ipabackup_controller_dir }}"
|
||||
dest: "{{ __derived_controller_dir }}"
|
||||
with_items:
|
||||
- "{{ result_find_backup_files.stdout_lines }}"
|
||||
|
||||
- name: Fix file modes for backup on controller
|
||||
file:
|
||||
dest: "{{ ipabackup_controller_dir }}"
|
||||
ansible.builtin.file:
|
||||
dest: "{{ __derived_controller_dir }}"
|
||||
mode: u=rwX,go=
|
||||
recurse: yes
|
||||
delegate_to: localhost
|
||||
|
||||
@@ -1,41 +1,43 @@
|
||||
---
|
||||
- name: Fail on invalid ipabackup_name
|
||||
fail: msg="ipabackup_name {{ ipabackup_name }} is not valid"
|
||||
ansible.builtin.fail:
|
||||
msg: "ipabackup_name {{ ipabackup_name }} is not valid"
|
||||
when: ipabackup_name is not defined or
|
||||
ipabackup_name | length < 1 or
|
||||
(ipabackup_name.find("ipa-full-") == -1 and
|
||||
ipabackup_name.find("ipa-data-") == -1)
|
||||
|
||||
- name: Set controller source directory
|
||||
set_fact:
|
||||
ipabackup_controller_dir:
|
||||
"{{ ipabackup_controller_path | default(lookup('env','PWD')) }}"
|
||||
ansible.builtin.set_fact:
|
||||
__derived_controller_dir:
|
||||
"{{ ipabackup_controller_path | default(lookup('env', 'PWD')) }}"
|
||||
|
||||
- name: Set ipabackup_item
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
ipabackup_item:
|
||||
"{{ ipabackup_name | regex_search('.*_(ipa-.+)','\\1') | first }}"
|
||||
"{{ ipabackup_name | regex_search('.*_(ipa-.+)', '\\1') | first }}"
|
||||
when: "'_ipa-' in ipabackup_name"
|
||||
|
||||
- name: Set ipabackup_item
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
ipabackup_item: "{{ ipabackup_name }}"
|
||||
when: "'_ipa-' not in ipabackup_name"
|
||||
|
||||
- name: Stat backup to copy
|
||||
stat:
|
||||
path: "{{ ipabackup_controller_dir }}/{{ ipabackup_name }}"
|
||||
ansible.builtin.stat:
|
||||
path: "{{ __derived_controller_dir }}/{{ ipabackup_name }}"
|
||||
register: result_backup_stat
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
|
||||
- name: Fail on missing backup to copy
|
||||
fail: msg="Unable to find backup {{ ipabackup_name }}"
|
||||
ansible.builtin.fail:
|
||||
msg: "Unable to find backup {{ ipabackup_name }}"
|
||||
when: result_backup_stat.stat.isdir is not defined
|
||||
|
||||
- name: Copy backup files to server for "{{ ipabackup_item }}"
|
||||
copy:
|
||||
src: "{{ ipabackup_controller_dir }}/{{ ipabackup_name }}/"
|
||||
ansible.builtin.copy:
|
||||
src: "{{ __derived_controller_dir }}/{{ ipabackup_name }}/"
|
||||
dest: "{{ ipabackup_dir }}/{{ ipabackup_item }}"
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
register: result_ipabackup_get_backup_dir
|
||||
|
||||
- name: Set IPA backup dir
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
ipabackup_dir: "{{ result_ipabackup_get_backup_dir.backup_dir }}"
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
# tasks file for ipabackup
|
||||
|
||||
- name: Check for empty vars
|
||||
fail: msg="Variable {{ item }} is empty"
|
||||
ansible.builtin.fail:
|
||||
msg: "Variable {{ item }} is empty"
|
||||
when: "item in vars and not vars[item]"
|
||||
with_items: "{{ ipabackup_empty_var_checks }}"
|
||||
vars:
|
||||
@@ -18,74 +19,82 @@
|
||||
- ipabackup_firewalld_zone
|
||||
|
||||
- name: Set ipabackup_data if ipabackup_data is not set but ipabackup_online is
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
ipabackup_data: yes
|
||||
when: ipabackup_online | bool and not ipabackup_data | bool
|
||||
|
||||
- name: Fail if ipabackup_from_controller and ipabackup_to_controller are set
|
||||
fail: msg="ipabackup_from_controller and ipabackup_to_controller are set"
|
||||
ansible.builtin.fail:
|
||||
msg: "ipabackup_from_controller and ipabackup_to_controller are set"
|
||||
when: ipabackup_from_controller | bool and ipabackup_to_controller | bool
|
||||
|
||||
- name: Get ipabackup_dir from IPA installation
|
||||
include_tasks: "{{ role_path }}/tasks/get_ipabackup_dir.yml"
|
||||
|
||||
- name: Backup IPA server
|
||||
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"
|
||||
ansible.builtin.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
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/get_ipabackup_dir.yml"
|
||||
|
||||
- name: Backup IPA server
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/backup.yml"
|
||||
when: state|default("present") == "present"
|
||||
|
||||
- name: Fail on missing ipabackup_name
|
||||
fail: msg="ipabackup_name is not set"
|
||||
ansible.builtin.fail:
|
||||
msg: "ipabackup_name is not set"
|
||||
when: (ipabackup_name is not defined or not ipabackup_name) and
|
||||
state is defined and
|
||||
(state == "copied" or state == "restored" or state == "absent")
|
||||
|
||||
- block:
|
||||
- name: Get all backup names for copy to controller
|
||||
when: state is defined and
|
||||
((state == "copied" and ipabackup_to_controller) or
|
||||
state == "absent") and
|
||||
ipabackup_name is defined and ipabackup_name == "all"
|
||||
block:
|
||||
- name: Get list of all backups on IPA server
|
||||
shell:
|
||||
ansible.builtin.shell:
|
||||
find . -name "ipa-full-*" -o -name "ipa-data-*" | cut -d"/" -f 2
|
||||
args:
|
||||
chdir: "{{ ipabackup_dir }}/"
|
||||
register: result_backup_find_backup_files
|
||||
|
||||
- name: Set ipabackup_names using backup list
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
ipabackup_names: "{{ result_backup_find_backup_files.stdout_lines }}"
|
||||
|
||||
when: state is defined and
|
||||
((state == "copied" and ipabackup_to_controller) or
|
||||
state == "absent") and
|
||||
ipabackup_name is defined and ipabackup_name == "all"
|
||||
|
||||
- block:
|
||||
- name: Set ipabackup_names from ipabackup_name
|
||||
when: ipabackup_names is not defined and ipabackup_name is defined
|
||||
block:
|
||||
- name: Fail on ipabackup_name all
|
||||
fail: msg="ipabackup_name can not be all in this case"
|
||||
ansible.builtin.fail:
|
||||
msg: "ipabackup_name can not be all in this case"
|
||||
when: ipabackup_name is defined and ipabackup_name == "all"
|
||||
|
||||
- name: Set ipabackup_names from ipabackup_name string
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
ipabackup_names: ["{{ ipabackup_name }}"]
|
||||
when: ipabackup_name | type_debug != "list"
|
||||
|
||||
- name: Set ipabackup_names from ipabackup_name list
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
ipabackup_names: "{{ ipabackup_name }}"
|
||||
when: ipabackup_name | type_debug == "list"
|
||||
when: ipabackup_names is not defined and ipabackup_name is defined
|
||||
|
||||
- name: Set empty ipabackup_names if ipabackup_name is not defined
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
ipabackup_names: []
|
||||
when: ipabackup_names is not defined and ipabackup_name is not defined
|
||||
|
||||
- block:
|
||||
- name: Process "{{ ipabackup_names }}"
|
||||
when: state is defined and
|
||||
((state == "copied" and ipabackup_to_controller) or state == "absent")
|
||||
block:
|
||||
- name: Copy backup from IPA server
|
||||
include_tasks: "{{ role_path }}/tasks/copy_backup_from_server.yml"
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/copy_backup_from_server.yml"
|
||||
vars:
|
||||
ipabackup_item: "{{ main_item | basename }}"
|
||||
with_items:
|
||||
@@ -95,7 +104,7 @@
|
||||
when: state is defined and state == "copied"
|
||||
|
||||
- name: Remove backup from IPA server
|
||||
include_tasks: "{{ role_path }}/tasks/remove_backup_from_server.yml"
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/remove_backup_from_server.yml"
|
||||
vars:
|
||||
ipabackup_item: "{{ main_item | basename }}"
|
||||
with_items:
|
||||
@@ -104,34 +113,32 @@
|
||||
loop_var: main_item
|
||||
when: state is defined and state == "absent"
|
||||
|
||||
when: state is defined and
|
||||
((state == "copied" and ipabackup_to_controller) or state == "absent")
|
||||
|
||||
# Fail with more than one entry in ipabackup_names for copy to sever and
|
||||
# restore.
|
||||
|
||||
- name: Fail to copy or restore more than one backup on the server
|
||||
fail: msg="Only one backup can be copied to the server or restored"
|
||||
ansible.builtin.fail:
|
||||
msg: "Only one backup can be copied to the server or restored"
|
||||
when: state is defined and (state == "copied" or state == "restored") and
|
||||
ipabackup_from_controller | bool and ipabackup_names | length != 1
|
||||
|
||||
# Use only first item in ipabackup_names for copy to server and for restore.
|
||||
|
||||
- block:
|
||||
- name: Copy backup to server
|
||||
include_tasks: "{{ role_path }}/tasks/copy_backup_to_server.yml"
|
||||
|
||||
- name: Restore IPA server after copy
|
||||
include_tasks: "{{ role_path }}/tasks/restore.yml"
|
||||
when: state|default("present") == "restored"
|
||||
|
||||
vars:
|
||||
ipabackup_name: "{{ ipabackup_names[0] }}"
|
||||
- name: Process "{{ ipabackup_names[0] }}"
|
||||
when: ipabackup_from_controller or
|
||||
(state|default("present") == "copied" and not ipabackup_to_controller)
|
||||
vars:
|
||||
ipabackup_name: "{{ ipabackup_names[0] }}"
|
||||
block:
|
||||
- name: Copy backup to server
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/copy_backup_to_server.yml"
|
||||
|
||||
- name: Restore IPA server after copy
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/restore.yml"
|
||||
when: state|default("present") == "restored"
|
||||
|
||||
- name: Restore IPA server
|
||||
include_tasks: "{{ role_path }}/tasks/restore.yml"
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/restore.yml"
|
||||
vars:
|
||||
ipabackup_item: "{{ ipabackup_names[0] | basename }}"
|
||||
when: not ipabackup_from_controller and
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: Remove backup "{{ ipabackup_item }}"
|
||||
file:
|
||||
ansible.builtin.file:
|
||||
path: "{{ ipabackup_dir }}/{{ ipabackup_item }}"
|
||||
state: absent
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user