mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-29 09:56:53 +00:00
Compare commits
159 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b02ea33f9b | ||
|
|
437d1bbf7a | ||
|
|
a1582aa8cb | ||
|
|
4816157c05 | ||
|
|
67356d287d | ||
|
|
2b76b1f43a | ||
|
|
0f2d5136b8 | ||
|
|
58a4610b61 | ||
|
|
d1a412dafc | ||
|
|
c82362194b | ||
|
|
bb80ff6aee | ||
|
|
15b950f1cf | ||
|
|
7577d5218a | ||
|
|
f317fd924a | ||
|
|
6070dc80d4 | ||
|
|
b3fad4fa87 | ||
|
|
76626eb7e8 | ||
|
|
37ba1d0e5e | ||
|
|
57d1e74f3d | ||
|
|
f6b5b793c8 | ||
|
|
6584348d05 | ||
|
|
a610e27853 | ||
|
|
01220475dc | ||
|
|
0a1b53a10e | ||
|
|
db8f38ea3a | ||
|
|
7c0e4bda35 | ||
|
|
50425a49ec | ||
|
|
ce30e0732b | ||
|
|
c2cbac062e | ||
|
|
ed4bc4c1d2 | ||
|
|
cda63f7221 | ||
|
|
ebaf490653 | ||
|
|
9027c367d4 | ||
|
|
e69ea28662 | ||
|
|
eccc41eadc | ||
|
|
b5d56463a6 | ||
|
|
3c5094d971 | ||
|
|
15cbc9665e | ||
|
|
4259792751 | ||
|
|
fe4099c163 | ||
|
|
b2417accbf | ||
|
|
9b21b0d31c | ||
|
|
330b0304ef | ||
|
|
f8fc18412c | ||
|
|
abd2a85709 | ||
|
|
c1536a3501 | ||
|
|
4fa1f1a6dd | ||
|
|
42cc5280d9 | ||
|
|
1c8fbed36c | ||
|
|
f8d0d07fed | ||
|
|
3ee01ddb7f | ||
|
|
5d5befdf96 | ||
|
|
98cea930f0 | ||
|
|
9036d8edd0 | ||
|
|
72d1af86f3 | ||
|
|
6c718a4f55 | ||
|
|
751e2400e6 | ||
|
|
c2ae3dd026 | ||
|
|
9a97d5e14a | ||
|
|
f794ba17c9 | ||
|
|
f4575816be | ||
|
|
fd3bc75fb3 | ||
|
|
dc898dfdf8 | ||
|
|
28c7a62989 | ||
|
|
f490bc1dba | ||
|
|
5bd671b8bf | ||
|
|
0057908705 | ||
|
|
39d83fefee | ||
|
|
145b4e7433 | ||
|
|
d45b112cc0 | ||
|
|
fc64490f89 | ||
|
|
4a0276261b | ||
|
|
2e0079cb3e | ||
|
|
4209c58ae1 | ||
|
|
e27851e2e3 | ||
|
|
ee4a4f3b49 | ||
|
|
50eb0a95de | ||
|
|
ba559d24cd | ||
|
|
c35d8b560c | ||
|
|
cbb29febd6 | ||
|
|
f24302f301 | ||
|
|
27cf237a86 | ||
|
|
6f518ba18b | ||
|
|
5d29270e23 | ||
|
|
920046beaf | ||
|
|
1592be779a | ||
|
|
e261332acf | ||
|
|
a406fb1e0c | ||
|
|
546eb77fd0 | ||
|
|
5c7b103936 | ||
|
|
91110f4933 | ||
|
|
7d7e099333 | ||
|
|
bee530b6cc | ||
|
|
34c4b1f367 | ||
|
|
f4af31b76b | ||
|
|
f583dbd2d3 | ||
|
|
be0d207f90 | ||
|
|
e968f89125 | ||
|
|
92466e0dbd | ||
|
|
ecf6f585ee | ||
|
|
6789f7939a | ||
|
|
94f23ee647 | ||
|
|
7dcbb1ade4 | ||
|
|
adca0d5d75 | ||
|
|
4699568996 | ||
|
|
41ba810463 | ||
|
|
a8f5926da3 | ||
|
|
3b24363383 | ||
|
|
7b0890c98f | ||
|
|
f986b97c9a | ||
|
|
396b94183d | ||
|
|
88b5e7ec0b | ||
|
|
bd1c1b257f | ||
|
|
211b520017 | ||
|
|
cae94f9d5e | ||
|
|
fc0981f3f1 | ||
|
|
d63658ea79 | ||
|
|
543792a68e | ||
|
|
1f518751a1 | ||
|
|
04162da6c9 | ||
|
|
b5a276dc77 | ||
|
|
ef0665843f | ||
|
|
c55585a0e2 | ||
|
|
c86d34f198 | ||
|
|
1eeff1556f | ||
|
|
75a69de909 | ||
|
|
1a35fb1d77 | ||
|
|
b4275969c1 | ||
|
|
41b5464942 | ||
|
|
7ee0389c98 | ||
|
|
816d4e8f49 | ||
|
|
07f854fff1 | ||
|
|
307a291b57 | ||
|
|
c4ebd482eb | ||
|
|
5cec31586f | ||
|
|
4bdd27de6a | ||
|
|
dd726d28ca | ||
|
|
e55df1c63e | ||
|
|
2a40169da5 | ||
|
|
131bf72d72 | ||
|
|
b49aeab5f5 | ||
|
|
91bfdbd7a0 | ||
|
|
f663fe73c1 | ||
|
|
703519197f | ||
|
|
fce8eac2a8 | ||
|
|
7531e97ddd | ||
|
|
7b83815835 | ||
|
|
70023f98f6 | ||
|
|
caa4e4feb4 | ||
|
|
714b24b01c | ||
|
|
5d5dd734e5 | ||
|
|
45d3708d31 | ||
|
|
5b7c759552 | ||
|
|
443d5a2a5f | ||
|
|
813030a5f2 | ||
|
|
ac398d8b2b | ||
|
|
f21f1cf461 | ||
|
|
b714bed0c1 | ||
|
|
3416a3c22a |
@@ -53,7 +53,7 @@ variables:
|
||||
resources:
|
||||
containers:
|
||||
- container: default
|
||||
image: quay.io/ansible/azure-pipelines-test-container:3.0.0
|
||||
image: quay.io/ansible/azure-pipelines-test-container:4.0.1
|
||||
|
||||
pool: Standard
|
||||
|
||||
@@ -112,19 +112,6 @@ stages:
|
||||
- test: 2
|
||||
- test: 3
|
||||
- test: 4
|
||||
- stage: Sanity_2_12
|
||||
displayName: Sanity 2.12
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Test {0}
|
||||
testFormat: 2.12/sanity/{0}
|
||||
targets:
|
||||
- test: 1
|
||||
- test: 2
|
||||
- test: 3
|
||||
- test: 4
|
||||
### Units
|
||||
- stage: Units_devel
|
||||
displayName: Units devel
|
||||
@@ -136,7 +123,6 @@ stages:
|
||||
testFormat: devel/units/{0}/1
|
||||
targets:
|
||||
- test: 2.7
|
||||
- test: 3.5
|
||||
- test: 3.6
|
||||
- test: 3.7
|
||||
- test: 3.8
|
||||
@@ -152,6 +138,7 @@ stages:
|
||||
nameFormat: Python {0}
|
||||
testFormat: 2.15/units/{0}/1
|
||||
targets:
|
||||
- test: 3.5
|
||||
- test: "3.10"
|
||||
- stage: Units_2_14
|
||||
displayName: Units 2.14
|
||||
@@ -174,17 +161,6 @@ stages:
|
||||
targets:
|
||||
- test: 2.7
|
||||
- test: 3.8
|
||||
- stage: Units_2_12
|
||||
displayName: Units 2.12
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: 2.12/units/{0}/1
|
||||
targets:
|
||||
- test: 2.6
|
||||
- test: 3.8
|
||||
|
||||
## Remote
|
||||
- stage: Remote_devel_extra_vms
|
||||
@@ -197,10 +173,8 @@ stages:
|
||||
targets:
|
||||
- name: Alpine 3.17
|
||||
test: alpine/3.17
|
||||
# - name: Fedora 37
|
||||
# test: fedora/37
|
||||
# - name: Ubuntu 20.04
|
||||
# test: ubuntu/20.04
|
||||
# - name: Fedora 38
|
||||
# test: fedora/38
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu/22.04
|
||||
groups:
|
||||
@@ -215,8 +189,10 @@ stages:
|
||||
targets:
|
||||
- name: macOS 13.2
|
||||
test: macos/13.2
|
||||
- name: RHEL 9.1
|
||||
test: rhel/9.1
|
||||
- name: RHEL 9.2
|
||||
test: rhel/9.2
|
||||
- name: RHEL 8.8
|
||||
test: rhel/8.8
|
||||
- name: FreeBSD 13.2
|
||||
test: freebsd/13.2
|
||||
- name: FreeBSD 12.4
|
||||
@@ -233,6 +209,10 @@ stages:
|
||||
parameters:
|
||||
testFormat: 2.15/{0}
|
||||
targets:
|
||||
- name: RHEL 9.1
|
||||
test: rhel/9.1
|
||||
- name: RHEL 8.7
|
||||
test: rhel/8.7
|
||||
- name: RHEL 7.9
|
||||
test: rhel/7.9
|
||||
- name: FreeBSD 13.1
|
||||
@@ -269,22 +249,6 @@ stages:
|
||||
test: macos/12.0
|
||||
- name: RHEL 8.5
|
||||
test: rhel/8.5
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- stage: Remote_2_12
|
||||
displayName: Remote 2.12
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: 2.12/{0}
|
||||
targets:
|
||||
- name: macOS 11.1
|
||||
test: macos/11.1
|
||||
- name: RHEL 8.4
|
||||
test: rhel/8.4
|
||||
- name: FreeBSD 13.0
|
||||
test: freebsd/13.0
|
||||
groups:
|
||||
@@ -301,8 +265,8 @@ stages:
|
||||
parameters:
|
||||
testFormat: devel/linux/{0}
|
||||
targets:
|
||||
- name: Fedora 37
|
||||
test: fedora37
|
||||
- name: Fedora 38
|
||||
test: fedora38
|
||||
- name: openSUSE 15
|
||||
test: opensuse15
|
||||
- name: Ubuntu 20.04
|
||||
@@ -323,6 +287,8 @@ stages:
|
||||
parameters:
|
||||
testFormat: 2.15/linux/{0}
|
||||
targets:
|
||||
- name: Fedora 37
|
||||
test: fedora37
|
||||
- name: CentOS 7
|
||||
test: centos7
|
||||
groups:
|
||||
@@ -361,24 +327,6 @@ stages:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- stage: Docker_2_12
|
||||
displayName: Docker 2.12
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: 2.12/linux/{0}
|
||||
targets:
|
||||
- name: CentOS 6
|
||||
test: centos6
|
||||
- name: Fedora 34
|
||||
test: fedora34
|
||||
- name: Ubuntu 18.04
|
||||
test: ubuntu1804
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
|
||||
### Community Docker
|
||||
- stage: Docker_community_devel
|
||||
@@ -391,6 +339,8 @@ stages:
|
||||
targets:
|
||||
- name: Debian Bullseye
|
||||
test: debian-bullseye/3.9
|
||||
- name: Debian Bookworm
|
||||
test: debian-bookworm/3.11
|
||||
- name: ArchLinux
|
||||
test: archlinux/3.11
|
||||
- name: CentOS Stream 8
|
||||
@@ -442,45 +392,30 @@ stages:
|
||||
testFormat: 2.13/generic/{0}/1
|
||||
targets:
|
||||
- test: 3.9
|
||||
- stage: Generic_2_12
|
||||
displayName: Generic 2.12
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: 2.12/generic/{0}/1
|
||||
targets:
|
||||
- test: 3.8
|
||||
|
||||
- stage: Summary
|
||||
condition: succeededOrFailed()
|
||||
dependsOn:
|
||||
- Sanity_devel
|
||||
- Sanity_2_12
|
||||
- Sanity_2_13
|
||||
- Sanity_2_14
|
||||
- Sanity_2_15
|
||||
- Units_devel
|
||||
- Units_2_12
|
||||
- Units_2_13
|
||||
- Units_2_14
|
||||
- Units_2_15
|
||||
- Remote_devel_extra_vms
|
||||
- Remote_devel
|
||||
- Remote_2_12
|
||||
- Remote_2_13
|
||||
- Remote_2_14
|
||||
- Remote_2_15
|
||||
- Docker_devel
|
||||
- Docker_2_12
|
||||
- Docker_2_13
|
||||
- Docker_2_14
|
||||
- Docker_2_15
|
||||
- Docker_community_devel
|
||||
# Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled.
|
||||
# - Generic_devel
|
||||
# - Generic_2_12
|
||||
# - Generic_2_13
|
||||
# - Generic_2_14
|
||||
# - Generic_2_15
|
||||
|
||||
31
.github/BOTMETA.yml
vendored
31
.github/BOTMETA.yml
vendored
@@ -204,6 +204,8 @@ files:
|
||||
maintainers: ddelnano shinuza
|
||||
$lookups/:
|
||||
labels: lookups
|
||||
$lookups/bitwarden_secrets_manager.py:
|
||||
maintainers: jantari
|
||||
$lookups/bitwarden.py:
|
||||
maintainers: lungj
|
||||
$lookups/cartesian.py: {}
|
||||
@@ -333,6 +335,9 @@ files:
|
||||
$module_utils/utm_utils.py:
|
||||
labels: utm_utils
|
||||
maintainers: $team_e_spirit
|
||||
$module_utils/vardict.py:
|
||||
labels: vardict
|
||||
maintainers: russoz
|
||||
$module_utils/wdc_redfish_utils.py:
|
||||
labels: wdc_redfish_utils
|
||||
maintainers: $team_wdc
|
||||
@@ -428,7 +433,7 @@ files:
|
||||
ignore: resmo
|
||||
maintainers: dmtrs
|
||||
$modules/consul:
|
||||
ignore: colin-nolan
|
||||
ignore: colin-nolan Hakon
|
||||
maintainers: $team_consul
|
||||
$modules/copr.py:
|
||||
maintainers: schlupov
|
||||
@@ -527,10 +532,15 @@ files:
|
||||
keywords: gitlab source_control
|
||||
maintainers: $team_gitlab
|
||||
notify: jlozadad
|
||||
ignore: dj-wasabi
|
||||
$modules/gitlab_branch.py:
|
||||
maintainers: paytroff
|
||||
$modules/gitlab_merge_request.py:
|
||||
maintainers: zvaraondrej
|
||||
$modules/gitlab_project_variable.py:
|
||||
maintainers: markuman
|
||||
$modules/gitlab_instance_variable.py:
|
||||
maintainers: benibr
|
||||
$modules/gitlab_runner.py:
|
||||
maintainers: SamyCoenen
|
||||
$modules/gitlab_user.py:
|
||||
@@ -680,8 +690,14 @@ files:
|
||||
maintainers: $team_keycloak
|
||||
$modules/keycloak_authentication.py:
|
||||
maintainers: elfelip Gaetan2907
|
||||
$modules/keycloak_authentication_required_actions.py:
|
||||
maintainers: Skrekulko
|
||||
$modules/keycloak_authz_authorization_scope.py:
|
||||
maintainers: mattock
|
||||
$modules/keycloak_authz_permission.py:
|
||||
maintainers: mattock
|
||||
$modules/keycloak_authz_permission_info.py:
|
||||
maintainers: mattock
|
||||
$modules/keycloak_client_rolemapping.py:
|
||||
maintainers: Gaetan2907
|
||||
$modules/keycloak_clientscope.py:
|
||||
@@ -702,6 +718,8 @@ files:
|
||||
maintainers: fynncfchen
|
||||
$modules/keycloak_role.py:
|
||||
maintainers: laurpaum
|
||||
$modules/keycloak_user.py:
|
||||
maintainers: elfelip
|
||||
$modules/keycloak_user_federation.py:
|
||||
maintainers: laurpaum
|
||||
$modules/keycloak_user_rolemapping.py:
|
||||
@@ -748,6 +766,8 @@ files:
|
||||
maintainers: nerzhul
|
||||
$modules/lvg.py:
|
||||
maintainers: abulimov
|
||||
$modules/lvg_rename.py:
|
||||
maintainers: lszomor
|
||||
$modules/lvol.py:
|
||||
maintainers: abulimov jhoekx zigaSRC unkaputtbar112
|
||||
$modules/lxc_container.py:
|
||||
@@ -929,7 +949,7 @@ files:
|
||||
$modules/pamd.py:
|
||||
maintainers: kevensen
|
||||
$modules/parted.py:
|
||||
maintainers: ColOfAbRiX rosowiecki jake2184
|
||||
maintainers: ColOfAbRiX jake2184
|
||||
$modules/pear.py:
|
||||
ignore: jle64
|
||||
labels: pear
|
||||
@@ -976,7 +996,8 @@ files:
|
||||
$modules/proxmox:
|
||||
keywords: kvm libvirt proxmox qemu
|
||||
labels: proxmox virt
|
||||
maintainers: $team_virt
|
||||
maintainers: $team_virt UnderGreen
|
||||
ignore: tleguern
|
||||
$modules/proxmox.py:
|
||||
ignore: skvidal
|
||||
maintainers: UnderGreen
|
||||
@@ -1389,7 +1410,7 @@ macros:
|
||||
team_cyberark_conjur: jvanderhoof ryanprior
|
||||
team_e_spirit: MatrixCrawler getjack
|
||||
team_flatpak: JayKayy oolongbrothers
|
||||
team_gitlab: Lunik Shaps dj-wasabi marwatk waheedi zanssa scodeman metanovii sh0shin nejch lgatellier suukit
|
||||
team_gitlab: Lunik Shaps marwatk waheedi zanssa scodeman metanovii sh0shin nejch lgatellier suukit
|
||||
team_hpux: bcoca davx8342
|
||||
team_huawei: QijunPan TommyLike edisonxiang freesky-edward hwDCN niuzhenguo xuxiaowei0512 yanzhangi zengchen1024 zhongjun2
|
||||
team_ipa: Akasurde Nosmoht fxfitz justchris1
|
||||
@@ -1408,5 +1429,5 @@ macros:
|
||||
team_scaleway: remyleone abarbare
|
||||
team_solaris: bcoca fishman jasperla jpdasma mator scathatheworm troy2914 xen0l
|
||||
team_suse: commel evrardjp lrupp toabctl AnderEnder alxgu andytom sealor
|
||||
team_virt: joshainglis karmab tleguern Thulium-Drake Ajpantuso
|
||||
team_virt: joshainglis karmab Thulium-Drake Ajpantuso
|
||||
team_wdc: mikemoerk
|
||||
|
||||
59
.github/workflows/ansible-test.yml
vendored
59
.github/workflows/ansible-test.yml
vendored
@@ -14,9 +14,9 @@ on:
|
||||
- main
|
||||
- stable-*
|
||||
pull_request:
|
||||
# Run EOL CI once per day (at 08:00 UTC)
|
||||
# Run EOL CI once per day (at 10:00 UTC)
|
||||
schedule:
|
||||
- cron: '0 8 * * *'
|
||||
- cron: '0 10 * * *'
|
||||
|
||||
concurrency:
|
||||
# Make sure there is at most one active run per PR, but do not cancel any non-PR runs
|
||||
@@ -30,6 +30,7 @@ jobs:
|
||||
matrix:
|
||||
ansible:
|
||||
- '2.11'
|
||||
- '2.12'
|
||||
# Ansible-test on various stable branches does not yet work well with cgroups v2.
|
||||
# Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04
|
||||
# image for these stable branches. The list of branches where this is necessary will
|
||||
@@ -43,7 +44,7 @@ jobs:
|
||||
- name: Perform sanity testing
|
||||
uses: felixfontein/ansible-test-gh-action@main
|
||||
with:
|
||||
ansible-core-github-repository-slug: felixfontein/ansible
|
||||
ansible-core-github-repository-slug: ${{ contains(fromJson('["2.10", "2.11"]'), matrix.ansible) && 'felixfontein/ansible' || 'ansible/ansible' }}
|
||||
ansible-core-version: stable-${{ matrix.ansible }}
|
||||
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
|
||||
pull-request-change-detection: 'true'
|
||||
@@ -75,6 +76,10 @@ jobs:
|
||||
python: '2.7'
|
||||
- ansible: '2.11'
|
||||
python: '3.5'
|
||||
- ansible: '2.12'
|
||||
python: '2.6'
|
||||
- ansible: '2.12'
|
||||
python: '3.8'
|
||||
|
||||
steps:
|
||||
- name: >-
|
||||
@@ -82,7 +87,7 @@ jobs:
|
||||
Ansible version ${{ matrix.ansible }}
|
||||
uses: felixfontein/ansible-test-gh-action@main
|
||||
with:
|
||||
ansible-core-github-repository-slug: felixfontein/ansible
|
||||
ansible-core-github-repository-slug: ${{ contains(fromJson('["2.10", "2.11"]'), matrix.ansible) && 'felixfontein/ansible' || 'ansible/ansible' }}
|
||||
ansible-core-version: stable-${{ matrix.ansible }}
|
||||
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
|
||||
pre-test-cmd: >-
|
||||
@@ -163,7 +168,49 @@ jobs:
|
||||
# - ansible: '2.11'
|
||||
# docker: default
|
||||
# python: '3.5'
|
||||
# target: azp/generic/2/
|
||||
# target: azp/generic/1/
|
||||
# 2.12
|
||||
- ansible: '2.12'
|
||||
docker: centos6
|
||||
python: ''
|
||||
target: azp/posix/1/
|
||||
- ansible: '2.12'
|
||||
docker: centos6
|
||||
python: ''
|
||||
target: azp/posix/2/
|
||||
- ansible: '2.12'
|
||||
docker: centos6
|
||||
python: ''
|
||||
target: azp/posix/3/
|
||||
- ansible: '2.12'
|
||||
docker: fedora34
|
||||
python: ''
|
||||
target: azp/posix/1/
|
||||
- ansible: '2.12'
|
||||
docker: fedora34
|
||||
python: ''
|
||||
target: azp/posix/2/
|
||||
- ansible: '2.12'
|
||||
docker: fedora34
|
||||
python: ''
|
||||
target: azp/posix/3/
|
||||
- ansible: '2.12'
|
||||
docker: ubuntu1804
|
||||
python: ''
|
||||
target: azp/posix/1/
|
||||
- ansible: '2.12'
|
||||
docker: ubuntu1804
|
||||
python: ''
|
||||
target: azp/posix/2/
|
||||
- ansible: '2.12'
|
||||
docker: ubuntu1804
|
||||
python: ''
|
||||
target: azp/posix/3/
|
||||
# Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled.
|
||||
# - ansible: '2.12'
|
||||
# docker: default
|
||||
# python: '3.8'
|
||||
# target: azp/generic/1/
|
||||
|
||||
steps:
|
||||
- name: >-
|
||||
@@ -172,7 +219,7 @@ jobs:
|
||||
under Python ${{ matrix.python }}
|
||||
uses: felixfontein/ansible-test-gh-action@main
|
||||
with:
|
||||
ansible-core-github-repository-slug: felixfontein/ansible
|
||||
ansible-core-github-repository-slug: ${{ contains(fromJson('["2.10", "2.11"]'), matrix.ansible) && 'felixfontein/ansible' || 'ansible/ansible' }}
|
||||
ansible-core-version: stable-${{ matrix.ansible }}
|
||||
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
|
||||
docker-image: ${{ matrix.docker }}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.0.1
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: mixed-line-ending
|
||||
args: [--fix=lf]
|
||||
- id: fix-encoding-pragma
|
||||
- id: check-ast
|
||||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||
rev: v1.9.0
|
||||
hooks:
|
||||
- id: rst-backticks
|
||||
types: [file]
|
||||
files: changelogs/fragments/.*\.(yml|yaml)$
|
||||
230
CHANGELOG.rst
230
CHANGELOG.rst
@@ -6,6 +6,236 @@ Community General Release Notes
|
||||
|
||||
This changelog describes changes after version 6.0.0.
|
||||
|
||||
v7.2.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix and feature release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- cobbler inventory plugin - convert Ansible unicode strings to native Python unicode strings before passing user/password to XMLRPC client (https://github.com/ansible-collections/community.general/pull/6923).
|
||||
- consul_session - drops requirement for the ``python-consul`` library to communicate with the Consul API, instead relying on the existing ``requests`` library requirement (https://github.com/ansible-collections/community.general/pull/6755).
|
||||
- gitlab_project_variable - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- gitlab_runner - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6927).
|
||||
- htpasswd - the parameter ``crypt_scheme`` is being renamed as ``hash_scheme`` and added as an alias to it (https://github.com/ansible-collections/community.general/pull/6841).
|
||||
- keycloak_authentication - added provider ID choices, since Keycloak supports only those two specific ones (https://github.com/ansible-collections/community.general/pull/6763).
|
||||
- keyring - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6927).
|
||||
- locale_gen - module has been refactored to use ``ModuleHelper`` and ``CmdRunner`` (https://github.com/ansible-collections/community.general/pull/6903).
|
||||
- locale_gen - module now using ``CmdRunner`` to execute external commands (https://github.com/ansible-collections/community.general/pull/6820).
|
||||
- make - add new ``targets`` parameter allowing multiple targets to be used with ``make`` (https://github.com/ansible-collections/community.general/pull/6882, https://github.com/ansible-collections/community.general/issues/4919).
|
||||
- nmcli - add support for ``ipv4.dns-options`` and ``ipv6.dns-options`` (https://github.com/ansible-collections/community.general/pull/6902).
|
||||
- npm - minor improvement on parameter validation (https://github.com/ansible-collections/community.general/pull/6848).
|
||||
- opkg - add ``executable`` parameter allowing to specify the path of the ``opkg`` command (https://github.com/ansible-collections/community.general/pull/6862).
|
||||
- pubnub_blocks - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- redfish_command - add ``account_types`` and ``oem_account_types`` as optional inputs to ``AddUser`` (https://github.com/ansible-collections/community.general/issues/6823, https://github.com/ansible-collections/community.general/pull/6871).
|
||||
- redfish_info - add ``AccountTypes`` and ``OEMAccountTypes`` to the output of ``ListUsers`` (https://github.com/ansible-collections/community.general/issues/6823, https://github.com/ansible-collections/community.general/pull/6871).
|
||||
- redfish_info - adds ``ProcessorArchitecture`` to CPU inventory (https://github.com/ansible-collections/community.general/pull/6864).
|
||||
- redfish_info - fix for ``GetVolumeInventory``, Controller name was getting populated incorrectly and duplicates were seen in the volumes retrieved (https://github.com/ansible-collections/community.general/pull/6719).
|
||||
- rhsm_repository - the interaction with ``subscription-manager`` was
|
||||
refactored by grouping things together, removing unused bits, and hardening
|
||||
the way it is run; also, the parsing of ``subscription-manager repos --list``
|
||||
was improved and made slightly faster; no behaviour change is expected
|
||||
(https://github.com/ansible-collections/community.general/pull/6783,
|
||||
https://github.com/ansible-collections/community.general/pull/6837).
|
||||
- scaleway_security_group_rule - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- snap - add option ``dangerous`` to the module, that will map into the command line argument ``--dangerous``, allowing unsigned snap files to be installed (https://github.com/ansible-collections/community.general/pull/6908, https://github.com/ansible-collections/community.general/issues/5715).
|
||||
- tss lookup plugin - allow to fetch secret by path. Previously, we could not fetch secret by path but now use ``secret_path`` option to indicate to fetch secret by secret path (https://github.com/ansible-collections/community.general/pull/6881).
|
||||
- xenserver_guest_info - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- xenserver_guest_powerstate - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- yum_versionlock - add support to pin specific package versions instead of only the package itself (https://github.com/ansible-collections/community.general/pull/6861, https://github.com/ansible-collections/community.general/issues/4470).
|
||||
|
||||
Deprecated Features
|
||||
-------------------
|
||||
|
||||
- flowdock - module relies entirely on no longer responsive API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6930).
|
||||
- proxmox - old feature flag ``proxmox_default_behavior`` will be removed in community.general 10.0.0 (https://github.com/ansible-collections/community.general/pull/6836).
|
||||
- stackdriver - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6887).
|
||||
- webfaction_app - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
- webfaction_db - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
- webfaction_domain - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
- webfaction_mailbox - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
- webfaction_site - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- cobbler inventory plugin - fix calculation of cobbler_ipv4/6_address (https://github.com/ansible-collections/community.general/pull/6925).
|
||||
- datadog_downtime - presence of ``rrule`` param lead to the Datadog API returning Bad Request due to a missing recurrence type (https://github.com/ansible-collections/community.general/pull/6811).
|
||||
- ipa_dnszone - fix 'idnsallowsyncptr' key error for reverse zone (https://github.com/ansible-collections/community.general/pull/6906, https://github.com/ansible-collections/community.general/issues/6905).
|
||||
- keycloak_authentication - fix Keycloak authentication flow (step or sub-flow) indexing during update, if not specified by the user (https://github.com/ansible-collections/community.general/pull/6734).
|
||||
- locale_gen - now works for locales without the underscore character such as ``C.UTF-8`` (https://github.com/ansible-collections/community.general/pull/6774, https://github.com/ansible-collections/community.general/issues/5142, https://github.com/ansible-collections/community.general/issues/4305).
|
||||
- machinectl become plugin - mark plugin as ``require_tty`` to automatically disable pipelining, with which this plugin is not compatible (https://github.com/ansible-collections/community.general/issues/6932, https://github.com/ansible-collections/community.general/pull/6935).
|
||||
- nmcli - fix support for empty list (in compare and scrape) (https://github.com/ansible-collections/community.general/pull/6769).
|
||||
- openbsd_pkg - the pkg_info(1) behavior has changed in OpenBSD >7.3. The error message ``Can't find`` should not lead to an error case (https://github.com/ansible-collections/community.general/pull/6785).
|
||||
- pacman - module recognizes the output of ``yay`` running as ``root`` (https://github.com/ansible-collections/community.general/pull/6713).
|
||||
- proxmox - fix error when a configuration had no ``template`` field (https://github.com/ansible-collections/community.general/pull/6838, https://github.com/ansible-collections/community.general/issues/5372).
|
||||
- proxmox module utils - add logic to detect whether an old Promoxer complains about the ``token_name`` and ``token_value`` parameters and provide a better error message when that happens (https://github.com/ansible-collections/community.general/pull/6839, https://github.com/ansible-collections/community.general/issues/5371).
|
||||
- proxmox_disk - fix unable to create ``cdrom`` media due to ``size`` always being appended (https://github.com/ansible-collections/community.general/pull/6770).
|
||||
- proxmox_kvm - ``absent`` state with ``force`` specified failed to stop the VM due to the ``timeout`` value not being passed to ``stop_vm`` (https://github.com/ansible-collections/community.general/pull/6827).
|
||||
- proxmox_kvm - ``restarted`` state did not actually restart a VM in some VM configurations. The state now uses the Proxmox reboot endpoint instead of calling the ``stop_vm`` and ``start_vm`` functions (https://github.com/ansible-collections/community.general/pull/6773).
|
||||
- proxmox_template - require ``requests_toolbelt`` module to fix issue with uploading large templates (https://github.com/ansible-collections/community.general/issues/5579, https://github.com/ansible-collections/community.general/pull/6757).
|
||||
- redfish_info - fix ``ListUsers`` to not show empty account slots (https://github.com/ansible-collections/community.general/issues/6771, https://github.com/ansible-collections/community.general/pull/6772).
|
||||
- refish_utils module utils - changing variable names to avoid issues occuring when fetching Volumes data (https://github.com/ansible-collections/community.general/pull/6883).
|
||||
- snap - assume default track ``latest`` in parameter ``channel`` when not specified (https://github.com/ansible-collections/community.general/pull/6835, https://github.com/ansible-collections/community.general/issues/6821).
|
||||
- snap - fix the processing of the commands' output, stripping spaces and newlines from it (https://github.com/ansible-collections/community.general/pull/6826, https://github.com/ansible-collections/community.general/issues/6803).
|
||||
|
||||
New Plugins
|
||||
-----------
|
||||
|
||||
Lookup
|
||||
~~~~~~
|
||||
|
||||
- bitwarden_secrets_manager - Retrieve secrets from Bitwarden Secrets Manager
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- consul_policy - Manipulate Consul policies
|
||||
- keycloak_authz_permission - Allows administration of Keycloak client authorization permissions via Keycloak API
|
||||
- keycloak_authz_permission_info - Query Keycloak client authorization permissions information
|
||||
- proxmox_vm_info - Retrieve information about one or more Proxmox VE virtual machines
|
||||
|
||||
v7.1.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix and feature release.
|
||||
|
||||
From this version on, community.general is using the new `Ansible semantic markup
|
||||
<https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_documenting.html#semantic-markup-within-module-documentation>`__
|
||||
in its documentation. If you look at documentation with the ansible-doc CLI tool
|
||||
from ansible-core before 2.15, please note that it does not render the markup
|
||||
correctly. You should be still able to read it in most cases, but you need
|
||||
ansible-core 2.15 or later to see it as it is intended. Alternatively you can
|
||||
look at `the devel docsite <https://docs.ansible.com/ansible/devel/collections/community/general/>`__
|
||||
for the rendered HTML version of the documentation of the latest release.
|
||||
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- The collection will start using semantic markup (https://github.com/ansible-collections/community.general/pull/6539).
|
||||
- VarDict module utils - add method ``VarDict.as_dict()`` to convert to a plain ``dict`` object (https://github.com/ansible-collections/community.general/pull/6602).
|
||||
- cobbler inventory plugin - add ``inventory_hostname`` option to allow using the system name for the inventory hostname (https://github.com/ansible-collections/community.general/pull/6502).
|
||||
- cobbler inventory plugin - add ``want_ip_addresses`` option to collect all interface DNS name to IP address mapping (https://github.com/ansible-collections/community.general/pull/6711).
|
||||
- cobbler inventory plugin - add primary IP addess to ``cobbler_ipv4_address`` and IPv6 address to ``cobbler_ipv6_address`` host variable (https://github.com/ansible-collections/community.general/pull/6711).
|
||||
- cobbler inventory plugin - add warning for systems with empty profiles (https://github.com/ansible-collections/community.general/pull/6502).
|
||||
- copr - respawn module to use the system python interpreter when the ``dnf`` python module is not available in ``ansible_python_interpreter`` (https://github.com/ansible-collections/community.general/pull/6522).
|
||||
- datadog_monitor - adds ``notification_preset_name``, ``renotify_occurrences`` and ``renotify_statuses`` parameters (https://github.com/ansible-collections/community.general/issues/6521,https://github.com/ansible-collections/community.general/issues/5823).
|
||||
- filesystem - add ``uuid`` parameter for UUID change feature (https://github.com/ansible-collections/community.general/pull/6680).
|
||||
- keycloak_client_rolemapping - adds support for subgroups with additional parameter ``parents`` (https://github.com/ansible-collections/community.general/pull/6687).
|
||||
- keycloak_role - add composite roles support for realm and client roles (https://github.com/ansible-collections/community.general/pull/6469).
|
||||
- ldap_* - add new arguments ``client_cert`` and ``client_key`` to the LDAP modules in order to allow certificate authentication (https://github.com/ansible-collections/community.general/pull/6668).
|
||||
- ldap_search - add a new ``page_size`` option to enable paged searches (https://github.com/ansible-collections/community.general/pull/6648).
|
||||
- lvg - add ``active`` and ``inactive`` values to the ``state`` option for active state management feature (https://github.com/ansible-collections/community.general/pull/6682).
|
||||
- lvg - add ``reset_vg_uuid``, ``reset_pv_uuid`` options for UUID reset feature (https://github.com/ansible-collections/community.general/pull/6682).
|
||||
- mas - disable sign-in check for macOS 12+ as ``mas account`` is non-functional (https://github.com/ansible-collections/community.general/pull/6520).
|
||||
- onepassword lookup plugin - add service account support (https://github.com/ansible-collections/community.general/issues/6635, https://github.com/ansible-collections/community.general/pull/6660).
|
||||
- onepassword_raw lookup plugin - add service account support (https://github.com/ansible-collections/community.general/issues/6635, https://github.com/ansible-collections/community.general/pull/6660).
|
||||
- opentelemetry callback plugin - add span attributes in the span event (https://github.com/ansible-collections/community.general/pull/6531).
|
||||
- opkg - remove default value ``""`` for parameter ``force`` as it causes the same behaviour of not having that parameter (https://github.com/ansible-collections/community.general/pull/6513).
|
||||
- proxmox - support ``timezone`` parameter at container creation (https://github.com/ansible-collections/community.general/pull/6510).
|
||||
- proxmox inventory plugin - add composite variables support for Proxmox nodes (https://github.com/ansible-collections/community.general/issues/6640).
|
||||
- proxmox_kvm - added support for ``tpmstate0`` parameter to configure TPM (Trusted Platform Module) disk. TPM is required for Windows 11 installations (https://github.com/ansible-collections/community.general/pull/6533).
|
||||
- proxmox_kvm - re-use ``timeout`` module param to forcefully shutdown a virtual machine when ``state`` is ``stopped`` (https://github.com/ansible-collections/community.general/issues/6257).
|
||||
- proxmox_snap - add ``retention`` parameter to delete old snapshots (https://github.com/ansible-collections/community.general/pull/6576).
|
||||
- redfish_command - add ``MultipartHTTPPushUpdate`` command (https://github.com/ansible-collections/community.general/issues/6471, https://github.com/ansible-collections/community.general/pull/6612).
|
||||
- redhat_subscription - the internal ``RegistrationBase`` class was folded
|
||||
into the other internal ``Rhsm`` class, as the separation had no purpose
|
||||
anymore
|
||||
(https://github.com/ansible-collections/community.general/pull/6658).
|
||||
- rhsm_release - improve/harden the way ``subscription-manager`` is run;
|
||||
no behaviour change is expected
|
||||
(https://github.com/ansible-collections/community.general/pull/6669).
|
||||
- snap - module is now aware of channel when deciding whether to install or refresh the snap (https://github.com/ansible-collections/community.general/pull/6435, https://github.com/ansible-collections/community.general/issues/1606).
|
||||
- sorcery - minor refactor (https://github.com/ansible-collections/community.general/pull/6525).
|
||||
- tss lookup plugin - allow to fetch secret IDs which are in a folder based on folder ID. Previously, we could not fetch secrets based on folder ID but now use ``fetch_secret_ids_from_folder`` option to indicate to fetch secret IDs based on folder ID (https://github.com/ansible-collections/community.general/issues/6223).
|
||||
|
||||
Deprecated Features
|
||||
-------------------
|
||||
|
||||
- CmdRunner module utils - deprecate ``cmd_runner_fmt.as_default_type()`` formatter (https://github.com/ansible-collections/community.general/pull/6601).
|
||||
- MH VarsMixin module utils - deprecates ``VarsMixin`` and supporting classes in favor of plain ``vardict`` module util (https://github.com/ansible-collections/community.general/pull/6649).
|
||||
- cpanm - value ``compatibility`` is deprecated as default for parameter ``mode`` (https://github.com/ansible-collections/community.general/pull/6512).
|
||||
- redhat module utils - the ``module_utils.redhat`` module is deprecated, as
|
||||
effectively unused: the ``Rhsm``, ``RhsmPool``, and ``RhsmPools`` classes
|
||||
will be removed in community.general 9.0.0; the ``RegistrationBase`` class
|
||||
will be removed in community.general 10.0.0 together with the
|
||||
``rhn_register`` module, as it is the only user of this class; this means
|
||||
that the whole ``module_utils.redhat`` module will be dropped in
|
||||
community.general 10.0.0, so importing it without even using anything of it
|
||||
will fail
|
||||
(https://github.com/ansible-collections/community.general/pull/6663).
|
||||
- redhat_subscription - the ``autosubscribe`` alias for the ``auto_attach`` option has been
|
||||
deprecated for many years, although only in the documentation. Officially mark this alias
|
||||
as deprecated, and it will be removed in community.general 9.0.0
|
||||
(https://github.com/ansible-collections/community.general/pull/6646).
|
||||
- redhat_subscription - the ``pool`` option is deprecated in favour of the
|
||||
more precise and flexible ``pool_ids`` option
|
||||
(https://github.com/ansible-collections/community.general/pull/6650).
|
||||
- rhsm_repository - ``state=present`` has not been working as expected for many years,
|
||||
and it seems it was not noticed so far; also, "presence" is not really a valid concept
|
||||
for subscription repositories, which can only be enabled or disabled. Hence, mark the
|
||||
``present`` and ``absent`` values of the ``state`` option as deprecated, slating them
|
||||
for removal in community.general 10.0.0
|
||||
(https://github.com/ansible-collections/community.general/pull/6673).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- MH DependencyMixin module utils - deprecation notice was popping up for modules not using dependencies (https://github.com/ansible-collections/community.general/pull/6644, https://github.com/ansible-collections/community.general/issues/6639).
|
||||
- csv module utils - detects and remove unicode BOM markers from incoming CSV content (https://github.com/ansible-collections/community.general/pull/6662).
|
||||
- gitlab_group - the module passed parameters to the API call even when not set. The module is now filtering out ``None`` values to remediate this (https://github.com/ansible-collections/community.general/pull/6712).
|
||||
- icinga2_host - fix a key error when updating an existing host (https://github.com/ansible-collections/community.general/pull/6748).
|
||||
- ini_file - add the ``follow`` paramter to follow the symlinks instead of replacing them (https://github.com/ansible-collections/community.general/pull/6546).
|
||||
- ini_file - fix a bug where the inactive options were not used when possible (https://github.com/ansible-collections/community.general/pull/6575).
|
||||
- keycloak module utils - fix ``is_struct_included`` handling of lists of lists/dictionaries (https://github.com/ansible-collections/community.general/pull/6688).
|
||||
- keycloak module utils - the function ``get_user_by_username`` now return the user representation or ``None`` as stated in the documentation (https://github.com/ansible-collections/community.general/pull/6758).
|
||||
- proxmox_kvm - allow creation of VM with existing name but new vmid (https://github.com/ansible-collections/community.general/issues/6155, https://github.com/ansible-collections/community.general/pull/6709).
|
||||
- rhsm_repository - when using the ``purge`` option, the ``repositories``
|
||||
dictionary element in the returned JSON is now properly updated according
|
||||
to the pruning operation
|
||||
(https://github.com/ansible-collections/community.general/pull/6676).
|
||||
- tss lookup plugin - fix multiple issues when using ``fetch_attachments=true`` (https://github.com/ansible-collections/community.general/pull/6720).
|
||||
|
||||
Known Issues
|
||||
------------
|
||||
|
||||
- Ansible markup will show up in raw form on ansible-doc text output for ansible-core before 2.15. If you have trouble deciphering the documentation markup, please upgrade to ansible-core 2.15 (or newer), or read the HTML documentation on https://docs.ansible.com/ansible/devel/collections/community/general/ (https://github.com/ansible-collections/community.general/pull/6539).
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- gitlab_instance_variable - Creates, updates, or deletes GitLab instance variables
|
||||
- gitlab_merge_request - Create, update, or delete GitLab merge requests
|
||||
- keycloak_authentication_required_actions - Allows administration of Keycloak authentication required actions
|
||||
- keycloak_user - Create and configure a user in Keycloak
|
||||
- lvg_rename - Renames LVM volume groups
|
||||
- proxmox_pool - Pool management for Proxmox VE cluster
|
||||
- proxmox_pool_member - Add or delete members from Proxmox VE cluster pools
|
||||
|
||||
v7.0.1
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Bugfix release for Ansible 8.0.0rc1.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- nmcli - fix bond option ``xmit_hash_policy`` (https://github.com/ansible-collections/community.general/pull/6527).
|
||||
- portage - fix ``changed_use`` and ``newuse`` not triggering rebuilds (https://github.com/ansible-collections/community.general/issues/6008, https://github.com/ansible-collections/community.general/pull/6548).
|
||||
- proxmox_tasks_info - remove ``api_user`` + ``api_password`` constraint from ``required_together`` as it causes to require ``api_password`` even when API token param is used (https://github.com/ansible-collections/community.general/issues/6201).
|
||||
- zypper - added handling of zypper exitcode 102. Changed state is set correctly now and rc 102 is still preserved to be evaluated by the playbook (https://github.com/ansible-collections/community.general/pull/6534).
|
||||
|
||||
v7.0.0
|
||||
======
|
||||
|
||||
|
||||
@@ -121,19 +121,3 @@ Creating new modules and plugins requires a bit more work than other Pull Reques
|
||||
listed as `maintainers` will be pinged for new issues and PRs that modify the module/plugin or its tests.
|
||||
|
||||
When you add a new plugin/module, we expect that you perform maintainer duty for at least some time after contributing it.
|
||||
|
||||
## pre-commit
|
||||
|
||||
To help ensure high-quality contributions this repository includes a [pre-commit](https://pre-commit.com) configuration which
|
||||
corrects and tests against common issues that would otherwise cause CI to fail. To begin using these pre-commit hooks see
|
||||
the [Installation](#installation) section below.
|
||||
|
||||
This is optional and not required to contribute to this repository.
|
||||
|
||||
### Installation
|
||||
|
||||
Follow the [instructions](https://pre-commit.com/#install) provided with pre-commit and run `pre-commit install` under the repository base. If for any reason you would like to disable the pre-commit hooks run `pre-commit uninstall`.
|
||||
|
||||
This is optional to run it locally.
|
||||
|
||||
You can trigger it locally with `pre-commit run --all-files` or even to run only for a given file `pre-commit run --files YOUR_FILE`.
|
||||
|
||||
@@ -24,7 +24,7 @@ If you encounter abusive behavior violating the [Ansible Code of Conduct](https:
|
||||
|
||||
## Tested with Ansible
|
||||
|
||||
Tested with the current ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, ansible-core 2.14 releases and the current development version of ansible-core. Ansible-core versions before 2.11.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases.
|
||||
Tested with the current ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, ansible-core 2.14, ansible-core 2.15 releases and the current development version of ansible-core. Ansible-core versions before 2.11.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases.
|
||||
|
||||
Parts of this collection will not work with ansible-core 2.11 on Python 3.12+.
|
||||
|
||||
|
||||
@@ -803,3 +803,471 @@ releases:
|
||||
name: merge_variables
|
||||
namespace: null
|
||||
release_date: '2023-05-09'
|
||||
7.0.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- nmcli - fix bond option ``xmit_hash_policy`` (https://github.com/ansible-collections/community.general/pull/6527).
|
||||
- portage - fix ``changed_use`` and ``newuse`` not triggering rebuilds (https://github.com/ansible-collections/community.general/issues/6008,
|
||||
https://github.com/ansible-collections/community.general/pull/6548).
|
||||
- proxmox_tasks_info - remove ``api_user`` + ``api_password`` constraint from
|
||||
``required_together`` as it causes to require ``api_password`` even when API
|
||||
token param is used (https://github.com/ansible-collections/community.general/issues/6201).
|
||||
- zypper - added handling of zypper exitcode 102. Changed state is set correctly
|
||||
now and rc 102 is still preserved to be evaluated by the playbook (https://github.com/ansible-collections/community.general/pull/6534).
|
||||
release_summary: Bugfix release for Ansible 8.0.0rc1.
|
||||
fragments:
|
||||
- 6527-nmcli-bond-fix-xmit_hash_policy.yml
|
||||
- 6534-zypper-exitcode-102-handled.yaml
|
||||
- 6548-portage-changed_use-newuse.yml
|
||||
- 6554-proxmox-tasks-info-fix-required-password.yaml
|
||||
- 7.0.1.yml
|
||||
release_date: '2023-05-22'
|
||||
7.1.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- MH DependencyMixin module utils - deprecation notice was popping up for modules
|
||||
not using dependencies (https://github.com/ansible-collections/community.general/pull/6644,
|
||||
https://github.com/ansible-collections/community.general/issues/6639).
|
||||
- csv module utils - detects and remove unicode BOM markers from incoming CSV
|
||||
content (https://github.com/ansible-collections/community.general/pull/6662).
|
||||
- gitlab_group - the module passed parameters to the API call even when not
|
||||
set. The module is now filtering out ``None`` values to remediate this (https://github.com/ansible-collections/community.general/pull/6712).
|
||||
- icinga2_host - fix a key error when updating an existing host (https://github.com/ansible-collections/community.general/pull/6748).
|
||||
- ini_file - add the ``follow`` paramter to follow the symlinks instead of replacing
|
||||
them (https://github.com/ansible-collections/community.general/pull/6546).
|
||||
- ini_file - fix a bug where the inactive options were not used when possible
|
||||
(https://github.com/ansible-collections/community.general/pull/6575).
|
||||
- keycloak module utils - fix ``is_struct_included`` handling of lists of lists/dictionaries
|
||||
(https://github.com/ansible-collections/community.general/pull/6688).
|
||||
- keycloak module utils - the function ``get_user_by_username`` now return the
|
||||
user representation or ``None`` as stated in the documentation (https://github.com/ansible-collections/community.general/pull/6758).
|
||||
- proxmox_kvm - allow creation of VM with existing name but new vmid (https://github.com/ansible-collections/community.general/issues/6155,
|
||||
https://github.com/ansible-collections/community.general/pull/6709).
|
||||
- 'rhsm_repository - when using the ``purge`` option, the ``repositories``
|
||||
|
||||
dictionary element in the returned JSON is now properly updated according
|
||||
|
||||
to the pruning operation
|
||||
|
||||
(https://github.com/ansible-collections/community.general/pull/6676).
|
||||
|
||||
'
|
||||
- tss lookup plugin - fix multiple issues when using ``fetch_attachments=true``
|
||||
(https://github.com/ansible-collections/community.general/pull/6720).
|
||||
deprecated_features:
|
||||
- CmdRunner module utils - deprecate ``cmd_runner_fmt.as_default_type()`` formatter
|
||||
(https://github.com/ansible-collections/community.general/pull/6601).
|
||||
- MH VarsMixin module utils - deprecates ``VarsMixin`` and supporting classes
|
||||
in favor of plain ``vardict`` module util (https://github.com/ansible-collections/community.general/pull/6649).
|
||||
- cpanm - value ``compatibility`` is deprecated as default for parameter ``mode``
|
||||
(https://github.com/ansible-collections/community.general/pull/6512).
|
||||
- 'redhat module utils - the ``module_utils.redhat`` module is deprecated, as
|
||||
|
||||
effectively unused: the ``Rhsm``, ``RhsmPool``, and ``RhsmPools`` classes
|
||||
|
||||
will be removed in community.general 9.0.0; the ``RegistrationBase`` class
|
||||
|
||||
will be removed in community.general 10.0.0 together with the
|
||||
|
||||
``rhn_register`` module, as it is the only user of this class; this means
|
||||
|
||||
that the whole ``module_utils.redhat`` module will be dropped in
|
||||
|
||||
community.general 10.0.0, so importing it without even using anything of it
|
||||
|
||||
will fail
|
||||
|
||||
(https://github.com/ansible-collections/community.general/pull/6663).
|
||||
|
||||
'
|
||||
- 'redhat_subscription - the ``autosubscribe`` alias for the ``auto_attach``
|
||||
option has been
|
||||
|
||||
deprecated for many years, although only in the documentation. Officially
|
||||
mark this alias
|
||||
|
||||
as deprecated, and it will be removed in community.general 9.0.0
|
||||
|
||||
(https://github.com/ansible-collections/community.general/pull/6646).
|
||||
|
||||
'
|
||||
- 'redhat_subscription - the ``pool`` option is deprecated in favour of the
|
||||
|
||||
more precise and flexible ``pool_ids`` option
|
||||
|
||||
(https://github.com/ansible-collections/community.general/pull/6650).
|
||||
|
||||
'
|
||||
- 'rhsm_repository - ``state=present`` has not been working as expected for
|
||||
many years,
|
||||
|
||||
and it seems it was not noticed so far; also, "presence" is not really a valid
|
||||
concept
|
||||
|
||||
for subscription repositories, which can only be enabled or disabled. Hence,
|
||||
mark the
|
||||
|
||||
``present`` and ``absent`` values of the ``state`` option as deprecated, slating
|
||||
them
|
||||
|
||||
for removal in community.general 10.0.0
|
||||
|
||||
(https://github.com/ansible-collections/community.general/pull/6673).
|
||||
|
||||
'
|
||||
known_issues:
|
||||
- Ansible markup will show up in raw form on ansible-doc text output for ansible-core
|
||||
before 2.15. If you have trouble deciphering the documentation markup, please
|
||||
upgrade to ansible-core 2.15 (or newer), or read the HTML documentation on
|
||||
https://docs.ansible.com/ansible/devel/collections/community/general/ (https://github.com/ansible-collections/community.general/pull/6539).
|
||||
minor_changes:
|
||||
- The collection will start using semantic markup (https://github.com/ansible-collections/community.general/pull/6539).
|
||||
- VarDict module utils - add method ``VarDict.as_dict()`` to convert to a plain
|
||||
``dict`` object (https://github.com/ansible-collections/community.general/pull/6602).
|
||||
- cobbler inventory plugin - add ``inventory_hostname`` option to allow using
|
||||
the system name for the inventory hostname (https://github.com/ansible-collections/community.general/pull/6502).
|
||||
- cobbler inventory plugin - add ``want_ip_addresses`` option to collect all
|
||||
interface DNS name to IP address mapping (https://github.com/ansible-collections/community.general/pull/6711).
|
||||
- cobbler inventory plugin - add primary IP addess to ``cobbler_ipv4_address``
|
||||
and IPv6 address to ``cobbler_ipv6_address`` host variable (https://github.com/ansible-collections/community.general/pull/6711).
|
||||
- cobbler inventory plugin - add warning for systems with empty profiles (https://github.com/ansible-collections/community.general/pull/6502).
|
||||
- copr - respawn module to use the system python interpreter when the ``dnf``
|
||||
python module is not available in ``ansible_python_interpreter`` (https://github.com/ansible-collections/community.general/pull/6522).
|
||||
- datadog_monitor - adds ``notification_preset_name``, ``renotify_occurrences``
|
||||
and ``renotify_statuses`` parameters (https://github.com/ansible-collections/community.general/issues/6521,https://github.com/ansible-collections/community.general/issues/5823).
|
||||
- filesystem - add ``uuid`` parameter for UUID change feature (https://github.com/ansible-collections/community.general/pull/6680).
|
||||
- keycloak_client_rolemapping - adds support for subgroups with additional parameter
|
||||
``parents`` (https://github.com/ansible-collections/community.general/pull/6687).
|
||||
- keycloak_role - add composite roles support for realm and client roles (https://github.com/ansible-collections/community.general/pull/6469).
|
||||
- ldap_* - add new arguments ``client_cert`` and ``client_key`` to the LDAP
|
||||
modules in order to allow certificate authentication (https://github.com/ansible-collections/community.general/pull/6668).
|
||||
- ldap_search - add a new ``page_size`` option to enable paged searches (https://github.com/ansible-collections/community.general/pull/6648).
|
||||
- lvg - add ``active`` and ``inactive`` values to the ``state`` option for active
|
||||
state management feature (https://github.com/ansible-collections/community.general/pull/6682).
|
||||
- lvg - add ``reset_vg_uuid``, ``reset_pv_uuid`` options for UUID reset feature
|
||||
(https://github.com/ansible-collections/community.general/pull/6682).
|
||||
- mas - disable sign-in check for macOS 12+ as ``mas account`` is non-functional
|
||||
(https://github.com/ansible-collections/community.general/pull/6520).
|
||||
- onepassword lookup plugin - add service account support (https://github.com/ansible-collections/community.general/issues/6635,
|
||||
https://github.com/ansible-collections/community.general/pull/6660).
|
||||
- onepassword_raw lookup plugin - add service account support (https://github.com/ansible-collections/community.general/issues/6635,
|
||||
https://github.com/ansible-collections/community.general/pull/6660).
|
||||
- opentelemetry callback plugin - add span attributes in the span event (https://github.com/ansible-collections/community.general/pull/6531).
|
||||
- opkg - remove default value ``""`` for parameter ``force`` as it causes the
|
||||
same behaviour of not having that parameter (https://github.com/ansible-collections/community.general/pull/6513).
|
||||
- proxmox - support ``timezone`` parameter at container creation (https://github.com/ansible-collections/community.general/pull/6510).
|
||||
- proxmox inventory plugin - add composite variables support for Proxmox nodes
|
||||
(https://github.com/ansible-collections/community.general/issues/6640).
|
||||
- proxmox_kvm - added support for ``tpmstate0`` parameter to configure TPM (Trusted
|
||||
Platform Module) disk. TPM is required for Windows 11 installations (https://github.com/ansible-collections/community.general/pull/6533).
|
||||
- proxmox_kvm - re-use ``timeout`` module param to forcefully shutdown a virtual
|
||||
machine when ``state`` is ``stopped`` (https://github.com/ansible-collections/community.general/issues/6257).
|
||||
- proxmox_snap - add ``retention`` parameter to delete old snapshots (https://github.com/ansible-collections/community.general/pull/6576).
|
||||
- redfish_command - add ``MultipartHTTPPushUpdate`` command (https://github.com/ansible-collections/community.general/issues/6471,
|
||||
https://github.com/ansible-collections/community.general/pull/6612).
|
||||
- 'redhat_subscription - the internal ``RegistrationBase`` class was folded
|
||||
|
||||
into the other internal ``Rhsm`` class, as the separation had no purpose
|
||||
|
||||
anymore
|
||||
|
||||
(https://github.com/ansible-collections/community.general/pull/6658).
|
||||
|
||||
'
|
||||
- 'rhsm_release - improve/harden the way ``subscription-manager`` is run;
|
||||
|
||||
no behaviour change is expected
|
||||
|
||||
(https://github.com/ansible-collections/community.general/pull/6669).
|
||||
|
||||
'
|
||||
- snap - module is now aware of channel when deciding whether to install or
|
||||
refresh the snap (https://github.com/ansible-collections/community.general/pull/6435,
|
||||
https://github.com/ansible-collections/community.general/issues/1606).
|
||||
- sorcery - minor refactor (https://github.com/ansible-collections/community.general/pull/6525).
|
||||
- tss lookup plugin - allow to fetch secret IDs which are in a folder based
|
||||
on folder ID. Previously, we could not fetch secrets based on folder ID but
|
||||
now use ``fetch_secret_ids_from_folder`` option to indicate to fetch secret
|
||||
IDs based on folder ID (https://github.com/ansible-collections/community.general/issues/6223).
|
||||
release_summary: 'Regular bugfix and feature release.
|
||||
|
||||
|
||||
From this version on, community.general is using the new `Ansible semantic
|
||||
markup
|
||||
|
||||
<https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_documenting.html#semantic-markup-within-module-documentation>`__
|
||||
|
||||
in its documentation. If you look at documentation with the ansible-doc CLI
|
||||
tool
|
||||
|
||||
from ansible-core before 2.15, please note that it does not render the markup
|
||||
|
||||
correctly. You should be still able to read it in most cases, but you need
|
||||
|
||||
ansible-core 2.15 or later to see it as it is intended. Alternatively you
|
||||
can
|
||||
|
||||
look at `the devel docsite <https://docs.ansible.com/ansible/devel/collections/community/general/>`__
|
||||
|
||||
for the rendered HTML version of the documentation of the latest release.
|
||||
|
||||
'
|
||||
fragments:
|
||||
- 6223-get-secret-ids-by-folderid.yml
|
||||
- 6435-snap-channel-aware.yml
|
||||
- 6469-add-composites-support-for-keycloak-role.yml
|
||||
- 6471-redfish-add-multipart-http-push-command.yml
|
||||
- 6502-cobbler-inventory_hostname.yml
|
||||
- 6510-proxmox-create-support_timezone.yaml
|
||||
- 6512-cpanm-default-mode.yml
|
||||
- 6513-opkg-default-force.yml
|
||||
- 6520-mas-disable-signin.yaml
|
||||
- 6522-copr-respawn.yaml
|
||||
- 6523-datadog-monitor-notification-preset-name-and-renotify.yaml
|
||||
- 6525-sorcery-import.yaml
|
||||
- 6531-opentelemetry-add-event-attributes.yml
|
||||
- 6533-proxmox_kvm-tpmstate0-support.yaml
|
||||
- 6539-semantic-markup.yml
|
||||
- 6568-fix-get-user-by-username-in-keycloak-module-utils.yml
|
||||
- 6570-handle-shutdown-timeout.yaml
|
||||
- 6576-proxmox-snap-allow-to-remove-old-snapshots.yml
|
||||
- 6601-cmdrunner-deprecate-default-type.yml
|
||||
- 6602-vardict-as-dict.yml
|
||||
- 6640-proxmox-composite-variables-support.yml
|
||||
- 6644-dependencymixin-fix.yml
|
||||
- 6646-redhat_subscription-deprecate-autosubscribe.yml
|
||||
- 6648_ldap_search_page_size.yml
|
||||
- 6649-varsmixin-deprecation.yml
|
||||
- 6650-redhat_subscription-deprecate-pool.yml
|
||||
- 6658-redhat_subscription-internal-rhsm-refactor.yml
|
||||
- 6660-onepassword-lookup-service-account.yaml
|
||||
- 6662-csv-bom.yml
|
||||
- 6663-deprecate-module_utils-redhat.yml
|
||||
- 6668-ldap-client-cert.yml
|
||||
- 6669-rhsm_release-internal-sub-man-exec.yml
|
||||
- 6673-rhsm_repository-deprecate-present-absent.yml
|
||||
- 6676-rhsm_repository-fix-returned-repositories-with-purge.yml
|
||||
- 6680-filesystem-uuid-change.yml
|
||||
- 6682-lvg-clonesupport.yml
|
||||
- 6687-support-subgroups-for-keycloak-client-rolemapping.yml
|
||||
- 6688-is-struct-included-bug-in-keycloak-py.yml
|
||||
- 6709-proxmox-create-vm-with-existing-name.yml
|
||||
- 6711-cobbler-ip-address.yml
|
||||
- 6712-gitlab_group-filtered-for-none-values.yml
|
||||
- 6720-tss-fix-fetch-attachments.yml
|
||||
- 6748-icinga2_host-datafix.yml
|
||||
- 7.1.0.yml
|
||||
- ini_file-preserve-symlink.yml
|
||||
- ini_file-use-inactive-options-when-possible.yml
|
||||
modules:
|
||||
- description: Creates, updates, or deletes GitLab instance variables
|
||||
name: gitlab_instance_variable
|
||||
namespace: ''
|
||||
- description: Create, update, or delete GitLab merge requests
|
||||
name: gitlab_merge_request
|
||||
namespace: ''
|
||||
- description: Allows administration of Keycloak authentication required actions
|
||||
name: keycloak_authentication_required_actions
|
||||
namespace: ''
|
||||
- description: Create and configure a user in Keycloak
|
||||
name: keycloak_user
|
||||
namespace: ''
|
||||
- description: Renames LVM volume groups
|
||||
name: lvg_rename
|
||||
namespace: ''
|
||||
- description: Pool management for Proxmox VE cluster
|
||||
name: proxmox_pool
|
||||
namespace: ''
|
||||
- description: Add or delete members from Proxmox VE cluster pools
|
||||
name: proxmox_pool_member
|
||||
namespace: ''
|
||||
release_date: '2023-06-20'
|
||||
7.2.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- cobbler inventory plugin - fix calculation of cobbler_ipv4/6_address (https://github.com/ansible-collections/community.general/pull/6925).
|
||||
- datadog_downtime - presence of ``rrule`` param lead to the Datadog API returning
|
||||
Bad Request due to a missing recurrence type (https://github.com/ansible-collections/community.general/pull/6811).
|
||||
- ipa_dnszone - fix 'idnsallowsyncptr' key error for reverse zone (https://github.com/ansible-collections/community.general/pull/6906,
|
||||
https://github.com/ansible-collections/community.general/issues/6905).
|
||||
- keycloak_authentication - fix Keycloak authentication flow (step or sub-flow)
|
||||
indexing during update, if not specified by the user (https://github.com/ansible-collections/community.general/pull/6734).
|
||||
- locale_gen - now works for locales without the underscore character such as
|
||||
``C.UTF-8`` (https://github.com/ansible-collections/community.general/pull/6774,
|
||||
https://github.com/ansible-collections/community.general/issues/5142, https://github.com/ansible-collections/community.general/issues/4305).
|
||||
- machinectl become plugin - mark plugin as ``require_tty`` to automatically
|
||||
disable pipelining, with which this plugin is not compatible (https://github.com/ansible-collections/community.general/issues/6932,
|
||||
https://github.com/ansible-collections/community.general/pull/6935).
|
||||
- nmcli - fix support for empty list (in compare and scrape) (https://github.com/ansible-collections/community.general/pull/6769).
|
||||
- openbsd_pkg - the pkg_info(1) behavior has changed in OpenBSD >7.3. The error
|
||||
message ``Can't find`` should not lead to an error case (https://github.com/ansible-collections/community.general/pull/6785).
|
||||
- pacman - module recognizes the output of ``yay`` running as ``root`` (https://github.com/ansible-collections/community.general/pull/6713).
|
||||
- proxmox - fix error when a configuration had no ``template`` field (https://github.com/ansible-collections/community.general/pull/6838,
|
||||
https://github.com/ansible-collections/community.general/issues/5372).
|
||||
- proxmox module utils - add logic to detect whether an old Promoxer complains
|
||||
about the ``token_name`` and ``token_value`` parameters and provide a better
|
||||
error message when that happens (https://github.com/ansible-collections/community.general/pull/6839,
|
||||
https://github.com/ansible-collections/community.general/issues/5371).
|
||||
- proxmox_disk - fix unable to create ``cdrom`` media due to ``size`` always
|
||||
being appended (https://github.com/ansible-collections/community.general/pull/6770).
|
||||
- proxmox_kvm - ``absent`` state with ``force`` specified failed to stop the
|
||||
VM due to the ``timeout`` value not being passed to ``stop_vm`` (https://github.com/ansible-collections/community.general/pull/6827).
|
||||
- proxmox_kvm - ``restarted`` state did not actually restart a VM in some VM
|
||||
configurations. The state now uses the Proxmox reboot endpoint instead of
|
||||
calling the ``stop_vm`` and ``start_vm`` functions (https://github.com/ansible-collections/community.general/pull/6773).
|
||||
- proxmox_template - require ``requests_toolbelt`` module to fix issue with
|
||||
uploading large templates (https://github.com/ansible-collections/community.general/issues/5579,
|
||||
https://github.com/ansible-collections/community.general/pull/6757).
|
||||
- redfish_info - fix ``ListUsers`` to not show empty account slots (https://github.com/ansible-collections/community.general/issues/6771,
|
||||
https://github.com/ansible-collections/community.general/pull/6772).
|
||||
- refish_utils module utils - changing variable names to avoid issues occuring
|
||||
when fetching Volumes data (https://github.com/ansible-collections/community.general/pull/6883).
|
||||
- snap - assume default track ``latest`` in parameter ``channel`` when not specified
|
||||
(https://github.com/ansible-collections/community.general/pull/6835, https://github.com/ansible-collections/community.general/issues/6821).
|
||||
- snap - fix the processing of the commands' output, stripping spaces and newlines
|
||||
from it (https://github.com/ansible-collections/community.general/pull/6826,
|
||||
https://github.com/ansible-collections/community.general/issues/6803).
|
||||
deprecated_features:
|
||||
- flowdock - module relies entirely on no longer responsive API endpoints, and
|
||||
it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6930).
|
||||
- proxmox - old feature flag ``proxmox_default_behavior`` will be removed in
|
||||
community.general 10.0.0 (https://github.com/ansible-collections/community.general/pull/6836).
|
||||
- stackdriver - module relies entirely on no longer existent API endpoints,
|
||||
and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6887).
|
||||
- webfaction_app - module relies entirely on no longer existent API endpoints,
|
||||
and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
- webfaction_db - module relies entirely on no longer existent API endpoints,
|
||||
and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
- webfaction_domain - module relies entirely on no longer existent API endpoints,
|
||||
and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
- webfaction_mailbox - module relies entirely on no longer existent API endpoints,
|
||||
and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
- webfaction_site - module relies entirely on no longer existent API endpoints,
|
||||
and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
minor_changes:
|
||||
- cobbler inventory plugin - convert Ansible unicode strings to native Python
|
||||
unicode strings before passing user/password to XMLRPC client (https://github.com/ansible-collections/community.general/pull/6923).
|
||||
- consul_session - drops requirement for the ``python-consul`` library to communicate
|
||||
with the Consul API, instead relying on the existing ``requests`` library
|
||||
requirement (https://github.com/ansible-collections/community.general/pull/6755).
|
||||
- gitlab_project_variable - minor refactor removing unnecessary code statements
|
||||
(https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- gitlab_runner - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6927).
|
||||
- htpasswd - the parameter ``crypt_scheme`` is being renamed as ``hash_scheme``
|
||||
and added as an alias to it (https://github.com/ansible-collections/community.general/pull/6841).
|
||||
- keycloak_authentication - added provider ID choices, since Keycloak supports
|
||||
only those two specific ones (https://github.com/ansible-collections/community.general/pull/6763).
|
||||
- keyring - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6927).
|
||||
- locale_gen - module has been refactored to use ``ModuleHelper`` and ``CmdRunner``
|
||||
(https://github.com/ansible-collections/community.general/pull/6903).
|
||||
- locale_gen - module now using ``CmdRunner`` to execute external commands (https://github.com/ansible-collections/community.general/pull/6820).
|
||||
- make - add new ``targets`` parameter allowing multiple targets to be used
|
||||
with ``make`` (https://github.com/ansible-collections/community.general/pull/6882,
|
||||
https://github.com/ansible-collections/community.general/issues/4919).
|
||||
- nmcli - add support for ``ipv4.dns-options`` and ``ipv6.dns-options`` (https://github.com/ansible-collections/community.general/pull/6902).
|
||||
- npm - minor improvement on parameter validation (https://github.com/ansible-collections/community.general/pull/6848).
|
||||
- opkg - add ``executable`` parameter allowing to specify the path of the ``opkg``
|
||||
command (https://github.com/ansible-collections/community.general/pull/6862).
|
||||
- pubnub_blocks - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- redfish_command - add ``account_types`` and ``oem_account_types`` as optional
|
||||
inputs to ``AddUser`` (https://github.com/ansible-collections/community.general/issues/6823,
|
||||
https://github.com/ansible-collections/community.general/pull/6871).
|
||||
- redfish_info - add ``AccountTypes`` and ``OEMAccountTypes`` to the output
|
||||
of ``ListUsers`` (https://github.com/ansible-collections/community.general/issues/6823,
|
||||
https://github.com/ansible-collections/community.general/pull/6871).
|
||||
- redfish_info - adds ``ProcessorArchitecture`` to CPU inventory (https://github.com/ansible-collections/community.general/pull/6864).
|
||||
- redfish_info - fix for ``GetVolumeInventory``, Controller name was getting
|
||||
populated incorrectly and duplicates were seen in the volumes retrieved (https://github.com/ansible-collections/community.general/pull/6719).
|
||||
- 'rhsm_repository - the interaction with ``subscription-manager`` was
|
||||
|
||||
refactored by grouping things together, removing unused bits, and hardening
|
||||
|
||||
the way it is run; also, the parsing of ``subscription-manager repos --list``
|
||||
|
||||
was improved and made slightly faster; no behaviour change is expected
|
||||
|
||||
(https://github.com/ansible-collections/community.general/pull/6783,
|
||||
|
||||
https://github.com/ansible-collections/community.general/pull/6837).
|
||||
|
||||
'
|
||||
- scaleway_security_group_rule - minor refactor removing unnecessary code statements
|
||||
(https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- snap - add option ``dangerous`` to the module, that will map into the command
|
||||
line argument ``--dangerous``, allowing unsigned snap files to be installed
|
||||
(https://github.com/ansible-collections/community.general/pull/6908, https://github.com/ansible-collections/community.general/issues/5715).
|
||||
- tss lookup plugin - allow to fetch secret by path. Previously, we could not
|
||||
fetch secret by path but now use ``secret_path`` option to indicate to fetch
|
||||
secret by secret path (https://github.com/ansible-collections/community.general/pull/6881).
|
||||
- xenserver_guest_info - minor refactor removing unnecessary code statements
|
||||
(https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- xenserver_guest_powerstate - minor refactor removing unnecessary code statements
|
||||
(https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- yum_versionlock - add support to pin specific package versions instead of
|
||||
only the package itself (https://github.com/ansible-collections/community.general/pull/6861,
|
||||
https://github.com/ansible-collections/community.general/issues/4470).
|
||||
release_summary: Regular bugfix and feature release.
|
||||
fragments:
|
||||
- 6713-yay-become.yml
|
||||
- 6719-redfish-utils-fix-for-get-volume-inventory.yml
|
||||
- 6734-keycloak-auth-management-indexing.yml
|
||||
- 6755-refactor-consul-session-to-use-requests-lib-instead-of-consul.yml
|
||||
- 6757-proxmox-template-fix-upload-error.yml
|
||||
- 6763-keycloak-auth-provider-choices.yml
|
||||
- 6769-nmcli-fix-empty-list.yml
|
||||
- 6770-proxmox_disk_create_cdrom.yml
|
||||
- 6771-redfish-filter-empty-account-slots.yml
|
||||
- 6773-proxmox_kvm-restarted-state-bug-fix.yaml
|
||||
- 6774-locale-gen-fix.yml
|
||||
- 6783-6837-rhsm_repository-internal-refactor.yml
|
||||
- 6785-openbsd_pkg_pkg_info_handling.yml
|
||||
- 6811-datadog-downtime-rrule-type.yaml
|
||||
- 6820-locale-gen-cmdrunner.yml
|
||||
- 6823-redfish-add-account-type-management.yml
|
||||
- 6826-snap-out-strip.yml
|
||||
- 6827-proxmox_kvm-force-delete-bug-fix.yaml
|
||||
- 6835-snap-missing-track.yml
|
||||
- 6836-proxmox-deprecate-compatibility.yml
|
||||
- 6838-proxmox-dict-template.yml
|
||||
- 6839-promoxer-tokens.yml
|
||||
- 6841-htpasswd-crypt-scheme.yml
|
||||
- 6848-npm-required-if.yml
|
||||
- 6861-yum_versionlock_minor_change_add-pinning-specific-versions.yml
|
||||
- 6862-opkg-exec.yml
|
||||
- 6864-redfish-utils-fix-for-processorarchitecture-in-cpu-inventory.yaml
|
||||
- 6882-make-multiple-targets.yml
|
||||
- 6883-redfish-utils-changing-variable-names-in-get-volume-inventory.yml
|
||||
- 6887-deprecate-stackdrive.yml
|
||||
- 6902-added-support-in-nmcli-for-ipvx-dns-options.yml
|
||||
- 6903-locale-gen-refactor.yml
|
||||
- 6905-ipa_dnszone-key-error-fix.yml
|
||||
- 6908-snap-dangerous.yml
|
||||
- 6909-deprecate-webfaction.yml
|
||||
- 6923-cobbler-inventory_unicode.yml
|
||||
- 6925-cobbler-inventory-bugfix.yml
|
||||
- 6927-pylint-comments.yml
|
||||
- 6928-noqa-comments.yml
|
||||
- 6930-deprecate-flowdock.yml
|
||||
- 6935-machinectl-become.yml
|
||||
- 7.2.0.yml
|
||||
- get-secret-by-path.yml
|
||||
modules:
|
||||
- description: Manipulate Consul policies
|
||||
name: consul_policy
|
||||
namespace: ''
|
||||
- description: Allows administration of Keycloak client authorization permissions
|
||||
via Keycloak API
|
||||
name: keycloak_authz_permission
|
||||
namespace: ''
|
||||
- description: Query Keycloak client authorization permissions information
|
||||
name: keycloak_authz_permission_info
|
||||
namespace: ''
|
||||
- description: Retrieve information about one or more Proxmox VE virtual machines
|
||||
name: proxmox_vm_info
|
||||
namespace: ''
|
||||
plugins:
|
||||
lookup:
|
||||
- description: Retrieve secrets from Bitwarden Secrets Manager
|
||||
name: bitwarden_secrets_manager
|
||||
namespace: null
|
||||
release_date: '2023-07-17'
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace: community
|
||||
name: general
|
||||
version: 7.0.0
|
||||
version: 7.2.0
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (https://github.com/ansible)
|
||||
|
||||
@@ -150,6 +150,12 @@ plugin_routing:
|
||||
warning_text: You are using an internal name to access the community.general.airbrake_deployment
|
||||
modules. This has never been supported or documented, and will stop working
|
||||
in community.general 9.0.0.
|
||||
stackdriver:
|
||||
deprecation:
|
||||
removal_version: 9.0.0
|
||||
warning_text: >
|
||||
This module relies on HTTPS APIs that do not exist anymore, and any new development in the
|
||||
direction of providing an alternative should happen in the context of the google.cloud collection.
|
||||
system.aix_devices:
|
||||
redirect: community.general.aix_devices
|
||||
deprecation:
|
||||
@@ -798,6 +804,10 @@ plugin_routing:
|
||||
warning_text: You are using an internal name to access the community.general.flatpak_remote
|
||||
modules. This has never been supported or documented, and will stop working
|
||||
in community.general 9.0.0.
|
||||
flowdock:
|
||||
deprecation:
|
||||
removal_version: 9.0.0
|
||||
warning_text: This module relies on HTTPS APIs that do not exist anymore and there is no clear path to update.
|
||||
notification.flowdock:
|
||||
redirect: community.general.flowdock
|
||||
deprecation:
|
||||
@@ -4433,6 +4443,10 @@ plugin_routing:
|
||||
warning_text: You are using an internal name to access the community.general.wdc_redfish_info
|
||||
modules. This has never been supported or documented, and will stop working
|
||||
in community.general 9.0.0.
|
||||
webfaction_app:
|
||||
deprecation:
|
||||
removal_version: 9.0.0
|
||||
warning_text: This module relies on HTTPS APIs that do not exist anymore and there is no clear path to update.
|
||||
cloud.webfaction.webfaction_app:
|
||||
redirect: community.general.webfaction_app
|
||||
deprecation:
|
||||
@@ -4440,6 +4454,10 @@ plugin_routing:
|
||||
warning_text: You are using an internal name to access the community.general.webfaction_app
|
||||
modules. This has never been supported or documented, and will stop working
|
||||
in community.general 9.0.0.
|
||||
webfaction_db:
|
||||
deprecation:
|
||||
removal_version: 9.0.0
|
||||
warning_text: This module relies on HTTPS APIs that do not exist anymore and there is no clear path to update.
|
||||
cloud.webfaction.webfaction_db:
|
||||
redirect: community.general.webfaction_db
|
||||
deprecation:
|
||||
@@ -4447,6 +4465,10 @@ plugin_routing:
|
||||
warning_text: You are using an internal name to access the community.general.webfaction_db
|
||||
modules. This has never been supported or documented, and will stop working
|
||||
in community.general 9.0.0.
|
||||
webfaction_domain:
|
||||
deprecation:
|
||||
removal_version: 9.0.0
|
||||
warning_text: This module relies on HTTPS APIs that do not exist anymore and there is no clear path to update.
|
||||
cloud.webfaction.webfaction_domain:
|
||||
redirect: community.general.webfaction_domain
|
||||
deprecation:
|
||||
@@ -4454,6 +4476,10 @@ plugin_routing:
|
||||
warning_text: You are using an internal name to access the community.general.webfaction_domain
|
||||
modules. This has never been supported or documented, and will stop working
|
||||
in community.general 9.0.0.
|
||||
webfaction_mailbox:
|
||||
deprecation:
|
||||
removal_version: 9.0.0
|
||||
warning_text: This module relies on HTTPS APIs that do not exist anymore and there is no clear path to update.
|
||||
cloud.webfaction.webfaction_mailbox:
|
||||
redirect: community.general.webfaction_mailbox
|
||||
deprecation:
|
||||
@@ -4461,6 +4487,10 @@ plugin_routing:
|
||||
warning_text: You are using an internal name to access the community.general.webfaction_mailbox
|
||||
modules. This has never been supported or documented, and will stop working
|
||||
in community.general 9.0.0.
|
||||
webfaction_site:
|
||||
deprecation:
|
||||
removal_version: 9.0.0
|
||||
warning_text: This module relies on HTTPS APIs that do not exist anymore and there is no clear path to update.
|
||||
cloud.webfaction.webfaction_site:
|
||||
redirect: community.general.webfaction_site
|
||||
deprecation:
|
||||
|
||||
@@ -68,7 +68,7 @@ DOCUMENTATION = '''
|
||||
- section: machinectl_become_plugin
|
||||
key: password
|
||||
notes:
|
||||
- When not using this plugin with user C(root), it only works correctly with a polkit rule which will alter
|
||||
- When not using this plugin with user V(root), it only works correctly with a polkit rule which will alter
|
||||
the behaviour of machinectl. This rule must alter the prompt behaviour to ask directly for the user credentials,
|
||||
if the user is allowed to perform the action (take a look at the examples section).
|
||||
If such a rule is not present the plugin only work if it is used in context with the root user,
|
||||
@@ -102,6 +102,7 @@ class BecomeModule(BecomeBase):
|
||||
prompt = 'Password: '
|
||||
fail = ('==== AUTHENTICATION FAILED ====',)
|
||||
success = ('==== AUTHENTICATION COMPLETE ====',)
|
||||
require_tty = True # see https://github.com/ansible-collections/community.general/issues/6932
|
||||
|
||||
@staticmethod
|
||||
def remove_ansi_codes(line):
|
||||
|
||||
@@ -82,7 +82,7 @@ DOCUMENTATION = '''
|
||||
env:
|
||||
- name: ANSIBLE_PFEXEC_WRAP_EXECUTION
|
||||
notes:
|
||||
- This plugin ignores I(become_user) as pfexec uses it's own C(exec_attr) to figure this out.
|
||||
- This plugin ignores O(become_user) as pfexec uses it's own C(exec_attr) to figure this out.
|
||||
'''
|
||||
|
||||
from ansible.plugins.become import BecomeBase
|
||||
|
||||
6
plugins/cache/redis.py
vendored
6
plugins/cache/redis.py
vendored
@@ -18,9 +18,9 @@ DOCUMENTATION = '''
|
||||
_uri:
|
||||
description:
|
||||
- A colon separated string of connection information for Redis.
|
||||
- The format is C(host:port:db:password), for example C(localhost:6379:0:changeme).
|
||||
- To use encryption in transit, prefix the connection with C(tls://), as in C(tls://localhost:6379:0:changeme).
|
||||
- To use redis sentinel, use separator C(;), for example C(localhost:26379;localhost:26379;0:changeme). Requires redis>=2.9.0.
|
||||
- The format is V(host:port:db:password), for example V(localhost:6379:0:changeme).
|
||||
- To use encryption in transit, prefix the connection with V(tls://), as in V(tls://localhost:6379:0:changeme).
|
||||
- To use redis sentinel, use separator V(;), for example V(localhost:26379;localhost:26379;0:changeme). Requires redis>=2.9.0.
|
||||
required: true
|
||||
env:
|
||||
- name: ANSIBLE_CACHE_PLUGIN_CONNECTION
|
||||
|
||||
@@ -24,7 +24,7 @@ DOCUMENTATION = '''
|
||||
options:
|
||||
max_mem_file:
|
||||
required: true
|
||||
description: Path to cgroups C(memory.max_usage_in_bytes) file. Example C(/sys/fs/cgroup/memory/ansible_profile/memory.max_usage_in_bytes).
|
||||
description: Path to cgroups C(memory.max_usage_in_bytes) file. Example V(/sys/fs/cgroup/memory/ansible_profile/memory.max_usage_in_bytes).
|
||||
env:
|
||||
- name: CGROUP_MAX_MEM_FILE
|
||||
ini:
|
||||
@@ -32,7 +32,7 @@ DOCUMENTATION = '''
|
||||
key: max_mem_file
|
||||
cur_mem_file:
|
||||
required: true
|
||||
description: Path to C(memory.usage_in_bytes) file. Example C(/sys/fs/cgroup/memory/ansible_profile/memory.usage_in_bytes).
|
||||
description: Path to C(memory.usage_in_bytes) file. Example V(/sys/fs/cgroup/memory/ansible_profile/memory.usage_in_bytes).
|
||||
env:
|
||||
- name: CGROUP_CUR_MEM_FILE
|
||||
ini:
|
||||
|
||||
@@ -18,7 +18,7 @@ DOCUMENTATION = r'''
|
||||
extends_documentation_fragment:
|
||||
- default_callback
|
||||
notes:
|
||||
- Uses the C(default) callback plugin output when a custom callback message(C(msg)) is not provided.
|
||||
- Uses the P(ansible.builtin.default#callback) callback plugin output when a custom callback V(message(msg\)) is not provided.
|
||||
- Makes the callback event data available via the C(ansible_callback_diy) dictionary, which can be used in the templating context for the options.
|
||||
The dictionary is only available in the templating context for the options. It is not a variable that is available via the other
|
||||
various execution contexts, such as playbook, play, task etc.
|
||||
@@ -40,8 +40,8 @@ DOCUMENTATION = r'''
|
||||
if value C(is not None and not omit and length is greater than 0),
|
||||
then the option is being used with output.
|
||||
**Effect**: render value as template and output"
|
||||
- "Valid color values: C(black), C(bright gray), C(blue), C(white), C(green), C(bright blue), C(cyan), C(bright green), C(red), C(bright cyan),
|
||||
C(purple), C(bright red), C(yellow), C(bright purple), C(dark gray), C(bright yellow), C(magenta), C(bright magenta), C(normal)"
|
||||
- "Valid color values: V(black), V(bright gray), V(blue), V(white), V(green), V(bright blue), V(cyan), V(bright green), V(red), V(bright cyan),
|
||||
V(purple), V(bright red), V(yellow), V(bright purple), V(dark gray), V(bright yellow), V(magenta), V(bright magenta), V(normal)"
|
||||
seealso:
|
||||
- name: default – default Ansible screen output
|
||||
description: The official documentation on the B(default) callback plugin.
|
||||
@@ -62,7 +62,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
on_any_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(on_any_msg).
|
||||
- Output color to be used for O(on_any_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -86,7 +86,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
runner_on_failed_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(runner_on_failed_msg).
|
||||
- Output color to be used for O(runner_on_failed_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -110,7 +110,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
runner_on_ok_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(runner_on_ok_msg).
|
||||
- Output color to be used for O(runner_on_ok_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -134,7 +134,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
runner_on_skipped_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(runner_on_skipped_msg).
|
||||
- Output color to be used for O(runner_on_skipped_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -158,7 +158,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
runner_on_unreachable_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(runner_on_unreachable_msg).
|
||||
- Output color to be used for O(runner_on_unreachable_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -182,7 +182,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
playbook_on_start_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(playbook_on_start_msg).
|
||||
- Output color to be used for O(playbook_on_start_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -206,7 +206,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
playbook_on_notify_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(playbook_on_notify_msg).
|
||||
- Output color to be used for O(playbook_on_notify_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -230,7 +230,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
playbook_on_no_hosts_matched_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(playbook_on_no_hosts_matched_msg).
|
||||
- Output color to be used for O(playbook_on_no_hosts_matched_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -254,7 +254,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
playbook_on_no_hosts_remaining_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(playbook_on_no_hosts_remaining_msg).
|
||||
- Output color to be used for O(playbook_on_no_hosts_remaining_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -278,7 +278,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
playbook_on_task_start_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(playbook_on_task_start_msg).
|
||||
- Output color to be used for O(playbook_on_task_start_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -302,7 +302,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
playbook_on_handler_task_start_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(playbook_on_handler_task_start_msg).
|
||||
- Output color to be used for O(playbook_on_handler_task_start_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -326,7 +326,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
playbook_on_vars_prompt_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(playbook_on_vars_prompt_msg).
|
||||
- Output color to be used for O(playbook_on_vars_prompt_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -350,7 +350,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
playbook_on_play_start_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(playbook_on_play_start_msg).
|
||||
- Output color to be used for O(playbook_on_play_start_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -374,7 +374,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
playbook_on_stats_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(playbook_on_stats_msg).
|
||||
- Output color to be used for O(playbook_on_stats_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -398,7 +398,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
on_file_diff_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(on_file_diff_msg).
|
||||
- Output color to be used for O(on_file_diff_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -422,7 +422,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
playbook_on_include_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(playbook_on_include_msg).
|
||||
- Output color to be used for O(playbook_on_include_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -446,7 +446,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
runner_item_on_ok_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(runner_item_on_ok_msg).
|
||||
- Output color to be used for O(runner_item_on_ok_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -470,7 +470,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
runner_item_on_failed_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(runner_item_on_failed_msg).
|
||||
- Output color to be used for O(runner_item_on_failed_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -494,7 +494,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
runner_item_on_skipped_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(runner_item_on_skipped_msg).
|
||||
- Output color to be used for O(runner_item_on_skipped_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -518,7 +518,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
runner_retry_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(runner_retry_msg).
|
||||
- Output color to be used for O(runner_retry_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -542,7 +542,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
runner_on_start_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(runner_on_start_msg).
|
||||
- Output color to be used for O(runner_on_start_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -566,7 +566,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
runner_on_no_hosts_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(runner_on_no_hosts_msg).
|
||||
- Output color to be used for O(runner_on_no_hosts_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
@@ -590,7 +590,7 @@ DOCUMENTATION = r'''
|
||||
|
||||
playbook_on_setup_msg_color:
|
||||
description:
|
||||
- Output color to be used for I(playbook_on_setup_msg).
|
||||
- Output color to be used for O(playbook_on_setup_msg).
|
||||
- Template should render a L(valid color value,#notes).
|
||||
ini:
|
||||
- section: callback_diy
|
||||
|
||||
@@ -32,10 +32,10 @@ DOCUMENTATION = '''
|
||||
enable_from_environment:
|
||||
type: str
|
||||
description:
|
||||
- Whether to enable this callback only if the given environment variable exists and it is set to C(true).
|
||||
- Whether to enable this callback only if the given environment variable exists and it is set to V(true).
|
||||
- This is handy when you use Configuration as Code and want to send distributed traces
|
||||
if running in the CI rather when running Ansible locally.
|
||||
- For such, it evaluates the given I(enable_from_environment) value as environment variable
|
||||
- For such, it evaluates the given O(enable_from_environment) value as environment variable
|
||||
and if set to true this plugin will be enabled.
|
||||
env:
|
||||
- name: ANSIBLE_OPENTELEMETRY_ENABLE_FROM_ENVIRONMENT
|
||||
@@ -73,6 +73,17 @@ DOCUMENTATION = '''
|
||||
- section: callback_opentelemetry
|
||||
key: disable_logs
|
||||
version_added: 5.8.0
|
||||
disable_attributes_in_logs:
|
||||
default: false
|
||||
type: bool
|
||||
description:
|
||||
- Disable populating span attributes to the logs.
|
||||
env:
|
||||
- name: ANSIBLE_OPENTELEMETRY_DISABLE_ATTRIBUTES_IN_LOGS
|
||||
ini:
|
||||
- section: callback_opentelemetry
|
||||
key: disable_attributes_in_logs
|
||||
version_added: 7.1.0
|
||||
requirements:
|
||||
- opentelemetry-api (Python library)
|
||||
- opentelemetry-exporter-otlp (Python library)
|
||||
@@ -244,7 +255,7 @@ class OpenTelemetrySource(object):
|
||||
task.dump = dump
|
||||
task.add_host(HostData(host_uuid, host_name, status, result))
|
||||
|
||||
def generate_distributed_traces(self, otel_service_name, ansible_playbook, tasks_data, status, traceparent, disable_logs):
|
||||
def generate_distributed_traces(self, otel_service_name, ansible_playbook, tasks_data, status, traceparent, disable_logs, disable_attributes_in_logs):
|
||||
""" generate distributed traces from the collected TaskData and HostData """
|
||||
|
||||
tasks = []
|
||||
@@ -280,9 +291,9 @@ class OpenTelemetrySource(object):
|
||||
for task in tasks:
|
||||
for host_uuid, host_data in task.host_data.items():
|
||||
with tracer.start_as_current_span(task.name, start_time=task.start, end_on_exit=False) as span:
|
||||
self.update_span_data(task, host_data, span, disable_logs)
|
||||
self.update_span_data(task, host_data, span, disable_logs, disable_attributes_in_logs)
|
||||
|
||||
def update_span_data(self, task_data, host_data, span, disable_logs):
|
||||
def update_span_data(self, task_data, host_data, span, disable_logs, disable_attributes_in_logs):
|
||||
""" update the span with the given TaskData and HostData """
|
||||
|
||||
name = '[%s] %s: %s' % (host_data.name, task_data.play, task_data.name)
|
||||
@@ -315,39 +326,47 @@ class OpenTelemetrySource(object):
|
||||
status = Status(status_code=StatusCode.UNSET)
|
||||
|
||||
span.set_status(status)
|
||||
|
||||
# Create the span and log attributes
|
||||
attributes = {
|
||||
"ansible.task.module": task_data.action,
|
||||
"ansible.task.message": message,
|
||||
"ansible.task.name": name,
|
||||
"ansible.task.result": rc,
|
||||
"ansible.task.host.name": host_data.name,
|
||||
"ansible.task.host.status": host_data.status
|
||||
}
|
||||
if isinstance(task_data.args, dict) and "gather_facts" not in task_data.action:
|
||||
names = tuple(self.transform_ansible_unicode_to_str(k) for k in task_data.args.keys())
|
||||
values = tuple(self.transform_ansible_unicode_to_str(k) for k in task_data.args.values())
|
||||
self.set_span_attribute(span, ("ansible.task.args.name"), names)
|
||||
self.set_span_attribute(span, ("ansible.task.args.value"), values)
|
||||
self.set_span_attribute(span, "ansible.task.module", task_data.action)
|
||||
self.set_span_attribute(span, "ansible.task.message", message)
|
||||
self.set_span_attribute(span, "ansible.task.name", name)
|
||||
self.set_span_attribute(span, "ansible.task.result", rc)
|
||||
self.set_span_attribute(span, "ansible.task.host.name", host_data.name)
|
||||
self.set_span_attribute(span, "ansible.task.host.status", host_data.status)
|
||||
attributes[("ansible.task.args.name")] = names
|
||||
attributes[("ansible.task.args.value")] = values
|
||||
|
||||
self.set_span_attributes(span, attributes)
|
||||
|
||||
# This will allow to enrich the service map
|
||||
self.add_attributes_for_service_map_if_possible(span, task_data)
|
||||
# Send logs
|
||||
if not disable_logs:
|
||||
span.add_event(task_data.dump)
|
||||
span.end(end_time=host_data.finish)
|
||||
# This will avoid populating span attributes to the logs
|
||||
span.add_event(task_data.dump, attributes={} if disable_attributes_in_logs else attributes)
|
||||
span.end(end_time=host_data.finish)
|
||||
|
||||
def set_span_attribute(self, span, attributeName, attributeValue):
|
||||
""" update the span attribute with the given attribute and value if not None """
|
||||
def set_span_attributes(self, span, attributes):
|
||||
""" update the span attributes with the given attributes if not None """
|
||||
|
||||
if span is None and self._display is not None:
|
||||
self._display.warning('span object is None. Please double check if that is expected.')
|
||||
else:
|
||||
if attributeValue is not None:
|
||||
span.set_attribute(attributeName, attributeValue)
|
||||
if attributes is not None:
|
||||
span.set_attributes(attributes)
|
||||
|
||||
def add_attributes_for_service_map_if_possible(self, span, task_data):
|
||||
"""Update the span attributes with the service that the task interacted with, if possible."""
|
||||
|
||||
redacted_url = self.parse_and_redact_url_if_possible(task_data.args)
|
||||
if redacted_url:
|
||||
self.set_span_attribute(span, "http.url", redacted_url.geturl())
|
||||
span.set_attribute("http.url", redacted_url.geturl())
|
||||
|
||||
@staticmethod
|
||||
def parse_and_redact_url_if_possible(args):
|
||||
@@ -434,6 +453,7 @@ class CallbackModule(CallbackBase):
|
||||
def __init__(self, display=None):
|
||||
super(CallbackModule, self).__init__(display=display)
|
||||
self.hide_task_arguments = None
|
||||
self.disable_attributes_in_logs = None
|
||||
self.disable_logs = None
|
||||
self.otel_service_name = None
|
||||
self.ansible_playbook = None
|
||||
@@ -465,6 +485,8 @@ class CallbackModule(CallbackBase):
|
||||
|
||||
self.hide_task_arguments = self.get_option('hide_task_arguments')
|
||||
|
||||
self.disable_attributes_in_logs = self.get_option('disable_attributes_in_logs')
|
||||
|
||||
self.disable_logs = self.get_option('disable_logs')
|
||||
|
||||
self.otel_service_name = self.get_option('otel_service_name')
|
||||
@@ -562,7 +584,8 @@ class CallbackModule(CallbackBase):
|
||||
self.tasks_data,
|
||||
status,
|
||||
self.traceparent,
|
||||
self.disable_logs
|
||||
self.disable_logs,
|
||||
self.disable_attributes_in_logs
|
||||
)
|
||||
|
||||
def v2_runner_on_async_failed(self, result, **kwargs):
|
||||
|
||||
@@ -36,8 +36,8 @@ DOCUMENTATION = '''
|
||||
key: authtoken
|
||||
validate_certs:
|
||||
description: Whether to validate certificates for connections to HEC. It is not recommended to set to
|
||||
C(false) except when you are sure that nobody can intercept the connection
|
||||
between this plugin and HEC, as setting it to C(false) allows man-in-the-middle attacks!
|
||||
V(false) except when you are sure that nobody can intercept the connection
|
||||
between this plugin and HEC, as setting it to V(false) allows man-in-the-middle attacks!
|
||||
env:
|
||||
- name: SPLUNK_VALIDATE_CERTS
|
||||
ini:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = '''
|
||||
DOCUMENTATION = r'''
|
||||
name: sumologic
|
||||
type: notification
|
||||
short_description: Sends task result events to Sumologic
|
||||
@@ -15,8 +15,8 @@ description:
|
||||
- This callback plugin will send task results as JSON formatted events to a Sumologic HTTP collector source.
|
||||
requirements:
|
||||
- Whitelisting this callback plugin
|
||||
- 'Create a HTTP collector source in Sumologic and specify a custom timestamp format of C(yyyy-MM-dd HH:mm:ss ZZZZ) and a custom timestamp locator
|
||||
of C("timestamp": "(.*)")'
|
||||
- 'Create a HTTP collector source in Sumologic and specify a custom timestamp format of V(yyyy-MM-dd HH:mm:ss ZZZZ) and a custom timestamp locator
|
||||
of V("timestamp": "(.*\)")'
|
||||
options:
|
||||
url:
|
||||
description: URL to the Sumologic HTTP collector source.
|
||||
|
||||
@@ -48,6 +48,25 @@ DOCUMENTATION = '''
|
||||
default: chroot
|
||||
'''
|
||||
|
||||
EXAMPLES = r"""
|
||||
# Static inventory file
|
||||
#
|
||||
# [chroots]
|
||||
# /path/to/debootstrap
|
||||
# /path/to/feboostrap
|
||||
# /path/to/lxc-image
|
||||
# /path/to/chroot
|
||||
|
||||
# playbook
|
||||
---
|
||||
- hosts: chroots
|
||||
connection: community.general.chroot
|
||||
tasks:
|
||||
- debug:
|
||||
msg: "This is coming from chroot environment"
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
|
||||
@@ -15,40 +15,40 @@ class ModuleDocFragment(object):
|
||||
options:
|
||||
alicloud_access_key:
|
||||
description:
|
||||
- Alibaba Cloud access key. If not set then the value of environment variable C(ALICLOUD_ACCESS_KEY),
|
||||
C(ALICLOUD_ACCESS_KEY_ID) will be used instead.
|
||||
- Alibaba Cloud access key. If not set then the value of environment variable E(ALICLOUD_ACCESS_KEY),
|
||||
E(ALICLOUD_ACCESS_KEY_ID) will be used instead.
|
||||
aliases: ['access_key_id', 'access_key']
|
||||
type: str
|
||||
alicloud_secret_key:
|
||||
description:
|
||||
- Alibaba Cloud secret key. If not set then the value of environment variable C(ALICLOUD_SECRET_KEY),
|
||||
C(ALICLOUD_SECRET_ACCESS_KEY) will be used instead.
|
||||
- Alibaba Cloud secret key. If not set then the value of environment variable E(ALICLOUD_SECRET_KEY),
|
||||
E(ALICLOUD_SECRET_ACCESS_KEY) will be used instead.
|
||||
aliases: ['secret_access_key', 'secret_key']
|
||||
type: str
|
||||
alicloud_region:
|
||||
description:
|
||||
- The Alibaba Cloud region to use. If not specified then the value of environment variable
|
||||
C(ALICLOUD_REGION), C(ALICLOUD_REGION_ID) will be used instead.
|
||||
E(ALICLOUD_REGION), E(ALICLOUD_REGION_ID) will be used instead.
|
||||
aliases: ['region', 'region_id']
|
||||
required: true
|
||||
type: str
|
||||
alicloud_security_token:
|
||||
description:
|
||||
- The Alibaba Cloud security token. If not specified then the value of environment variable
|
||||
C(ALICLOUD_SECURITY_TOKEN) will be used instead.
|
||||
E(ALICLOUD_SECURITY_TOKEN) will be used instead.
|
||||
aliases: ['security_token']
|
||||
type: str
|
||||
alicloud_assume_role:
|
||||
description:
|
||||
- If provided with a role ARN, Ansible will attempt to assume this role using the supplied credentials.
|
||||
- The nested assume_role block supports I(alicloud_assume_role_arn), I(alicloud_assume_role_session_name),
|
||||
I(alicloud_assume_role_session_expiration) and I(alicloud_assume_role_policy)
|
||||
- The nested assume_role block supports C(alicloud_assume_role_arn), C(alicloud_assume_role_session_name),
|
||||
C(alicloud_assume_role_session_expiration) and C(alicloud_assume_role_policy).
|
||||
type: dict
|
||||
aliases: ['assume_role']
|
||||
alicloud_assume_role_arn:
|
||||
description:
|
||||
- The Alibaba Cloud role_arn. The ARN of the role to assume. If ARN is set to an empty string,
|
||||
it does not perform role switching. It supports environment variable ALICLOUD_ASSUME_ROLE_ARN.
|
||||
it does not perform role switching. It supports environment variable E(ALICLOUD_ASSUME_ROLE_ARN).
|
||||
ansible will execute with provided credentials.
|
||||
aliases: ['assume_role_arn']
|
||||
type: str
|
||||
@@ -56,14 +56,14 @@ options:
|
||||
description:
|
||||
- The Alibaba Cloud session_name. The session name to use when assuming the role. If omitted,
|
||||
'ansible' is passed to the AssumeRole call as session name. It supports environment variable
|
||||
ALICLOUD_ASSUME_ROLE_SESSION_NAME
|
||||
E(ALICLOUD_ASSUME_ROLE_SESSION_NAME).
|
||||
aliases: ['assume_role_session_name']
|
||||
type: str
|
||||
alicloud_assume_role_session_expiration:
|
||||
description:
|
||||
- The Alibaba Cloud session_expiration. The time after which the established session for assuming
|
||||
role expires. Valid value range 900-3600 seconds. Default to 3600 (in this case Alicloud use own default
|
||||
value). It supports environment variable ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION
|
||||
value). It supports environment variable E(ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION).
|
||||
aliases: ['assume_role_session_expiration']
|
||||
type: int
|
||||
ecs_role_name:
|
||||
@@ -79,11 +79,11 @@ options:
|
||||
profile:
|
||||
description:
|
||||
- This is the Alicloud profile name as set in the shared credentials file. It can also be sourced from the
|
||||
ALICLOUD_PROFILE environment variable.
|
||||
E(ALICLOUD_PROFILE) environment variable.
|
||||
type: str
|
||||
shared_credentials_file:
|
||||
description:
|
||||
- This is the path to the shared credentials file. It can also be sourced from the ALICLOUD_SHARED_CREDENTIALS_FILE
|
||||
- This is the path to the shared credentials file. It can also be sourced from the E(ALICLOUD_SHARED_CREDENTIALS_FILE)
|
||||
environment variable.
|
||||
- If this is not set and a profile is specified, ~/.aliyun/config.json will be used.
|
||||
type: str
|
||||
@@ -94,16 +94,16 @@ requirements:
|
||||
notes:
|
||||
- If parameters are not set within the module, the following
|
||||
environment variables can be used in decreasing order of precedence
|
||||
C(ALICLOUD_ACCESS_KEY) or C(ALICLOUD_ACCESS_KEY_ID),
|
||||
C(ALICLOUD_SECRET_KEY) or C(ALICLOUD_SECRET_ACCESS_KEY),
|
||||
C(ALICLOUD_REGION) or C(ALICLOUD_REGION_ID),
|
||||
C(ALICLOUD_SECURITY_TOKEN),
|
||||
C(ALICLOUD_ECS_ROLE_NAME),
|
||||
C(ALICLOUD_SHARED_CREDENTIALS_FILE),
|
||||
C(ALICLOUD_PROFILE),
|
||||
C(ALICLOUD_ASSUME_ROLE_ARN),
|
||||
C(ALICLOUD_ASSUME_ROLE_SESSION_NAME),
|
||||
C(ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION),
|
||||
- C(ALICLOUD_REGION) or C(ALICLOUD_REGION_ID) can be typically be used to specify the
|
||||
E(ALICLOUD_ACCESS_KEY) or E(ALICLOUD_ACCESS_KEY_ID),
|
||||
E(ALICLOUD_SECRET_KEY) or E(ALICLOUD_SECRET_ACCESS_KEY),
|
||||
E(ALICLOUD_REGION) or E(ALICLOUD_REGION_ID),
|
||||
E(ALICLOUD_SECURITY_TOKEN),
|
||||
E(ALICLOUD_ECS_ROLE_NAME),
|
||||
E(ALICLOUD_SHARED_CREDENTIALS_FILE),
|
||||
E(ALICLOUD_PROFILE),
|
||||
E(ALICLOUD_ASSUME_ROLE_ARN),
|
||||
E(ALICLOUD_ASSUME_ROLE_SESSION_NAME),
|
||||
E(ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION),
|
||||
- E(ALICLOUD_REGION) or E(ALICLOUD_REGION_ID) can be typically be used to specify the
|
||||
ALICLOUD region, when required, but this can also be configured in the footmark config file
|
||||
'''
|
||||
|
||||
@@ -16,25 +16,25 @@ options:
|
||||
client_id:
|
||||
description:
|
||||
- The OAuth consumer key.
|
||||
- If not set the environment variable C(BITBUCKET_CLIENT_ID) will be used.
|
||||
- If not set the environment variable E(BITBUCKET_CLIENT_ID) will be used.
|
||||
type: str
|
||||
client_secret:
|
||||
description:
|
||||
- The OAuth consumer secret.
|
||||
- If not set the environment variable C(BITBUCKET_CLIENT_SECRET) will be used.
|
||||
- If not set the environment variable E(BITBUCKET_CLIENT_SECRET) will be used.
|
||||
type: str
|
||||
user:
|
||||
description:
|
||||
- The username.
|
||||
- If not set the environment variable C(BITBUCKET_USERNAME) will be used.
|
||||
- I(username) is an alias of I(user) since community.genreal 6.0.0. It was an alias of I(workspace) before.
|
||||
- If not set the environment variable E(BITBUCKET_USERNAME) will be used.
|
||||
- O(ignore:username) is an alias of O(user) since community.general 6.0.0. It was an alias of O(workspace) before.
|
||||
type: str
|
||||
version_added: 4.0.0
|
||||
aliases: [ username ]
|
||||
password:
|
||||
description:
|
||||
- The App password.
|
||||
- If not set the environment variable C(BITBUCKET_PASSWORD) will be used.
|
||||
- If not set the environment variable E(BITBUCKET_PASSWORD) will be used.
|
||||
type: str
|
||||
version_added: 4.0.0
|
||||
notes:
|
||||
|
||||
@@ -29,13 +29,13 @@ options:
|
||||
mcp_user:
|
||||
description:
|
||||
- The username used to authenticate to the CloudControl API.
|
||||
- If not specified, will fall back to C(MCP_USER) from environment variable or C(~/.dimensiondata).
|
||||
- If not specified, will fall back to E(MCP_USER) from environment variable or C(~/.dimensiondata).
|
||||
type: str
|
||||
mcp_password:
|
||||
description:
|
||||
- The password used to authenticate to the CloudControl API.
|
||||
- If not specified, will fall back to C(MCP_PASSWORD) from environment variable or C(~/.dimensiondata).
|
||||
- Required if I(mcp_user) is specified.
|
||||
- If not specified, will fall back to E(MCP_PASSWORD) from environment variable or C(~/.dimensiondata).
|
||||
- Required if O(mcp_user) is specified.
|
||||
type: str
|
||||
location:
|
||||
description:
|
||||
@@ -44,7 +44,7 @@ options:
|
||||
required: true
|
||||
validate_certs:
|
||||
description:
|
||||
- If C(false), SSL certificates will not be validated.
|
||||
- If V(false), SSL certificates will not be validated.
|
||||
- This should only be used on private instances of the CloudControl API that use self-signed certificates.
|
||||
type: bool
|
||||
default: true
|
||||
|
||||
@@ -25,13 +25,13 @@ options:
|
||||
wait_time:
|
||||
description:
|
||||
- The maximum amount of time (in seconds) to wait for the task to complete.
|
||||
- Only applicable if I(wait=true).
|
||||
- Only applicable if O(wait=true).
|
||||
type: int
|
||||
default: 600
|
||||
wait_poll_interval:
|
||||
description:
|
||||
- The amount of time (in seconds) to wait between checks for task completion.
|
||||
- Only applicable if I(wait=true).
|
||||
- Only applicable if O(wait=true).
|
||||
type: int
|
||||
default: 2
|
||||
'''
|
||||
|
||||
@@ -51,16 +51,16 @@ options:
|
||||
type: str
|
||||
notes:
|
||||
- For authentication, you can set identity_endpoint using the
|
||||
C(ANSIBLE_HWC_IDENTITY_ENDPOINT) env variable.
|
||||
E(ANSIBLE_HWC_IDENTITY_ENDPOINT) env variable.
|
||||
- For authentication, you can set user using the
|
||||
C(ANSIBLE_HWC_USER) env variable.
|
||||
- For authentication, you can set password using the C(ANSIBLE_HWC_PASSWORD) env
|
||||
E(ANSIBLE_HWC_USER) env variable.
|
||||
- For authentication, you can set password using the E(ANSIBLE_HWC_PASSWORD) env
|
||||
variable.
|
||||
- For authentication, you can set domain using the C(ANSIBLE_HWC_DOMAIN) env
|
||||
- For authentication, you can set domain using the E(ANSIBLE_HWC_DOMAIN) env
|
||||
variable.
|
||||
- For authentication, you can set project using the C(ANSIBLE_HWC_PROJECT) env
|
||||
- For authentication, you can set project using the E(ANSIBLE_HWC_PROJECT) env
|
||||
variable.
|
||||
- For authentication, you can set region using the C(ANSIBLE_HWC_REGION) env variable.
|
||||
- For authentication, you can set region using the E(ANSIBLE_HWC_REGION) env variable.
|
||||
- Environment variables values will only be used if the playbook values are
|
||||
not set.
|
||||
'''
|
||||
|
||||
@@ -22,14 +22,14 @@ options:
|
||||
username:
|
||||
description:
|
||||
- Username that will be used to authenticate against InfluxDB server.
|
||||
- Alias C(login_username) added in Ansible 2.5.
|
||||
- Alias O(login_username) added in Ansible 2.5.
|
||||
type: str
|
||||
default: root
|
||||
aliases: [ login_username ]
|
||||
password:
|
||||
description:
|
||||
- Password that will be used to authenticate against InfluxDB server.
|
||||
- Alias C(login_password) added in Ansible 2.5.
|
||||
- Alias O(login_password) added in Ansible 2.5.
|
||||
type: str
|
||||
default: root
|
||||
aliases: [ login_password ]
|
||||
@@ -47,8 +47,8 @@ options:
|
||||
version_added: '0.2.0'
|
||||
validate_certs:
|
||||
description:
|
||||
- If set to C(false), the SSL certificates will not be validated.
|
||||
- This should only set to C(false) used on personally controlled sites using self-signed certificates.
|
||||
- If set to V(false), the SSL certificates will not be validated.
|
||||
- This should only set to V(false) used on personally controlled sites using self-signed certificates.
|
||||
type: bool
|
||||
default: true
|
||||
ssl:
|
||||
@@ -63,7 +63,7 @@ options:
|
||||
retries:
|
||||
description:
|
||||
- Number of retries client will try before aborting.
|
||||
- C(0) indicates try until success.
|
||||
- V(0) indicates try until success.
|
||||
- Only available when using python-influxdb >= 4.1.0
|
||||
type: int
|
||||
default: 3
|
||||
|
||||
@@ -16,61 +16,61 @@ options:
|
||||
ipa_port:
|
||||
description:
|
||||
- Port of FreeIPA / IPA server.
|
||||
- If the value is not specified in the task, the value of environment variable C(IPA_PORT) will be used instead.
|
||||
- If both the environment variable C(IPA_PORT) and the value are not specified in the task, then default value is set.
|
||||
- If the value is not specified in the task, the value of environment variable E(IPA_PORT) will be used instead.
|
||||
- If both the environment variable E(IPA_PORT) and the value are not specified in the task, then default value is set.
|
||||
- Environment variable fallback mechanism is added in Ansible 2.5.
|
||||
type: int
|
||||
default: 443
|
||||
ipa_host:
|
||||
description:
|
||||
- IP or hostname of IPA server.
|
||||
- If the value is not specified in the task, the value of environment variable C(IPA_HOST) will be used instead.
|
||||
- If both the environment variable C(IPA_HOST) and the value are not specified in the task, then DNS will be used to try to discover the FreeIPA server.
|
||||
- If the value is not specified in the task, the value of environment variable E(IPA_HOST) will be used instead.
|
||||
- If both the environment variable E(IPA_HOST) and the value are not specified in the task, then DNS will be used to try to discover the FreeIPA server.
|
||||
- The relevant entry needed in FreeIPA is the 'ipa-ca' entry.
|
||||
- If neither the DNS entry, nor the environment C(IPA_HOST), nor the value are available in the task, then the default value will be used.
|
||||
- If neither the DNS entry, nor the environment E(IPA_HOST), nor the value are available in the task, then the default value will be used.
|
||||
- Environment variable fallback mechanism is added in Ansible 2.5.
|
||||
type: str
|
||||
default: ipa.example.com
|
||||
ipa_user:
|
||||
description:
|
||||
- Administrative account used on IPA server.
|
||||
- If the value is not specified in the task, the value of environment variable C(IPA_USER) will be used instead.
|
||||
- If both the environment variable C(IPA_USER) and the value are not specified in the task, then default value is set.
|
||||
- If the value is not specified in the task, the value of environment variable E(IPA_USER) will be used instead.
|
||||
- If both the environment variable E(IPA_USER) and the value are not specified in the task, then default value is set.
|
||||
- Environment variable fallback mechanism is added in Ansible 2.5.
|
||||
type: str
|
||||
default: admin
|
||||
ipa_pass:
|
||||
description:
|
||||
- Password of administrative user.
|
||||
- If the value is not specified in the task, the value of environment variable C(IPA_PASS) will be used instead.
|
||||
- Note that if the 'urllib_gssapi' library is available, it is possible to use GSSAPI to authenticate to FreeIPA.
|
||||
- If the environment variable C(KRB5CCNAME) is available, the module will use this kerberos credentials cache to authenticate to the FreeIPA server.
|
||||
- If the environment variable C(KRB5_CLIENT_KTNAME) is available, and C(KRB5CCNAME) is not; the module will use this kerberos keytab to authenticate.
|
||||
- If GSSAPI is not available, the usage of 'ipa_pass' is required.
|
||||
- If the value is not specified in the task, the value of environment variable E(IPA_PASS) will be used instead.
|
||||
- Note that if the C(urllib_gssapi) library is available, it is possible to use GSSAPI to authenticate to FreeIPA.
|
||||
- If the environment variable E(KRB5CCNAME) is available, the module will use this kerberos credentials cache to authenticate to the FreeIPA server.
|
||||
- If the environment variable E(KRB5_CLIENT_KTNAME) is available, and E(KRB5CCNAME) is not; the module will use this kerberos keytab to authenticate.
|
||||
- If GSSAPI is not available, the usage of O(ipa_pass) is required.
|
||||
- Environment variable fallback mechanism is added in Ansible 2.5.
|
||||
type: str
|
||||
ipa_prot:
|
||||
description:
|
||||
- Protocol used by IPA server.
|
||||
- If the value is not specified in the task, the value of environment variable C(IPA_PROT) will be used instead.
|
||||
- If both the environment variable C(IPA_PROT) and the value are not specified in the task, then default value is set.
|
||||
- If the value is not specified in the task, the value of environment variable E(IPA_PROT) will be used instead.
|
||||
- If both the environment variable E(IPA_PROT) and the value are not specified in the task, then default value is set.
|
||||
- Environment variable fallback mechanism is added in Ansible 2.5.
|
||||
type: str
|
||||
choices: [ http, https ]
|
||||
default: https
|
||||
validate_certs:
|
||||
description:
|
||||
- This only applies if C(ipa_prot) is I(https).
|
||||
- If set to C(false), the SSL certificates will not be validated.
|
||||
- This should only set to C(false) used on personally controlled sites using self-signed certificates.
|
||||
- This only applies if O(ipa_prot) is V(https).
|
||||
- If set to V(false), the SSL certificates will not be validated.
|
||||
- This should only set to V(false) used on personally controlled sites using self-signed certificates.
|
||||
type: bool
|
||||
default: true
|
||||
ipa_timeout:
|
||||
description:
|
||||
- Specifies idle timeout (in seconds) for the connection.
|
||||
- For bulk operations, you may want to increase this in order to avoid timeout from IPA server.
|
||||
- If the value is not specified in the task, the value of environment variable C(IPA_TIMEOUT) will be used instead.
|
||||
- If both the environment variable C(IPA_TIMEOUT) and the value are not specified in the task, then default value is set.
|
||||
- If the value is not specified in the task, the value of environment variable E(IPA_TIMEOUT) will be used instead.
|
||||
- If both the environment variable E(IPA_TIMEOUT) and the value are not specified in the task, then default value is set.
|
||||
type: int
|
||||
default: 10
|
||||
'''
|
||||
|
||||
@@ -23,7 +23,7 @@ options:
|
||||
|
||||
auth_client_id:
|
||||
description:
|
||||
- OpenID Connect I(client_id) to authenticate to the API with.
|
||||
- OpenID Connect C(client_id) to authenticate to the API with.
|
||||
type: str
|
||||
default: admin-cli
|
||||
|
||||
@@ -34,7 +34,7 @@ options:
|
||||
|
||||
auth_client_secret:
|
||||
description:
|
||||
- Client Secret to use in conjunction with I(auth_client_id) (if required).
|
||||
- Client Secret to use in conjunction with O(auth_client_id) (if required).
|
||||
type: str
|
||||
|
||||
auth_username:
|
||||
|
||||
@@ -21,7 +21,7 @@ options:
|
||||
type: str
|
||||
bind_pw:
|
||||
description:
|
||||
- The password to use with I(bind_dn).
|
||||
- The password to use with O(bind_dn).
|
||||
type: str
|
||||
default: ''
|
||||
ca_path:
|
||||
@@ -29,6 +29,18 @@ options:
|
||||
- Set the path to PEM file with CA certs.
|
||||
type: path
|
||||
version_added: "6.5.0"
|
||||
client_cert:
|
||||
type: path
|
||||
description:
|
||||
- PEM formatted certificate chain file to be used for SSL client authentication.
|
||||
- Required if O(client_key) is defined.
|
||||
version_added: "7.1.0"
|
||||
client_key:
|
||||
type: path
|
||||
description:
|
||||
- PEM formatted file that contains your private key to be used for SSL client authentication.
|
||||
- Required if O(client_cert) is defined.
|
||||
version_added: "7.1.0"
|
||||
dn:
|
||||
required: true
|
||||
description:
|
||||
@@ -40,12 +52,12 @@ options:
|
||||
type: str
|
||||
description:
|
||||
- Set the referrals chasing behavior.
|
||||
- C(anonymous) follow referrals anonymously. This is the default behavior.
|
||||
- C(disabled) disable referrals chasing. This sets C(OPT_REFERRALS) to off.
|
||||
- V(anonymous) follow referrals anonymously. This is the default behavior.
|
||||
- V(disabled) disable referrals chasing. This sets C(OPT_REFERRALS) to off.
|
||||
version_added: 2.0.0
|
||||
server_uri:
|
||||
description:
|
||||
- The I(server_uri) parameter may be a comma- or whitespace-separated list of URIs containing only the schema, the host, and the port fields.
|
||||
- The O(server_uri) parameter may be a comma- or whitespace-separated list of URIs containing only the schema, the host, and the port fields.
|
||||
- The default value lets the underlying LDAP client library look for a UNIX domain socket in its default location.
|
||||
- Note that when using multiple URIs you cannot determine to which URI your client gets connected.
|
||||
- For URIs containing additional fields, particularly when using commas, behavior is undefined.
|
||||
@@ -58,14 +70,13 @@ options:
|
||||
default: false
|
||||
validate_certs:
|
||||
description:
|
||||
- If set to C(false), SSL certificates will not be validated.
|
||||
- If set to V(false), SSL certificates will not be validated.
|
||||
- This should only be used on sites using self-signed certificates.
|
||||
type: bool
|
||||
default: true
|
||||
sasl_class:
|
||||
description:
|
||||
- The class to use for SASL authentication.
|
||||
- Possible choices are C(external), C(gssapi).
|
||||
type: str
|
||||
choices: ['external', 'gssapi']
|
||||
default: external
|
||||
@@ -73,10 +84,9 @@ options:
|
||||
xorder_discovery:
|
||||
description:
|
||||
- Set the behavior on how to process Xordered DNs.
|
||||
- C(enable) will perform a C(ONELEVEL) search below the superior RDN to find the matching DN.
|
||||
- C(disable) will always use the DN unmodified (as passed by the I(dn) parameter).
|
||||
- C(auto) will only perform a search if the first RDN does not contain an index number (C({x})).
|
||||
- Possible choices are C(enable), C(auto), C(disable).
|
||||
- V(enable) will perform a C(ONELEVEL) search below the superior RDN to find the matching DN.
|
||||
- V(disable) will always use the DN unmodified (as passed by the O(dn) parameter).
|
||||
- V(auto) will only perform a search if the first RDN does not contain an index number (C({x})).
|
||||
type: str
|
||||
choices: ['enable', 'auto', 'disable']
|
||||
default: auto
|
||||
|
||||
@@ -21,30 +21,30 @@ options:
|
||||
suboptions:
|
||||
url:
|
||||
description:
|
||||
- ManageIQ environment url. C(MIQ_URL) env var if set. otherwise, it is required to pass it.
|
||||
- ManageIQ environment URL. E(MIQ_URL) environment variable if set. Otherwise, it is required to pass it.
|
||||
type: str
|
||||
required: false
|
||||
username:
|
||||
description:
|
||||
- ManageIQ username. C(MIQ_USERNAME) env var if set. otherwise, required if no token is passed in.
|
||||
- ManageIQ username. E(MIQ_USERNAME) environment variable if set. Otherwise, required if no token is passed in.
|
||||
type: str
|
||||
password:
|
||||
description:
|
||||
- ManageIQ password. C(MIQ_PASSWORD) env var if set. otherwise, required if no token is passed in.
|
||||
- ManageIQ password. E(MIQ_PASSWORD) environment variable if set. Otherwise, required if no token is passed in.
|
||||
type: str
|
||||
token:
|
||||
description:
|
||||
- ManageIQ token. C(MIQ_TOKEN) env var if set. otherwise, required if no username or password is passed in.
|
||||
- ManageIQ token. E(MIQ_TOKEN) environment variable if set. Otherwise, required if no username or password is passed in.
|
||||
type: str
|
||||
validate_certs:
|
||||
description:
|
||||
- Whether SSL certificates should be verified for HTTPS requests. defaults to True.
|
||||
- Whether SSL certificates should be verified for HTTPS requests.
|
||||
type: bool
|
||||
default: true
|
||||
aliases: [ verify_ssl ]
|
||||
ca_cert:
|
||||
description:
|
||||
- The path to a CA bundle file or directory with certificates. defaults to None.
|
||||
- The path to a CA bundle file or directory with certificates.
|
||||
type: str
|
||||
aliases: [ ca_bundle_path ]
|
||||
|
||||
|
||||
@@ -37,9 +37,9 @@ options:
|
||||
default: true
|
||||
notes:
|
||||
- Also see the API documentation on U(https://console.online.net/en/api/)
|
||||
- If C(api_token) is not set within the module, the following
|
||||
- If O(api_token) is not set within the module, the following
|
||||
environment variables can be used in decreasing order of precedence
|
||||
C(ONLINE_TOKEN), C(ONLINE_API_KEY), C(ONLINE_OAUTH_TOKEN), C(ONLINE_API_TOKEN)
|
||||
- If one wants to use a different C(api_url) one can also set the C(ONLINE_API_URL)
|
||||
E(ONLINE_TOKEN), E(ONLINE_API_KEY), E(ONLINE_OAUTH_TOKEN), E(ONLINE_API_TOKEN).
|
||||
- If one wants to use a different O(api_url) one can also set the E(ONLINE_API_URL)
|
||||
environment variable.
|
||||
'''
|
||||
|
||||
@@ -15,26 +15,26 @@ options:
|
||||
api_url:
|
||||
description:
|
||||
- The ENDPOINT URL of the XMLRPC server.
|
||||
- If not specified then the value of the ONE_URL environment variable, if any, is used.
|
||||
- If not specified then the value of the E(ONE_URL) environment variable, if any, is used.
|
||||
type: str
|
||||
aliases:
|
||||
- api_endpoint
|
||||
api_username:
|
||||
description:
|
||||
- The name of the user for XMLRPC authentication.
|
||||
- If not specified then the value of the ONE_USERNAME environment variable, if any, is used.
|
||||
- If not specified then the value of the E(ONE_USERNAME) environment variable, if any, is used.
|
||||
type: str
|
||||
api_password:
|
||||
description:
|
||||
- The password or token for XMLRPC authentication.
|
||||
- If not specified then the value of the ONE_PASSWORD environment variable, if any, is used.
|
||||
- If not specified then the value of the E(ONE_PASSWORD) environment variable, if any, is used.
|
||||
type: str
|
||||
aliases:
|
||||
- api_token
|
||||
validate_certs:
|
||||
description:
|
||||
- Whether to validate the SSL certificates or not.
|
||||
- This parameter is ignored if PYTHONHTTPSVERIFY environment variable is used.
|
||||
- Whether to validate the TLS/SSL certificates or not.
|
||||
- This parameter is ignored if E(PYTHONHTTPSVERIFY) environment variable is used.
|
||||
type: bool
|
||||
default: true
|
||||
wait_timeout:
|
||||
|
||||
@@ -23,7 +23,7 @@ options:
|
||||
port:
|
||||
description:
|
||||
- Specifies the port to use when building the connection to the remote
|
||||
device. This value applies to either I(cli) or I(rest). The port
|
||||
device. This value applies to either O(transport=cli) or O(transport=rest). The port
|
||||
value will default to the appropriate transport common port if
|
||||
none is provided in the task. (cli=22, http=80, https=443). Note
|
||||
this argument does not affect the SSH transport.
|
||||
@@ -36,15 +36,15 @@ options:
|
||||
either the CLI login or the eAPI authentication depending on which
|
||||
transport is used. Note this argument does not affect the SSH
|
||||
transport. If the value is not specified in the task, the value of
|
||||
environment variable C(ANSIBLE_NET_USERNAME) will be used instead.
|
||||
environment variable E(ANSIBLE_NET_USERNAME) will be used instead.
|
||||
type: str
|
||||
password:
|
||||
description:
|
||||
- Specifies the password to use to authenticate the connection to
|
||||
the remote device. This is a common argument used for either I(cli)
|
||||
or I(rest) transports. Note this argument does not affect the SSH
|
||||
the remote device. This is a common argument used for either O(transport=cli)
|
||||
or O(transport=rest). Note this argument does not affect the SSH
|
||||
transport. If the value is not specified in the task, the value of
|
||||
environment variable C(ANSIBLE_NET_PASSWORD) will be used instead.
|
||||
environment variable E(ANSIBLE_NET_PASSWORD) will be used instead.
|
||||
type: str
|
||||
timeout:
|
||||
description:
|
||||
@@ -56,9 +56,9 @@ options:
|
||||
ssh_keyfile:
|
||||
description:
|
||||
- Specifies the SSH key to use to authenticate the connection to
|
||||
the remote device. This argument is only used for the I(cli)
|
||||
transports. If the value is not specified in the task, the value of
|
||||
environment variable C(ANSIBLE_NET_SSH_KEYFILE) will be used instead.
|
||||
the remote device. This argument is only used for O(transport=cli).
|
||||
If the value is not specified in the task, the value of
|
||||
environment variable E(ANSIBLE_NET_SSH_KEYFILE) will be used instead.
|
||||
type: path
|
||||
transport:
|
||||
description:
|
||||
@@ -71,14 +71,14 @@ options:
|
||||
default: ssh
|
||||
use_ssl:
|
||||
description:
|
||||
- Configures the I(transport) to use SSL if set to C(true) only when the
|
||||
I(transport) argument is configured as rest. If the transport
|
||||
argument is not I(rest), this value is ignored.
|
||||
- Configures the O(transport) to use SSL if set to V(true) only when the
|
||||
O(transport) argument is configured as rest. If the transport
|
||||
argument is not V(rest), this value is ignored.
|
||||
type: bool
|
||||
default: true
|
||||
provider:
|
||||
description:
|
||||
- Convenience method that allows all I(openswitch) arguments to be passed as
|
||||
- Convenience method that allows all C(openswitch) arguments to be passed as
|
||||
a dict object. All constraints (required, choices, etc) must be
|
||||
met either by individual arguments or values in this dict.
|
||||
type: dict
|
||||
|
||||
@@ -18,28 +18,28 @@ class ModuleDocFragment(object):
|
||||
options:
|
||||
config_file_location:
|
||||
description:
|
||||
- Path to configuration file. If not set then the value of the OCI_CONFIG_FILE environment variable,
|
||||
- Path to configuration file. If not set then the value of the E(OCI_CONFIG_FILE) environment variable,
|
||||
if any, is used. Otherwise, defaults to ~/.oci/config.
|
||||
type: str
|
||||
config_profile_name:
|
||||
description:
|
||||
- The profile to load from the config file referenced by C(config_file_location). If not set, then the
|
||||
value of the OCI_CONFIG_PROFILE environment variable, if any, is used. Otherwise, defaults to the
|
||||
"DEFAULT" profile in C(config_file_location).
|
||||
- The profile to load from the config file referenced by O(config_file_location). If not set, then the
|
||||
value of the E(OCI_CONFIG_PROFILE) environment variable, if any, is used. Otherwise, defaults to the
|
||||
"DEFAULT" profile in O(config_file_location).
|
||||
default: "DEFAULT"
|
||||
type: str
|
||||
api_user:
|
||||
description:
|
||||
- The OCID of the user, on whose behalf, OCI APIs are invoked. If not set, then the
|
||||
value of the OCI_USER_OCID environment variable, if any, is used. This option is required if the user
|
||||
is not specified through a configuration file (See C(config_file_location)). To get the user's OCID,
|
||||
value of the E(OCI_USER_OCID) environment variable, if any, is used. This option is required if the user
|
||||
is not specified through a configuration file (See O(config_file_location)). To get the user's OCID,
|
||||
please refer U(https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm).
|
||||
type: str
|
||||
api_user_fingerprint:
|
||||
description:
|
||||
- Fingerprint for the key pair being used. If not set, then the value of the OCI_USER_FINGERPRINT
|
||||
- Fingerprint for the key pair being used. If not set, then the value of the E(OCI_USER_FINGERPRINT)
|
||||
environment variable, if any, is used. This option is required if the key fingerprint is not
|
||||
specified through a configuration file (See C(config_file_location)). To get the key pair's
|
||||
specified through a configuration file (See O(config_file_location)). To get the key pair's
|
||||
fingerprint value please refer
|
||||
U(https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm).
|
||||
type: str
|
||||
@@ -47,21 +47,21 @@ class ModuleDocFragment(object):
|
||||
description:
|
||||
- Full path and filename of the private key (in PEM format). If not set, then the value of the
|
||||
OCI_USER_KEY_FILE variable, if any, is used. This option is required if the private key is
|
||||
not specified through a configuration file (See C(config_file_location)). If the key is encrypted
|
||||
with a pass-phrase, the C(api_user_key_pass_phrase) option must also be provided.
|
||||
not specified through a configuration file (See O(config_file_location)). If the key is encrypted
|
||||
with a pass-phrase, the O(api_user_key_pass_phrase) option must also be provided.
|
||||
type: path
|
||||
api_user_key_pass_phrase:
|
||||
description:
|
||||
- Passphrase used by the key referenced in C(api_user_key_file), if it is encrypted. If not set, then
|
||||
- Passphrase used by the key referenced in O(api_user_key_file), if it is encrypted. If not set, then
|
||||
the value of the OCI_USER_KEY_PASS_PHRASE variable, if any, is used. This option is required if the
|
||||
key passphrase is not specified through a configuration file (See C(config_file_location)).
|
||||
key passphrase is not specified through a configuration file (See O(config_file_location)).
|
||||
type: str
|
||||
auth_type:
|
||||
description:
|
||||
- The type of authentication to use for making API requests. By default C(auth_type="api_key") based
|
||||
authentication is performed and the API key (see I(api_user_key_file)) in your config file will be
|
||||
- The type of authentication to use for making API requests. By default O(auth_type=api_key) based
|
||||
authentication is performed and the API key (see O(api_user_key_file)) in your config file will be
|
||||
used. If this 'auth_type' module option is not specified, the value of the OCI_ANSIBLE_AUTH_TYPE,
|
||||
if any, is used. Use C(auth_type="instance_principal") to use instance principal based authentication
|
||||
if any, is used. Use O(auth_type=instance_principal) to use instance principal based authentication
|
||||
when running ansible playbooks within an OCI compute instance.
|
||||
choices: ['api_key', 'instance_principal']
|
||||
default: 'api_key'
|
||||
@@ -70,14 +70,14 @@ class ModuleDocFragment(object):
|
||||
description:
|
||||
- OCID of your tenancy. If not set, then the value of the OCI_TENANCY variable, if any, is
|
||||
used. This option is required if the tenancy OCID is not specified through a configuration file
|
||||
(See C(config_file_location)). To get the tenancy OCID, please refer
|
||||
(See O(config_file_location)). To get the tenancy OCID, please refer
|
||||
U(https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm)
|
||||
type: str
|
||||
region:
|
||||
description:
|
||||
- The Oracle Cloud Infrastructure region to use for all OCI API requests. If not set, then the
|
||||
value of the OCI_REGION variable, if any, is used. This option is required if the region is
|
||||
not specified through a configuration file (See C(config_file_location)). Please refer to
|
||||
not specified through a configuration file (See O(config_file_location)). Please refer to
|
||||
U(https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/regions.htm) for more information
|
||||
on OCI regions.
|
||||
type: str
|
||||
|
||||
@@ -14,13 +14,13 @@ class ModuleDocFragment(object):
|
||||
description: Whether to attempt non-idempotent creation of a resource. By default, create resource is an
|
||||
idempotent operation, and doesn't create the resource if it already exists. Setting this option
|
||||
to true, forcefully creates a copy of the resource, even if it already exists.This option is
|
||||
mutually exclusive with I(key_by).
|
||||
mutually exclusive with O(key_by).
|
||||
default: false
|
||||
type: bool
|
||||
key_by:
|
||||
description: The list of comma-separated attributes of this resource which should be used to uniquely
|
||||
identify an instance of the resource. By default, all the attributes of a resource except
|
||||
I(freeform_tags) are used to uniquely identify a resource.
|
||||
O(freeform_tags) are used to uniquely identify a resource.
|
||||
type: list
|
||||
elements: str
|
||||
"""
|
||||
|
||||
@@ -11,7 +11,7 @@ class ModuleDocFragment(object):
|
||||
DOCUMENTATION = """
|
||||
options:
|
||||
display_name:
|
||||
description: Use I(display_name) along with the other options to return only resources that match the given
|
||||
description: Use O(display_name) along with the other options to return only resources that match the given
|
||||
display name exactly.
|
||||
type: str
|
||||
"""
|
||||
|
||||
@@ -11,7 +11,7 @@ class ModuleDocFragment(object):
|
||||
DOCUMENTATION = """
|
||||
options:
|
||||
name:
|
||||
description: Use I(name) along with the other options to return only resources that match the given name
|
||||
description: Use O(name) along with the other options to return only resources that match the given name
|
||||
exactly.
|
||||
type: str
|
||||
"""
|
||||
|
||||
@@ -15,12 +15,12 @@ class ModuleDocFragment(object):
|
||||
default: true
|
||||
type: bool
|
||||
wait_timeout:
|
||||
description: Time, in seconds, to wait when I(wait=true).
|
||||
description: Time, in seconds, to wait when O(wait=true).
|
||||
default: 1200
|
||||
type: int
|
||||
wait_until:
|
||||
description: The lifecycle state to wait for the resource to transition into when I(wait=true). By default,
|
||||
when I(wait=true), we wait for the resource to get into ACTIVE/ATTACHED/AVAILABLE/PROVISIONED/
|
||||
description: The lifecycle state to wait for the resource to transition into when O(wait=true). By default,
|
||||
when O(wait=true), we wait for the resource to get into ACTIVE/ATTACHED/AVAILABLE/PROVISIONED/
|
||||
RUNNING applicable lifecycle state during create operation & to get into DELETED/DETACHED/
|
||||
TERMINATED lifecycle state during delete operation.
|
||||
type: str
|
||||
|
||||
@@ -38,7 +38,7 @@ options:
|
||||
default: true
|
||||
description:
|
||||
- If certificates should be validated or not.
|
||||
- This should never be set to C(false), except if you are very sure that
|
||||
- This should never be set to V(false), except if you are very sure that
|
||||
your connection to the server can not be subject to a Man In The Middle
|
||||
attack.
|
||||
"""
|
||||
|
||||
@@ -24,21 +24,23 @@ options:
|
||||
api_password:
|
||||
description:
|
||||
- Specify the password to authenticate with.
|
||||
- You can use C(PROXMOX_PASSWORD) environment variable.
|
||||
- You can use E(PROXMOX_PASSWORD) environment variable.
|
||||
type: str
|
||||
api_token_id:
|
||||
description:
|
||||
- Specify the token ID.
|
||||
- Requires C(proxmoxer>=1.1.0) to work.
|
||||
type: str
|
||||
version_added: 1.3.0
|
||||
api_token_secret:
|
||||
description:
|
||||
- Specify the token secret.
|
||||
- Requires C(proxmoxer>=1.1.0) to work.
|
||||
type: str
|
||||
version_added: 1.3.0
|
||||
validate_certs:
|
||||
description:
|
||||
- If C(false), SSL certificates will not be validated.
|
||||
- If V(false), SSL certificates will not be validated.
|
||||
- This should only be used on personally controlled sites using self-signed certificates.
|
||||
type: bool
|
||||
default: false
|
||||
@@ -55,7 +57,7 @@ options:
|
||||
node:
|
||||
description:
|
||||
- Proxmox VE node on which to operate.
|
||||
- Only required for I(state=present).
|
||||
- Only required for O(state=present).
|
||||
- For every other states it will be autodiscovered.
|
||||
type: str
|
||||
pool:
|
||||
|
||||
@@ -33,8 +33,8 @@ options:
|
||||
type: str
|
||||
notes:
|
||||
- This module requires the C(purity_fb) Python library
|
||||
- You must set C(PUREFB_URL) and C(PUREFB_API) environment variables
|
||||
if I(fb_url) and I(api_token) arguments are not passed to the module directly
|
||||
- You must set E(PUREFB_URL) and E(PUREFB_API) environment variables
|
||||
if O(fb_url) and O(api_token) arguments are not passed to the module directly
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- purity_fb >= 1.1
|
||||
@@ -55,8 +55,8 @@ options:
|
||||
required: true
|
||||
notes:
|
||||
- This module requires the C(purestorage) Python library
|
||||
- You must set C(PUREFA_URL) and C(PUREFA_API) environment variables
|
||||
if I(fa_url) and I(api_token) arguments are not passed to the module directly
|
||||
- You must set E(PUREFA_URL) and E(PUREFA_API) environment variables
|
||||
if O(fa_url) and O(api_token) arguments are not passed to the module directly
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- purestorage
|
||||
|
||||
@@ -15,18 +15,18 @@ class ModuleDocFragment(object):
|
||||
options:
|
||||
api_key:
|
||||
description:
|
||||
- Rackspace API key, overrides I(credentials).
|
||||
- Rackspace API key, overrides O(credentials).
|
||||
type: str
|
||||
aliases: [ password ]
|
||||
credentials:
|
||||
description:
|
||||
- File to find the Rackspace credentials in. Ignored if I(api_key) and
|
||||
I(username) are provided.
|
||||
- File to find the Rackspace credentials in. Ignored if O(api_key) and
|
||||
O(username) are provided.
|
||||
type: path
|
||||
aliases: [ creds_file ]
|
||||
env:
|
||||
description:
|
||||
- Environment as configured in I(~/.pyrax.cfg),
|
||||
- Environment as configured in C(~/.pyrax.cfg),
|
||||
see U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#pyrax-configuration).
|
||||
type: str
|
||||
region:
|
||||
@@ -35,7 +35,7 @@ options:
|
||||
type: str
|
||||
username:
|
||||
description:
|
||||
- Rackspace username, overrides I(credentials).
|
||||
- Rackspace username, overrides O(credentials).
|
||||
type: str
|
||||
validate_certs:
|
||||
description:
|
||||
@@ -46,12 +46,12 @@ requirements:
|
||||
- python >= 2.6
|
||||
- pyrax
|
||||
notes:
|
||||
- The following environment variables can be used, C(RAX_USERNAME),
|
||||
C(RAX_API_KEY), C(RAX_CREDS_FILE), C(RAX_CREDENTIALS), C(RAX_REGION).
|
||||
- C(RAX_CREDENTIALS) and C(RAX_CREDS_FILE) points to a credentials file
|
||||
- The following environment variables can be used, E(RAX_USERNAME),
|
||||
E(RAX_API_KEY), E(RAX_CREDS_FILE), E(RAX_CREDENTIALS), E(RAX_REGION).
|
||||
- E(RAX_CREDENTIALS) and E(RAX_CREDS_FILE) point to a credentials file
|
||||
appropriate for pyrax. See U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating)
|
||||
- C(RAX_USERNAME) and C(RAX_API_KEY) obviate the use of a credentials file
|
||||
- C(RAX_REGION) defines a Rackspace Public Cloud region (DFW, ORD, LON, ...)
|
||||
- E(RAX_USERNAME) and E(RAX_API_KEY) obviate the use of a credentials file
|
||||
- E(RAX_REGION) defines a Rackspace Public Cloud region (DFW, ORD, LON, ...)
|
||||
'''
|
||||
|
||||
# Documentation fragment including attributes to enable communication
|
||||
@@ -61,7 +61,7 @@ options:
|
||||
api_key:
|
||||
type: str
|
||||
description:
|
||||
- Rackspace API key, overrides I(credentials).
|
||||
- Rackspace API key, overrides O(credentials).
|
||||
aliases: [ password ]
|
||||
auth_endpoint:
|
||||
type: str
|
||||
@@ -71,13 +71,13 @@ options:
|
||||
credentials:
|
||||
type: path
|
||||
description:
|
||||
- File to find the Rackspace credentials in. Ignored if I(api_key) and
|
||||
I(username) are provided.
|
||||
- File to find the Rackspace credentials in. Ignored if O(api_key) and
|
||||
O(username) are provided.
|
||||
aliases: [ creds_file ]
|
||||
env:
|
||||
type: str
|
||||
description:
|
||||
- Environment as configured in I(~/.pyrax.cfg),
|
||||
- Environment as configured in C(~/.pyrax.cfg),
|
||||
see U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#pyrax-configuration).
|
||||
identity_type:
|
||||
type: str
|
||||
@@ -99,7 +99,7 @@ options:
|
||||
username:
|
||||
type: str
|
||||
description:
|
||||
- Rackspace username, overrides I(credentials).
|
||||
- Rackspace username, overrides O(credentials).
|
||||
validate_certs:
|
||||
description:
|
||||
- Whether or not to require SSL validation of API endpoints.
|
||||
@@ -113,10 +113,10 @@ requirements:
|
||||
- python >= 2.6
|
||||
- pyrax
|
||||
notes:
|
||||
- The following environment variables can be used, C(RAX_USERNAME),
|
||||
C(RAX_API_KEY), C(RAX_CREDS_FILE), C(RAX_CREDENTIALS), C(RAX_REGION).
|
||||
- C(RAX_CREDENTIALS) and C(RAX_CREDS_FILE) points to a credentials file
|
||||
- The following environment variables can be used, E(RAX_USERNAME),
|
||||
E(RAX_API_KEY), E(RAX_CREDS_FILE), E(RAX_CREDENTIALS), E(RAX_REGION).
|
||||
- E(RAX_CREDENTIALS) and E(RAX_CREDS_FILE) points to a credentials file
|
||||
appropriate for pyrax. See U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating)
|
||||
- C(RAX_USERNAME) and C(RAX_API_KEY) obviate the use of a credentials file
|
||||
- C(RAX_REGION) defines a Rackspace Public Cloud region (DFW, ORD, LON, ...)
|
||||
- E(RAX_USERNAME) and E(RAX_API_KEY) obviate the use of a credentials file
|
||||
- E(RAX_REGION) defines a Rackspace Public Cloud region (DFW, ORD, LON, ...)
|
||||
'''
|
||||
|
||||
@@ -46,8 +46,8 @@ options:
|
||||
default: true
|
||||
ca_certs:
|
||||
description:
|
||||
- Path to root certificates file. If not set and I(tls) is
|
||||
set to C(true), certifi ca-certificates will be used.
|
||||
- Path to root certificates file. If not set and O(tls) is
|
||||
set to V(true), certifi ca-certificates will be used.
|
||||
type: str
|
||||
requirements: [ "redis", "certifi" ]
|
||||
|
||||
|
||||
@@ -43,9 +43,9 @@ options:
|
||||
default: true
|
||||
notes:
|
||||
- Also see the API documentation on U(https://developer.scaleway.com/)
|
||||
- If C(api_token) is not set within the module, the following
|
||||
- If O(api_token) is not set within the module, the following
|
||||
environment variables can be used in decreasing order of precedence
|
||||
C(SCW_TOKEN), C(SCW_API_KEY), C(SCW_OAUTH_TOKEN) or C(SCW_API_TOKEN).
|
||||
- If one wants to use a different C(api_url) one can also set the C(SCW_API_URL)
|
||||
E(SCW_TOKEN), E(SCW_API_KEY), E(SCW_OAUTH_TOKEN) or E(SCW_API_TOKEN).
|
||||
- If one wants to use a different O(api_url) one can also set the E(SCW_API_URL)
|
||||
environment variable.
|
||||
'''
|
||||
|
||||
@@ -48,8 +48,8 @@ options:
|
||||
state:
|
||||
description:
|
||||
- The desired state of the object.
|
||||
- C(present) will create or update an object
|
||||
- C(absent) will delete an object if it was present
|
||||
- V(present) will create or update an object
|
||||
- V(absent) will delete an object if it was present
|
||||
type: str
|
||||
choices: [ absent, present ]
|
||||
default: present
|
||||
|
||||
@@ -39,8 +39,8 @@ options:
|
||||
type: str
|
||||
validate_certs:
|
||||
description:
|
||||
- Allows connection when SSL certificates are not valid. Set to C(false) when certificates are not trusted.
|
||||
- If set to C(true), please make sure Python >= 2.7.9 is installed on the given machine.
|
||||
- Allows connection when SSL certificates are not valid. Set to V(false) when certificates are not trusted.
|
||||
- If set to V(true), please make sure Python >= 2.7.9 is installed on the given machine.
|
||||
required: false
|
||||
type: bool
|
||||
default: false
|
||||
|
||||
@@ -15,27 +15,27 @@ options:
|
||||
hostname:
|
||||
description:
|
||||
- The hostname or IP address of the XenServer host or XenServer pool master.
|
||||
- If the value is not specified in the task, the value of environment variable C(XENSERVER_HOST) will be used instead.
|
||||
- If the value is not specified in the task, the value of environment variable E(XENSERVER_HOST) will be used instead.
|
||||
type: str
|
||||
default: localhost
|
||||
aliases: [ host, pool ]
|
||||
username:
|
||||
description:
|
||||
- The username to use for connecting to XenServer.
|
||||
- If the value is not specified in the task, the value of environment variable C(XENSERVER_USER) will be used instead.
|
||||
- If the value is not specified in the task, the value of environment variable E(XENSERVER_USER) will be used instead.
|
||||
type: str
|
||||
default: root
|
||||
aliases: [ admin, user ]
|
||||
password:
|
||||
description:
|
||||
- The password to use for connecting to XenServer.
|
||||
- If the value is not specified in the task, the value of environment variable C(XENSERVER_PASSWORD) will be used instead.
|
||||
- If the value is not specified in the task, the value of environment variable E(XENSERVER_PASSWORD) will be used instead.
|
||||
type: str
|
||||
aliases: [ pass, pwd ]
|
||||
validate_certs:
|
||||
description:
|
||||
- Allows connection when SSL certificates are not valid. Set to C(false) when certificates are not trusted.
|
||||
- If the value is not specified in the task, the value of environment variable C(XENSERVER_VALIDATE_CERTS) will be used instead.
|
||||
- Allows connection when SSL certificates are not valid. Set to V(false) when certificates are not trusted.
|
||||
- If the value is not specified in the task, the value of environment variable E(XENSERVER_VALIDATE_CERTS) will be used instead.
|
||||
type: bool
|
||||
default: true
|
||||
'''
|
||||
|
||||
@@ -23,7 +23,7 @@ DOCUMENTATION = '''
|
||||
dialect:
|
||||
description:
|
||||
- The CSV dialect to use when parsing the CSV file.
|
||||
- Possible values include C(excel), C(excel-tab) or C(unix).
|
||||
- Possible values include V(excel), V(excel-tab) or V(unix).
|
||||
type: str
|
||||
default: excel
|
||||
fieldnames:
|
||||
@@ -35,19 +35,19 @@ DOCUMENTATION = '''
|
||||
delimiter:
|
||||
description:
|
||||
- A one-character string used to separate fields.
|
||||
- When using this parameter, you change the default value used by I(dialect).
|
||||
- When using this parameter, you change the default value used by O(dialect).
|
||||
- The default value depends on the dialect used.
|
||||
type: str
|
||||
skipinitialspace:
|
||||
description:
|
||||
- Whether to ignore any whitespaces immediately following the delimiter.
|
||||
- When using this parameter, you change the default value used by I(dialect).
|
||||
- When using this parameter, you change the default value used by O(dialect).
|
||||
- The default value depends on the dialect used.
|
||||
type: bool
|
||||
strict:
|
||||
description:
|
||||
- Whether to raise an exception on bad CSV input.
|
||||
- When using this parameter, you change the default value used by I(dialect).
|
||||
- When using this parameter, you change the default value used by O(dialect).
|
||||
- The default value depends on the dialect used.
|
||||
type: bool
|
||||
'''
|
||||
|
||||
@@ -25,17 +25,17 @@ DOCUMENTATION = '''
|
||||
parser:
|
||||
description:
|
||||
- The correct parser for the input data.
|
||||
- For example C(ifconfig).
|
||||
- For example V(ifconfig).
|
||||
- "Note: use underscores instead of dashes (if any) in the parser module name."
|
||||
- See U(https://github.com/kellyjonbrazil/jc#parsers) for the latest list of parsers.
|
||||
type: string
|
||||
required: true
|
||||
quiet:
|
||||
description: Set to C(false) to not suppress warnings.
|
||||
description: Set to V(false) to not suppress warnings.
|
||||
type: boolean
|
||||
default: true
|
||||
raw:
|
||||
description: Set to C(true) to return pre-processed JSON.
|
||||
description: Set to V(true) to return pre-processed JSON.
|
||||
type: boolean
|
||||
default: false
|
||||
requirements:
|
||||
|
||||
@@ -12,9 +12,9 @@ DOCUMENTATION = '''
|
||||
version_added: 2.0.0
|
||||
author: Vladimir Botka (@vbotka)
|
||||
description:
|
||||
- Merge two or more lists by attribute I(index). Optional parameters 'recursive' and 'list_merge'
|
||||
- Merge two or more lists by attribute O(index). Optional parameters O(recursive) and O(list_merge)
|
||||
control the merging of the lists in values. The function merge_hash from ansible.utils.vars
|
||||
is used. To learn details on how to use the parameters 'recursive' and 'list_merge' see
|
||||
is used. To learn details on how to use the parameters O(recursive) and O(list_merge) see
|
||||
Ansible User's Guide chapter "Using filters to manipulate data" section "Combining
|
||||
hashes/dictionaries".
|
||||
positional: another_list, index
|
||||
|
||||
@@ -13,12 +13,12 @@ DOCUMENTATION:
|
||||
_input:
|
||||
description:
|
||||
- The time string to convert.
|
||||
- Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week,
|
||||
C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec)
|
||||
and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s)
|
||||
can be added to a unit as well, so C(seconds) is the same as C(second).
|
||||
- Can use the units V(y) and V(year) for a year, V(mo) and V(month) for a month, V(w) and V(week) for a week,
|
||||
V(d) and V(day) for a day, V(h) and V(hour) for a hour, V(m), V(min) and V(minute) for minutes, V(s), V(sec)
|
||||
and V(second) for seconds, V(ms), V(msec), V(msecond) and V(millisecond) for milliseconds. The suffix V(s)
|
||||
can be added to a unit as well, so V(seconds) is the same as V(second).
|
||||
- Valid strings are space separated combinations of an integer with an optional minus sign and a unit.
|
||||
- Examples are C(1h), C(-5m), and C(3h -5m 6s).
|
||||
- Examples are V(1h), V(-5m), and V(3h -5m 6s).
|
||||
type: string
|
||||
required: true
|
||||
year:
|
||||
|
||||
@@ -13,12 +13,12 @@ DOCUMENTATION:
|
||||
_input:
|
||||
description:
|
||||
- The time string to convert.
|
||||
- Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week,
|
||||
C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec)
|
||||
and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s)
|
||||
can be added to a unit as well, so C(seconds) is the same as C(second).
|
||||
- Can use the units V(y) and V(year) for a year, V(mo) and V(month) for a month, V(w) and V(week) for a week,
|
||||
V(d) and V(day) for a day, V(h) and V(hour) for a hour, V(m), V(min) and V(minute) for minutes, V(s), V(sec)
|
||||
and V(second) for seconds, V(ms), V(msec), V(msecond) and V(millisecond) for milliseconds. The suffix V(s)
|
||||
can be added to a unit as well, so V(seconds) is the same as V(second).
|
||||
- Valid strings are space separated combinations of an integer with an optional minus sign and a unit.
|
||||
- Examples are C(1h), C(-5m), and C(3h -5m 6s).
|
||||
- Examples are V(1h), V(-5m), and V(3h -5m 6s).
|
||||
type: string
|
||||
required: true
|
||||
year:
|
||||
|
||||
@@ -13,12 +13,12 @@ DOCUMENTATION:
|
||||
_input:
|
||||
description:
|
||||
- The time string to convert.
|
||||
- Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week,
|
||||
C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec)
|
||||
and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s)
|
||||
can be added to a unit as well, so C(seconds) is the same as C(second).
|
||||
- Can use the units V(y) and V(year) for a year, V(mo) and V(month) for a month, V(w) and V(week) for a week,
|
||||
V(d) and V(day) for a day, V(h) and V(hour) for a hour, V(m), V(min) and V(minute) for minutes, V(s), V(sec)
|
||||
and V(second) for seconds, V(ms), V(msec), V(msecond) and V(millisecond) for milliseconds. The suffix V(s)
|
||||
can be added to a unit as well, so V(seconds) is the same as V(second).
|
||||
- Valid strings are space separated combinations of an integer with an optional minus sign and a unit.
|
||||
- Examples are C(1h), C(-5m), and C(3h -5m 6s).
|
||||
- Examples are V(1h), V(-5m), and V(3h -5m 6s).
|
||||
type: string
|
||||
required: true
|
||||
year:
|
||||
|
||||
@@ -13,12 +13,12 @@ DOCUMENTATION:
|
||||
_input:
|
||||
description:
|
||||
- The time string to convert.
|
||||
- Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week,
|
||||
C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec)
|
||||
and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s)
|
||||
can be added to a unit as well, so C(seconds) is the same as C(second).
|
||||
- Can use the units V(y) and V(year) for a year, V(mo) and V(month) for a month, V(w) and V(week) for a week,
|
||||
V(d) and V(day) for a day, V(h) and V(hour) for a hour, V(m), V(min) and V(minute) for minutes, V(s), V(sec)
|
||||
and V(second) for seconds, V(ms), V(msec), V(msecond) and V(millisecond) for milliseconds. The suffix V(s)
|
||||
can be added to a unit as well, so V(seconds) is the same as V(second).
|
||||
- Valid strings are space separated combinations of an integer with an optional minus sign and a unit.
|
||||
- Examples are C(1h), C(-5m), and C(3h -5m 6s).
|
||||
- Examples are V(1h), V(-5m), and V(3h -5m 6s).
|
||||
type: string
|
||||
required: true
|
||||
year:
|
||||
|
||||
@@ -13,12 +13,12 @@ DOCUMENTATION:
|
||||
_input:
|
||||
description:
|
||||
- The time string to convert.
|
||||
- Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week,
|
||||
C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec)
|
||||
and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s)
|
||||
can be added to a unit as well, so C(seconds) is the same as C(second).
|
||||
- Can use the units V(y) and V(year) for a year, V(mo) and V(month) for a month, V(w) and V(week) for a week,
|
||||
V(d) and V(day) for a day, V(h) and V(hour) for a hour, V(m), V(min) and V(minute) for minutes, V(s), V(sec)
|
||||
and V(second) for seconds, V(ms), V(msec), V(msecond) and V(millisecond) for milliseconds. The suffix V(s)
|
||||
can be added to a unit as well, so V(seconds) is the same as V(second).
|
||||
- Valid strings are space separated combinations of an integer with an optional minus sign and a unit.
|
||||
- Examples are C(1h), C(-5m), and C(3h -5m 6s).
|
||||
- Examples are V(1h), V(-5m), and V(3h -5m 6s).
|
||||
type: string
|
||||
required: true
|
||||
year:
|
||||
|
||||
@@ -13,12 +13,12 @@ DOCUMENTATION:
|
||||
_input:
|
||||
description:
|
||||
- The time string to convert.
|
||||
- Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week,
|
||||
C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec)
|
||||
and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s)
|
||||
can be added to a unit as well, so C(seconds) is the same as C(second).
|
||||
- Can use the units V(y) and V(year) for a year, V(mo) and V(month) for a month, V(w) and V(week) for a week,
|
||||
V(d) and V(day) for a day, V(h) and V(hour) for a hour, V(m), V(min) and V(minute) for minutes, V(s), V(sec)
|
||||
and V(second) for seconds, V(ms), V(msec), V(msecond) and V(millisecond) for milliseconds. The suffix V(s)
|
||||
can be added to a unit as well, so V(seconds) is the same as V(second).
|
||||
- Valid strings are space separated combinations of an integer with an optional minus sign and a unit.
|
||||
- Examples are C(1h), C(-5m), and C(3h -5m 6s).
|
||||
- Examples are V(1h), V(-5m), and V(3h -5m 6s).
|
||||
type: string
|
||||
required: true
|
||||
year:
|
||||
|
||||
@@ -14,12 +14,12 @@ DOCUMENTATION:
|
||||
_input:
|
||||
description:
|
||||
- The time string to convert.
|
||||
- Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week,
|
||||
C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec)
|
||||
and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s)
|
||||
can be added to a unit as well, so C(seconds) is the same as C(second).
|
||||
- Can use the units V(y) and V(year) for a year, V(mo) and V(month) for a month, V(w) and V(week) for a week,
|
||||
V(d) and V(day) for a day, V(h) and V(hour) for a hour, V(m), V(min) and V(minute) for minutes, V(s), V(sec)
|
||||
and V(second) for seconds, V(ms), V(msec), V(msecond) and V(millisecond) for milliseconds. The suffix V(s)
|
||||
can be added to a unit as well, so V(seconds) is the same as V(second).
|
||||
- Valid strings are space separated combinations of an integer with an optional minus sign and a unit.
|
||||
- Examples are C(1h), C(-5m), and C(3h -5m 6s).
|
||||
- Examples are V(1h), V(-5m), and V(3h -5m 6s).
|
||||
type: string
|
||||
required: true
|
||||
unit:
|
||||
|
||||
@@ -13,12 +13,12 @@ DOCUMENTATION:
|
||||
_input:
|
||||
description:
|
||||
- The time string to convert.
|
||||
- Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week,
|
||||
C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec)
|
||||
and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s)
|
||||
can be added to a unit as well, so C(seconds) is the same as C(second).
|
||||
- Can use the units V(y) and V(year) for a year, V(mo) and V(month) for a month, V(w) and V(week) for a week,
|
||||
V(d) and V(day) for a day, V(h) and V(hour) for a hour, V(m), V(min) and V(minute) for minutes, V(s), V(sec)
|
||||
and V(second) for seconds, V(ms), V(msec), V(msecond) and V(millisecond) for milliseconds. The suffix V(s)
|
||||
can be added to a unit as well, so V(seconds) is the same as V(second).
|
||||
- Valid strings are space separated combinations of an integer with an optional minus sign and a unit.
|
||||
- Examples are C(1h), C(-5m), and C(3h -5m 6s).
|
||||
- Examples are V(1h), V(-5m), and V(3h -5m 6s).
|
||||
type: string
|
||||
required: true
|
||||
year:
|
||||
|
||||
@@ -13,12 +13,12 @@ DOCUMENTATION:
|
||||
_input:
|
||||
description:
|
||||
- The time string to convert.
|
||||
- Can use the units C(y) and C(year) for a year, C(mo) and C(month) for a month, C(w) and C(week) for a week,
|
||||
C(d) and C(day) for a day, C(h) and C(hour) for a hour, C(m), C(min) and C(minute) for minutes, C(s), C(sec)
|
||||
and C(second) for seconds, C(ms), C(msec), C(msecond) and C(millisecond) for milliseconds. The suffix C(s)
|
||||
can be added to a unit as well, so C(seconds) is the same as C(second).
|
||||
- Can use the units V(y) and V(year) for a year, V(mo) and V(month) for a month, V(w) and V(week) for a week,
|
||||
V(d) and V(day) for a day, V(h) and V(hour) for a hour, V(m), V(min) and V(minute) for minutes, V(s), V(sec)
|
||||
and V(second) for seconds, V(ms), V(msec), V(msecond) and V(millisecond) for milliseconds. The suffix V(s)
|
||||
can be added to a unit as well, so V(seconds) is the same as V(second).
|
||||
- Valid strings are space separated combinations of an integer with an optional minus sign and a unit.
|
||||
- Examples are C(1h), C(-5m), and C(3h -5m 6s).
|
||||
- Examples are V(1h), V(-5m), and V(3h -5m 6s).
|
||||
type: string
|
||||
required: true
|
||||
year:
|
||||
|
||||
@@ -13,12 +13,14 @@ DOCUMENTATION = '''
|
||||
version_added: 1.0.0
|
||||
description:
|
||||
- Get inventory hosts from the cobbler service.
|
||||
- "Uses a configuration file as an inventory source, it must end in C(.cobbler.yml) or C(.cobbler.yaml) and has a C(plugin: cobbler) entry."
|
||||
- "Uses a configuration file as an inventory source, it must end in C(.cobbler.yml) or C(.cobbler.yaml) and have a C(plugin: cobbler) entry."
|
||||
- Adds the primary IP addresses to C(cobbler_ipv4_address) and C(cobbler_ipv6_address) host variables if defined in Cobbler. The primary IP address is
|
||||
defined as the management interface if defined, or the interface who's DNS name matches the hostname of the system, or else the first interface found.
|
||||
extends_documentation_fragment:
|
||||
- inventory_cache
|
||||
options:
|
||||
plugin:
|
||||
description: The name of this plugin, it should always be set to C(community.general.cobbler) for this plugin to recognize it as it's own.
|
||||
description: The name of this plugin, it should always be set to V(community.general.cobbler) for this plugin to recognize it as it's own.
|
||||
required: true
|
||||
choices: [ 'cobbler', 'community.general.cobbler' ]
|
||||
url:
|
||||
@@ -32,18 +34,18 @@ DOCUMENTATION = '''
|
||||
env:
|
||||
- name: COBBLER_USER
|
||||
password:
|
||||
description: Cobbler authentication password
|
||||
description: Cobbler authentication password.
|
||||
required: false
|
||||
env:
|
||||
- name: COBBLER_PASSWORD
|
||||
cache_fallback:
|
||||
description: Fallback to cached results if connection to cobbler fails
|
||||
description: Fallback to cached results if connection to cobbler fails.
|
||||
type: boolean
|
||||
default: false
|
||||
exclude_profiles:
|
||||
description:
|
||||
- Profiles to exclude from inventory.
|
||||
- Ignored if I(include_profiles) is specified.
|
||||
- Ignored if O(include_profiles) is specified.
|
||||
type: list
|
||||
default: []
|
||||
elements: str
|
||||
@@ -51,26 +53,42 @@ DOCUMENTATION = '''
|
||||
description:
|
||||
- Profiles to include from inventory.
|
||||
- If specified, all other profiles will be excluded.
|
||||
- I(exclude_profiles) is ignored if I(include_profiles) is specified.
|
||||
- O(exclude_profiles) is ignored if O(include_profiles) is specified.
|
||||
type: list
|
||||
default: []
|
||||
elements: str
|
||||
version_added: 4.4.0
|
||||
inventory_hostname:
|
||||
description:
|
||||
- What to use for the ansible inventory hostname.
|
||||
- By default the networking hostname is used if defined, otherwise the DNS name of the management or first non-static interface.
|
||||
- If set to V(system), the cobbler system name is used.
|
||||
type: str
|
||||
choices: [ 'hostname', 'system' ]
|
||||
default: hostname
|
||||
version_added: 7.1.0
|
||||
group_by:
|
||||
description: Keys to group hosts by
|
||||
description: Keys to group hosts by.
|
||||
type: list
|
||||
elements: string
|
||||
default: [ 'mgmt_classes', 'owners', 'status' ]
|
||||
group:
|
||||
description: Group to place all hosts into
|
||||
description: Group to place all hosts into.
|
||||
default: cobbler
|
||||
group_prefix:
|
||||
description: Prefix to apply to cobbler groups
|
||||
description: Prefix to apply to cobbler groups.
|
||||
default: cobbler_
|
||||
want_facts:
|
||||
description: Toggle, if C(true) the plugin will retrieve host facts from the server
|
||||
description: Toggle, if V(true) the plugin will retrieve host facts from the server.
|
||||
type: boolean
|
||||
default: true
|
||||
want_ip_addresses:
|
||||
description:
|
||||
- Toggle, if V(true) the plugin will add a C(cobbler_ipv4_addresses) and C(cobbleer_ipv6_addresses) dictionary to the defined O(group) mapping
|
||||
interface DNS names to IP addresses.
|
||||
type: boolean
|
||||
default: true
|
||||
version_added: 7.1.0
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -85,8 +103,8 @@ import socket
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils.six import iteritems
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, to_safe_group_name
|
||||
from ansible.module_utils.six import text_type
|
||||
|
||||
# xmlrpc
|
||||
try:
|
||||
@@ -128,7 +146,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||
self.connection = xmlrpc_client.Server(self.cobbler_url, allow_none=True)
|
||||
self.token = None
|
||||
if self.get_option('user') is not None:
|
||||
self.token = self.connection.login(self.get_option('user'), self.get_option('password'))
|
||||
self.token = self.connection.login(text_type(self.get_option('user')), text_type(self.get_option('password')))
|
||||
return self.connection
|
||||
|
||||
def _init_cache(self):
|
||||
@@ -201,6 +219,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||
self.exclude_profiles = self.get_option('exclude_profiles')
|
||||
self.include_profiles = self.get_option('include_profiles')
|
||||
self.group_by = self.get_option('group_by')
|
||||
self.inventory_hostname = self.get_option('inventory_hostname')
|
||||
|
||||
for profile in self._get_profiles():
|
||||
if profile['parent']:
|
||||
@@ -236,9 +255,14 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||
self.inventory.add_group(self.group)
|
||||
self.display.vvvv('Added site group %s\n' % self.group)
|
||||
|
||||
ip_addresses = {}
|
||||
ipv6_addresses = {}
|
||||
for host in self._get_systems():
|
||||
# Get the FQDN for the host and add it to the right groups
|
||||
hostname = host['hostname'] # None
|
||||
if self.inventory_hostname == 'system':
|
||||
hostname = host['name'] # None
|
||||
else:
|
||||
hostname = host['hostname'] # None
|
||||
interfaces = host['interfaces']
|
||||
|
||||
if self._exclude_profile(host['profile']):
|
||||
@@ -247,7 +271,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||
|
||||
# hostname is often empty for non-static IP hosts
|
||||
if hostname == '':
|
||||
for (iname, ivalue) in iteritems(interfaces):
|
||||
for iname, ivalue in interfaces.items():
|
||||
if ivalue['management'] or not ivalue['static']:
|
||||
this_dns_name = ivalue.get('dns_name', None)
|
||||
if this_dns_name is not None and this_dns_name != "":
|
||||
@@ -262,8 +286,11 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||
self.display.vvvv('Added host %s hostname %s\n' % (host['name'], hostname))
|
||||
|
||||
# Add host to profile group
|
||||
group_name = self._add_safe_group_name(host['profile'], child=hostname)
|
||||
self.display.vvvv('Added host %s to profile group %s\n' % (hostname, group_name))
|
||||
if host['profile'] != '':
|
||||
group_name = self._add_safe_group_name(host['profile'], child=hostname)
|
||||
self.display.vvvv('Added host %s to profile group %s\n' % (hostname, group_name))
|
||||
else:
|
||||
self.display.warning('Host %s has an empty profile\n' % (hostname))
|
||||
|
||||
# Add host to groups specified by group_by fields
|
||||
for group_by in self.group_by:
|
||||
@@ -280,8 +307,51 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||
self.inventory.add_child(self.group, hostname)
|
||||
|
||||
# Add host variables
|
||||
ip_address = None
|
||||
ip_address_first = None
|
||||
ipv6_address = None
|
||||
ipv6_address_first = None
|
||||
for iname, ivalue in interfaces.items():
|
||||
# Set to first interface or management interface if defined or hostname matches dns_name
|
||||
if ivalue['ip_address'] != "":
|
||||
if ip_address_first is None:
|
||||
ip_address_first = ivalue['ip_address']
|
||||
if ivalue['management']:
|
||||
ip_address = ivalue['ip_address']
|
||||
elif ivalue['dns_name'] == hostname and ip_address is None:
|
||||
ip_address = ivalue['ip_address']
|
||||
if ivalue['ipv6_address'] != "":
|
||||
if ipv6_address_first is None:
|
||||
ipv6_address_first = ivalue['ipv6_address']
|
||||
if ivalue['management']:
|
||||
ipv6_address = ivalue['ipv6_address']
|
||||
elif ivalue['dns_name'] == hostname and ipv6_address is None:
|
||||
ipv6_address = ivalue['ipv6_address']
|
||||
|
||||
# Collect all interface name mappings for adding to group vars
|
||||
if self.get_option('want_ip_addresses'):
|
||||
if ivalue['dns_name'] != "":
|
||||
if ivalue['ip_address'] != "":
|
||||
ip_addresses[ivalue['dns_name']] = ivalue['ip_address']
|
||||
if ivalue['ipv6_address'] != "":
|
||||
ip_addresses[ivalue['dns_name']] = ivalue['ipv6_address']
|
||||
|
||||
# Add ip_address to host if defined, use first if no management or matched dns_name
|
||||
if ip_address is None and ip_address_first is not None:
|
||||
ip_address = ip_address_first
|
||||
if ip_address is not None:
|
||||
self.inventory.set_variable(hostname, 'cobbler_ipv4_address', ip_address)
|
||||
if ipv6_address is None and ipv6_address_first is not None:
|
||||
ipv6_address = ipv6_address_first
|
||||
if ipv6_address is not None:
|
||||
self.inventory.set_variable(hostname, 'cobbler_ipv6_address', ipv6_address)
|
||||
|
||||
if self.get_option('want_facts'):
|
||||
try:
|
||||
self.inventory.set_variable(hostname, 'cobbler', host)
|
||||
except ValueError as e:
|
||||
self.display.warning("Could not set host info for %s: %s" % (hostname, to_text(e)))
|
||||
|
||||
if self.get_option('want_ip_addresses'):
|
||||
self.inventory.set_variable(self.group, 'cobbler_ipv4_addresses', ip_addresses)
|
||||
self.inventory.set_variable(self.group, 'cobbler_ipv6_addresses', ipv6_addresses)
|
||||
|
||||
@@ -58,7 +58,7 @@ DOCUMENTATION = '''
|
||||
description:
|
||||
- Allows the override of the inventory name based on different attributes.
|
||||
- This allows for changing the way limits are used.
|
||||
- The current default, C(address), is sometimes not unique or present. We recommend to use C(name) instead.
|
||||
- The current default, V(address), is sometimes not unique or present. We recommend to use V(name) instead.
|
||||
type: string
|
||||
default: address
|
||||
choices: ['name', 'display_name', 'address']
|
||||
|
||||
@@ -48,7 +48,7 @@ DOCUMENTATION = r'''
|
||||
running this module using the following command
|
||||
C(lxc config set core.trust_password <some random password>)
|
||||
See U(https://www.stgraber.org/2016/04/18/lxd-api-direct-interaction/).
|
||||
- If I(trust_password) is set, this module send a request for authentication before sending any requests.
|
||||
- If O(trust_password) is set, this module send a request for authentication before sending any requests.
|
||||
type: str
|
||||
state:
|
||||
description: Filter the instance according to the current status.
|
||||
@@ -62,7 +62,7 @@ DOCUMENTATION = r'''
|
||||
version_added: 6.2.0
|
||||
type_filter:
|
||||
description:
|
||||
- Filter the instances by type C(virtual-machine), C(container) or C(both).
|
||||
- Filter the instances by type V(virtual-machine), V(container) or V(both).
|
||||
- The first version of the inventory only supported containers.
|
||||
type: str
|
||||
default: container
|
||||
@@ -72,8 +72,8 @@ DOCUMENTATION = r'''
|
||||
description:
|
||||
- If an instance has multiple network interfaces, select which one is the prefered as pattern.
|
||||
- Combined with the first number that can be found e.g. 'eth' + 0.
|
||||
- The option has been renamed from I(prefered_container_network_interface) to I(prefered_instance_network_interface) in community.general 3.8.0.
|
||||
The old name still works as an alias.
|
||||
- The option has been renamed from O(prefered_container_network_interface) to O(prefered_instance_network_interface)
|
||||
in community.general 3.8.0. The old name still works as an alias.
|
||||
type: str
|
||||
default: eth
|
||||
aliases:
|
||||
@@ -81,7 +81,7 @@ DOCUMENTATION = r'''
|
||||
prefered_instance_network_family:
|
||||
description:
|
||||
- If an instance has multiple network interfaces, which one is the prefered by family.
|
||||
- Specify C(inet) for IPv4 and C(inet6) for IPv6.
|
||||
- Specify V(inet) for IPv4 and V(inet6) for IPv6.
|
||||
type: str
|
||||
default: inet
|
||||
choices: [ 'inet', 'inet6' ]
|
||||
|
||||
@@ -23,7 +23,7 @@ DOCUMENTATION = '''
|
||||
required: true
|
||||
choices: ['nmap', 'community.general.nmap']
|
||||
sudo:
|
||||
description: Set to C(true) to execute a C(sudo nmap) plugin scan.
|
||||
description: Set to V(true) to execute a C(sudo nmap) plugin scan.
|
||||
version_added: 4.8.0
|
||||
default: false
|
||||
type: boolean
|
||||
@@ -36,7 +36,7 @@ DOCUMENTATION = '''
|
||||
exclude:
|
||||
description:
|
||||
- List of addresses to exclude.
|
||||
- For example C(10.2.2.15-25) or C(10.2.2.15,10.2.2.16).
|
||||
- For example V(10.2.2.15-25) or V(10.2.2.15,10.2.2.16).
|
||||
type: list
|
||||
elements: string
|
||||
env:
|
||||
@@ -45,8 +45,8 @@ DOCUMENTATION = '''
|
||||
port:
|
||||
description:
|
||||
- Only scan specific port or port range (C(-p)).
|
||||
- For example, you could pass C(22) for a single port, C(1-65535) for a range of ports,
|
||||
or C(U:53,137,T:21-25,139,8080,S:9) to check port 53 with UDP, ports 21-25 with TCP, port 9 with SCTP, and ports 137, 139, and 8080 with all.
|
||||
- For example, you could pass V(22) for a single port, V(1-65535) for a range of ports,
|
||||
or V(U:53,137,T:21-25,139,8080,S:9) to check port 53 with UDP, ports 21-25 with TCP, port 9 with SCTP, and ports 137, 139, and 8080 with all.
|
||||
type: string
|
||||
version_added: 6.5.0
|
||||
ports:
|
||||
@@ -64,14 +64,14 @@ DOCUMENTATION = '''
|
||||
udp_scan:
|
||||
description:
|
||||
- Scan via UDP.
|
||||
- Depending on your system you might need I(sudo=true) for this to work.
|
||||
- Depending on your system you might need O(sudo=true) for this to work.
|
||||
type: boolean
|
||||
default: false
|
||||
version_added: 6.1.0
|
||||
icmp_timestamp:
|
||||
description:
|
||||
- Scan via ICMP Timestamp (C(-PP)).
|
||||
- Depending on your system you might need I(sudo=true) for this to work.
|
||||
- Depending on your system you might need O(sudo=true) for this to work.
|
||||
type: boolean
|
||||
default: false
|
||||
version_added: 6.1.0
|
||||
@@ -81,7 +81,7 @@ DOCUMENTATION = '''
|
||||
default: false
|
||||
version_added: 6.5.0
|
||||
dns_resolve:
|
||||
description: Whether to always (C(true)) or never (C(false)) do DNS resolution.
|
||||
description: Whether to always (V(true)) or never (V(false)) do DNS resolution.
|
||||
type: boolean
|
||||
default: false
|
||||
version_added: 6.1.0
|
||||
|
||||
@@ -17,9 +17,9 @@ DOCUMENTATION = r'''
|
||||
- constructed
|
||||
description:
|
||||
- Get inventory hosts from OpenNebula cloud.
|
||||
- Uses an YAML configuration file ending with either I(opennebula.yml) or I(opennebula.yaml)
|
||||
- Uses an YAML configuration file ending with either C(opennebula.yml) or C(opennebula.yaml)
|
||||
to set parameter values.
|
||||
- Uses I(api_authfile), C(~/.one/one_auth), or C(ONE_AUTH) pointing to a OpenNebula credentials file.
|
||||
- Uses O(api_authfile), C(~/.one/one_auth), or E(ONE_AUTH) pointing to a OpenNebula credentials file.
|
||||
options:
|
||||
plugin:
|
||||
description: Token that ensures this is a source file for the 'opennebula' plugin.
|
||||
@@ -31,7 +31,7 @@ DOCUMENTATION = r'''
|
||||
- URL of the OpenNebula RPC server.
|
||||
- It is recommended to use HTTPS so that the username/password are not
|
||||
transferred over the network unencrypted.
|
||||
- If not set then the value of the C(ONE_URL) environment variable is used.
|
||||
- If not set then the value of the E(ONE_URL) environment variable is used.
|
||||
env:
|
||||
- name: ONE_URL
|
||||
required: true
|
||||
@@ -39,29 +39,29 @@ DOCUMENTATION = r'''
|
||||
api_username:
|
||||
description:
|
||||
- Name of the user to login into the OpenNebula RPC server. If not set
|
||||
then the value of the C(ONE_USERNAME) environment variable is used.
|
||||
then the value of the E(ONE_USERNAME) environment variable is used.
|
||||
env:
|
||||
- name: ONE_USERNAME
|
||||
type: string
|
||||
api_password:
|
||||
description:
|
||||
- Password or a token of the user to login into OpenNebula RPC server.
|
||||
- If not set, the value of the C(ONE_PASSWORD) environment variable is used.
|
||||
- If not set, the value of the E(ONE_PASSWORD) environment variable is used.
|
||||
env:
|
||||
- name: ONE_PASSWORD
|
||||
required: false
|
||||
type: string
|
||||
api_authfile:
|
||||
description:
|
||||
- If both I(api_username) or I(api_password) are not set, then it will try
|
||||
- If both O(api_username) or O(api_password) are not set, then it will try
|
||||
authenticate with ONE auth file. Default path is C(~/.one/one_auth).
|
||||
- Set environment variable C(ONE_AUTH) to override this path.
|
||||
- Set environment variable E(ONE_AUTH) to override this path.
|
||||
env:
|
||||
- name: ONE_AUTH
|
||||
required: false
|
||||
type: string
|
||||
hostname:
|
||||
description: Field to match the hostname. Note C(v4_first_ip) corresponds to the first IPv4 found on VM.
|
||||
description: Field to match the hostname. Note V(v4_first_ip) corresponds to the first IPv4 found on VM.
|
||||
type: string
|
||||
default: v4_first_ip
|
||||
choices:
|
||||
|
||||
@@ -25,15 +25,15 @@ DOCUMENTATION = '''
|
||||
- inventory_cache
|
||||
options:
|
||||
plugin:
|
||||
description: The name of this plugin, it should always be set to C(community.general.proxmox) for this plugin to recognize it as it's own.
|
||||
description: The name of this plugin, it should always be set to V(community.general.proxmox) for this plugin to recognize it as it's own.
|
||||
required: true
|
||||
choices: ['community.general.proxmox']
|
||||
type: str
|
||||
url:
|
||||
description:
|
||||
- URL to Proxmox cluster.
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable C(PROXMOX_URL) will be used instead.
|
||||
- Since community.general 4.7.0 you can also use templating to specify the value of the I(url).
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable E(PROXMOX_URL) will be used instead.
|
||||
- Since community.general 4.7.0 you can also use templating to specify the value of the O(url).
|
||||
default: 'http://localhost:8006'
|
||||
type: str
|
||||
env:
|
||||
@@ -42,8 +42,8 @@ DOCUMENTATION = '''
|
||||
user:
|
||||
description:
|
||||
- Proxmox authentication user.
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable C(PROXMOX_USER) will be used instead.
|
||||
- Since community.general 4.7.0 you can also use templating to specify the value of the I(user).
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable E(PROXMOX_USER) will be used instead.
|
||||
- Since community.general 4.7.0 you can also use templating to specify the value of the O(user).
|
||||
required: true
|
||||
type: str
|
||||
env:
|
||||
@@ -52,9 +52,9 @@ DOCUMENTATION = '''
|
||||
password:
|
||||
description:
|
||||
- Proxmox authentication password.
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable C(PROXMOX_PASSWORD) will be used instead.
|
||||
- Since community.general 4.7.0 you can also use templating to specify the value of the I(password).
|
||||
- If you do not specify a password, you must set I(token_id) and I(token_secret) instead.
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable E(PROXMOX_PASSWORD) will be used instead.
|
||||
- Since community.general 4.7.0 you can also use templating to specify the value of the O(password).
|
||||
- If you do not specify a password, you must set O(token_id) and O(token_secret) instead.
|
||||
type: str
|
||||
env:
|
||||
- name: PROXMOX_PASSWORD
|
||||
@@ -62,8 +62,8 @@ DOCUMENTATION = '''
|
||||
token_id:
|
||||
description:
|
||||
- Proxmox authentication token ID.
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable C(PROXMOX_TOKEN_ID) will be used instead.
|
||||
- To use token authentication, you must also specify I(token_secret). If you do not specify I(token_id) and I(token_secret),
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable E(PROXMOX_TOKEN_ID) will be used instead.
|
||||
- To use token authentication, you must also specify O(token_secret). If you do not specify O(token_id) and O(token_secret),
|
||||
you must set a password instead.
|
||||
- Make sure to grant explicit pve permissions to the token or disable 'privilege separation' to use the users' privileges instead.
|
||||
version_added: 4.8.0
|
||||
@@ -73,8 +73,8 @@ DOCUMENTATION = '''
|
||||
token_secret:
|
||||
description:
|
||||
- Proxmox authentication token secret.
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable C(PROXMOX_TOKEN_SECRET) will be used instead.
|
||||
- To use token authentication, you must also specify I(token_id). If you do not specify I(token_id) and I(token_secret),
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable E(PROXMOX_TOKEN_SECRET) will be used instead.
|
||||
- To use token authentication, you must also specify O(token_id). If you do not specify O(token_id) and O(token_secret),
|
||||
you must set a password instead.
|
||||
version_added: 4.8.0
|
||||
type: str
|
||||
@@ -95,25 +95,25 @@ DOCUMENTATION = '''
|
||||
want_facts:
|
||||
description:
|
||||
- Gather LXC/QEMU configuration facts.
|
||||
- When I(want_facts) is set to C(true) more details about QEMU VM status are possible, besides the running and stopped states.
|
||||
- When O(want_facts) is set to V(true) more details about QEMU VM status are possible, besides the running and stopped states.
|
||||
Currently if the VM is running and it is suspended, the status will be running and the machine will be in C(running) group,
|
||||
but its actual state will be paused. See I(qemu_extended_statuses) for how to retrieve the real status.
|
||||
but its actual state will be paused. See O(qemu_extended_statuses) for how to retrieve the real status.
|
||||
default: false
|
||||
type: bool
|
||||
qemu_extended_statuses:
|
||||
description:
|
||||
- Requires I(want_facts) to be set to C(true) to function. This will allow you to differentiate betweend C(paused) and C(prelaunch)
|
||||
- Requires O(want_facts) to be set to V(true) to function. This will allow you to differentiate betweend C(paused) and C(prelaunch)
|
||||
statuses of the QEMU VMs.
|
||||
- This introduces multiple groups [prefixed with I(group_prefix)] C(prelaunch) and C(paused).
|
||||
- This introduces multiple groups [prefixed with O(group_prefix)] C(prelaunch) and C(paused).
|
||||
default: false
|
||||
type: bool
|
||||
version_added: 5.1.0
|
||||
want_proxmox_nodes_ansible_host:
|
||||
version_added: 3.0.0
|
||||
description:
|
||||
- Whether to set C(ansbile_host) for proxmox nodes.
|
||||
- When set to C(true) (default), will use the first available interface. This can be different from what you expect.
|
||||
- The default of this option changed from C(true) to C(false) in community.general 6.0.0.
|
||||
- Whether to set C(ansible_host) for proxmox nodes.
|
||||
- When set to V(true) (default), will use the first available interface. This can be different from what you expect.
|
||||
- The default of this option changed from V(true) to V(false) in community.general 6.0.0.
|
||||
type: bool
|
||||
default: false
|
||||
filters:
|
||||
@@ -590,6 +590,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
ip = self._get_node_ip(node['node'])
|
||||
self.inventory.set_variable(node['node'], 'ansible_host', ip)
|
||||
|
||||
# Setting composite variables
|
||||
variables = self.inventory.get_host(node['node']).get_vars()
|
||||
self._set_composite_vars(self.get_option('compose'), variables, node['node'], strict=self.strict)
|
||||
|
||||
# add LXC/Qemu groups for the node
|
||||
for ittype in ('lxc', 'qemu'):
|
||||
node_type_group = self._group('%s_%s' % (node['node'], ittype))
|
||||
|
||||
@@ -37,7 +37,7 @@ DOCUMENTATION = r'''
|
||||
scw_profile:
|
||||
description:
|
||||
- The config profile to use in config file.
|
||||
- By default uses the one specified as C(active_profile) in the config file, or falls back to C(default) if that is not defined.
|
||||
- By default uses the one specified as C(active_profile) in the config file, or falls back to V(default) if that is not defined.
|
||||
type: string
|
||||
version_added: 4.4.0
|
||||
oauth_token:
|
||||
|
||||
@@ -23,21 +23,21 @@ DOCUMENTATION = '''
|
||||
- inventory_cache
|
||||
options:
|
||||
plugin:
|
||||
description: The name of this plugin, it should always be set to C(community.general.xen_orchestra) for this plugin to recognize it as its own.
|
||||
description: The name of this plugin, it should always be set to V(community.general.xen_orchestra) for this plugin to recognize it as its own.
|
||||
required: true
|
||||
choices: ['community.general.xen_orchestra']
|
||||
type: str
|
||||
api_host:
|
||||
description:
|
||||
- API host to XOA API.
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable C(ANSIBLE_XO_HOST) will be used instead.
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable E(ANSIBLE_XO_HOST) will be used instead.
|
||||
type: str
|
||||
env:
|
||||
- name: ANSIBLE_XO_HOST
|
||||
user:
|
||||
description:
|
||||
- Xen Orchestra user.
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable C(ANSIBLE_XO_USER) will be used instead.
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable E(ANSIBLE_XO_USER) will be used instead.
|
||||
required: true
|
||||
type: str
|
||||
env:
|
||||
@@ -45,7 +45,7 @@ DOCUMENTATION = '''
|
||||
password:
|
||||
description:
|
||||
- Xen Orchestra password.
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable C(ANSIBLE_XO_PASSWORD) will be used instead.
|
||||
- If the value is not specified in the inventory configuration, the value of environment variable E(ANSIBLE_XO_PASSWORD) will be used instead.
|
||||
required: true
|
||||
type: str
|
||||
env:
|
||||
|
||||
@@ -12,6 +12,8 @@ DOCUMENTATION = """
|
||||
requirements:
|
||||
- bw (command line utility)
|
||||
- be logged into bitwarden
|
||||
- bitwarden vault unlocked
|
||||
- E(BW_SESSION) environment variable set
|
||||
short_description: Retrieve secrets from Bitwarden
|
||||
version_added: 5.4.0
|
||||
description:
|
||||
@@ -23,7 +25,7 @@ DOCUMENTATION = """
|
||||
type: list
|
||||
elements: str
|
||||
search:
|
||||
description: Field to retrieve, for example C(name) or C(id).
|
||||
description: Field to retrieve, for example V(name) or V(id).
|
||||
type: str
|
||||
default: name
|
||||
version_added: 5.7.0
|
||||
|
||||
125
plugins/lookup/bitwarden_secrets_manager.py
Normal file
125
plugins/lookup/bitwarden_secrets_manager.py
Normal file
@@ -0,0 +1,125 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2023, jantari (https://github.com/jantari)
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
name: bitwarden_secrets_manager
|
||||
author:
|
||||
- jantari (@jantari)
|
||||
requirements:
|
||||
- bws (command line utility)
|
||||
short_description: Retrieve secrets from Bitwarden Secrets Manager
|
||||
version_added: 7.2.0
|
||||
description:
|
||||
- Retrieve secrets from Bitwarden Secrets Manager.
|
||||
options:
|
||||
_terms:
|
||||
description: Secret ID(s) to fetch values for.
|
||||
required: true
|
||||
type: list
|
||||
elements: str
|
||||
bws_access_token:
|
||||
description: The BWS access token to use for this lookup.
|
||||
env:
|
||||
- name: BWS_ACCESS_TOKEN
|
||||
required: true
|
||||
type: str
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
- name: Get a secret relying on the BWS_ACCESS_TOKEN environment variable for authentication
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
{{ lookup("community.general.bitwarden_secrets_manager", "2bc23e48-4932-40de-a047-5524b7ddc972") }}
|
||||
|
||||
- name: Get a secret passing an explicit access token for authentication
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
{{
|
||||
lookup(
|
||||
"community.general.bitwarden_secrets_manager",
|
||||
"2bc23e48-4932-40de-a047-5524b7ddc972",
|
||||
bws_access_token="9.4f570d14-4b54-42f5-bc07-60f4450b1db5.YmluYXJ5LXNvbWV0aGluZy0xMjMK:d2h5IGhlbGxvIHRoZXJlCg=="
|
||||
)
|
||||
}}
|
||||
|
||||
- name: Get two different secrets each using a different access token for authentication
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- '{{ lookup("community.general.bitwarden_secrets_manager", "2bc23e48-4932-40de-a047-5524b7ddc972", bws_access_token=token1) }}'
|
||||
- '{{ lookup("community.general.bitwarden_secrets_manager", "9d89af4c-eb5d-41f5-bb0f-4ae81215c768", bws_access_token=token2) }}'
|
||||
vars:
|
||||
token1: "9.4f570d14-4b54-42f5-bc07-60f4450b1db5.YmluYXJ5LXNvbWV0aGluZy0xMjMK:d2h5IGhlbGxvIHRoZXJlCg=="
|
||||
token2: "1.69b72797-6ea9-4687-a11e-848e41a30ae6.YW5zaWJsZSBpcyBncmVhdD8K:YW5zaWJsZSBpcyBncmVhdAo="
|
||||
|
||||
- name: Get just the value of a secret
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
{{ lookup("community.general.bitwarden_secrets_manager", "2bc23e48-4932-40de-a047-5524b7ddc972").value }}
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
_raw:
|
||||
description: List containing one or more secrets.
|
||||
type: list
|
||||
elements: dict
|
||||
"""
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from ansible.errors import AnsibleLookupError
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.parsing.ajson import AnsibleJSONDecoder
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
|
||||
class BitwardenSecretsManagerException(AnsibleLookupError):
|
||||
pass
|
||||
|
||||
|
||||
class BitwardenSecretsManager(object):
|
||||
def __init__(self, path='bws'):
|
||||
self._cli_path = path
|
||||
|
||||
@property
|
||||
def cli_path(self):
|
||||
return self._cli_path
|
||||
|
||||
def _run(self, args, stdin=None):
|
||||
p = Popen([self.cli_path] + args, stdout=PIPE, stderr=PIPE, stdin=PIPE)
|
||||
out, err = p.communicate(stdin)
|
||||
rc = p.wait()
|
||||
return to_text(out, errors='surrogate_or_strict'), to_text(err, errors='surrogate_or_strict'), rc
|
||||
|
||||
def get_secret(self, secret_id, bws_access_token):
|
||||
"""Get and return the secret with the given secret_id.
|
||||
"""
|
||||
|
||||
# Prepare set of params for Bitwarden Secrets Manager CLI
|
||||
# Color output was not always disabled correctly with the default 'auto' setting so explicitly disable it.
|
||||
params = [
|
||||
'--color', 'no',
|
||||
'--access-token', bws_access_token,
|
||||
'get', 'secret', secret_id
|
||||
]
|
||||
|
||||
out, err, rc = self._run(params)
|
||||
if rc != 0:
|
||||
raise BitwardenSecretsManagerException(to_text(err))
|
||||
|
||||
return AnsibleJSONDecoder().raw_decode(out)[0]
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
bws_access_token = self.get_option('bws_access_token')
|
||||
|
||||
return [_bitwarden_secrets_manager.get_secret(term, bws_access_token) for term in terms]
|
||||
|
||||
|
||||
_bitwarden_secrets_manager = BitwardenSecretsManager()
|
||||
@@ -13,22 +13,22 @@ short_description: Retrieves the version of an installed collection
|
||||
description:
|
||||
- This lookup allows to query the version of an installed collection, and to determine whether a
|
||||
collection is installed at all.
|
||||
- By default it returns C(none) for non-existing collections and C(*) for collections without a
|
||||
- By default it returns V(none) for non-existing collections and V(*) for collections without a
|
||||
version number. The latter should only happen in development environments, or when installing
|
||||
a collection from git which has no version in its C(galaxy.yml). This behavior can be adjusted
|
||||
by providing other values with I(result_not_found) and I(result_no_version).
|
||||
by providing other values with O(result_not_found) and O(result_no_version).
|
||||
options:
|
||||
_terms:
|
||||
description:
|
||||
- The collections to look for.
|
||||
- For example C(community.general).
|
||||
- For example V(community.general).
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
result_not_found:
|
||||
description:
|
||||
- The value to return when the collection could not be found.
|
||||
- By default, C(none) is returned.
|
||||
- By default, V(none) is returned.
|
||||
type: string
|
||||
default: ~
|
||||
result_no_version:
|
||||
@@ -36,7 +36,7 @@ options:
|
||||
- The value to return when the collection has no version number.
|
||||
- This can happen for collections installed from git which do not have a version number
|
||||
in C(galaxy.yml).
|
||||
- By default, C(*) is returned.
|
||||
- By default, V(*) is returned.
|
||||
type: string
|
||||
default: '*'
|
||||
"""
|
||||
@@ -51,11 +51,11 @@ RETURN = """
|
||||
_raw:
|
||||
description:
|
||||
- The version number of the collections listed as input.
|
||||
- If a collection can not be found, it will return the value provided in I(result_not_found).
|
||||
By default, this is C(none).
|
||||
- If a collection can not be found, it will return the value provided in O(result_not_found).
|
||||
By default, this is V(none).
|
||||
- If a collection can be found, but the version not identified, it will return the value provided in
|
||||
I(result_no_version). By default, this is C(*). This can happen for collections installed
|
||||
from git which do not have a version number in C(galaxy.yml).
|
||||
O(result_no_version). By default, this is V(*). This can happen for collections installed
|
||||
from git which do not have a version number in V(galaxy.yml).
|
||||
type: list
|
||||
elements: str
|
||||
"""
|
||||
|
||||
@@ -38,23 +38,20 @@ DOCUMENTATION = '''
|
||||
default: localhost
|
||||
description:
|
||||
- The target to connect to, must be a resolvable address.
|
||||
Will be determined from C(ANSIBLE_CONSUL_URL) if that is set.
|
||||
- "C(ANSIBLE_CONSUL_URL) should look like this: C(https://my.consul.server:8500)"
|
||||
env:
|
||||
- name: ANSIBLE_CONSUL_URL
|
||||
- Will be determined from E(ANSIBLE_CONSUL_URL) if that is set.
|
||||
ini:
|
||||
- section: lookup_consul
|
||||
key: host
|
||||
port:
|
||||
description:
|
||||
- The port of the target host to connect to.
|
||||
- If you use C(ANSIBLE_CONSUL_URL) this value will be used from there.
|
||||
- If you use E(ANSIBLE_CONSUL_URL) this value will be used from there.
|
||||
default: 8500
|
||||
scheme:
|
||||
default: http
|
||||
description:
|
||||
- Whether to use http or https.
|
||||
- If you use C(ANSIBLE_CONSUL_URL) this value will be used from there.
|
||||
- If you use E(ANSIBLE_CONSUL_URL) this value will be used from there.
|
||||
validate_certs:
|
||||
default: true
|
||||
description: Whether to verify the ssl connection or not.
|
||||
@@ -71,7 +68,9 @@ DOCUMENTATION = '''
|
||||
- section: lookup_consul
|
||||
key: client_cert
|
||||
url:
|
||||
description: "The target to connect to, should look like this: C(https://my.consul.server:8500)."
|
||||
description:
|
||||
- The target to connect to.
|
||||
- "Should look like this: V(https://my.consul.server:8500)."
|
||||
type: str
|
||||
version_added: 1.0.0
|
||||
env:
|
||||
|
||||
@@ -22,7 +22,7 @@ options:
|
||||
The name is the index that is used in the result object. The value is iterated over as described below.
|
||||
- If the value is a list, it is simply iterated over.
|
||||
- If the value is a dictionary, it is iterated over and returned as if they would be processed by the
|
||||
R(ansible.builtin.dict2items filter,ansible_collections.ansible.builtin.dict2items_filter).
|
||||
P(ansible.builtin.dict2items#filter) filter.
|
||||
- If the value is a string, it is evaluated as Jinja2 expressions which can access the previously chosen
|
||||
elements with C(item.<index_name>). The result must be a list or a dictionary.
|
||||
type: list
|
||||
|
||||
@@ -21,7 +21,7 @@ DOCUMENTATION = '''
|
||||
- In addition to (default) A record, it is also possible to specify a different record type that should be queried.
|
||||
This can be done by either passing-in additional parameter of format qtype=TYPE to the dig lookup, or by appending /TYPE to the FQDN being queried.
|
||||
- If multiple values are associated with the requested record, the results will be returned as a comma-separated list.
|
||||
In such cases you may want to pass option I(wantlist=true) to the lookup call, or alternatively use C(query) instead of C(lookup),
|
||||
In such cases you may want to pass option C(wantlist=true) to the lookup call, or alternatively use C(query) instead of C(lookup),
|
||||
which will result in the record values being returned as a list over which you can iterate later on.
|
||||
- By default, the lookup will rely on system-wide configured DNS servers for performing the query.
|
||||
It is also possible to explicitly specify DNS servers to query using the @DNS_SERVER_1,DNS_SERVER_2,...,DNS_SERVER_N notation.
|
||||
@@ -34,8 +34,8 @@ DOCUMENTATION = '''
|
||||
qtype:
|
||||
description:
|
||||
- Record type to query.
|
||||
- C(DLV) has been removed in community.general 6.0.0.
|
||||
- C(CAA) has been added in community.general 6.3.0.
|
||||
- V(DLV) has been removed in community.general 6.0.0.
|
||||
- V(CAA) has been added in community.general 6.3.0.
|
||||
type: str
|
||||
default: 'A'
|
||||
choices: [A, ALL, AAAA, CAA, CNAME, DNAME, DNSKEY, DS, HINFO, LOC, MX, NAPTR, NS, NSEC3PARAM, PTR, RP, RRSIG, SOA, SPF, SRV, SSHFP, TLSA, TXT]
|
||||
@@ -51,17 +51,17 @@ DOCUMENTATION = '''
|
||||
fail_on_error:
|
||||
description:
|
||||
- Abort execution on lookup errors.
|
||||
- The default for this option will likely change to C(true) in the future.
|
||||
The current default, C(false), is used for backwards compatibility, and will result in empty strings
|
||||
or the string C(NXDOMAIN) in the result in case of errors.
|
||||
- The default for this option will likely change to V(true) in the future.
|
||||
The current default, V(false), is used for backwards compatibility, and will result in empty strings
|
||||
or the string V(NXDOMAIN) in the result in case of errors.
|
||||
default: false
|
||||
type: bool
|
||||
version_added: 5.4.0
|
||||
real_empty:
|
||||
description:
|
||||
- Return empty result without empty strings, and return empty list instead of C(NXDOMAIN).
|
||||
- The default for this option will likely change to C(true) in the future.
|
||||
- This option will be forced to C(true) if multiple domains to be queried are specified.
|
||||
- Return empty result without empty strings, and return empty list instead of V(NXDOMAIN).
|
||||
- The default for this option will likely change to V(true) in the future.
|
||||
- This option will be forced to V(true) if multiple domains to be queried are specified.
|
||||
default: false
|
||||
type: bool
|
||||
version_added: 6.0.0
|
||||
|
||||
@@ -22,8 +22,8 @@ DOCUMENTATION = '''
|
||||
elements: string
|
||||
real_empty:
|
||||
description:
|
||||
- Return empty result without empty strings, and return empty list instead of C(NXDOMAIN).
|
||||
- The default for this option will likely change to C(true) in the future.
|
||||
- Return empty result without empty strings, and return empty list instead of V(NXDOMAIN).
|
||||
- The default for this option will likely change to V(true) in the future.
|
||||
default: false
|
||||
type: bool
|
||||
version_added: 6.0.0
|
||||
|
||||
@@ -13,15 +13,15 @@ short_description: Get secrets from Thycotic DevOps Secrets Vault
|
||||
version_added: 1.0.0
|
||||
description:
|
||||
- Uses the Thycotic DevOps Secrets Vault Python SDK to get Secrets from a
|
||||
DSV I(tenant) using a I(client_id) and I(client_secret).
|
||||
DSV O(tenant) using a O(client_id) and O(client_secret).
|
||||
requirements:
|
||||
- python-dsv-sdk - https://pypi.org/project/python-dsv-sdk/
|
||||
options:
|
||||
_terms:
|
||||
description: The path to the secret, e.g. C(/staging/servers/web1).
|
||||
description: The path to the secret, for example V(/staging/servers/web1).
|
||||
required: true
|
||||
tenant:
|
||||
description: The first format parameter in the default I(url_template).
|
||||
description: The first format parameter in the default O(url_template).
|
||||
env:
|
||||
- name: DSV_TENANT
|
||||
ini:
|
||||
@@ -31,7 +31,7 @@ options:
|
||||
tld:
|
||||
default: com
|
||||
description: The top-level domain of the tenant; the second format
|
||||
parameter in the default I(url_template).
|
||||
parameter in the default O(url_template).
|
||||
env:
|
||||
- name: DSV_TLD
|
||||
ini:
|
||||
@@ -47,7 +47,7 @@ options:
|
||||
key: client_id
|
||||
required: true
|
||||
client_secret:
|
||||
description: The client secret associated with the specific I(client_id).
|
||||
description: The client secret associated with the specific O(client_id).
|
||||
env:
|
||||
- name: DSV_CLIENT_SECRET
|
||||
ini:
|
||||
|
||||
@@ -24,7 +24,7 @@ DOCUMENTATION = '''
|
||||
required: true
|
||||
url:
|
||||
description:
|
||||
- Environment variable with the url for the etcd server
|
||||
- Environment variable with the URL for the etcd server
|
||||
default: 'http://127.0.0.1:4001'
|
||||
env:
|
||||
- name: ANSIBLE_ETCD_URL
|
||||
@@ -39,6 +39,10 @@ DOCUMENTATION = '''
|
||||
- toggle checking that the ssl certificates are valid, you normally only want to turn this off with self-signed certs.
|
||||
default: true
|
||||
type: boolean
|
||||
seealso:
|
||||
- module: community.general.etcd3
|
||||
- plugin: community.general.etcd3
|
||||
plugin_type: lookup
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
|
||||
@@ -32,10 +32,10 @@ DOCUMENTATION = '''
|
||||
default: false
|
||||
endpoints:
|
||||
description:
|
||||
- Counterpart of C(ETCDCTL_ENDPOINTS) environment variable.
|
||||
Specify the etcd3 connection with and URL form eg. C(https://hostname:2379) or C(<host>:<port>) form.
|
||||
- The C(host) part is overwritten by I(host) option, if defined.
|
||||
- The C(port) part is overwritten by I(port) option, if defined.
|
||||
- Counterpart of E(ETCDCTL_ENDPOINTS) environment variable.
|
||||
Specify the etcd3 connection with and URL form, for example V(https://hostname:2379), or V(<host>:<port>) form.
|
||||
- The V(host) part is overwritten by O(host) option, if defined.
|
||||
- The V(port) part is overwritten by O(port) option, if defined.
|
||||
env:
|
||||
- name: ETCDCTL_ENDPOINTS
|
||||
default: '127.0.0.1:2379'
|
||||
@@ -43,12 +43,12 @@ DOCUMENTATION = '''
|
||||
host:
|
||||
description:
|
||||
- etcd3 listening client host.
|
||||
- Takes precedence over I(endpoints).
|
||||
- Takes precedence over O(endpoints).
|
||||
type: str
|
||||
port:
|
||||
description:
|
||||
- etcd3 listening client port.
|
||||
- Takes precedence over I(endpoints).
|
||||
- Takes precedence over O(endpoints).
|
||||
type: int
|
||||
ca_cert:
|
||||
description:
|
||||
@@ -89,13 +89,13 @@ DOCUMENTATION = '''
|
||||
type: str
|
||||
|
||||
notes:
|
||||
- I(host) and I(port) options take precedence over (endpoints) option.
|
||||
- The recommended way to connect to etcd3 server is using C(ETCDCTL_ENDPOINT)
|
||||
environment variable and keep I(endpoints), I(host), and I(port) unused.
|
||||
- O(host) and O(port) options take precedence over (endpoints) option.
|
||||
- The recommended way to connect to etcd3 server is using E(ETCDCTL_ENDPOINT)
|
||||
environment variable and keep O(endpoints), O(host), and O(port) unused.
|
||||
seealso:
|
||||
- module: community.general.etcd3
|
||||
- ref: ansible_collections.community.general.etcd_lookup
|
||||
description: The etcd v2 lookup.
|
||||
- plugin: community.general.etcd
|
||||
plugin_type: lookup
|
||||
|
||||
requirements:
|
||||
- "etcd3 >= 0.10"
|
||||
|
||||
@@ -65,7 +65,7 @@ RETURN = r"""
|
||||
src:
|
||||
description:
|
||||
- Full path to file.
|
||||
- Not returned when I(item.state) is set to C(directory).
|
||||
- Not returned when RV(_raw[].state) is set to V(directory).
|
||||
type: path
|
||||
root:
|
||||
description: Allows filtering by original location.
|
||||
|
||||
@@ -19,7 +19,7 @@ DOCUMENTATION = '''
|
||||
elements: raw
|
||||
required: true
|
||||
notes:
|
||||
- Unlike the R(items lookup,ansible_collections.ansible.builtin.items_lookup) which only flattens 1 level,
|
||||
- Unlike the P(ansible.builtin.items#lookup) lookup which only flattens 1 level,
|
||||
this plugin will continue to flatten until it cannot find lists anymore.
|
||||
- Aka highlander plugin, there can only be one (list).
|
||||
'''
|
||||
|
||||
@@ -15,7 +15,7 @@ DOCUMENTATION = '''
|
||||
description:
|
||||
- This lookup returns a list of results from an LMDB DB corresponding to a list of items given to it.
|
||||
requirements:
|
||||
- lmdb (python library https://lmdb.readthedocs.io/en/release/)
|
||||
- lmdb (Python library U(https://lmdb.readthedocs.io/en/release/))
|
||||
options:
|
||||
_terms:
|
||||
description: List of keys to query.
|
||||
|
||||
@@ -19,7 +19,7 @@ DOCUMENTATION = """
|
||||
options:
|
||||
_terms:
|
||||
description:
|
||||
- Depending on the value of I(pattern_type), this is a list of prefixes, suffixes, or regular expressions
|
||||
- Depending on the value of O(pattern_type), this is a list of prefixes, suffixes, or regular expressions
|
||||
that will be used to match all variables that should be merged.
|
||||
required: true
|
||||
type: list
|
||||
@@ -45,11 +45,11 @@ DOCUMENTATION = """
|
||||
override:
|
||||
description:
|
||||
- Return an error, print a warning or ignore it when a key will be overwritten.
|
||||
- The default behavior C(error) makes the plugin fail when a key would be overwritten.
|
||||
- When C(warn) and C(ignore) are used, note that it is important to know that the variables
|
||||
- The default behavior V(error) makes the plugin fail when a key would be overwritten.
|
||||
- When V(warn) and V(ignore) are used, note that it is important to know that the variables
|
||||
are sorted by name before being merged. Keys for later variables in this order will overwrite
|
||||
keys of the same name for variables earlier in this order. To avoid potential confusion,
|
||||
better use I(override=error) whenever possible.
|
||||
better use O(override=error) whenever possible.
|
||||
type: str
|
||||
default: 'error'
|
||||
choices:
|
||||
|
||||
@@ -18,7 +18,7 @@ DOCUMENTATION = '''
|
||||
- C(op) 1Password command line utility. See U(https://support.1password.com/command-line/)
|
||||
short_description: fetch field values from 1Password
|
||||
description:
|
||||
- C(onepassword) wraps the C(op) command line utility to fetch specific field values from 1Password.
|
||||
- P(community.general.onepassword#lookup) wraps the C(op) command line utility to fetch specific field values from 1Password.
|
||||
options:
|
||||
_terms:
|
||||
description: identifier(s) (UUID, name, or subdomain; case-insensitive) of item(s) to retrieve.
|
||||
@@ -42,13 +42,19 @@ DOCUMENTATION = '''
|
||||
description: The username used to sign in.
|
||||
secret_key:
|
||||
description: The secret key used when performing an initial sign in.
|
||||
service_account_token:
|
||||
description:
|
||||
- The access key for a service account.
|
||||
- Only works with 1Password CLI version 2 or later.
|
||||
type: str
|
||||
version_added: 7.1.0
|
||||
vault:
|
||||
description: Vault containing the item to retrieve (case-insensitive). If absent will search all vaults.
|
||||
notes:
|
||||
- This lookup will use an existing 1Password session if one exists. If not, and you have already
|
||||
performed an initial sign in (meaning C(~/.op/config), C(~/.config/op/config) or C(~/.config/.op/config) exists), then only the
|
||||
C(master_password) is required. You may optionally specify C(subdomain) in this scenario, otherwise the last used subdomain will be used by C(op).
|
||||
- This lookup can perform an initial login by providing C(subdomain), C(username), C(secret_key), and C(master_password).
|
||||
C(master_password) is required. You may optionally specify O(subdomain) in this scenario, otherwise the last used subdomain will be used by C(op).
|
||||
- This lookup can perform an initial login by providing O(subdomain), O(username), O(secret_key), and O(master_password).
|
||||
- Due to the B(very) sensitive nature of these credentials, it is B(highly) recommended that you only pass in the minimal credentials
|
||||
needed at any given time. Also, store these credentials in an Ansible Vault using a key that is equal to or greater in strength
|
||||
to the 1Password master password.
|
||||
@@ -74,18 +80,18 @@ EXAMPLES = """
|
||||
|
||||
- name: Retrieve password for HAL when not signed in to 1Password
|
||||
ansible.builtin.debug:
|
||||
var: lookup('community.general.onepassword'
|
||||
'HAL 9000'
|
||||
subdomain='Discovery'
|
||||
var: lookup('community.general.onepassword',
|
||||
'HAL 9000',
|
||||
subdomain='Discovery',
|
||||
master_password=vault_master_password)
|
||||
|
||||
- name: Retrieve password for HAL when never signed in to 1Password
|
||||
ansible.builtin.debug:
|
||||
var: lookup('community.general.onepassword'
|
||||
'HAL 9000'
|
||||
subdomain='Discovery'
|
||||
master_password=vault_master_password
|
||||
username='tweety@acme.com'
|
||||
var: lookup('community.general.onepassword',
|
||||
'HAL 9000',
|
||||
subdomain='Discovery',
|
||||
master_password=vault_master_password,
|
||||
username='tweety@acme.com',
|
||||
secret_key=vault_secret_key)
|
||||
"""
|
||||
|
||||
@@ -113,12 +119,13 @@ from ansible_collections.community.general.plugins.module_utils.onepassword impo
|
||||
class OnePassCLIBase(with_metaclass(abc.ABCMeta, object)):
|
||||
bin = "op"
|
||||
|
||||
def __init__(self, subdomain=None, domain="1password.com", username=None, secret_key=None, master_password=None):
|
||||
def __init__(self, subdomain=None, domain="1password.com", username=None, secret_key=None, master_password=None, service_account_token=None):
|
||||
self.subdomain = subdomain
|
||||
self.domain = domain
|
||||
self.username = username
|
||||
self.master_password = master_password
|
||||
self.secret_key = secret_key
|
||||
self.service_account_token = service_account_token
|
||||
|
||||
self._path = None
|
||||
self._version = None
|
||||
@@ -295,6 +302,10 @@ class OnePassCLIv1(OnePassCLIBase):
|
||||
return not bool(rc)
|
||||
|
||||
def full_signin(self):
|
||||
if self.service_account_token:
|
||||
raise AnsibleLookupError(
|
||||
"1Password CLI version 1 does not support Service Accounts. Please use version 2 or later.")
|
||||
|
||||
required_params = [
|
||||
"subdomain",
|
||||
"username",
|
||||
@@ -472,6 +483,13 @@ class OnePassCLIv2(OnePassCLIBase):
|
||||
return ""
|
||||
|
||||
def assert_logged_in(self):
|
||||
if self.service_account_token:
|
||||
args = ["whoami"]
|
||||
environment_update = {"OP_SERVICE_ACCOUNT_TOKEN": self.service_account_token}
|
||||
rc, out, err = self._run(args, environment_update=environment_update)
|
||||
|
||||
return not bool(rc)
|
||||
|
||||
args = ["account", "list"]
|
||||
if self.subdomain:
|
||||
account = "{subdomain}.{domain}".format(subdomain=self.subdomain, domain=self.domain)
|
||||
@@ -517,6 +535,13 @@ class OnePassCLIv2(OnePassCLIBase):
|
||||
args = ["item", "get", item_id, "--format", "json"]
|
||||
if vault is not None:
|
||||
args += ["--vault={0}".format(vault)]
|
||||
|
||||
if self.service_account_token:
|
||||
if vault is None:
|
||||
raise AnsibleLookupError("'vault' is required with 'service_account_token'")
|
||||
environment_update = {"OP_SERVICE_ACCOUNT_TOKEN": self.service_account_token}
|
||||
return self._run(args, environment_update=environment_update)
|
||||
|
||||
if token is not None:
|
||||
args += [to_bytes("--session=") + token]
|
||||
|
||||
@@ -533,12 +558,14 @@ class OnePassCLIv2(OnePassCLIBase):
|
||||
|
||||
|
||||
class OnePass(object):
|
||||
def __init__(self, subdomain=None, domain="1password.com", username=None, secret_key=None, master_password=None):
|
||||
def __init__(self, subdomain=None, domain="1password.com", username=None, secret_key=None, master_password=None,
|
||||
service_account_token=None):
|
||||
self.subdomain = subdomain
|
||||
self.domain = domain
|
||||
self.username = username
|
||||
self.secret_key = secret_key
|
||||
self.master_password = master_password
|
||||
self.service_account_token = service_account_token
|
||||
|
||||
self.logged_in = False
|
||||
self.token = None
|
||||
@@ -551,7 +578,7 @@ class OnePass(object):
|
||||
for cls in OnePassCLIBase.__subclasses__():
|
||||
if cls.supports_version == version.split(".")[0]:
|
||||
try:
|
||||
return cls(self.subdomain, self.domain, self.username, self.secret_key, self.master_password)
|
||||
return cls(self.subdomain, self.domain, self.username, self.secret_key, self.master_password, self.service_account_token)
|
||||
except TypeError as e:
|
||||
raise AnsibleLookupError(e)
|
||||
|
||||
@@ -614,8 +641,9 @@ class LookupModule(LookupBase):
|
||||
username = self.get_option("username")
|
||||
secret_key = self.get_option("secret_key")
|
||||
master_password = self.get_option("master_password")
|
||||
service_account_token = self.get_option("service_account_token")
|
||||
|
||||
op = OnePass(subdomain, domain, username, secret_key, master_password)
|
||||
op = OnePass(subdomain, domain, username, secret_key, master_password, service_account_token)
|
||||
op.assert_logged_in()
|
||||
|
||||
values = []
|
||||
|
||||
@@ -18,7 +18,7 @@ DOCUMENTATION = '''
|
||||
- C(op) 1Password command line utility. See U(https://support.1password.com/command-line/)
|
||||
short_description: fetch an entire item from 1Password
|
||||
description:
|
||||
- C(onepassword_raw) wraps C(op) command line utility to fetch an entire item from 1Password
|
||||
- P(community.general.onepassword_raw#lookup) wraps C(op) command line utility to fetch an entire item from 1Password.
|
||||
options:
|
||||
_terms:
|
||||
description: identifier(s) (UUID, name, or domain; case-insensitive) of item(s) to retrieve.
|
||||
@@ -39,13 +39,19 @@ DOCUMENTATION = '''
|
||||
description: The username used to sign in.
|
||||
secret_key:
|
||||
description: The secret key used when performing an initial sign in.
|
||||
service_account_token:
|
||||
description:
|
||||
- The access key for a service account.
|
||||
- Only works with 1Password CLI version 2 or later.
|
||||
type: string
|
||||
version_added: 7.1.0
|
||||
vault:
|
||||
description: Vault containing the item to retrieve (case-insensitive). If absent will search all vaults.
|
||||
notes:
|
||||
- This lookup will use an existing 1Password session if one exists. If not, and you have already
|
||||
performed an initial sign in (meaning C(~/.op/config exists)), then only the C(master_password) is required.
|
||||
You may optionally specify C(subdomain) in this scenario, otherwise the last used subdomain will be used by C(op).
|
||||
- This lookup can perform an initial login by providing C(subdomain), C(username), C(secret_key), and C(master_password).
|
||||
performed an initial sign in (meaning C(~/.op/config exists)), then only the O(master_password) is required.
|
||||
You may optionally specify O(subdomain) in this scenario, otherwise the last used subdomain will be used by C(op).
|
||||
- This lookup can perform an initial login by providing O(subdomain), O(username), O(secret_key), and O(master_password).
|
||||
- Due to the B(very) sensitive nature of these credentials, it is B(highly) recommended that you only pass in the minimal credentials
|
||||
needed at any given time. Also, store these credentials in an Ansible Vault using a key that is equal to or greater in strength
|
||||
to the 1Password master password.
|
||||
@@ -89,8 +95,9 @@ class LookupModule(LookupBase):
|
||||
username = self.get_option("username")
|
||||
secret_key = self.get_option("secret_key")
|
||||
master_password = self.get_option("master_password")
|
||||
service_account_token = self.get_option("service_account_token")
|
||||
|
||||
op = OnePass(subdomain, domain, username, secret_key, master_password)
|
||||
op = OnePass(subdomain, domain, username, secret_key, master_password, service_account_token)
|
||||
op.assert_logged_in()
|
||||
|
||||
values = []
|
||||
|
||||
@@ -16,7 +16,7 @@ DOCUMENTATION = '''
|
||||
- Enables Ansible to retrieve, create or update passwords from the passwordstore.org pass utility.
|
||||
It also retrieves YAML style keys stored as multilines in the passwordfile.
|
||||
- To avoid problems when accessing multiple secrets at once, add C(auto-expand-secmem) to
|
||||
C(~/.gnupg/gpg-agent.conf). Where this is not possible, consider using I(lock=readwrite) instead.
|
||||
C(~/.gnupg/gpg-agent.conf). Where this is not possible, consider using O(lock=readwrite) instead.
|
||||
options:
|
||||
_terms:
|
||||
description: query key.
|
||||
@@ -24,16 +24,16 @@ DOCUMENTATION = '''
|
||||
directory:
|
||||
description:
|
||||
- The directory of the password store.
|
||||
- If I(backend=pass), the default is C(~/.password-store) is used.
|
||||
- If I(backend=gopass), then the default is the C(path) field in C(~/.config/gopass/config.yml),
|
||||
falling back to C(~/.local/share/gopass/stores/root) if C(path) is not defined in the gopass config.
|
||||
- If O(backend=pass), the default is V(~/.password-store) is used.
|
||||
- If O(backend=gopass), then the default is the C(path) field in C(~/.config/gopass/config.yml),
|
||||
falling back to V(~/.local/share/gopass/stores/root) if C(path) is not defined in the gopass config.
|
||||
type: path
|
||||
vars:
|
||||
- name: passwordstore
|
||||
env:
|
||||
- name: PASSWORD_STORE_DIR
|
||||
create:
|
||||
description: Create the password if it does not already exist. Takes precedence over C(missing).
|
||||
description: Create the password if it does not already exist. Takes precedence over O(missing).
|
||||
type: bool
|
||||
default: false
|
||||
overwrite:
|
||||
@@ -43,7 +43,7 @@ DOCUMENTATION = '''
|
||||
umask:
|
||||
description:
|
||||
- Sets the umask for the created .gpg files. The first octed must be greater than 3 (user readable).
|
||||
- Note pass' default value is C('077').
|
||||
- Note pass' default value is V('077').
|
||||
env:
|
||||
- name: PASSWORD_STORE_UMASK
|
||||
version_added: 1.3.0
|
||||
@@ -52,7 +52,7 @@ DOCUMENTATION = '''
|
||||
type: bool
|
||||
default: false
|
||||
subkey:
|
||||
description: Return a specific subkey of the password. When set to C(password), always returns the first line.
|
||||
description: Return a specific subkey of the password. When set to V(password), always returns the first line.
|
||||
type: str
|
||||
default: password
|
||||
userpass:
|
||||
@@ -63,7 +63,7 @@ DOCUMENTATION = '''
|
||||
type: integer
|
||||
default: 16
|
||||
backup:
|
||||
description: Used with C(overwrite=true). Backup the previous password in a subkey.
|
||||
description: Used with O(overwrite=true). Backup the previous password in a subkey.
|
||||
type: bool
|
||||
default: false
|
||||
nosymbols:
|
||||
@@ -73,10 +73,10 @@ DOCUMENTATION = '''
|
||||
missing:
|
||||
description:
|
||||
- List of preference about what to do if the password file is missing.
|
||||
- If I(create=true), the value for this option is ignored and assumed to be C(create).
|
||||
- If set to C(error), the lookup will error out if the passname does not exist.
|
||||
- If set to C(create), the passname will be created with the provided length I(length) if it does not exist.
|
||||
- If set to C(empty) or C(warn), will return a C(none) in case the passname does not exist.
|
||||
- If O(create=true), the value for this option is ignored and assumed to be V(create).
|
||||
- If set to V(error), the lookup will error out if the passname does not exist.
|
||||
- If set to V(create), the passname will be created with the provided length O(length) if it does not exist.
|
||||
- If set to V(empty) or V(warn), will return a V(none) in case the passname does not exist.
|
||||
When using C(lookup) and not C(query), this will be translated to an empty string.
|
||||
version_added: 3.1.0
|
||||
type: str
|
||||
@@ -89,9 +89,9 @@ DOCUMENTATION = '''
|
||||
lock:
|
||||
description:
|
||||
- How to synchronize operations.
|
||||
- The default of C(write) only synchronizes write operations.
|
||||
- C(readwrite) synchronizes all operations (including read). This makes sure that gpg-agent is never called in parallel.
|
||||
- C(none) does not do any synchronization.
|
||||
- The default of V(write) only synchronizes write operations.
|
||||
- V(readwrite) synchronizes all operations (including read). This makes sure that gpg-agent is never called in parallel.
|
||||
- V(none) does not do any synchronization.
|
||||
ini:
|
||||
- section: passwordstore_lookup
|
||||
key: lock
|
||||
@@ -104,8 +104,8 @@ DOCUMENTATION = '''
|
||||
version_added: 4.5.0
|
||||
locktimeout:
|
||||
description:
|
||||
- Lock timeout applied when I(lock) is not C(none).
|
||||
- Time with a unit suffix, C(s), C(m), C(h) for seconds, minutes, and hours, respectively. For example, C(900s) equals C(15m).
|
||||
- Lock timeout applied when O(lock) is not V(none).
|
||||
- Time with a unit suffix, V(s), V(m), V(h) for seconds, minutes, and hours, respectively. For example, V(900s) equals V(15m).
|
||||
- Correlates with C(pinentry-timeout) in C(~/.gnupg/gpg-agent.conf), see C(man gpg-agent) for details.
|
||||
ini:
|
||||
- section: passwordstore_lookup
|
||||
@@ -116,8 +116,8 @@ DOCUMENTATION = '''
|
||||
backend:
|
||||
description:
|
||||
- Specify which backend to use.
|
||||
- Defaults to C(pass), passwordstore.org's original pass utility.
|
||||
- C(gopass) support is incomplete.
|
||||
- Defaults to V(pass), passwordstore.org's original pass utility.
|
||||
- V(gopass) support is incomplete.
|
||||
ini:
|
||||
- section: passwordstore_lookup
|
||||
key: backend
|
||||
|
||||
@@ -16,6 +16,8 @@ DOCUMENTATION = r"""
|
||||
version_added: '3.2.0'
|
||||
description:
|
||||
- Generates random string based upon the given constraints.
|
||||
- Uses L(random.SystemRandom,https://docs.python.org/3/library/random.html#random.SystemRandom),
|
||||
so should be strong enough for cryptographic purposes.
|
||||
options:
|
||||
length:
|
||||
description: The length of the string.
|
||||
@@ -42,25 +44,25 @@ DOCUMENTATION = r"""
|
||||
- Special characters are taken from Python standard library C(string).
|
||||
See L(the documentation of string.punctuation,https://docs.python.org/3/library/string.html#string.punctuation)
|
||||
for which characters will be used.
|
||||
- The choice of special characters can be changed to setting I(override_special).
|
||||
- The choice of special characters can be changed to setting O(override_special).
|
||||
default: true
|
||||
type: bool
|
||||
min_numeric:
|
||||
description:
|
||||
- Minimum number of numeric characters in the string.
|
||||
- If set, overrides I(numbers=false).
|
||||
- If set, overrides O(numbers=false).
|
||||
default: 0
|
||||
type: int
|
||||
min_upper:
|
||||
description:
|
||||
- Minimum number of uppercase alphabets in the string.
|
||||
- If set, overrides I(upper=false).
|
||||
- If set, overrides O(upper=false).
|
||||
default: 0
|
||||
type: int
|
||||
min_lower:
|
||||
description:
|
||||
- Minimum number of lowercase alphabets in the string.
|
||||
- If set, overrides I(lower=false).
|
||||
- If set, overrides O(lower=false).
|
||||
default: 0
|
||||
type: int
|
||||
min_special:
|
||||
@@ -71,11 +73,11 @@ DOCUMENTATION = r"""
|
||||
override_special:
|
||||
description:
|
||||
- Overide a list of special characters to use in the string.
|
||||
- If set I(min_special) should be set to a non-default value.
|
||||
- If set O(min_special) should be set to a non-default value.
|
||||
type: str
|
||||
override_all:
|
||||
description:
|
||||
- Override all values of I(numbers), I(upper), I(lower), and I(special) with
|
||||
- Override all values of O(numbers), O(upper), O(lower), and O(special) with
|
||||
the given list of characters.
|
||||
type: str
|
||||
base64:
|
||||
|
||||
@@ -25,7 +25,7 @@ options:
|
||||
elements: string
|
||||
base_url:
|
||||
description:
|
||||
- This will be the base URL of the server, for example C(https://server-url-here).
|
||||
- This will be the base URL of the server, for example V(https://server-url-here).
|
||||
required: true
|
||||
type: string
|
||||
api_key:
|
||||
|
||||
@@ -13,10 +13,10 @@ short_description: Get secrets from Thycotic Secret Server
|
||||
version_added: 1.0.0
|
||||
description:
|
||||
- Uses the Thycotic Secret Server Python SDK to get Secrets from Secret
|
||||
Server using token authentication with I(username) and I(password) on
|
||||
the REST API at I(base_url).
|
||||
Server using token authentication with O(username) and O(password) on
|
||||
the REST API at O(base_url).
|
||||
- When using self-signed certificates the environment variable
|
||||
C(REQUESTS_CA_BUNDLE) can be set to a file containing the trusted certificates
|
||||
E(REQUESTS_CA_BUNDLE) can be set to a file containing the trusted certificates
|
||||
(in C(.pem) format).
|
||||
- For example, C(export REQUESTS_CA_BUNDLE='/etc/ssl/certs/ca-bundle.trust.crt').
|
||||
requirements:
|
||||
@@ -26,10 +26,22 @@ options:
|
||||
description: The integer ID of the secret.
|
||||
required: true
|
||||
type: int
|
||||
secret_path:
|
||||
description: Indicate a full path of secret including folder and secret name when the secret ID is set to 0.
|
||||
required: false
|
||||
type: str
|
||||
version_added: 7.2.0
|
||||
fetch_secret_ids_from_folder:
|
||||
description:
|
||||
- Boolean flag which indicates whether secret ids are in a folder is fetched by folder ID or not.
|
||||
- V(true) then the terms will be considered as a folder IDs. Otherwise (default), they are considered as secret IDs.
|
||||
required: false
|
||||
type: bool
|
||||
version_added: 7.1.0
|
||||
fetch_attachments:
|
||||
description:
|
||||
- Boolean flag which indicates whether attached files will get downloaded or not.
|
||||
- The download will only happen if I(file_download_path) has been provided.
|
||||
- The download will only happen if O(file_download_path) has been provided.
|
||||
required: false
|
||||
type: bool
|
||||
version_added: 7.0.0
|
||||
@@ -39,7 +51,7 @@ options:
|
||||
type: path
|
||||
version_added: 7.0.0
|
||||
base_url:
|
||||
description: The base URL of the server, e.g. C(https://localhost/SecretServer).
|
||||
description: The base URL of the server, for example V(https://localhost/SecretServer).
|
||||
env:
|
||||
- name: TSS_BASE_URL
|
||||
ini:
|
||||
@@ -56,7 +68,7 @@ options:
|
||||
password:
|
||||
description:
|
||||
- The password associated with the supplied username.
|
||||
- Required when I(token) is not provided.
|
||||
- Required when O(token) is not provided.
|
||||
env:
|
||||
- name: TSS_PASSWORD
|
||||
ini:
|
||||
@@ -66,7 +78,7 @@ options:
|
||||
default: ""
|
||||
description:
|
||||
- The domain with which to request the OAuth2 Access Grant.
|
||||
- Optional when I(token) is not provided.
|
||||
- Optional when O(token) is not provided.
|
||||
- Requires C(python-tss-sdk) version 1.0.0 or greater.
|
||||
env:
|
||||
- name: TSS_DOMAIN
|
||||
@@ -78,7 +90,7 @@ options:
|
||||
token:
|
||||
description:
|
||||
- Existing token for Thycotic authorizer.
|
||||
- If provided, I(username) and I(password) are not needed.
|
||||
- If provided, O(username) and O(password) are not needed.
|
||||
- Requires C(python-tss-sdk) version 1.0.0 or greater.
|
||||
env:
|
||||
- name: TSS_TOKEN
|
||||
@@ -194,6 +206,49 @@ EXAMPLES = r"""
|
||||
| items2dict(key_name='slug',
|
||||
value_name='itemValue'))['private-key']
|
||||
}}
|
||||
|
||||
# If fetch_secret_ids_from_folder=true then secret IDs are in a folder is fetched based on folder ID
|
||||
- hosts: localhost
|
||||
vars:
|
||||
secret: >-
|
||||
{{
|
||||
lookup(
|
||||
'community.general.tss',
|
||||
102,
|
||||
fetch_secret_ids_from_folder=true,
|
||||
base_url='https://secretserver.domain.com/SecretServer/',
|
||||
token='thycotic_access_token'
|
||||
)
|
||||
}}
|
||||
tasks:
|
||||
- ansible.builtin.debug:
|
||||
msg: >
|
||||
the secret id's are {{
|
||||
secret
|
||||
}}
|
||||
|
||||
# If secret ID is 0 and secret_path has value then secret is fetched by secret path
|
||||
- hosts: localhost
|
||||
vars:
|
||||
secret: >-
|
||||
{{
|
||||
lookup(
|
||||
'community.general.tss',
|
||||
0,
|
||||
secret_path='\folderName\secretName'
|
||||
base_url='https://secretserver.domain.com/SecretServer/',
|
||||
username='user.name',
|
||||
password='password'
|
||||
)
|
||||
}}
|
||||
tasks:
|
||||
- ansible.builtin.debug:
|
||||
msg: >
|
||||
the password is {{
|
||||
(secret['items']
|
||||
| items2dict(key_name='slug',
|
||||
value_name='itemValue'))['password']
|
||||
}}
|
||||
"""
|
||||
|
||||
import abc
|
||||
@@ -204,29 +259,23 @@ from ansible.plugins.lookup import LookupBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
try:
|
||||
from thycotic.secrets.server import SecretServer, SecretServerError
|
||||
from delinea.secrets.server import SecretServer, SecretServerError, PasswordGrantAuthorizer, DomainPasswordGrantAuthorizer, AccessTokenAuthorizer
|
||||
|
||||
HAS_TSS_SDK = True
|
||||
HAS_DELINEA_SS_SDK = True
|
||||
HAS_TSS_AUTHORIZER = True
|
||||
except ImportError:
|
||||
try:
|
||||
from delinea.secrets.server import SecretServer, SecretServerError
|
||||
from thycotic.secrets.server import SecretServer, SecretServerError, PasswordGrantAuthorizer, DomainPasswordGrantAuthorizer, AccessTokenAuthorizer
|
||||
|
||||
HAS_TSS_SDK = True
|
||||
HAS_DELINEA_SS_SDK = False
|
||||
HAS_TSS_AUTHORIZER = True
|
||||
except ImportError:
|
||||
SecretServer = None
|
||||
SecretServerError = None
|
||||
HAS_TSS_SDK = False
|
||||
|
||||
try:
|
||||
from thycotic.secrets.server import PasswordGrantAuthorizer, DomainPasswordGrantAuthorizer, AccessTokenAuthorizer
|
||||
|
||||
HAS_TSS_AUTHORIZER = True
|
||||
except ImportError:
|
||||
try:
|
||||
from delinea.secrets.server import PasswordGrantAuthorizer, DomainPasswordGrantAuthorizer, AccessTokenAuthorizer
|
||||
|
||||
HAS_TSS_AUTHORIZER = True
|
||||
except ImportError:
|
||||
HAS_DELINEA_SS_SDK = False
|
||||
PasswordGrantAuthorizer = None
|
||||
DomainPasswordGrantAuthorizer = None
|
||||
AccessTokenAuthorizer = None
|
||||
@@ -248,27 +297,49 @@ class TSSClient(object):
|
||||
else:
|
||||
return TSSClientV0(**server_parameters)
|
||||
|
||||
def get_secret(self, term, fetch_file_attachments, file_download_path):
|
||||
def get_secret(self, term, secret_path, fetch_file_attachments, file_download_path):
|
||||
display.debug("tss_lookup term: %s" % term)
|
||||
secret_id = self._term_to_secret_id(term)
|
||||
display.vvv(u"Secret Server lookup of Secret with ID %d" % secret_id)
|
||||
if secret_id == 0 and secret_path:
|
||||
fetch_secret_by_path = True
|
||||
display.vvv(u"Secret Server lookup of Secret with path %s" % secret_path)
|
||||
else:
|
||||
fetch_secret_by_path = False
|
||||
display.vvv(u"Secret Server lookup of Secret with ID %d" % secret_id)
|
||||
|
||||
if fetch_file_attachments:
|
||||
obj = self._client.get_secret(secret_id, fetch_file_attachments)
|
||||
if fetch_secret_by_path:
|
||||
obj = self._client.get_secret_by_path(secret_path, fetch_file_attachments)
|
||||
else:
|
||||
obj = self._client.get_secret(secret_id, fetch_file_attachments)
|
||||
for i in obj['items']:
|
||||
if file_download_path and os.path.isdir(file_download_path):
|
||||
if i['isFile']:
|
||||
try:
|
||||
with open(os.path.join(file_download_path, str(obj['id']) + "_" + i['slug']), "w") as f:
|
||||
f.write(i['itemValue'].text)
|
||||
i['itemValue'] = "*** Not Valid For Display ***"
|
||||
file_content = i['itemValue'].content
|
||||
with open(os.path.join(file_download_path, str(obj['id']) + "_" + i['slug']), "wb") as f:
|
||||
f.write(file_content)
|
||||
except ValueError:
|
||||
raise AnsibleOptionsError("Failed to download {0}".format(str(i['slug'])))
|
||||
except AttributeError:
|
||||
display.warning("Could not read file content for {0}".format(str(i['slug'])))
|
||||
finally:
|
||||
i['itemValue'] = "*** Not Valid For Display ***"
|
||||
else:
|
||||
raise AnsibleOptionsError("File download path does not exist")
|
||||
return obj
|
||||
else:
|
||||
return self._client.get_secret_json(secret_id)
|
||||
if fetch_secret_by_path:
|
||||
return self._client.get_secret_by_path(secret_path, False)
|
||||
else:
|
||||
return self._client.get_secret_json(secret_id)
|
||||
|
||||
def get_secret_ids_by_folderid(self, term):
|
||||
display.debug("tss_lookup term: %s" % term)
|
||||
folder_id = self._term_to_folder_id(term)
|
||||
display.vvv(u"Secret Server lookup of Secret id's with Folder ID %d" % folder_id)
|
||||
|
||||
return self._client.get_secret_ids_by_folderid(folder_id)
|
||||
|
||||
@staticmethod
|
||||
def _term_to_secret_id(term):
|
||||
@@ -277,6 +348,13 @@ class TSSClient(object):
|
||||
except ValueError:
|
||||
raise AnsibleOptionsError("Secret ID must be an integer")
|
||||
|
||||
@staticmethod
|
||||
def _term_to_folder_id(term):
|
||||
try:
|
||||
return int(term)
|
||||
except ValueError:
|
||||
raise AnsibleOptionsError("Folder ID must be an integer")
|
||||
|
||||
|
||||
class TSSClientV0(TSSClient):
|
||||
def __init__(self, **server_parameters):
|
||||
@@ -345,6 +423,20 @@ class LookupModule(LookupBase):
|
||||
)
|
||||
|
||||
try:
|
||||
return [tss.get_secret(term, self.get_option("fetch_attachments"), self.get_option("file_download_path")) for term in terms]
|
||||
if self.get_option("fetch_secret_ids_from_folder"):
|
||||
if HAS_DELINEA_SS_SDK:
|
||||
return [tss.get_secret_ids_by_folderid(term) for term in terms]
|
||||
else:
|
||||
raise AnsibleError("latest python-tss-sdk must be installed to use this plugin")
|
||||
else:
|
||||
return [
|
||||
tss.get_secret(
|
||||
term,
|
||||
self.get_option("secret_path"),
|
||||
self.get_option("fetch_attachments"),
|
||||
self.get_option("file_download_path"),
|
||||
)
|
||||
for term in terms
|
||||
]
|
||||
except SecretServerError as error:
|
||||
raise AnsibleError("Secret Server lookup failure: %s" % error.message)
|
||||
|
||||
@@ -147,6 +147,11 @@ class _Format(object):
|
||||
|
||||
@staticmethod
|
||||
def as_default_type(_type, arg="", ignore_none=None):
|
||||
#
|
||||
# DEPRECATION: This method is deprecated and will be removed in community.general 10.0.0
|
||||
#
|
||||
# Instead of using the implicit formats provided here, use the explicit necessary format method.
|
||||
#
|
||||
fmt = _Format
|
||||
if _type == "dict":
|
||||
return fmt.as_func(lambda d: ["--{0}={1}".format(*a) for a in iteritems(d)], ignore_none=ignore_none)
|
||||
|
||||
@@ -55,8 +55,10 @@ def initialize_dialect(dialect, **kwargs):
|
||||
|
||||
|
||||
def read_csv(data, dialect, fieldnames=None):
|
||||
|
||||
BOM = to_native(u'\ufeff')
|
||||
data = to_native(data, errors='surrogate_or_strict')
|
||||
if data.startswith(BOM):
|
||||
data = data[len(BOM):]
|
||||
|
||||
if PY3:
|
||||
fake_fh = StringIO(data)
|
||||
|
||||
@@ -9,6 +9,7 @@ __metaclass__ = type
|
||||
|
||||
import json
|
||||
import traceback
|
||||
import copy
|
||||
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlencode, quote
|
||||
@@ -64,6 +65,14 @@ URL_CLIENT_GROUP_ROLEMAPPINGS_AVAILABLE = "{url}/admin/realms/{realm}/groups/{id
|
||||
URL_CLIENT_GROUP_ROLEMAPPINGS_COMPOSITE = "{url}/admin/realms/{realm}/groups/{id}/role-mappings/clients/{client}/composite"
|
||||
|
||||
URL_USERS = "{url}/admin/realms/{realm}/users"
|
||||
URL_USER = "{url}/admin/realms/{realm}/users/{id}"
|
||||
URL_USER_ROLE_MAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings"
|
||||
URL_USER_REALM_ROLE_MAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings/realm"
|
||||
URL_USER_CLIENTS_ROLE_MAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients"
|
||||
URL_USER_CLIENT_ROLE_MAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client_id}"
|
||||
URL_USER_GROUPS = "{url}/admin/realms/{realm}/users/{id}/groups"
|
||||
URL_USER_GROUP = "{url}/admin/realms/{realm}/users/{id}/groups/{group_id}"
|
||||
|
||||
URL_CLIENT_SERVICE_ACCOUNT_USER = "{url}/admin/realms/{realm}/clients/{id}/service-account-user"
|
||||
URL_CLIENT_USER_ROLEMAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client}"
|
||||
URL_CLIENT_USER_ROLEMAPPINGS_AVAILABLE = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client}/available"
|
||||
@@ -81,6 +90,9 @@ URL_AUTHENTICATION_EXECUTION_CONFIG = "{url}/admin/realms/{realm}/authentication
|
||||
URL_AUTHENTICATION_EXECUTION_RAISE_PRIORITY = "{url}/admin/realms/{realm}/authentication/executions/{id}/raise-priority"
|
||||
URL_AUTHENTICATION_EXECUTION_LOWER_PRIORITY = "{url}/admin/realms/{realm}/authentication/executions/{id}/lower-priority"
|
||||
URL_AUTHENTICATION_CONFIG = "{url}/admin/realms/{realm}/authentication/config/{id}"
|
||||
URL_AUTHENTICATION_REGISTER_REQUIRED_ACTION = "{url}/admin/realms/{realm}/authentication/register-required-action"
|
||||
URL_AUTHENTICATION_REQUIRED_ACTIONS = "{url}/admin/realms/{realm}/authentication/required-actions"
|
||||
URL_AUTHENTICATION_REQUIRED_ACTIONS_ALIAS = "{url}/admin/realms/{realm}/authentication/required-actions/{alias}"
|
||||
|
||||
URL_IDENTITY_PROVIDERS = "{url}/admin/realms/{realm}/identity-provider/instances"
|
||||
URL_IDENTITY_PROVIDER = "{url}/admin/realms/{realm}/identity-provider/instances/{alias}"
|
||||
@@ -93,6 +105,17 @@ URL_COMPONENT = "{url}/admin/realms/{realm}/components/{id}"
|
||||
URL_AUTHZ_AUTHORIZATION_SCOPE = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/scope/{id}"
|
||||
URL_AUTHZ_AUTHORIZATION_SCOPES = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/scope"
|
||||
|
||||
# This URL is used for:
|
||||
# - Querying client authorization permissions
|
||||
# - Removing client authorization permissions
|
||||
URL_AUTHZ_POLICIES = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/policy"
|
||||
URL_AUTHZ_POLICY = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/policy/{id}"
|
||||
|
||||
URL_AUTHZ_PERMISSION = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/permission/{permission_type}/{id}"
|
||||
URL_AUTHZ_PERMISSIONS = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/permission/{permission_type}"
|
||||
|
||||
URL_AUTHZ_RESOURCES = "{url}/admin/realms/{realm}/clients/{client_id}/authz/resource-server/resource"
|
||||
|
||||
|
||||
def keycloak_argument_spec():
|
||||
"""
|
||||
@@ -207,24 +230,30 @@ def is_struct_included(struct1, struct2, exclude=None):
|
||||
Return True if all element of dict 1 are present in dict 2, return false otherwise.
|
||||
"""
|
||||
if isinstance(struct1, list) and isinstance(struct2, list):
|
||||
if not struct1 and not struct2:
|
||||
return True
|
||||
for item1 in struct1:
|
||||
if isinstance(item1, (list, dict)):
|
||||
for item2 in struct2:
|
||||
if not is_struct_included(item1, item2, exclude):
|
||||
return False
|
||||
if is_struct_included(item1, item2, exclude):
|
||||
break
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
if item1 not in struct2:
|
||||
return False
|
||||
return True
|
||||
elif isinstance(struct1, dict) and isinstance(struct2, dict):
|
||||
if not struct1 and not struct2:
|
||||
return True
|
||||
try:
|
||||
for key in struct1:
|
||||
if not (exclude and key in exclude):
|
||||
if not is_struct_included(struct1[key], struct2[key], exclude):
|
||||
return False
|
||||
return True
|
||||
except KeyError:
|
||||
return False
|
||||
return True
|
||||
elif isinstance(struct1, bool) and isinstance(struct2, bool):
|
||||
return struct1 == struct2
|
||||
else:
|
||||
@@ -747,8 +776,15 @@ class KeycloakAPI(object):
|
||||
users_url = URL_USERS.format(url=self.baseurl, realm=realm)
|
||||
users_url += '?username=%s&exact=true' % username
|
||||
try:
|
||||
return json.loads(to_native(open_url(users_url, method='GET', headers=self.restheaders, timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
userrep = None
|
||||
users = json.loads(to_native(open_url(users_url, method='GET', headers=self.restheaders, timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
for user in users:
|
||||
if user['username'] == username:
|
||||
userrep = user
|
||||
break
|
||||
return userrep
|
||||
|
||||
except ValueError as e:
|
||||
self.module.fail_json(msg='API returned incorrect JSON when trying to obtain the user for realm %s and username %s: %s'
|
||||
% (realm, username, str(e)))
|
||||
@@ -1658,6 +1694,9 @@ class KeycloakAPI(object):
|
||||
"""
|
||||
roles_url = URL_REALM_ROLES.format(url=self.baseurl, realm=realm)
|
||||
try:
|
||||
if "composites" in rolerep:
|
||||
keycloak_compatible_composites = self.convert_role_composites(rolerep["composites"])
|
||||
rolerep["composites"] = keycloak_compatible_composites
|
||||
return open_url(roles_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(rolerep), validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
@@ -1672,12 +1711,124 @@ class KeycloakAPI(object):
|
||||
"""
|
||||
role_url = URL_REALM_ROLE.format(url=self.baseurl, realm=realm, name=quote(rolerep['name']))
|
||||
try:
|
||||
return open_url(role_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(rolerep), validate_certs=self.validate_certs)
|
||||
composites = None
|
||||
if "composites" in rolerep:
|
||||
composites = copy.deepcopy(rolerep["composites"])
|
||||
del rolerep["composites"]
|
||||
role_response = open_url(role_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(rolerep), validate_certs=self.validate_certs)
|
||||
if composites is not None:
|
||||
self.update_role_composites(rolerep=rolerep, composites=composites, realm=realm)
|
||||
return role_response
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not update role %s in realm %s: %s'
|
||||
% (rolerep['name'], realm, str(e)))
|
||||
|
||||
def get_role_composites(self, rolerep, clientid=None, realm='master'):
|
||||
composite_url = ''
|
||||
try:
|
||||
if clientid is not None:
|
||||
client = self.get_client_by_clientid(client_id=clientid, realm=realm)
|
||||
cid = client['id']
|
||||
composite_url = URL_CLIENT_ROLE_COMPOSITES.format(url=self.baseurl, realm=realm, id=cid, name=quote(rolerep["name"]))
|
||||
else:
|
||||
composite_url = URL_REALM_ROLE_COMPOSITES.format(url=self.baseurl, realm=realm, name=quote(rolerep["name"]))
|
||||
# Get existing composites
|
||||
return json.loads(to_native(open_url(
|
||||
composite_url,
|
||||
method='GET',
|
||||
http_agent=self.http_agent,
|
||||
headers=self.restheaders,
|
||||
timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not get role %s composites in realm %s: %s'
|
||||
% (rolerep['name'], realm, str(e)))
|
||||
|
||||
def create_role_composites(self, rolerep, composites, clientid=None, realm='master'):
|
||||
composite_url = ''
|
||||
try:
|
||||
if clientid is not None:
|
||||
client = self.get_client_by_clientid(client_id=clientid, realm=realm)
|
||||
cid = client['id']
|
||||
composite_url = URL_CLIENT_ROLE_COMPOSITES.format(url=self.baseurl, realm=realm, id=cid, name=quote(rolerep["name"]))
|
||||
else:
|
||||
composite_url = URL_REALM_ROLE_COMPOSITES.format(url=self.baseurl, realm=realm, name=quote(rolerep["name"]))
|
||||
# Get existing composites
|
||||
# create new composites
|
||||
return open_url(composite_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(composites), validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not create role %s composites in realm %s: %s'
|
||||
% (rolerep['name'], realm, str(e)))
|
||||
|
||||
def delete_role_composites(self, rolerep, composites, clientid=None, realm='master'):
|
||||
composite_url = ''
|
||||
try:
|
||||
if clientid is not None:
|
||||
client = self.get_client_by_clientid(client_id=clientid, realm=realm)
|
||||
cid = client['id']
|
||||
composite_url = URL_CLIENT_ROLE_COMPOSITES.format(url=self.baseurl, realm=realm, id=cid, name=quote(rolerep["name"]))
|
||||
else:
|
||||
composite_url = URL_REALM_ROLE_COMPOSITES.format(url=self.baseurl, realm=realm, name=quote(rolerep["name"]))
|
||||
# Get existing composites
|
||||
# create new composites
|
||||
return open_url(composite_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(composites), validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not create role %s composites in realm %s: %s'
|
||||
% (rolerep['name'], realm, str(e)))
|
||||
|
||||
def update_role_composites(self, rolerep, composites, clientid=None, realm='master'):
|
||||
# Get existing composites
|
||||
existing_composites = self.get_role_composites(rolerep=rolerep, clientid=clientid, realm=realm)
|
||||
composites_to_be_created = []
|
||||
composites_to_be_deleted = []
|
||||
for composite in composites:
|
||||
composite_found = False
|
||||
existing_composite_client = None
|
||||
for existing_composite in existing_composites:
|
||||
if existing_composite["clientRole"]:
|
||||
existing_composite_client = self.get_client_by_id(existing_composite["containerId"], realm=realm)
|
||||
if ("client_id" in composite
|
||||
and composite['client_id'] is not None
|
||||
and existing_composite_client["clientId"] == composite["client_id"]
|
||||
and composite["name"] == existing_composite["name"]):
|
||||
composite_found = True
|
||||
break
|
||||
else:
|
||||
if (("client_id" not in composite or composite['client_id'] is None)
|
||||
and composite["name"] == existing_composite["name"]):
|
||||
composite_found = True
|
||||
break
|
||||
if (not composite_found and ('state' not in composite or composite['state'] == 'present')):
|
||||
if "client_id" in composite and composite['client_id'] is not None:
|
||||
client_roles = self.get_client_roles(clientid=composite['client_id'], realm=realm)
|
||||
for client_role in client_roles:
|
||||
if client_role['name'] == composite['name']:
|
||||
composites_to_be_created.append(client_role)
|
||||
break
|
||||
else:
|
||||
realm_role = self.get_realm_role(name=composite["name"], realm=realm)
|
||||
composites_to_be_created.append(realm_role)
|
||||
elif composite_found and 'state' in composite and composite['state'] == 'absent':
|
||||
if "client_id" in composite and composite['client_id'] is not None:
|
||||
client_roles = self.get_client_roles(clientid=composite['client_id'], realm=realm)
|
||||
for client_role in client_roles:
|
||||
if client_role['name'] == composite['name']:
|
||||
composites_to_be_deleted.append(client_role)
|
||||
break
|
||||
else:
|
||||
realm_role = self.get_realm_role(name=composite["name"], realm=realm)
|
||||
composites_to_be_deleted.append(realm_role)
|
||||
|
||||
if len(composites_to_be_created) > 0:
|
||||
# create new composites
|
||||
self.create_role_composites(rolerep=rolerep, composites=composites_to_be_created, clientid=clientid, realm=realm)
|
||||
if len(composites_to_be_deleted) > 0:
|
||||
# delete new composites
|
||||
self.delete_role_composites(rolerep=rolerep, composites=composites_to_be_deleted, clientid=clientid, realm=realm)
|
||||
|
||||
def delete_realm_role(self, name, realm='master'):
|
||||
""" Delete a realm role.
|
||||
|
||||
@@ -1756,12 +1907,30 @@ class KeycloakAPI(object):
|
||||
% (clientid, realm))
|
||||
roles_url = URL_CLIENT_ROLES.format(url=self.baseurl, realm=realm, id=cid)
|
||||
try:
|
||||
if "composites" in rolerep:
|
||||
keycloak_compatible_composites = self.convert_role_composites(rolerep["composites"])
|
||||
rolerep["composites"] = keycloak_compatible_composites
|
||||
return open_url(roles_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(rolerep), validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not create role %s for client %s in realm %s: %s'
|
||||
% (rolerep['name'], clientid, realm, str(e)))
|
||||
|
||||
def convert_role_composites(self, composites):
|
||||
keycloak_compatible_composites = {
|
||||
'client': {},
|
||||
'realm': []
|
||||
}
|
||||
for composite in composites:
|
||||
if 'state' not in composite or composite['state'] == 'present':
|
||||
if "client_id" in composite and composite["client_id"] is not None:
|
||||
if composite["client_id"] not in keycloak_compatible_composites["client"]:
|
||||
keycloak_compatible_composites["client"][composite["client_id"]] = []
|
||||
keycloak_compatible_composites["client"][composite["client_id"]].append(composite["name"])
|
||||
else:
|
||||
keycloak_compatible_composites["realm"].append(composite["name"])
|
||||
return keycloak_compatible_composites
|
||||
|
||||
def update_client_role(self, rolerep, clientid, realm="master"):
|
||||
""" Update an existing client role.
|
||||
|
||||
@@ -1776,8 +1945,15 @@ class KeycloakAPI(object):
|
||||
% (clientid, realm))
|
||||
role_url = URL_CLIENT_ROLE.format(url=self.baseurl, realm=realm, id=cid, name=quote(rolerep['name']))
|
||||
try:
|
||||
return open_url(role_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(rolerep), validate_certs=self.validate_certs)
|
||||
composites = None
|
||||
if "composites" in rolerep:
|
||||
composites = copy.deepcopy(rolerep["composites"])
|
||||
del rolerep['composites']
|
||||
update_role_response = open_url(role_url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(rolerep), validate_certs=self.validate_certs)
|
||||
if composites is not None:
|
||||
self.update_role_composites(rolerep=rolerep, clientid=clientid, composites=composites, realm=realm)
|
||||
return update_role_response
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not update role %s for client %s in realm %s: %s'
|
||||
% (rolerep['name'], clientid, realm, str(e)))
|
||||
@@ -2084,6 +2260,116 @@ class KeycloakAPI(object):
|
||||
self.module.fail_json(msg='Could not get executions for authentication flow %s in realm %s: %s'
|
||||
% (config["alias"], realm, str(e)))
|
||||
|
||||
def get_required_actions(self, realm='master'):
|
||||
"""
|
||||
Get required actions.
|
||||
:param realm: Realm name (not id).
|
||||
:return: List of representations of the required actions.
|
||||
"""
|
||||
|
||||
try:
|
||||
required_actions = json.load(
|
||||
open_url(
|
||||
URL_AUTHENTICATION_REQUIRED_ACTIONS.format(
|
||||
url=self.baseurl,
|
||||
realm=realm
|
||||
),
|
||||
method='GET',
|
||||
http_agent=self.http_agent, headers=self.restheaders,
|
||||
timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs
|
||||
)
|
||||
)
|
||||
|
||||
return required_actions
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def register_required_action(self, rep, realm='master'):
|
||||
"""
|
||||
Register required action.
|
||||
:param rep: JSON containing 'providerId', and 'name' attributes.
|
||||
:param realm: Realm name (not id).
|
||||
:return: Representation of the required action.
|
||||
"""
|
||||
|
||||
data = {
|
||||
'name': rep['name'],
|
||||
'providerId': rep['providerId']
|
||||
}
|
||||
|
||||
try:
|
||||
return open_url(
|
||||
URL_AUTHENTICATION_REGISTER_REQUIRED_ACTION.format(
|
||||
url=self.baseurl,
|
||||
realm=realm
|
||||
),
|
||||
method='POST',
|
||||
http_agent=self.http_agent, headers=self.restheaders,
|
||||
data=json.dumps(data),
|
||||
timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs
|
||||
)
|
||||
except Exception as e:
|
||||
self.module.fail_json(
|
||||
msg='Unable to register required action %s in realm %s: %s'
|
||||
% (rep["name"], realm, str(e))
|
||||
)
|
||||
|
||||
def update_required_action(self, alias, rep, realm='master'):
|
||||
"""
|
||||
Update required action.
|
||||
:param alias: Alias of required action.
|
||||
:param rep: JSON describing new state of required action.
|
||||
:param realm: Realm name (not id).
|
||||
:return: HTTPResponse object on success.
|
||||
"""
|
||||
|
||||
try:
|
||||
return open_url(
|
||||
URL_AUTHENTICATION_REQUIRED_ACTIONS_ALIAS.format(
|
||||
url=self.baseurl,
|
||||
alias=quote(alias),
|
||||
realm=realm
|
||||
),
|
||||
method='PUT',
|
||||
http_agent=self.http_agent, headers=self.restheaders,
|
||||
data=json.dumps(rep),
|
||||
timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs
|
||||
)
|
||||
except Exception as e:
|
||||
self.module.fail_json(
|
||||
msg='Unable to update required action %s in realm %s: %s'
|
||||
% (alias, realm, str(e))
|
||||
)
|
||||
|
||||
def delete_required_action(self, alias, realm='master'):
|
||||
"""
|
||||
Delete required action.
|
||||
:param alias: Alias of required action.
|
||||
:param realm: Realm name (not id).
|
||||
:return: HTTPResponse object on success.
|
||||
"""
|
||||
|
||||
try:
|
||||
return open_url(
|
||||
URL_AUTHENTICATION_REQUIRED_ACTIONS_ALIAS.format(
|
||||
url=self.baseurl,
|
||||
alias=quote(alias),
|
||||
realm=realm
|
||||
),
|
||||
method='DELETE',
|
||||
http_agent=self.http_agent, headers=self.restheaders,
|
||||
timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs
|
||||
)
|
||||
except Exception as e:
|
||||
self.module.fail_json(
|
||||
msg='Unable to delete required action %s in realm %s: %s'
|
||||
% (alias, realm, str(e))
|
||||
)
|
||||
|
||||
def get_identity_providers(self, realm='master'):
|
||||
""" Fetch representations for identity providers in a realm
|
||||
:param realm: realm to be queried
|
||||
@@ -2375,3 +2661,311 @@ class KeycloakAPI(object):
|
||||
validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not delete scope %s for client %s in realm %s: %s' % (id, client_id, realm, str(e)))
|
||||
|
||||
def get_user_by_id(self, user_id, realm='master'):
|
||||
"""
|
||||
Get a User by its ID.
|
||||
:param user_id: ID of the user.
|
||||
:param realm: Realm
|
||||
:return: Representation of the user.
|
||||
"""
|
||||
try:
|
||||
user_url = URL_USER.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
id=user_id)
|
||||
userrep = json.load(
|
||||
open_url(
|
||||
user_url,
|
||||
method='GET',
|
||||
headers=self.restheaders))
|
||||
return userrep
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not get user %s in realm %s: %s'
|
||||
% (user_id, realm, str(e)))
|
||||
|
||||
def create_user(self, userrep, realm='master'):
|
||||
"""
|
||||
Create a new User.
|
||||
:param userrep: Representation of the user to create
|
||||
:param realm: Realm
|
||||
:return: Representation of the user created.
|
||||
"""
|
||||
try:
|
||||
if 'attributes' in userrep and isinstance(userrep['attributes'], list):
|
||||
attributes = copy.deepcopy(userrep['attributes'])
|
||||
userrep['attributes'] = self.convert_user_attributes_to_keycloak_dict(attributes=attributes)
|
||||
users_url = URL_USERS.format(
|
||||
url=self.baseurl,
|
||||
realm=realm)
|
||||
open_url(users_url,
|
||||
method='POST',
|
||||
headers=self.restheaders,
|
||||
data=json.dumps(userrep))
|
||||
created_user = self.get_user_by_username(
|
||||
username=userrep['username'],
|
||||
realm=realm)
|
||||
return created_user
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not create user %s in realm %s: %s'
|
||||
% (userrep['username'], realm, str(e)))
|
||||
|
||||
def convert_user_attributes_to_keycloak_dict(self, attributes):
|
||||
keycloak_user_attributes_dict = {}
|
||||
for attribute in attributes:
|
||||
if ('state' not in attribute or attribute['state'] == 'present') and 'name' in attribute:
|
||||
keycloak_user_attributes_dict[attribute['name']] = attribute['values'] if 'values' in attribute else []
|
||||
return keycloak_user_attributes_dict
|
||||
|
||||
def convert_keycloak_user_attributes_dict_to_module_list(self, attributes):
|
||||
module_attributes_list = []
|
||||
for key in attributes:
|
||||
attr = {}
|
||||
attr['name'] = key
|
||||
attr['values'] = attributes[key]
|
||||
module_attributes_list.append(attr)
|
||||
return module_attributes_list
|
||||
|
||||
def update_user(self, userrep, realm='master'):
|
||||
"""
|
||||
Update a User.
|
||||
:param userrep: Representation of the user to update. This representation must include the ID of the user.
|
||||
:param realm: Realm
|
||||
:return: Representation of the updated user.
|
||||
"""
|
||||
try:
|
||||
if 'attributes' in userrep and isinstance(userrep['attributes'], list):
|
||||
attributes = copy.deepcopy(userrep['attributes'])
|
||||
userrep['attributes'] = self.convert_user_attributes_to_keycloak_dict(attributes=attributes)
|
||||
user_url = URL_USER.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
id=userrep["id"])
|
||||
open_url(
|
||||
user_url,
|
||||
method='PUT',
|
||||
headers=self.restheaders,
|
||||
data=json.dumps(userrep))
|
||||
updated_user = self.get_user_by_id(
|
||||
user_id=userrep['id'],
|
||||
realm=realm)
|
||||
return updated_user
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not update user %s in realm %s: %s'
|
||||
% (userrep['username'], realm, str(e)))
|
||||
|
||||
def delete_user(self, user_id, realm='master'):
|
||||
"""
|
||||
Delete a User.
|
||||
:param user_id: ID of the user to be deleted
|
||||
:param realm: Realm
|
||||
:return: HTTP response.
|
||||
"""
|
||||
try:
|
||||
user_url = URL_USER.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
id=user_id)
|
||||
return open_url(
|
||||
user_url,
|
||||
method='DELETE',
|
||||
headers=self.restheaders)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not delete user %s in realm %s: %s'
|
||||
% (user_id, realm, str(e)))
|
||||
|
||||
def get_user_groups(self, user_id, realm='master'):
|
||||
"""
|
||||
Get groups for a user.
|
||||
:param user_id: User ID
|
||||
:param realm: Realm
|
||||
:return: Representation of the client groups.
|
||||
"""
|
||||
try:
|
||||
groups = []
|
||||
user_groups_url = URL_USER_GROUPS.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
id=user_id)
|
||||
user_groups = json.load(
|
||||
open_url(
|
||||
user_groups_url,
|
||||
method='GET',
|
||||
headers=self.restheaders))
|
||||
for user_group in user_groups:
|
||||
groups.append(user_group["name"])
|
||||
return groups
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not get groups for user %s in realm %s: %s'
|
||||
% (user_id, realm, str(e)))
|
||||
|
||||
def add_user_in_group(self, user_id, group_id, realm='master'):
|
||||
"""
|
||||
Add a user to a group.
|
||||
:param user_id: User ID
|
||||
:param group_id: Group Id to add the user to.
|
||||
:param realm: Realm
|
||||
:return: HTTP Response
|
||||
"""
|
||||
try:
|
||||
user_group_url = URL_USER_GROUP.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
id=user_id,
|
||||
group_id=group_id)
|
||||
return open_url(
|
||||
user_group_url,
|
||||
method='PUT',
|
||||
headers=self.restheaders)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not add user %s in group %s in realm %s: %s'
|
||||
% (user_id, group_id, realm, str(e)))
|
||||
|
||||
def remove_user_from_group(self, user_id, group_id, realm='master'):
|
||||
"""
|
||||
Remove a user from a group for a user.
|
||||
:param user_id: User ID
|
||||
:param group_id: Group Id to add the user to.
|
||||
:param realm: Realm
|
||||
:return: HTTP response
|
||||
"""
|
||||
try:
|
||||
user_group_url = URL_USER_GROUP.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
id=user_id,
|
||||
group_id=group_id)
|
||||
return open_url(
|
||||
user_group_url,
|
||||
method='DELETE',
|
||||
headers=self.restheaders)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not remove user %s from group %s in realm %s: %s'
|
||||
% (user_id, group_id, realm, str(e)))
|
||||
|
||||
def update_user_groups_membership(self, userrep, groups, realm='master'):
|
||||
"""
|
||||
Update user's group membership
|
||||
:param userrep: Representation of the user. This representation must include the ID.
|
||||
:param realm: Realm
|
||||
:return: True if group membership has been changed. False Otherwise.
|
||||
"""
|
||||
changed = False
|
||||
try:
|
||||
user_existing_groups = self.get_user_groups(
|
||||
user_id=userrep['id'],
|
||||
realm=realm)
|
||||
groups_to_add_and_remove = self.extract_groups_to_add_to_and_remove_from_user(groups)
|
||||
# If group membership need to be changed
|
||||
if not is_struct_included(groups_to_add_and_remove['add'], user_existing_groups):
|
||||
# Get available goups in the realm
|
||||
realm_groups = self.get_groups(realm=realm)
|
||||
for realm_group in realm_groups:
|
||||
if "name" in realm_group and realm_group["name"] in groups_to_add_and_remove['add']:
|
||||
self.add_user_in_group(
|
||||
user_id=userrep["id"],
|
||||
group_id=realm_group["id"],
|
||||
realm=realm)
|
||||
changed = True
|
||||
elif "name" in realm_group and realm_group['name'] in groups_to_add_and_remove['remove']:
|
||||
self.remove_user_from_group(
|
||||
user_id=userrep['id'],
|
||||
group_id=realm_group['id'],
|
||||
realm=realm)
|
||||
changed = True
|
||||
return changed
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not update group membership for user %s in realm %s: %s'
|
||||
% (userrep['id]'], realm, str(e)))
|
||||
|
||||
def extract_groups_to_add_to_and_remove_from_user(self, groups):
|
||||
groups_extract = {}
|
||||
groups_to_add = []
|
||||
groups_to_remove = []
|
||||
if isinstance(groups, list) and len(groups) > 0:
|
||||
for group in groups:
|
||||
group_name = group['name'] if isinstance(group, dict) and 'name' in group else group
|
||||
if isinstance(group, dict) and ('state' not in group or group['state'] == 'present'):
|
||||
groups_to_add.append(group_name)
|
||||
else:
|
||||
groups_to_remove.append(group_name)
|
||||
groups_extract['add'] = groups_to_add
|
||||
groups_extract['remove'] = groups_to_remove
|
||||
|
||||
return groups_extract
|
||||
|
||||
def convert_user_group_list_of_str_to_list_of_dict(self, groups):
|
||||
list_of_groups = []
|
||||
if isinstance(groups, list) and len(groups) > 0:
|
||||
for group in groups:
|
||||
if isinstance(group, str):
|
||||
group_dict = {}
|
||||
group_dict['name'] = group
|
||||
list_of_groups.append(group_dict)
|
||||
return list_of_groups
|
||||
|
||||
def get_authz_permission_by_name(self, name, client_id, realm):
|
||||
"""Get authorization permission by name"""
|
||||
url = URL_AUTHZ_POLICIES.format(url=self.baseurl, client_id=client_id, realm=realm)
|
||||
search_url = "%s/search?name=%s" % (url, name.replace(' ', '%20'))
|
||||
|
||||
try:
|
||||
return json.loads(to_native(open_url(search_url, method='GET', http_agent=self.http_agent, headers=self.restheaders,
|
||||
timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def create_authz_permission(self, payload, permission_type, client_id, realm):
|
||||
"""Create an authorization permission for a Keycloak client"""
|
||||
url = URL_AUTHZ_PERMISSIONS.format(url=self.baseurl, permission_type=permission_type, client_id=client_id, realm=realm)
|
||||
|
||||
try:
|
||||
return open_url(url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(payload), validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not create permission %s for client %s in realm %s: %s' % (payload['name'], client_id, realm, str(e)))
|
||||
|
||||
def remove_authz_permission(self, id, client_id, realm):
|
||||
"""Create an authorization permission for a Keycloak client"""
|
||||
url = URL_AUTHZ_POLICY.format(url=self.baseurl, id=id, client_id=client_id, realm=realm)
|
||||
|
||||
try:
|
||||
return open_url(url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not delete permission %s for client %s in realm %s: %s' % (id, client_id, realm, str(e)))
|
||||
|
||||
def update_authz_permission(self, payload, permission_type, id, client_id, realm):
|
||||
"""Update a permission for a Keycloak client"""
|
||||
url = URL_AUTHZ_PERMISSION.format(url=self.baseurl, permission_type=permission_type, id=id, client_id=client_id, realm=realm)
|
||||
|
||||
try:
|
||||
return open_url(url, method='PUT', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(payload), validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not create update permission %s for client %s in realm %s: %s' % (payload['name'], client_id, realm, str(e)))
|
||||
|
||||
def get_authz_resource_by_name(self, name, client_id, realm):
|
||||
"""Get authorization resource by name"""
|
||||
url = URL_AUTHZ_RESOURCES.format(url=self.baseurl, client_id=client_id, realm=realm)
|
||||
search_url = "%s/search?name=%s" % (url, name.replace(' ', '%20'))
|
||||
|
||||
try:
|
||||
return json.loads(to_native(open_url(search_url, method='GET', http_agent=self.http_agent, headers=self.restheaders,
|
||||
timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def get_authz_policy_by_name(self, name, client_id, realm):
|
||||
"""Get authorization policy by name"""
|
||||
url = URL_AUTHZ_POLICIES.format(url=self.baseurl, client_id=client_id, realm=realm)
|
||||
search_url = "%s/search?name=%s&permission=false" % (url, name.replace(' ', '%20'))
|
||||
|
||||
try:
|
||||
return json.loads(to_native(open_url(search_url, method='GET', http_agent=self.http_agent, headers=self.restheaders,
|
||||
timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
@@ -42,11 +42,17 @@ def gen_specs(**specs):
|
||||
'validate_certs': dict(default=True, type='bool'),
|
||||
'sasl_class': dict(choices=['external', 'gssapi'], default='external', type='str'),
|
||||
'xorder_discovery': dict(choices=['enable', 'auto', 'disable'], default='auto', type='str'),
|
||||
'client_cert': dict(default=None, type='path'),
|
||||
'client_key': dict(default=None, type='path'),
|
||||
})
|
||||
|
||||
return specs
|
||||
|
||||
|
||||
def ldap_required_together():
|
||||
return [['client_cert', 'client_key']]
|
||||
|
||||
|
||||
class LdapGeneric(object):
|
||||
def __init__(self, module):
|
||||
# Shortcuts
|
||||
@@ -60,6 +66,8 @@ class LdapGeneric(object):
|
||||
self.verify_cert = self.module.params['validate_certs']
|
||||
self.sasl_class = self.module.params['sasl_class']
|
||||
self.xorder_discovery = self.module.params['xorder_discovery']
|
||||
self.client_cert = self.module.params['client_cert']
|
||||
self.client_key = self.module.params['client_key']
|
||||
|
||||
# Establish connection
|
||||
self.connection = self._connect_to_ldap()
|
||||
@@ -102,6 +110,10 @@ class LdapGeneric(object):
|
||||
if self.ca_path:
|
||||
ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, self.ca_path)
|
||||
|
||||
if self.client_cert and self.client_key:
|
||||
ldap.set_option(ldap.OPT_X_TLS_CERTFILE, self.client_cert)
|
||||
ldap.set_option(ldap.OPT_X_TLS_KEYFILE, self.client_key)
|
||||
|
||||
connection = ldap.initialize(self.server_uri)
|
||||
|
||||
if self.referrals_chasing == 'disabled':
|
||||
|
||||
31
plugins/module_utils/locale_gen.py
Normal file
31
plugins/module_utils/locale_gen.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2023, Alexei Znamensky <russoz@gmail.com>
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt
|
||||
|
||||
|
||||
def locale_runner(module):
|
||||
runner = CmdRunner(
|
||||
module,
|
||||
command=["locale", "-a"],
|
||||
check_rc=True,
|
||||
)
|
||||
return runner
|
||||
|
||||
|
||||
def locale_gen_runner(module):
|
||||
runner = CmdRunner(
|
||||
module,
|
||||
command="locale-gen",
|
||||
arg_formats=dict(
|
||||
name=cmd_runner_fmt.as_list(),
|
||||
purge=cmd_runner_fmt.as_fixed('--purge'),
|
||||
),
|
||||
check_rc=True,
|
||||
)
|
||||
return runner
|
||||
@@ -52,6 +52,8 @@ class DependencyMixin(ModuleHelperBase):
|
||||
return cls._dependencies[-1]
|
||||
|
||||
def fail_on_missing_deps(self):
|
||||
if not self._dependencies:
|
||||
return
|
||||
self.module.deprecate(
|
||||
'The DependencyMixin is being deprecated. '
|
||||
'Modules should use community.general.plugins.module_utils.deps instead.',
|
||||
|
||||
@@ -11,6 +11,13 @@ import copy
|
||||
|
||||
|
||||
class VarMeta(object):
|
||||
"""
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 10.0.0
|
||||
Modules should use the VarDict from plugins/module_utils/vardict.py instead.
|
||||
"""
|
||||
|
||||
NOTHING = object()
|
||||
|
||||
def __init__(self, diff=False, output=True, change=None, fact=False):
|
||||
@@ -60,6 +67,12 @@ class VarMeta(object):
|
||||
|
||||
|
||||
class VarDict(object):
|
||||
"""
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 10.0.0
|
||||
Modules should use the VarDict from plugins/module_utils/vardict.py instead.
|
||||
"""
|
||||
def __init__(self):
|
||||
self._data = dict()
|
||||
self._meta = dict()
|
||||
@@ -123,7 +136,12 @@ class VarDict(object):
|
||||
|
||||
|
||||
class VarsMixin(object):
|
||||
"""
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 10.0.0
|
||||
Modules should use the VarDict from plugins/module_utils/vardict.py instead.
|
||||
"""
|
||||
def __init__(self, module=None):
|
||||
self.vars = VarDict()
|
||||
super(VarsMixin, self).__init__(module)
|
||||
|
||||
@@ -18,6 +18,7 @@ import traceback
|
||||
PROXMOXER_IMP_ERR = None
|
||||
try:
|
||||
from proxmoxer import ProxmoxAPI
|
||||
from proxmoxer import __version__ as proxmoxer_version
|
||||
HAS_PROXMOXER = True
|
||||
except ImportError:
|
||||
HAS_PROXMOXER = False
|
||||
@@ -80,6 +81,7 @@ class ProxmoxAnsible(object):
|
||||
|
||||
self.module = module
|
||||
self.proxmox_api = self._connect()
|
||||
self.proxmoxer_version = proxmoxer_version
|
||||
# Test token validity
|
||||
try:
|
||||
self.proxmox_api.version.get()
|
||||
@@ -98,6 +100,8 @@ class ProxmoxAnsible(object):
|
||||
if api_password:
|
||||
auth_args['password'] = api_password
|
||||
else:
|
||||
if self.version() < LooseVersion('1.1.0'):
|
||||
self.module.fail_json('Using "token_name" and "token_value" require proxmoxer>=1.1.0')
|
||||
auth_args['token_name'] = api_token_id
|
||||
auth_args['token_value'] = api_token_secret
|
||||
|
||||
@@ -107,19 +111,30 @@ class ProxmoxAnsible(object):
|
||||
self.module.fail_json(msg='%s' % e, exception=traceback.format_exc())
|
||||
|
||||
def version(self):
|
||||
apireturn = self.proxmox_api.version.get()
|
||||
return LooseVersion(apireturn['version'])
|
||||
try:
|
||||
apiversion = self.proxmox_api.version.get()
|
||||
return LooseVersion(apiversion['version'])
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Unable to retrieve Proxmox VE version: %s' % e)
|
||||
|
||||
def get_node(self, node):
|
||||
nodes = [n for n in self.proxmox_api.nodes.get() if n['node'] == node]
|
||||
try:
|
||||
nodes = [n for n in self.proxmox_api.nodes.get() if n['node'] == node]
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Unable to retrieve Proxmox VE node: %s' % e)
|
||||
return nodes[0] if nodes else None
|
||||
|
||||
def get_nextvmid(self):
|
||||
vmid = self.proxmox_api.cluster.nextid.get()
|
||||
return vmid
|
||||
try:
|
||||
return self.proxmox_api.cluster.nextid.get()
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Unable to retrieve next free vmid: %s' % e)
|
||||
|
||||
def get_vmid(self, name, ignore_missing=False, choose_first_if_multiple=False):
|
||||
vms = [vm['vmid'] for vm in self.proxmox_api.cluster.resources.get(type='vm') if vm.get('name') == name]
|
||||
try:
|
||||
vms = [vm['vmid'] for vm in self.proxmox_api.cluster.resources.get(type='vm') if vm.get('name') == name]
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Unable to retrieve list of VMs filtered by name %s: %s' % (name, e))
|
||||
|
||||
if not vms:
|
||||
if ignore_missing:
|
||||
@@ -132,7 +147,10 @@ class ProxmoxAnsible(object):
|
||||
return vms[0]
|
||||
|
||||
def get_vm(self, vmid, ignore_missing=False):
|
||||
vms = [vm for vm in self.proxmox_api.cluster.resources.get(type='vm') if vm['vmid'] == int(vmid)]
|
||||
try:
|
||||
vms = [vm for vm in self.proxmox_api.cluster.resources.get(type='vm') if vm['vmid'] == int(vmid)]
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Unable to retrieve list of VMs filtered by vmid %s: %s' % (vmid, e))
|
||||
|
||||
if vms:
|
||||
return vms[0]
|
||||
@@ -143,5 +161,30 @@ class ProxmoxAnsible(object):
|
||||
self.module.fail_json(msg='VM with vmid %s does not exist in cluster' % vmid)
|
||||
|
||||
def api_task_ok(self, node, taskid):
|
||||
status = self.proxmox_api.nodes(node).tasks(taskid).status.get()
|
||||
return status['status'] == 'stopped' and status['exitstatus'] == 'OK'
|
||||
try:
|
||||
status = self.proxmox_api.nodes(node).tasks(taskid).status.get()
|
||||
return status['status'] == 'stopped' and status['exitstatus'] == 'OK'
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Unable to retrieve API task ID from node %s: %s' % (node, e))
|
||||
|
||||
def get_pool(self, poolid):
|
||||
"""Retrieve pool information
|
||||
|
||||
:param poolid: str - name of the pool
|
||||
:return: dict - pool information
|
||||
"""
|
||||
try:
|
||||
return self.proxmox_api.pools(poolid).get()
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Unable to retrieve pool %s information: %s" % (poolid, e))
|
||||
|
||||
def get_storages(self, type):
|
||||
"""Retrieve storages information
|
||||
|
||||
:param type: str, optional - type of storages
|
||||
:return: list of dicts - array of storages
|
||||
"""
|
||||
try:
|
||||
return self.proxmox_api.storage.get(type=type)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Unable to retrieve storages information with type %s: %s" % (type, e))
|
||||
|
||||
@@ -7,9 +7,14 @@ from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import string
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.module_utils.six import text_type
|
||||
from ansible.module_utils.six.moves import http_client
|
||||
from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlparse
|
||||
@@ -153,7 +158,7 @@ class RedfishUtils(object):
|
||||
'msg': "Failed GET request to '%s': '%s'" % (uri, to_text(e))}
|
||||
return {'ret': True, 'data': data, 'headers': headers, 'resp': resp}
|
||||
|
||||
def post_request(self, uri, pyld):
|
||||
def post_request(self, uri, pyld, multipart=False):
|
||||
req_headers = dict(POST_HEADERS)
|
||||
username, password, basic_auth = self._auth_params(req_headers)
|
||||
try:
|
||||
@@ -162,7 +167,14 @@ class RedfishUtils(object):
|
||||
# header since this can cause conflicts with some services
|
||||
if self.sessions_uri is not None and uri == (self.root_uri + self.sessions_uri):
|
||||
basic_auth = False
|
||||
resp = open_url(uri, data=json.dumps(pyld),
|
||||
if multipart:
|
||||
# Multipart requests require special handling to encode the request body
|
||||
multipart_encoder = self._prepare_multipart(pyld)
|
||||
data = multipart_encoder[0]
|
||||
req_headers['content-type'] = multipart_encoder[1]
|
||||
else:
|
||||
data = json.dumps(pyld)
|
||||
resp = open_url(uri, data=data,
|
||||
headers=req_headers, method="POST",
|
||||
url_username=username, url_password=password,
|
||||
force_basic_auth=basic_auth, validate_certs=False,
|
||||
@@ -298,6 +310,59 @@ class RedfishUtils(object):
|
||||
'msg': "Failed DELETE request to '%s': '%s'" % (uri, to_text(e))}
|
||||
return {'ret': True, 'resp': resp}
|
||||
|
||||
@staticmethod
|
||||
def _prepare_multipart(fields):
|
||||
"""Prepares a multipart body based on a set of fields provided.
|
||||
|
||||
Ideally it would have been good to use the existing 'prepare_multipart'
|
||||
found in ansible.module_utils.urls, but it takes files and encodes them
|
||||
as Base64 strings, which is not expected by Redfish services. It also
|
||||
adds escaping of certain bytes in the payload, such as inserting '\r'
|
||||
any time it finds a standlone '\n', which corrupts the image payload
|
||||
send to the service. This implementation is simplified to Redfish's
|
||||
usage and doesn't necessarily represent an exhaustive method of
|
||||
building multipart requests.
|
||||
"""
|
||||
|
||||
def write_buffer(body, line):
|
||||
# Adds to the multipart body based on the provided data type
|
||||
# At this time there is only support for strings, dictionaries, and bytes (default)
|
||||
if isinstance(line, text_type):
|
||||
body.append(to_bytes(line, encoding='utf-8'))
|
||||
elif isinstance(line, dict):
|
||||
body.append(to_bytes(json.dumps(line), encoding='utf-8'))
|
||||
else:
|
||||
body.append(line)
|
||||
return
|
||||
|
||||
# Generate a random boundary marker; may need to consider probing the
|
||||
# payload for potential conflicts in the future
|
||||
boundary = ''.join(random.choice(string.digits + string.ascii_letters) for i in range(30))
|
||||
body = []
|
||||
for form in fields:
|
||||
# Fill in the form details
|
||||
write_buffer(body, '--' + boundary)
|
||||
|
||||
# Insert the headers (Content-Disposition and Content-Type)
|
||||
if 'filename' in fields[form]:
|
||||
name = os.path.basename(fields[form]['filename']).replace('"', '\\"')
|
||||
write_buffer(body, u'Content-Disposition: form-data; name="%s"; filename="%s"' % (to_text(form), to_text(name)))
|
||||
else:
|
||||
write_buffer(body, 'Content-Disposition: form-data; name="%s"' % form)
|
||||
write_buffer(body, 'Content-Type: %s' % fields[form]['mime_type'])
|
||||
write_buffer(body, '')
|
||||
|
||||
# Insert the payload; read from the file if not given by the caller
|
||||
if 'content' not in fields[form]:
|
||||
with open(to_bytes(fields[form]['filename'], errors='surrogate_or_strict'), 'rb') as f:
|
||||
fields[form]['content'] = f.read()
|
||||
write_buffer(body, fields[form]['content'])
|
||||
|
||||
# Finalize the entire request
|
||||
write_buffer(body, '--' + boundary + '--')
|
||||
write_buffer(body, '')
|
||||
return (b'\r\n'.join(body), 'multipart/form-data; boundary=' + boundary)
|
||||
|
||||
@staticmethod
|
||||
def _get_extended_message(error):
|
||||
"""
|
||||
@@ -832,13 +897,13 @@ class RedfishUtils(object):
|
||||
if data.get('Members'):
|
||||
for controller in data[u'Members']:
|
||||
controller_list.append(controller[u'@odata.id'])
|
||||
for c in controller_list:
|
||||
for idx, c in enumerate(controller_list):
|
||||
uri = self.root_uri + c
|
||||
response = self.get_request(uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
data = response['data']
|
||||
controller_name = 'Controller 1'
|
||||
controller_name = 'Controller %s' % str(idx)
|
||||
if 'StorageControllers' in data:
|
||||
sc = data['StorageControllers']
|
||||
if sc:
|
||||
@@ -847,7 +912,26 @@ class RedfishUtils(object):
|
||||
else:
|
||||
sc_id = sc[0].get('Id', '1')
|
||||
controller_name = 'Controller %s' % sc_id
|
||||
elif 'Controllers' in data:
|
||||
response = self.get_request(self.root_uri + data['Controllers'][u'@odata.id'])
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
c_data = response['data']
|
||||
|
||||
if c_data.get('Members') and c_data['Members']:
|
||||
response = self.get_request(self.root_uri + c_data['Members'][0][u'@odata.id'])
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
member_data = response['data']
|
||||
|
||||
if member_data:
|
||||
if 'Name' in member_data:
|
||||
controller_name = member_data['Name']
|
||||
else:
|
||||
controller_id = member_data.get('Id', '1')
|
||||
controller_name = 'Controller %s' % controller_id
|
||||
volume_results = []
|
||||
volume_list = []
|
||||
if 'Volumes' in data:
|
||||
# Get a list of all volumes and build respective URIs
|
||||
volumes_uri = data[u'Volumes'][u'@odata.id']
|
||||
@@ -1056,7 +1140,8 @@ class RedfishUtils(object):
|
||||
user_list = []
|
||||
users_results = []
|
||||
# Get these entries, but does not fail if not found
|
||||
properties = ['Id', 'Name', 'UserName', 'RoleId', 'Locked', 'Enabled']
|
||||
properties = ['Id', 'Name', 'UserName', 'RoleId', 'Locked', 'Enabled',
|
||||
'AccountTypes', 'OEMAccountTypes']
|
||||
|
||||
response = self.get_request(self.root_uri + self.accounts_uri)
|
||||
if response['ret'] is False:
|
||||
@@ -1079,6 +1164,12 @@ class RedfishUtils(object):
|
||||
if property in data:
|
||||
user[property] = data[property]
|
||||
|
||||
# Filter out empty account slots
|
||||
# An empty account slot can be detected if the username is an empty
|
||||
# string and if the account is disabled
|
||||
if user.get('UserName', '') == '' and not user.get('Enabled', False):
|
||||
continue
|
||||
|
||||
users_results.append(user)
|
||||
result["entries"] = users_results
|
||||
return result
|
||||
@@ -1101,6 +1192,10 @@ class RedfishUtils(object):
|
||||
payload['Password'] = user.get('account_password')
|
||||
if user.get('account_roleid'):
|
||||
payload['RoleId'] = user.get('account_roleid')
|
||||
if user.get('account_accounttypes'):
|
||||
payload['AccountTypes'] = user.get('account_accounttypes')
|
||||
if user.get('account_oemaccounttypes'):
|
||||
payload['OEMAccountTypes'] = user.get('account_oemaccounttypes')
|
||||
return self.patch_request(self.root_uri + uri, payload, check_pyld=True)
|
||||
|
||||
def add_user(self, user):
|
||||
@@ -1131,6 +1226,10 @@ class RedfishUtils(object):
|
||||
payload['Password'] = user.get('account_password')
|
||||
if user.get('account_roleid'):
|
||||
payload['RoleId'] = user.get('account_roleid')
|
||||
if user.get('account_accounttypes'):
|
||||
payload['AccountTypes'] = user.get('account_accounttypes')
|
||||
if user.get('account_oemaccounttypes'):
|
||||
payload['OEMAccountTypes'] = user.get('account_oemaccounttypes')
|
||||
if user.get('account_id'):
|
||||
payload['Id'] = user.get('account_id')
|
||||
|
||||
@@ -1572,6 +1671,61 @@ class RedfishUtils(object):
|
||||
'msg': "SimpleUpdate requested",
|
||||
'update_status': self._operation_results(response['resp'], response['data'])}
|
||||
|
||||
def multipath_http_push_update(self, update_opts):
|
||||
"""
|
||||
Provides a software update via the URI specified by the
|
||||
MultipartHttpPushUri property. Callers should adjust the 'timeout'
|
||||
variable in the base object to accommodate the size of the image and
|
||||
speed of the transfer. For example, a 200MB image will likely take
|
||||
more than the default 10 second timeout.
|
||||
|
||||
:param update_opts: The parameters for the update operation
|
||||
:return: dict containing the response of the update request
|
||||
"""
|
||||
image_file = update_opts.get('update_image_file')
|
||||
targets = update_opts.get('update_targets')
|
||||
apply_time = update_opts.get('update_apply_time')
|
||||
|
||||
# Ensure the image file is provided
|
||||
if not image_file:
|
||||
return {'ret': False, 'msg':
|
||||
'Must specify update_image_file for the MultipartHTTPPushUpdate command'}
|
||||
if not os.path.isfile(image_file):
|
||||
return {'ret': False, 'msg':
|
||||
'Must specify a valid file for the MultipartHTTPPushUpdate command'}
|
||||
try:
|
||||
with open(image_file, 'rb') as f:
|
||||
image_payload = f.read()
|
||||
except Exception as e:
|
||||
return {'ret': False, 'msg':
|
||||
'Could not read file %s' % image_file}
|
||||
|
||||
# Check that multipart HTTP push updates are supported
|
||||
response = self.get_request(self.root_uri + self.update_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
data = response['data']
|
||||
if 'MultipartHttpPushUri' not in data:
|
||||
return {'ret': False, 'msg': 'Service does not support MultipartHttpPushUri'}
|
||||
update_uri = data['MultipartHttpPushUri']
|
||||
|
||||
# Assemble the JSON payload portion of the request
|
||||
payload = {"@Redfish.OperationApplyTime": "Immediate"}
|
||||
if targets:
|
||||
payload["Targets"] = targets
|
||||
if apply_time:
|
||||
payload["@Redfish.OperationApplyTime"] = apply_time
|
||||
multipart_payload = {
|
||||
'UpdateParameters': {'content': json.dumps(payload), 'mime_type': 'application/json'},
|
||||
'UpdateFile': {'filename': image_file, 'content': image_payload, 'mime_type': 'application/octet-stream'}
|
||||
}
|
||||
response = self.post_request(self.root_uri + update_uri, multipart_payload, multipart=True)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
return {'ret': True, 'changed': True,
|
||||
'msg': "MultipartHTTPPushUpdate requested",
|
||||
'update_status': self._operation_results(response['resp'], response['data'])}
|
||||
|
||||
def get_update_status(self, update_handle):
|
||||
"""
|
||||
Gets the status of an update operation.
|
||||
@@ -2142,7 +2296,7 @@ class RedfishUtils(object):
|
||||
key = "Processors"
|
||||
# Get these entries, but does not fail if not found
|
||||
properties = ['Id', 'Name', 'Manufacturer', 'Model', 'MaxSpeedMHz',
|
||||
'TotalCores', 'TotalThreads', 'Status']
|
||||
'ProcessorArchitecture', 'TotalCores', 'TotalThreads', 'Status']
|
||||
|
||||
# Search for 'key' entry and extract URI from it
|
||||
response = self.get_request(self.root_uri + systems_uri)
|
||||
|
||||
@@ -24,6 +24,14 @@ from ansible.module_utils.six.moves import configparser
|
||||
|
||||
|
||||
class RegistrationBase(object):
|
||||
"""
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 10.0.0.
|
||||
There is no replacement for it; please contact the community.general
|
||||
maintainers in case you are using it.
|
||||
"""
|
||||
|
||||
def __init__(self, module, username=None, password=None):
|
||||
self.module = module
|
||||
self.username = username
|
||||
@@ -71,10 +79,23 @@ class RegistrationBase(object):
|
||||
|
||||
|
||||
class Rhsm(RegistrationBase):
|
||||
"""
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 9.0.0.
|
||||
There is no replacement for it; please contact the community.general
|
||||
maintainers in case you are using it.
|
||||
"""
|
||||
|
||||
def __init__(self, module, username=None, password=None):
|
||||
RegistrationBase.__init__(self, module, username, password)
|
||||
self.config = self._read_config()
|
||||
self.module = module
|
||||
self.module.deprecate(
|
||||
'The Rhsm class is deprecated with no replacement.',
|
||||
version='9.0.0',
|
||||
collection_name='community.general',
|
||||
)
|
||||
|
||||
def _read_config(self, rhsm_conf='/etc/rhsm/rhsm.conf'):
|
||||
'''
|
||||
@@ -200,14 +221,25 @@ class Rhsm(RegistrationBase):
|
||||
|
||||
|
||||
class RhsmPool(object):
|
||||
'''
|
||||
Convenience class for housing subscription information
|
||||
'''
|
||||
"""
|
||||
Convenience class for housing subscription information
|
||||
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 9.0.0.
|
||||
There is no replacement for it; please contact the community.general
|
||||
maintainers in case you are using it.
|
||||
"""
|
||||
|
||||
def __init__(self, module, **kwargs):
|
||||
self.module = module
|
||||
for k, v in kwargs.items():
|
||||
setattr(self, k, v)
|
||||
self.module.deprecate(
|
||||
'The RhsmPool class is deprecated with no replacement.',
|
||||
version='9.0.0',
|
||||
collection_name='community.general',
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.__getattribute__('_name'))
|
||||
@@ -223,11 +255,23 @@ class RhsmPool(object):
|
||||
|
||||
class RhsmPools(object):
|
||||
"""
|
||||
This class is used for manipulating pools subscriptions with RHSM
|
||||
This class is used for manipulating pools subscriptions with RHSM
|
||||
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 9.0.0.
|
||||
There is no replacement for it; please contact the community.general
|
||||
maintainers in case you are using it.
|
||||
"""
|
||||
|
||||
def __init__(self, module):
|
||||
self.module = module
|
||||
self.products = self._load_product_list()
|
||||
self.module.deprecate(
|
||||
'The RhsmPools class is deprecated with no replacement.',
|
||||
version='9.0.0',
|
||||
collection_name='community.general',
|
||||
)
|
||||
|
||||
def __iter__(self):
|
||||
return self.products.__iter__()
|
||||
|
||||
@@ -20,6 +20,7 @@ _state_map = dict(
|
||||
absent='remove',
|
||||
enabled='enable',
|
||||
disabled='disable',
|
||||
refresh='refresh',
|
||||
)
|
||||
|
||||
|
||||
@@ -38,6 +39,8 @@ def snap_runner(module, **kwargs):
|
||||
classic=cmd_runner_fmt.as_bool("--classic"),
|
||||
channel=cmd_runner_fmt.as_func(lambda v: [] if v == 'stable' else ['--channel', '{0}'.format(v)]),
|
||||
options=cmd_runner_fmt.as_list(),
|
||||
info=cmd_runner_fmt.as_fixed("info"),
|
||||
dangerous=cmd_runner_fmt.as_bool("--dangerous"),
|
||||
),
|
||||
check_rc=False,
|
||||
**kwargs
|
||||
|
||||
178
plugins/module_utils/vardict.py
Normal file
178
plugins/module_utils/vardict.py
Normal file
@@ -0,0 +1,178 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) 2023, Alexei Znamensky <russoz@gmail.com>
|
||||
# Copyright (c) 2023, Ansible Project
|
||||
# Simplified BSD License (see LICENSES/BSD-2-Clause.txt or https://opensource.org/licenses/BSD-2-Clause)
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
import copy
|
||||
|
||||
|
||||
class _Variable(object):
|
||||
NOTHING = object()
|
||||
|
||||
def __init__(self, diff=False, output=True, change=None, fact=False, verbosity=0):
|
||||
self.init = False
|
||||
self.initial_value = None
|
||||
self.value = None
|
||||
|
||||
self.diff = None
|
||||
self._change = None
|
||||
self.output = None
|
||||
self.fact = None
|
||||
self._verbosity = None
|
||||
self.set_meta(output=output, diff=diff, change=change, fact=fact, verbosity=verbosity)
|
||||
|
||||
def getchange(self):
|
||||
return self.diff if self._change is None else self._change
|
||||
|
||||
def setchange(self, value):
|
||||
self._change = value
|
||||
|
||||
def getverbosity(self):
|
||||
return self._verbosity
|
||||
|
||||
def setverbosity(self, v):
|
||||
if not (0 <= v <= 4):
|
||||
raise ValueError("verbosity must be an int in the range 0 to 4")
|
||||
self._verbosity = v
|
||||
|
||||
change = property(getchange, setchange)
|
||||
verbosity = property(getverbosity, setverbosity)
|
||||
|
||||
def set_meta(self, output=None, diff=None, change=None, fact=None, initial_value=NOTHING, verbosity=None):
|
||||
"""Set the metadata for the variable
|
||||
|
||||
Args:
|
||||
output (bool, optional): flag indicating whether the variable should be in the output of the module. Defaults to None.
|
||||
diff (bool, optional): flag indicating whether to generate diff mode output for this variable. Defaults to None.
|
||||
change (bool, optional): flag indicating whether to track if changes happened to this variable. Defaults to None.
|
||||
fact (bool, optional): flag indicating whether the varaiable should be exposed as a fact of the module. Defaults to None.
|
||||
initial_value (any, optional): initial value of the variable, to be used with `change`. Defaults to NOTHING.
|
||||
verbosity (int, optional): level of verbosity in which this variable is reported by the module as `output`, `fact` or `diff`. Defaults to None.
|
||||
"""
|
||||
if output is not None:
|
||||
self.output = output
|
||||
if change is not None:
|
||||
self.change = change
|
||||
if diff is not None:
|
||||
self.diff = diff
|
||||
if fact is not None:
|
||||
self.fact = fact
|
||||
if initial_value is not _Variable.NOTHING:
|
||||
self.initial_value = copy.deepcopy(initial_value)
|
||||
if verbosity is not None:
|
||||
self.verbosity = verbosity
|
||||
|
||||
def set_value(self, value):
|
||||
if not self.init:
|
||||
self.initial_value = copy.deepcopy(value)
|
||||
self.init = True
|
||||
self.value = value
|
||||
return self
|
||||
|
||||
def is_visible(self, verbosity):
|
||||
return self.verbosity <= verbosity
|
||||
|
||||
@property
|
||||
def has_changed(self):
|
||||
return self.change and (self.initial_value != self.value)
|
||||
|
||||
@property
|
||||
def diff_result(self):
|
||||
if self.diff and self.has_changed:
|
||||
return {'before': self.initial_value, 'after': self.value}
|
||||
return
|
||||
|
||||
def __str__(self):
|
||||
return "<_Variable: value={0!r}, initial={1!r}, diff={2}, output={3}, change={4}, verbosity={5}>".format(
|
||||
self.value, self.initial_value, self.diff, self.output, self.change, self.verbosity
|
||||
)
|
||||
|
||||
|
||||
class VarDict(object):
|
||||
reserved_names = ('__vars__', 'var', 'set_meta', 'set', 'output', 'diff', 'facts', 'has_changed')
|
||||
|
||||
def __init__(self):
|
||||
self.__vars__ = dict()
|
||||
|
||||
def __getitem__(self, item):
|
||||
return self.__vars__[item].value
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self.set(key, value)
|
||||
|
||||
def __getattr__(self, item):
|
||||
try:
|
||||
return self.__vars__[item].value
|
||||
except KeyError:
|
||||
return getattr(super(VarDict, self), item)
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
if key == '__vars__':
|
||||
super(VarDict, self).__setattr__(key, value)
|
||||
else:
|
||||
self.set(key, value)
|
||||
|
||||
def _var(self, name):
|
||||
return self.__vars__[name]
|
||||
|
||||
def set_meta(self, name, **kwargs):
|
||||
"""Set the metadata for the variable
|
||||
|
||||
Args:
|
||||
name (str): name of the variable having its metadata changed
|
||||
output (bool, optional): flag indicating whether the variable should be in the output of the module. Defaults to None.
|
||||
diff (bool, optional): flag indicating whether to generate diff mode output for this variable. Defaults to None.
|
||||
change (bool, optional): flag indicating whether to track if changes happened to this variable. Defaults to None.
|
||||
fact (bool, optional): flag indicating whether the varaiable should be exposed as a fact of the module. Defaults to None.
|
||||
initial_value (any, optional): initial value of the variable, to be used with `change`. Defaults to NOTHING.
|
||||
verbosity (int, optional): level of verbosity in which this variable is reported by the module as `output`, `fact` or `diff`. Defaults to None.
|
||||
"""
|
||||
self._var(name).set_meta(**kwargs)
|
||||
|
||||
def set(self, name, value, **kwargs):
|
||||
"""Set the value and optionally metadata for a variable. The variable is not required to exist prior to calling `set`.
|
||||
|
||||
For details on the accepted metada see the documentation for method `set_meta`.
|
||||
|
||||
Args:
|
||||
name (str): name of the variable being changed
|
||||
value (any): the value of the variable, it can be of any type
|
||||
|
||||
Raises:
|
||||
ValueError: Raised if trying to set a variable with a reserved name.
|
||||
"""
|
||||
if name in self.reserved_names:
|
||||
raise ValueError("Name {0} is reserved".format(name))
|
||||
if name in self.__vars__:
|
||||
var = self._var(name)
|
||||
var.set_meta(**kwargs)
|
||||
else:
|
||||
var = _Variable(**kwargs)
|
||||
var.set_value(value)
|
||||
self.__vars__[name] = var
|
||||
|
||||
def output(self, verbosity=0):
|
||||
return dict((n, v.value) for n, v in self.__vars__.items() if v.output and v.is_visible(verbosity))
|
||||
|
||||
def diff(self, verbosity=0):
|
||||
diff_results = [(n, v.diff_result) for n, v in self.__vars__.items() if v.diff_result and v.is_visible(verbosity)]
|
||||
if diff_results:
|
||||
before = dict((n, dr['before']) for n, dr in diff_results)
|
||||
after = dict((n, dr['after']) for n, dr in diff_results)
|
||||
return {'before': before, 'after': after}
|
||||
return None
|
||||
|
||||
def facts(self, verbosity=0):
|
||||
facts_result = dict((n, v.value) for n, v in self.__vars__.items() if v.fact and v.is_visible(verbosity))
|
||||
return facts_result if facts_result else None
|
||||
|
||||
@property
|
||||
def has_changed(self):
|
||||
return any(True for var in self.__vars__.values() if var.has_changed)
|
||||
|
||||
def as_dict(self):
|
||||
return dict((name, var.value) for name, var in self.__vars__.items())
|
||||
@@ -72,7 +72,7 @@ options:
|
||||
type: str
|
||||
validate_certs:
|
||||
description:
|
||||
- If C(false), SSL certificates for the target url will not be validated. This should only be used
|
||||
- If V(false), SSL certificates for the target url will not be validated. This should only be used
|
||||
on personally controlled sites using self-signed certificates.
|
||||
required: false
|
||||
default: true
|
||||
|
||||
@@ -31,7 +31,7 @@ options:
|
||||
device:
|
||||
description:
|
||||
- The name of the device.
|
||||
- C(all) is valid to rescan C(available) all devices (AIX cfgmgr command).
|
||||
- V(all) is valid to rescan C(available) all devices (AIX cfgmgr command).
|
||||
type: str
|
||||
force:
|
||||
description:
|
||||
@@ -46,9 +46,9 @@ options:
|
||||
state:
|
||||
description:
|
||||
- Controls the device state.
|
||||
- C(available) (alias C(present)) rescan a specific device or all devices (when C(device) is not specified).
|
||||
- C(removed) (alias C(absent) removes a device.
|
||||
- C(defined) changes device to Defined state.
|
||||
- V(available) (alias V(present)) rescan a specific device or all devices (when O(device) is not specified).
|
||||
- V(removed) (alias V(absent) removes a device.
|
||||
- V(defined) changes device to Defined state.
|
||||
type: str
|
||||
choices: [ available, defined, removed ]
|
||||
default: available
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user