mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-30 10:26:52 +00:00
Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
adddf455fb | ||
|
|
0e3d9e1497 | ||
|
|
fec312eb54 | ||
|
|
f7b1393752 | ||
|
|
6f8d1849b5 | ||
|
|
6a4bc401c5 | ||
|
|
f5f1a33a7e | ||
|
|
0b0a4b0eaa | ||
|
|
24e5bf3d5b | ||
|
|
4f0b5b88a1 | ||
|
|
be4e7fc374 | ||
|
|
ba9f295b3f | ||
|
|
4b4a2a5977 | ||
|
|
5a1ee4e3ee | ||
|
|
11c0f9642c | ||
|
|
e42353d690 | ||
|
|
5af750d06b | ||
|
|
f745dd369e | ||
|
|
745c7a856e | ||
|
|
4e1e5a92e3 | ||
|
|
12b39987a0 | ||
|
|
32338f14e5 | ||
|
|
2583e3993d | ||
|
|
e4cef5cb24 | ||
|
|
cde2be8100 | ||
|
|
40ce650d08 | ||
|
|
c09b5e2c66 | ||
|
|
a618203c01 | ||
|
|
882ce25ce2 | ||
|
|
25a6603059 | ||
|
|
065287f260 | ||
|
|
b0cf8ce6e7 | ||
|
|
68eb07a900 | ||
|
|
a7d8397449 | ||
|
|
c71274639d | ||
|
|
5ef9476207 | ||
|
|
36edaaa6ea | ||
|
|
5c80ff00ab | ||
|
|
a45cb0ca04 | ||
|
|
838ff55003 | ||
|
|
8927dc777a | ||
|
|
baeae01797 | ||
|
|
c3df54689c | ||
|
|
e043274ced | ||
|
|
1355b8d533 | ||
|
|
5ea46a581d | ||
|
|
a8be2e2a58 | ||
|
|
07fa35791f | ||
|
|
06a3e3708d | ||
|
|
56532388fd | ||
|
|
6d09a3588e | ||
|
|
a73404ae3f | ||
|
|
ddf566a729 | ||
|
|
0c676df7cf | ||
|
|
3dcdd3b59e | ||
|
|
8b2e658fc0 | ||
|
|
9bf146a67a | ||
|
|
567b573971 | ||
|
|
b7b781a2be | ||
|
|
f852ac90a2 |
@@ -59,14 +59,14 @@ pool: Standard
|
||||
|
||||
stages:
|
||||
### Sanity
|
||||
- stage: Sanity_devel
|
||||
displayName: Sanity devel
|
||||
- stage: Sanity_2_17
|
||||
displayName: Sanity 2.17
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Test {0}
|
||||
testFormat: devel/sanity/{0}
|
||||
testFormat: 2.17/sanity/{0}
|
||||
targets:
|
||||
- test: 1
|
||||
- test: 2
|
||||
@@ -99,28 +99,15 @@ stages:
|
||||
- test: 2
|
||||
- test: 3
|
||||
- test: 4
|
||||
- stage: Sanity_2_14
|
||||
displayName: Sanity 2.14
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Test {0}
|
||||
testFormat: 2.14/sanity/{0}
|
||||
targets:
|
||||
- test: 1
|
||||
- test: 2
|
||||
- test: 3
|
||||
- test: 4
|
||||
### Units
|
||||
- stage: Units_devel
|
||||
displayName: Units devel
|
||||
- stage: Units_2_17
|
||||
displayName: Units 2.17
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: devel/units/{0}/1
|
||||
testFormat: 2.17/units/{0}/1
|
||||
targets:
|
||||
- test: 3.7
|
||||
- test: 3.8
|
||||
@@ -151,48 +138,40 @@ stages:
|
||||
targets:
|
||||
- test: 3.5
|
||||
- test: "3.10"
|
||||
- stage: Units_2_14
|
||||
displayName: Units 2.14
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: 2.14/units/{0}/1
|
||||
targets:
|
||||
- test: 3.9
|
||||
|
||||
## Remote
|
||||
- stage: Remote_devel_extra_vms
|
||||
displayName: Remote devel extra VMs
|
||||
- stage: Remote_2_17_extra_vms
|
||||
displayName: Remote 2.17 extra VMs
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: devel/{0}
|
||||
testFormat: 2.17/{0}
|
||||
targets:
|
||||
- name: Alpine 3.18
|
||||
test: alpine/3.18
|
||||
- name: Alpine 3.19
|
||||
test: alpine/3.19
|
||||
# - name: Fedora 39
|
||||
# test: fedora/39
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu/22.04
|
||||
groups:
|
||||
- vm
|
||||
- stage: Remote_devel
|
||||
displayName: Remote devel
|
||||
- stage: Remote_2_17
|
||||
displayName: Remote 2.17
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: devel/{0}
|
||||
testFormat: 2.17/{0}
|
||||
targets:
|
||||
- name: macOS 13.2
|
||||
test: macos/13.2
|
||||
- name: macOS 14.3
|
||||
test: macos/14.3
|
||||
- name: RHEL 9.3
|
||||
test: rhel/9.3
|
||||
- name: FreeBSD 13.2
|
||||
test: freebsd/13.2
|
||||
- name: FreeBSD 13.3
|
||||
test: freebsd/13.3
|
||||
- name: FreeBSD 14.0
|
||||
test: freebsd/14.0
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
@@ -205,14 +184,14 @@ stages:
|
||||
parameters:
|
||||
testFormat: 2.16/{0}
|
||||
targets:
|
||||
#- name: macOS 13.2
|
||||
# test: macos/13.2
|
||||
- name: macOS 13.2
|
||||
test: macos/13.2
|
||||
- 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 13.2
|
||||
test: freebsd/13.2
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
@@ -239,33 +218,15 @@ stages:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- stage: Remote_2_14
|
||||
displayName: Remote 2.14
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: 2.14/{0}
|
||||
targets:
|
||||
- name: RHEL 9.0
|
||||
test: rhel/9.0
|
||||
#- name: macOS 12.0
|
||||
# test: macos/12.0
|
||||
#- name: FreeBSD 12.4
|
||||
# test: freebsd/12.4
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
|
||||
### Docker
|
||||
- stage: Docker_devel
|
||||
displayName: Docker devel
|
||||
- stage: Docker_2_17
|
||||
displayName: Docker 2.17
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: devel/linux/{0}
|
||||
testFormat: 2.17/linux/{0}
|
||||
targets:
|
||||
- name: Fedora 39
|
||||
test: fedora39
|
||||
@@ -273,8 +234,8 @@ stages:
|
||||
test: ubuntu2004
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu2204
|
||||
- name: Alpine 3
|
||||
test: alpine3
|
||||
- name: Alpine 3.19
|
||||
test: alpine319
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
@@ -291,6 +252,8 @@ stages:
|
||||
test: fedora38
|
||||
- name: openSUSE 15
|
||||
test: opensuse15
|
||||
- name: Alpine 3
|
||||
test: alpine3
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
@@ -311,50 +274,36 @@ stages:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- stage: Docker_2_14
|
||||
displayName: Docker 2.14
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: 2.14/linux/{0}
|
||||
targets:
|
||||
- name: Alpine 3
|
||||
test: alpine3
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
|
||||
### Community Docker
|
||||
- stage: Docker_community_devel
|
||||
displayName: Docker (community images) devel
|
||||
- stage: Docker_community_2_17
|
||||
displayName: Docker (community images) 2.17
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: devel/linux-community/{0}
|
||||
testFormat: 2.17/linux-community/{0}
|
||||
targets:
|
||||
- name: Debian Bullseye
|
||||
test: debian-bullseye/3.9
|
||||
- name: Debian Bookworm
|
||||
test: debian-bookworm/3.11
|
||||
- name: ArchLinux
|
||||
test: archlinux/3.11
|
||||
test: archlinux/3.12
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
|
||||
### Generic
|
||||
- stage: Generic_devel
|
||||
displayName: Generic devel
|
||||
- stage: Generic_2_17
|
||||
displayName: Generic 2.17
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: devel/generic/{0}/1
|
||||
testFormat: 2.17/generic/{0}/1
|
||||
targets:
|
||||
- test: '3.7'
|
||||
- test: '3.12'
|
||||
@@ -380,42 +329,27 @@ stages:
|
||||
testFormat: 2.15/generic/{0}/1
|
||||
targets:
|
||||
- test: '3.9'
|
||||
- stage: Generic_2_14
|
||||
displayName: Generic 2.14
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: 2.14/generic/{0}/1
|
||||
targets:
|
||||
- test: '3.10'
|
||||
|
||||
- stage: Summary
|
||||
condition: succeededOrFailed()
|
||||
dependsOn:
|
||||
- Sanity_devel
|
||||
- Sanity_2_17
|
||||
- Sanity_2_16
|
||||
- Sanity_2_15
|
||||
- Sanity_2_14
|
||||
- Units_devel
|
||||
- Units_2_17
|
||||
- Units_2_16
|
||||
- Units_2_15
|
||||
- Units_2_14
|
||||
- Remote_devel_extra_vms
|
||||
- Remote_devel
|
||||
- Remote_2_17_extra_vms
|
||||
- Remote_2_17
|
||||
- Remote_2_16
|
||||
- Remote_2_15
|
||||
- Remote_2_14
|
||||
- Docker_devel
|
||||
- Docker_2_17
|
||||
- Docker_2_16
|
||||
- Docker_2_15
|
||||
- Docker_2_14
|
||||
- Docker_community_devel
|
||||
- Docker_community_2_17
|
||||
# Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled.
|
||||
# - Generic_devel
|
||||
# - Generic_2_17
|
||||
# - Generic_2_16
|
||||
# - Generic_2_15
|
||||
# - Generic_2_14
|
||||
jobs:
|
||||
- template: templates/coverage.yml
|
||||
|
||||
5
.github/BOTMETA.yml
vendored
5
.github/BOTMETA.yml
vendored
@@ -1395,6 +1395,8 @@ files:
|
||||
ignore: matze
|
||||
labels: zypper
|
||||
maintainers: $team_suse
|
||||
$plugin_utils/unsafe.py:
|
||||
maintainers: felixfontein
|
||||
$tests/a_module.py:
|
||||
maintainers: felixfontein
|
||||
#########################
|
||||
@@ -1414,7 +1416,6 @@ macros:
|
||||
becomes: plugins/become
|
||||
caches: plugins/cache
|
||||
callbacks: plugins/callback
|
||||
cliconfs: plugins/cliconf
|
||||
connections: plugins/connection
|
||||
doc_fragments: plugins/doc_fragments
|
||||
filters: plugins/filter
|
||||
@@ -1422,7 +1423,7 @@ macros:
|
||||
lookups: plugins/lookup
|
||||
module_utils: plugins/module_utils
|
||||
modules: plugins/modules
|
||||
terminals: plugins/terminal
|
||||
plugin_utils: plugins/plugin_utils
|
||||
tests: plugins/test
|
||||
team_ansible_core:
|
||||
team_aix: MorrisA bcoca d-little flynn1973 gforster kairoaraujo marvin-sinister mator molekuul ramooncamacho wtcross
|
||||
|
||||
24
.github/workflows/ansible-test.yml
vendored
24
.github/workflows/ansible-test.yml
vendored
@@ -32,6 +32,7 @@ jobs:
|
||||
- '2.11'
|
||||
- '2.12'
|
||||
- '2.13'
|
||||
- '2.14'
|
||||
# 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
|
||||
@@ -47,6 +48,7 @@ jobs:
|
||||
with:
|
||||
ansible-core-github-repository-slug: ${{ contains(fromJson('["2.10", "2.11"]'), matrix.ansible) && 'felixfontein/ansible' || 'ansible/ansible' }}
|
||||
ansible-core-version: stable-${{ matrix.ansible }}
|
||||
codecov-token: ${{ secrets.CODECOV_TOKEN }}
|
||||
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
|
||||
pull-request-change-detection: 'true'
|
||||
testing-type: sanity
|
||||
@@ -85,6 +87,8 @@ jobs:
|
||||
python: '2.7'
|
||||
- ansible: '2.13'
|
||||
python: '3.8'
|
||||
- ansible: '2.14'
|
||||
python: '3.9'
|
||||
|
||||
steps:
|
||||
- name: >-
|
||||
@@ -94,6 +98,7 @@ jobs:
|
||||
with:
|
||||
ansible-core-github-repository-slug: ${{ contains(fromJson('["2.10", "2.11"]'), matrix.ansible) && 'felixfontein/ansible' || 'ansible/ansible' }}
|
||||
ansible-core-version: stable-${{ matrix.ansible }}
|
||||
codecov-token: ${{ secrets.CODECOV_TOKEN }}
|
||||
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
|
||||
pre-test-cmd: >-
|
||||
mkdir -p ../../ansible
|
||||
@@ -258,6 +263,24 @@ jobs:
|
||||
# docker: default
|
||||
# python: '3.9'
|
||||
# target: azp/generic/1/
|
||||
# 2.14
|
||||
- ansible: '2.14'
|
||||
docker: alpine3
|
||||
python: ''
|
||||
target: azp/posix/1/
|
||||
- ansible: '2.14'
|
||||
docker: alpine3
|
||||
python: ''
|
||||
target: azp/posix/2/
|
||||
- ansible: '2.14'
|
||||
docker: alpine3
|
||||
python: ''
|
||||
target: azp/posix/3/
|
||||
# Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled.
|
||||
# - ansible: '2.14'
|
||||
# docker: default
|
||||
# python: '3.10'
|
||||
# target: azp/generic/1/
|
||||
|
||||
steps:
|
||||
- name: >-
|
||||
@@ -268,6 +291,7 @@ jobs:
|
||||
with:
|
||||
ansible-core-github-repository-slug: ${{ contains(fromJson('["2.10", "2.11"]'), matrix.ansible) && 'felixfontein/ansible' || 'ansible/ansible' }}
|
||||
ansible-core-version: stable-${{ matrix.ansible }}
|
||||
codecov-token: ${{ secrets.CODECOV_TOKEN }}
|
||||
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
|
||||
docker-image: ${{ matrix.docker }}
|
||||
integration-continue-on-error: 'false'
|
||||
|
||||
2
.github/workflows/reuse.yml
vendored
2
.github/workflows/reuse.yml
vendored
@@ -27,4 +27,4 @@ jobs:
|
||||
ref: ${{ github.event.pull_request.head.sha || '' }}
|
||||
|
||||
- name: REUSE Compliance Check
|
||||
uses: fsfe/reuse-action@v2
|
||||
uses: fsfe/reuse-action@v3
|
||||
|
||||
321
CHANGELOG.md
321
CHANGELOG.md
@@ -1,82 +1,173 @@
|
||||
# Community General Release Notes
|
||||
|
||||
**Topics**
|
||||
|
||||
- <a href="#v7-5-8">v7\.5\.8</a>
|
||||
- <a href="#release-summary">Release Summary</a>
|
||||
- <a href="#minor-changes">Minor Changes</a>
|
||||
- <a href="#security-fixes">Security Fixes</a>
|
||||
- <a href="#bugfixes">Bugfixes</a>
|
||||
- <a href="#v7-5-7">v7\.5\.7</a>
|
||||
- <a href="#release-summary-1">Release Summary</a>
|
||||
- <a href="#bugfixes-1">Bugfixes</a>
|
||||
- <a href="#v7-5-6">v7\.5\.6</a>
|
||||
- <a href="#release-summary-2">Release Summary</a>
|
||||
- <a href="#security-fixes-1">Security Fixes</a>
|
||||
- <a href="#bugfixes-2">Bugfixes</a>
|
||||
- <a href="#v7-5-5">v7\.5\.5</a>
|
||||
- <a href="#release-summary">Release Summary</a>
|
||||
- <a href="#bugfixes">Bugfixes</a>
|
||||
- <a href="#release-summary-3">Release Summary</a>
|
||||
- <a href="#bugfixes-3">Bugfixes</a>
|
||||
- <a href="#v7-5-4">v7\.5\.4</a>
|
||||
- <a href="#release-summary-1">Release Summary</a>
|
||||
- <a href="#bugfixes-1">Bugfixes</a>
|
||||
- <a href="#release-summary-4">Release Summary</a>
|
||||
- <a href="#bugfixes-4">Bugfixes</a>
|
||||
- <a href="#v7-5-3">v7\.5\.3</a>
|
||||
- <a href="#release-summary-2">Release Summary</a>
|
||||
- <a href="#bugfixes-2">Bugfixes</a>
|
||||
- <a href="#release-summary-5">Release Summary</a>
|
||||
- <a href="#bugfixes-5">Bugfixes</a>
|
||||
- <a href="#v7-5-2">v7\.5\.2</a>
|
||||
- <a href="#release-summary-3">Release Summary</a>
|
||||
- <a href="#minor-changes">Minor Changes</a>
|
||||
- <a href="#bugfixes-3">Bugfixes</a>
|
||||
- <a href="#release-summary-6">Release Summary</a>
|
||||
- <a href="#minor-changes-1">Minor Changes</a>
|
||||
- <a href="#bugfixes-6">Bugfixes</a>
|
||||
- <a href="#v7-5-1">v7\.5\.1</a>
|
||||
- <a href="#release-summary-4">Release Summary</a>
|
||||
- <a href="#bugfixes-4">Bugfixes</a>
|
||||
- <a href="#release-summary-7">Release Summary</a>
|
||||
- <a href="#bugfixes-7">Bugfixes</a>
|
||||
- <a href="#v7-5-0">v7\.5\.0</a>
|
||||
- <a href="#release-summary-5">Release Summary</a>
|
||||
- <a href="#minor-changes-1">Minor Changes</a>
|
||||
- <a href="#deprecated-features">Deprecated Features</a>
|
||||
- <a href="#bugfixes-5">Bugfixes</a>
|
||||
- <a href="#new-modules">New Modules</a>
|
||||
- <a href="#release-summary-8">Release Summary</a>
|
||||
- <a href="#minor-changes-2">Minor Changes</a>
|
||||
- <a href="#deprecated-features">Deprecated Features</a>
|
||||
- <a href="#bugfixes-8">Bugfixes</a>
|
||||
- <a href="#new-modules">New Modules</a>
|
||||
- <a href="#v7-4-0">v7\.4\.0</a>
|
||||
- <a href="#release-summary-6">Release Summary</a>
|
||||
- <a href="#minor-changes-2">Minor Changes</a>
|
||||
- <a href="#bugfixes-6">Bugfixes</a>
|
||||
- <a href="#new-modules-1">New Modules</a>
|
||||
- <a href="#release-summary-9">Release Summary</a>
|
||||
- <a href="#minor-changes-3">Minor Changes</a>
|
||||
- <a href="#bugfixes-9">Bugfixes</a>
|
||||
- <a href="#new-modules-1">New Modules</a>
|
||||
- <a href="#v7-3-0">v7\.3\.0</a>
|
||||
- <a href="#release-summary-7">Release Summary</a>
|
||||
- <a href="#minor-changes-3">Minor Changes</a>
|
||||
- <a href="#deprecated-features-1">Deprecated Features</a>
|
||||
- <a href="#bugfixes-7">Bugfixes</a>
|
||||
- <a href="#release-summary-10">Release Summary</a>
|
||||
- <a href="#minor-changes-4">Minor Changes</a>
|
||||
- <a href="#deprecated-features-1">Deprecated Features</a>
|
||||
- <a href="#bugfixes-10">Bugfixes</a>
|
||||
- <a href="#v7-2-1">v7\.2\.1</a>
|
||||
- <a href="#release-summary-8">Release Summary</a>
|
||||
- <a href="#bugfixes-8">Bugfixes</a>
|
||||
- <a href="#release-summary-11">Release Summary</a>
|
||||
- <a href="#bugfixes-11">Bugfixes</a>
|
||||
- <a href="#v7-2-0">v7\.2\.0</a>
|
||||
- <a href="#release-summary-9">Release Summary</a>
|
||||
- <a href="#minor-changes-4">Minor Changes</a>
|
||||
- <a href="#deprecated-features-2">Deprecated Features</a>
|
||||
- <a href="#bugfixes-9">Bugfixes</a>
|
||||
- <a href="#new-plugins">New Plugins</a>
|
||||
- <a href="#lookup">Lookup</a>
|
||||
- <a href="#new-modules-2">New Modules</a>
|
||||
- <a href="#release-summary-12">Release Summary</a>
|
||||
- <a href="#minor-changes-5">Minor Changes</a>
|
||||
- <a href="#deprecated-features-2">Deprecated Features</a>
|
||||
- <a href="#bugfixes-12">Bugfixes</a>
|
||||
- <a href="#new-plugins">New Plugins</a>
|
||||
- <a href="#lookup">Lookup</a>
|
||||
- <a href="#new-modules-2">New Modules</a>
|
||||
- <a href="#v7-1-0">v7\.1\.0</a>
|
||||
- <a href="#release-summary-10">Release Summary</a>
|
||||
- <a href="#minor-changes-5">Minor Changes</a>
|
||||
- <a href="#deprecated-features-3">Deprecated Features</a>
|
||||
- <a href="#bugfixes-10">Bugfixes</a>
|
||||
- <a href="#known-issues">Known Issues</a>
|
||||
- <a href="#new-modules-3">New Modules</a>
|
||||
- <a href="#release-summary-13">Release Summary</a>
|
||||
- <a href="#minor-changes-6">Minor Changes</a>
|
||||
- <a href="#deprecated-features-3">Deprecated Features</a>
|
||||
- <a href="#bugfixes-13">Bugfixes</a>
|
||||
- <a href="#known-issues">Known Issues</a>
|
||||
- <a href="#new-modules-3">New Modules</a>
|
||||
- <a href="#v7-0-1">v7\.0\.1</a>
|
||||
- <a href="#release-summary-11">Release Summary</a>
|
||||
- <a href="#bugfixes-11">Bugfixes</a>
|
||||
- <a href="#release-summary-14">Release Summary</a>
|
||||
- <a href="#bugfixes-14">Bugfixes</a>
|
||||
- <a href="#v7-0-0">v7\.0\.0</a>
|
||||
- <a href="#release-summary-12">Release Summary</a>
|
||||
- <a href="#minor-changes-6">Minor Changes</a>
|
||||
- <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
|
||||
- <a href="#deprecated-features-4">Deprecated Features</a>
|
||||
- <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
|
||||
- <a href="#bugfixes-12">Bugfixes</a>
|
||||
- <a href="#new-plugins-1">New Plugins</a>
|
||||
- <a href="#lookup-1">Lookup</a>
|
||||
- <a href="#new-modules-4">New Modules</a>
|
||||
- <a href="#release-summary-15">Release Summary</a>
|
||||
- <a href="#minor-changes-7">Minor Changes</a>
|
||||
- <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
|
||||
- <a href="#deprecated-features-4">Deprecated Features</a>
|
||||
- <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
|
||||
- <a href="#bugfixes-15">Bugfixes</a>
|
||||
- <a href="#new-plugins-1">New Plugins</a>
|
||||
- <a href="#lookup-1">Lookup</a>
|
||||
- <a href="#new-modules-4">New Modules</a>
|
||||
This changelog describes changes after version 6\.0\.0\.
|
||||
|
||||
<a id="v7-5-5"></a>
|
||||
## v7\.5\.5
|
||||
<a id="v7-5-8"></a>
|
||||
## v7\.5\.8
|
||||
|
||||
<a id="release-summary"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix release\.
|
||||
|
||||
Note that this is the last regular bugfix release\. From now on\, the 7\.x\.y release train
|
||||
will only receive major and security bugfixes\.
|
||||
|
||||
<a id="minor-changes"></a>
|
||||
### Minor Changes
|
||||
|
||||
* gitlab\_deploy\_key\, gitlab\_group\_members\, gitlab\_group\_variable\, gitlab\_hook\, gitlab\_instance\_variable\, gitlab\_project\_badge\, gitlab\_project\_variable\, gitlab\_user \- improve API pagination and compatibility with different versions of <code>python\-gitlab</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7790](https\://github\.com/ansible\-collections/community\.general/pull/7790)\)\.
|
||||
|
||||
<a id="security-fixes"></a>
|
||||
### Security Fixes
|
||||
|
||||
* keycloak\_identity\_provider \- the client secret was not correctly sanitized by the module\. The return values <code>proposed</code>\, <code>existing</code>\, and <code>end\_state</code>\, as well as the diff\, did contain the client secret unmasked \([https\://github\.com/ansible\-collections/community\.general/pull/8355](https\://github\.com/ansible\-collections/community\.general/pull/8355)\)\.
|
||||
|
||||
<a id="bugfixes"></a>
|
||||
### Bugfixes
|
||||
|
||||
* gitlab\_runner \- fix pagination when checking for existing runners \([https\://github\.com/ansible\-collections/community\.general/pull/7790](https\://github\.com/ansible\-collections/community\.general/pull/7790)\)\.
|
||||
* keycloak\_user\_federation \- fix diff of empty <code>krbPrincipalAttribute</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8320](https\://github\.com/ansible\-collections/community\.general/pull/8320)\)\.
|
||||
* opentelemetry callback plugin \- close spans always \([https\://github\.com/ansible\-collections/community\.general/pull/8367](https\://github\.com/ansible\-collections/community\.general/pull/8367)\)\.
|
||||
* opentelemetry callback plugin \- honour the <code>disable\_logs</code> option to avoid storing task results since they are not used regardless \([https\://github\.com/ansible\-collections/community\.general/pull/8373](https\://github\.com/ansible\-collections/community\.general/pull/8373)\)\.
|
||||
|
||||
<a id="v7-5-7"></a>
|
||||
## v7\.5\.7
|
||||
|
||||
<a id="release-summary-1"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix release\.
|
||||
|
||||
<a id="bugfixes-1"></a>
|
||||
### Bugfixes
|
||||
|
||||
* aix\_filesystem \- fix <code>\_validate\_vg</code> not passing VG name to <code>lsvg\_cmd</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8151](https\://github\.com/ansible\-collections/community\.general/issues/8151)\)\.
|
||||
* apt\_rpm \- when checking whether packages were installed after running <code>apt\-get \-y install \<packages\></code>\, only the last package name was checked \([https\://github\.com/ansible\-collections/community\.general/pull/8263](https\://github\.com/ansible\-collections/community\.general/pull/8263)\)\.
|
||||
* bitwarden\_secrets\_manager lookup plugin \- implements retry with exponential backoff to avoid lookup errors when Bitwardn\'s API rate limiting is encountered \([https\://github\.com/ansible\-collections/community\.general/issues/8230](https\://github\.com/ansible\-collections/community\.general/issues/8230)\, [https\://github\.com/ansible\-collections/community\.general/pull/8238](https\://github\.com/ansible\-collections/community\.general/pull/8238)\)\.
|
||||
* haproxy \- fix an issue where HAProxy could get stuck in DRAIN mode when the backend was unreachable \([https\://github\.com/ansible\-collections/community\.general/issues/8092](https\://github\.com/ansible\-collections/community\.general/issues/8092)\)\.
|
||||
* inventory plugins \- add unsafe wrapper to avoid marking strings that do not contain <code>\{</code> or <code>\}</code> as unsafe\, to work around a bug in AWX \(\([https\://github\.com/ansible\-collections/community\.general/issues/8212](https\://github\.com/ansible\-collections/community\.general/issues/8212)\, [https\://github\.com/ansible\-collections/community\.general/pull/8225](https\://github\.com/ansible\-collections/community\.general/pull/8225)\)\.
|
||||
* ipa \- fix get version regex in IPA module\_utils \([https\://github\.com/ansible\-collections/community\.general/pull/8175](https\://github\.com/ansible\-collections/community\.general/pull/8175)\)\.
|
||||
* keycloak\_client \- add sorted <code>defaultClientScopes</code> and <code>optionalClientScopes</code> to normalizations \([https\://github\.com/ansible\-collections/community\.general/pull/8223](https\://github\.com/ansible\-collections/community\.general/pull/8223)\)\.
|
||||
* keycloak\_realm \- add normalizations for <code>enabledEventTypes</code> and <code>supportedLocales</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8224](https\://github\.com/ansible\-collections/community\.general/pull/8224)\)\.
|
||||
* puppet \- add option <code>environment\_lang</code> to set the environment language encoding\. Defaults to lang <code>C</code>\. It is recommended to set it to <code>C\.UTF\-8</code> or <code>en\_US\.UTF\-8</code> depending on what is available on your system\. \([https\://github\.com/ansible\-collections/community\.general/issues/8000](https\://github\.com/ansible\-collections/community\.general/issues/8000)\)
|
||||
* riak \- support <code>riak admin</code> sub\-command in newer Riak KV versions beside the legacy <code>riak\-admin</code> main command \([https\://github\.com/ansible\-collections/community\.general/pull/8211](https\://github\.com/ansible\-collections/community\.general/pull/8211)\)\.
|
||||
* xml \- make module work with lxml 5\.1\.1\, which removed some internals that the module was relying on \([https\://github\.com/ansible\-collections/community\.general/pull/8169](https\://github\.com/ansible\-collections/community\.general/pull/8169)\)\.
|
||||
|
||||
<a id="v7-5-6"></a>
|
||||
## v7\.5\.6
|
||||
|
||||
<a id="release-summary-2"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix release with security fixes\.
|
||||
|
||||
<a id="security-fixes-1"></a>
|
||||
### Security Fixes
|
||||
|
||||
* cobbler\, gitlab\_runners\, icinga2\, linode\, lxd\, nmap\, online\, opennebula\, proxmox\, scaleway\, stackpath\_compute\, virtualbox\, and xen\_orchestra inventory plugin \- make sure all data received from the remote servers is marked as unsafe\, so remote code execution by obtaining texts that can be evaluated as templates is not possible \([https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/](https\://www\.die\-welt\.net/2024/03/remote\-code\-execution\-in\-ansible\-dynamic\-inventory\-plugins/)\, [https\://github\.com/ansible\-collections/community\.general/pull/8098](https\://github\.com/ansible\-collections/community\.general/pull/8098)\)\.
|
||||
|
||||
<a id="bugfixes-2"></a>
|
||||
### Bugfixes
|
||||
|
||||
* aix\_filesystem \- fix issue with empty list items in crfs logic and option order \([https\://github\.com/ansible\-collections/community\.general/pull/8052](https\://github\.com/ansible\-collections/community\.general/pull/8052)\)\.
|
||||
* homebrew \- error returned from brew command was ignored and tried to parse empty JSON\. Fix now checks for an error and raises it to give accurate error message to users \([https\://github\.com/ansible\-collections/community\.general/issues/8047](https\://github\.com/ansible\-collections/community\.general/issues/8047)\)\.
|
||||
* ipa\_hbacrule \- the module uses a string for <code>ipaenabledflag</code> for new FreeIPA versions while the returned value is a boolean \([https\://github\.com/ansible\-collections/community\.general/pull/7880](https\://github\.com/ansible\-collections/community\.general/pull/7880)\)\.
|
||||
* ipa\_sudorule \- the module uses a string for <code>ipaenabledflag</code> for new FreeIPA versions while the returned value is a boolean \([https\://github\.com/ansible\-collections/community\.general/pull/7880](https\://github\.com/ansible\-collections/community\.general/pull/7880)\)\.
|
||||
* iptables\_state \- fix idempotency issues when restoring incomplete iptables dumps \([https\://github\.com/ansible\-collections/community\.general/issues/8029](https\://github\.com/ansible\-collections/community\.general/issues/8029)\)\.
|
||||
* linode inventory plugin \- add descriptive error message for linode inventory plugin \([https\://github\.com/ansible\-collections/community\.general/pull/8133](https\://github\.com/ansible\-collections/community\.general/pull/8133)\)\.
|
||||
* pacemaker\_cluster \- actually implement check mode\, which the module claims to support\. This means that until now the module also did changes in check mode \([https\://github\.com/ansible\-collections/community\.general/pull/8081](https\://github\.com/ansible\-collections/community\.general/pull/8081)\)\.
|
||||
* pam\_limits \- when the file does not exist\, do not create it in check mode \([https\://github\.com/ansible\-collections/community\.general/issues/8050](https\://github\.com/ansible\-collections/community\.general/issues/8050)\, [https\://github\.com/ansible\-collections/community\.general/pull/8057](https\://github\.com/ansible\-collections/community\.general/pull/8057)\)\.
|
||||
* proxmox\_kvm \- fixed status check getting from node\-specific API endpoint \([https\://github\.com/ansible\-collections/community\.general/issues/7817](https\://github\.com/ansible\-collections/community\.general/issues/7817)\)\.
|
||||
|
||||
<a id="v7-5-5"></a>
|
||||
## v7\.5\.5
|
||||
|
||||
<a id="release-summary-3"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix release\.
|
||||
|
||||
<a id="bugfixes-3"></a>
|
||||
### Bugfixes
|
||||
|
||||
* cargo \- fix idempotency issues when using a custom installation path for packages \(using the <code>\-\-path</code> parameter\)\. The initial installation runs fine\, but subsequent runs use the <code>get\_installed\(\)</code> function which did not check the given installation location\, before running <code>cargo install</code>\. This resulted in a false <code>changed</code> state\. Also the removal of packeges using <code>state\: absent</code> failed\, as the installation check did not use the given parameter \([https\://github\.com/ansible\-collections/community\.general/pull/7970](https\://github\.com/ansible\-collections/community\.general/pull/7970)\)\.
|
||||
* keycloak\_client \- fixes issue when metadata is provided in desired state when task is in check mode \([https\://github\.com/ansible\-collections/community\.general/issues/1226](https\://github\.com/ansible\-collections/community\.general/issues/1226)\, [https\://github\.com/ansible\-collections/community\.general/pull/7881](https\://github\.com/ansible\-collections/community\.general/pull/7881)\)\.
|
||||
* modprobe \- listing modules files or modprobe files could trigger a FileNotFoundError if <code>/etc/modprobe\.d</code> or <code>/etc/modules\-load\.d</code> did not exist\. Relevant functions now return empty lists if the directories do not exist to avoid crashing the module \([https\://github\.com/ansible\-collections/community\.general/issues/7717](https\://github\.com/ansible\-collections/community\.general/issues/7717)\)\.
|
||||
@@ -88,12 +179,12 @@ Regular bugfix release\.
|
||||
<a id="v7-5-4"></a>
|
||||
## v7\.5\.4
|
||||
|
||||
<a id="release-summary-1"></a>
|
||||
<a id="release-summary-4"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix release\.
|
||||
|
||||
<a id="bugfixes-1"></a>
|
||||
<a id="bugfixes-4"></a>
|
||||
### Bugfixes
|
||||
|
||||
* homebrew \- detect already installed formulae and casks using JSON output from <code>brew info</code> \([https\://github\.com/ansible\-collections/community\.general/issues/864](https\://github\.com/ansible\-collections/community\.general/issues/864)\)\.
|
||||
@@ -105,12 +196,12 @@ Regular bugfix release\.
|
||||
<a id="v7-5-3"></a>
|
||||
## v7\.5\.3
|
||||
|
||||
<a id="release-summary-2"></a>
|
||||
<a id="release-summary-5"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix release\.
|
||||
|
||||
<a id="bugfixes-2"></a>
|
||||
<a id="bugfixes-5"></a>
|
||||
### Bugfixes
|
||||
|
||||
* keycloak\_identity\_provider \- <code>mappers</code> processing was not idempotent if the mappers configuration list had not been sorted by name \(in ascending order\)\. Fix resolves the issue by sorting mappers in the desired state using the same key which is used for obtaining existing state \([https\://github\.com/ansible\-collections/community\.general/pull/7418](https\://github\.com/ansible\-collections/community\.general/pull/7418)\)\.
|
||||
@@ -121,17 +212,17 @@ Regular bugfix release\.
|
||||
<a id="v7-5-2"></a>
|
||||
## v7\.5\.2
|
||||
|
||||
<a id="release-summary-3"></a>
|
||||
<a id="release-summary-6"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix release\.
|
||||
|
||||
<a id="minor-changes"></a>
|
||||
<a id="minor-changes-1"></a>
|
||||
### Minor Changes
|
||||
|
||||
* elastic callback plugin \- close elastic client to not leak resources \([https\://github\.com/ansible\-collections/community\.general/pull/7517](https\://github\.com/ansible\-collections/community\.general/pull/7517)\)\.
|
||||
|
||||
<a id="bugfixes-3"></a>
|
||||
<a id="bugfixes-6"></a>
|
||||
### Bugfixes
|
||||
|
||||
* cloudflare\_dns \- fix Cloudflare lookup of SHFP records \([https\://github\.com/ansible\-collections/community\.general/issues/7652](https\://github\.com/ansible\-collections/community\.general/issues/7652)\)\.
|
||||
@@ -153,12 +244,12 @@ Regular bugfix release\.
|
||||
<a id="v7-5-1"></a>
|
||||
## v7\.5\.1
|
||||
|
||||
<a id="release-summary-4"></a>
|
||||
<a id="release-summary-7"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix release\.
|
||||
|
||||
<a id="bugfixes-4"></a>
|
||||
<a id="bugfixes-7"></a>
|
||||
### Bugfixes
|
||||
|
||||
* composer \- fix impossible to run <code>working\_dir</code> dependent commands\. The module was throwing an error when trying to run a <code>working\_dir</code> dependent command\, because it tried to get the command help without passing the <code>working\_dir</code> \([https\://github\.com/ansible\-collections/community\.general/issues/3787](https\://github\.com/ansible\-collections/community\.general/issues/3787)\)\.
|
||||
@@ -180,7 +271,7 @@ Regular bugfix release\.
|
||||
<a id="v7-5-0"></a>
|
||||
## v7\.5\.0
|
||||
|
||||
<a id="release-summary-5"></a>
|
||||
<a id="release-summary-8"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix and feature release\.
|
||||
@@ -188,7 +279,7 @@ Regular bugfix and feature release\.
|
||||
Please note that this is the last minor 7\.x\.0 release\. Further releases
|
||||
with major version 7 will be bugfix releases 7\.5\.y\.
|
||||
|
||||
<a id="minor-changes-1"></a>
|
||||
<a id="minor-changes-2"></a>
|
||||
### Minor Changes
|
||||
|
||||
* cargo \- add option <code>executable</code>\, which allows user to specify path to the cargo binary \([https\://github\.com/ansible\-collections/community\.general/pull/7352](https\://github\.com/ansible\-collections/community\.general/pull/7352)\)\.
|
||||
@@ -217,7 +308,7 @@ with major version 7 will be bugfix releases 7\.5\.y\.
|
||||
* The next major release\, community\.general 8\.0\.0\, will drop support for ansible\-core 2\.11 and 2\.12\, which have been End of Life for some time now\. This means that this collection no longer supports Python 2\.6 on the target\. Individual content might still work with unsupported ansible\-core versions\, but that can change at any time\. Also please note that from now on\, for every new major community\.general release\, we will drop support for all ansible\-core versions that have been End of Life for more than a few weeks on the date of the major release \([https\://github\.com/ansible\-community/community\-topics/discussions/271](https\://github\.com/ansible\-community/community\-topics/discussions/271)\, [https\://github\.com/ansible\-collections/community\.general/pull/7259](https\://github\.com/ansible\-collections/community\.general/pull/7259)\)\.
|
||||
* redfish\_info\, redfish\_config\, redfish\_command \- the default value <code>10</code> for the <code>timeout</code> option is deprecated and will change to <code>60</code> in community\.general 9\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/7295](https\://github\.com/ansible\-collections/community\.general/pull/7295)\)\.
|
||||
|
||||
<a id="bugfixes-5"></a>
|
||||
<a id="bugfixes-8"></a>
|
||||
### Bugfixes
|
||||
|
||||
* gitlab\_group\_variable \- deleted all variables when used with <code>purge\=true</code> due to missing <code>raw</code> property in KNOWN attributes \([https\://github\.com/ansible\-collections/community\.general/issues/7250](https\://github\.com/ansible\-collections/community\.general/issues/7250)\)\.
|
||||
@@ -233,21 +324,21 @@ with major version 7 will be bugfix releases 7\.5\.y\.
|
||||
<a id="new-modules"></a>
|
||||
### New Modules
|
||||
|
||||
* consul\_role \- Manipulate Consul roles
|
||||
* gio\_mime \- Set default handler for MIME type\, for applications using Gnome GIO
|
||||
* keycloak\_authz\_custom\_policy \- Allows administration of Keycloak client custom Javascript policies via Keycloak API
|
||||
* keycloak\_realm\_key \- Allows administration of Keycloak realm keys via Keycloak API
|
||||
* simpleinit\_msb \- Manage services on Source Mage GNU/Linux
|
||||
* community\.general\.consul\_role \- Manipulate Consul roles
|
||||
* community\.general\.gio\_mime \- Set default handler for MIME type\, for applications using Gnome GIO
|
||||
* community\.general\.keycloak\_authz\_custom\_policy \- Allows administration of Keycloak client custom Javascript policies via Keycloak API
|
||||
* community\.general\.keycloak\_realm\_key \- Allows administration of Keycloak realm keys via Keycloak API
|
||||
* community\.general\.simpleinit\_msb \- Manage services on Source Mage GNU/Linux
|
||||
|
||||
<a id="v7-4-0"></a>
|
||||
## v7\.4\.0
|
||||
|
||||
<a id="release-summary-6"></a>
|
||||
<a id="release-summary-9"></a>
|
||||
### Release Summary
|
||||
|
||||
Bugfix and feature release\.
|
||||
|
||||
<a id="minor-changes-2"></a>
|
||||
<a id="minor-changes-3"></a>
|
||||
### Minor Changes
|
||||
|
||||
* cobbler inventory plugin \- add <code>exclude\_mgmt\_classes</code> and <code>include\_mgmt\_classes</code> options to exclude or include hosts based on management classes \([https\://github\.com/ansible\-collections/community\.general/pull/7184](https\://github\.com/ansible\-collections/community\.general/pull/7184)\)\.
|
||||
@@ -264,7 +355,7 @@ Bugfix and feature release\.
|
||||
* redfish\_utils module utils \- support <code>Volumes</code> in response for <code>GetDiskInventory</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6819](https\://github\.com/ansible\-collections/community\.general/pull/6819)\)\.
|
||||
* unixy callback plugin \- add support for <code>check\_mode\_markers</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7179](https\://github\.com/ansible\-collections/community\.general/pull/7179)\)\.
|
||||
|
||||
<a id="bugfixes-6"></a>
|
||||
<a id="bugfixes-9"></a>
|
||||
### Bugfixes
|
||||
|
||||
* CmdRunner module utils \- does not attempt to resolve path if executable is a relative or absolute path \([https\://github\.com/ansible\-collections/community\.general/pull/7200](https\://github\.com/ansible\-collections/community\.general/pull/7200)\)\.
|
||||
@@ -277,18 +368,18 @@ Bugfix and feature release\.
|
||||
<a id="new-modules-1"></a>
|
||||
### New Modules
|
||||
|
||||
* jenkins\_build\_info \- Get information about Jenkins builds
|
||||
* pnpm \- Manage node\.js packages with pnpm
|
||||
* community\.general\.jenkins\_build\_info \- Get information about Jenkins builds
|
||||
* community\.general\.pnpm \- Manage node\.js packages with pnpm
|
||||
|
||||
<a id="v7-3-0"></a>
|
||||
## v7\.3\.0
|
||||
|
||||
<a id="release-summary-7"></a>
|
||||
<a id="release-summary-10"></a>
|
||||
### Release Summary
|
||||
|
||||
Feature and bugfix release\.
|
||||
|
||||
<a id="minor-changes-3"></a>
|
||||
<a id="minor-changes-4"></a>
|
||||
### Minor Changes
|
||||
|
||||
* chroot connection plugin \- add <code>disable\_root\_check</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7099](https\://github\.com/ansible\-collections/community\.general/pull/7099)\)\.
|
||||
@@ -311,7 +402,7 @@ Feature and bugfix release\.
|
||||
|
||||
* ejabberd\_user \- deprecate the parameter <code>logging</code> in favour of producing more detailed information in the module output \([https\://github\.com/ansible\-collections/community\.general/pull/7043](https\://github\.com/ansible\-collections/community\.general/pull/7043)\)\.
|
||||
|
||||
<a id="bugfixes-7"></a>
|
||||
<a id="bugfixes-10"></a>
|
||||
### Bugfixes
|
||||
|
||||
* bitwarden lookup plugin \- the plugin made assumptions about the structure of a Bitwarden JSON object which may have been broken by an update in the Bitwarden API\. Remove assumptions\, and allow queries for general fields such as <code>notes</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7061](https\://github\.com/ansible\-collections/community\.general/pull/7061)\)\.
|
||||
@@ -330,12 +421,12 @@ Feature and bugfix release\.
|
||||
<a id="v7-2-1"></a>
|
||||
## v7\.2\.1
|
||||
|
||||
<a id="release-summary-8"></a>
|
||||
<a id="release-summary-11"></a>
|
||||
### Release Summary
|
||||
|
||||
Bugfix release\.
|
||||
|
||||
<a id="bugfixes-8"></a>
|
||||
<a id="bugfixes-11"></a>
|
||||
### Bugfixes
|
||||
|
||||
* cmd\_runner module utils \- when a parameter in <code>argument\_spec</code> has no type\, meaning it is implicitly a <code>str</code>\, <code>CmdRunner</code> would fail trying to find the <code>type</code> key in that dictionary \([https\://github\.com/ansible\-collections/community\.general/pull/6968](https\://github\.com/ansible\-collections/community\.general/pull/6968)\)\.
|
||||
@@ -347,12 +438,12 @@ Bugfix release\.
|
||||
<a id="v7-2-0"></a>
|
||||
## v7\.2\.0
|
||||
|
||||
<a id="release-summary-9"></a>
|
||||
<a id="release-summary-12"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix and feature release\.
|
||||
|
||||
<a id="minor-changes-4"></a>
|
||||
<a id="minor-changes-5"></a>
|
||||
### 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](https\://github\.com/ansible\-collections/community\.general/pull/6923)\)\.
|
||||
@@ -398,7 +489,7 @@ Regular bugfix and feature release\.
|
||||
* 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](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](https\://github\.com/ansible\-collections/community\.general/pull/6909)\)\.
|
||||
|
||||
<a id="bugfixes-9"></a>
|
||||
<a id="bugfixes-12"></a>
|
||||
### Bugfixes
|
||||
|
||||
* cobbler inventory plugin \- fix calculation of cobbler\_ipv4/6\_address \([https\://github\.com/ansible\-collections/community\.general/pull/6925](https\://github\.com/ansible\-collections/community\.general/pull/6925)\)\.
|
||||
@@ -427,20 +518,20 @@ Regular bugfix and feature release\.
|
||||
<a id="lookup"></a>
|
||||
#### Lookup
|
||||
|
||||
* bitwarden\_secrets\_manager \- Retrieve secrets from Bitwarden Secrets Manager
|
||||
* community\.general\.bitwarden\_secrets\_manager \- Retrieve secrets from Bitwarden Secrets Manager
|
||||
|
||||
<a id="new-modules-2"></a>
|
||||
### 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
|
||||
* community\.general\.consul\_policy \- Manipulate Consul policies
|
||||
* community\.general\.keycloak\_authz\_permission \- Allows administration of Keycloak client authorization permissions via Keycloak API
|
||||
* community\.general\.keycloak\_authz\_permission\_info \- Query Keycloak client authorization permissions information
|
||||
* community\.general\.proxmox\_vm\_info \- Retrieve information about one or more Proxmox VE virtual machines
|
||||
|
||||
<a id="v7-1-0"></a>
|
||||
## v7\.1\.0
|
||||
|
||||
<a id="release-summary-10"></a>
|
||||
<a id="release-summary-13"></a>
|
||||
### Release Summary
|
||||
|
||||
Regular bugfix and feature release\.
|
||||
@@ -453,7 +544,7 @@ 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\.
|
||||
|
||||
<a id="minor-changes-5"></a>
|
||||
<a id="minor-changes-6"></a>
|
||||
### Minor Changes
|
||||
|
||||
* The collection will start using semantic markup \([https\://github\.com/ansible\-collections/community\.general/pull/6539](https\://github\.com/ansible\-collections/community\.general/pull/6539)\)\.
|
||||
@@ -522,7 +613,7 @@ for the rendered HTML version of the documentation of the latest release\.
|
||||
for removal in community\.general 10\.0\.0
|
||||
\([https\://github\.com/ansible\-collections/community\.general/pull/6673](https\://github\.com/ansible\-collections/community\.general/pull/6673)\)\.
|
||||
|
||||
<a id="bugfixes-10"></a>
|
||||
<a id="bugfixes-13"></a>
|
||||
### 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/pull/6644)\, [https\://github\.com/ansible\-collections/community\.general/issues/6639](https\://github\.com/ansible\-collections/community\.general/issues/6639)\)\.
|
||||
@@ -548,23 +639,23 @@ for the rendered HTML version of the documentation of the latest release\.
|
||||
<a id="new-modules-3"></a>
|
||||
### 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
|
||||
* community\.general\.gitlab\_instance\_variable \- Creates\, updates\, or deletes GitLab instance variables
|
||||
* community\.general\.gitlab\_merge\_request \- Create\, update\, or delete GitLab merge requests
|
||||
* community\.general\.keycloak\_authentication\_required\_actions \- Allows administration of Keycloak authentication required actions
|
||||
* community\.general\.keycloak\_user \- Create and configure a user in Keycloak
|
||||
* community\.general\.lvg\_rename \- Renames LVM volume groups
|
||||
* community\.general\.proxmox\_pool \- Pool management for Proxmox VE cluster
|
||||
* community\.general\.proxmox\_pool\_member \- Add or delete members from Proxmox VE cluster pools
|
||||
|
||||
<a id="v7-0-1"></a>
|
||||
## v7\.0\.1
|
||||
|
||||
<a id="release-summary-11"></a>
|
||||
<a id="release-summary-14"></a>
|
||||
### Release Summary
|
||||
|
||||
Bugfix release for Ansible 8\.0\.0rc1\.
|
||||
|
||||
<a id="bugfixes-11"></a>
|
||||
<a id="bugfixes-14"></a>
|
||||
### Bugfixes
|
||||
|
||||
* nmcli \- fix bond option <code>xmit\_hash\_policy</code> \([https\://github\.com/ansible\-collections/community\.general/pull/6527](https\://github\.com/ansible\-collections/community\.general/pull/6527)\)\.
|
||||
@@ -575,12 +666,12 @@ Bugfix release for Ansible 8\.0\.0rc1\.
|
||||
<a id="v7-0-0"></a>
|
||||
## v7\.0\.0
|
||||
|
||||
<a id="release-summary-12"></a>
|
||||
<a id="release-summary-15"></a>
|
||||
### Release Summary
|
||||
|
||||
This is release 7\.0\.0 of <code>community\.general</code>\, released on 2023\-05\-09\.
|
||||
|
||||
<a id="minor-changes-6"></a>
|
||||
<a id="minor-changes-7"></a>
|
||||
### Minor Changes
|
||||
|
||||
* apache2\_module \- add module argument <code>warn\_mpm\_absent</code> to control whether warning are raised in some edge cases \([https\://github\.com/ansible\-collections/community\.general/pull/5793](https\://github\.com/ansible\-collections/community\.general/pull/5793)\)\.
|
||||
@@ -760,7 +851,7 @@ This is release 7\.0\.0 of <code>community\.general</code>\, released on 2023\-0
|
||||
* xfconf \- generating facts was deprecated in community\.general 3\.0\.0\, however three factoids\, <code>property</code>\, <code>channel</code> and <code>value</code> continued to be generated by mistake\. This behaviour has been removed and <code>xfconf</code> generate no facts whatsoever \([https\://github\.com/ansible\-collections/community\.general/pull/5502](https\://github\.com/ansible\-collections/community\.general/pull/5502)\)\.
|
||||
* xfconf \- generating facts was deprecated in community\.general 3\.0\.0\, however two factoids\, <code>previous\_value</code> and <code>type</code> continued to be generated by mistake\. This behaviour has been removed and <code>xfconf</code> generate no facts whatsoever \([https\://github\.com/ansible\-collections/community\.general/pull/5502](https\://github\.com/ansible\-collections/community\.general/pull/5502)\)\.
|
||||
|
||||
<a id="bugfixes-12"></a>
|
||||
<a id="bugfixes-15"></a>
|
||||
### Bugfixes
|
||||
|
||||
* ModuleHelper \- fix bug when adjusting the name of reserved output variables \([https\://github\.com/ansible\-collections/community\.general/pull/5755](https\://github\.com/ansible\-collections/community\.general/pull/5755)\)\.
|
||||
@@ -876,20 +967,20 @@ This is release 7\.0\.0 of <code>community\.general</code>\, released on 2023\-0
|
||||
<a id="lookup-1"></a>
|
||||
#### Lookup
|
||||
|
||||
* merge\_variables \- merge variables with a certain suffix
|
||||
* community\.general\.merge\_variables \- merge variables with a certain suffix
|
||||
|
||||
<a id="new-modules-4"></a>
|
||||
### New Modules
|
||||
|
||||
* btrfs\_info \- Query btrfs filesystem info
|
||||
* btrfs\_subvolume \- Manage btrfs subvolumes
|
||||
* gitlab\_project\_badge \- Manage project badges on GitLab Server
|
||||
* ilo\_redfish\_command \- Manages Out\-Of\-Band controllers using Redfish APIs
|
||||
* ipbase\_info \- Retrieve IP geolocation and other facts of a host\'s IP address using the ipbase\.com API
|
||||
* kdeconfig \- Manage KDE configuration files
|
||||
* keycloak\_authz\_authorization\_scope \- Allows administration of Keycloak client authorization scopes via Keycloak API
|
||||
* keycloak\_clientscope\_type \- Set the type of aclientscope in realm or client via Keycloak API
|
||||
* keycloak\_clientsecret\_info \- Retrieve client secret via Keycloak API
|
||||
* keycloak\_clientsecret\_regenerate \- Regenerate Keycloak client secret via Keycloak API
|
||||
* ocapi\_command \- Manages Out\-Of\-Band controllers using Open Composable API \(OCAPI\)
|
||||
* ocapi\_info \- Manages Out\-Of\-Band controllers using Open Composable API \(OCAPI\)
|
||||
* community\.general\.btrfs\_info \- Query btrfs filesystem info
|
||||
* community\.general\.btrfs\_subvolume \- Manage btrfs subvolumes
|
||||
* community\.general\.gitlab\_project\_badge \- Manage project badges on GitLab Server
|
||||
* community\.general\.ilo\_redfish\_command \- Manages Out\-Of\-Band controllers using Redfish APIs
|
||||
* community\.general\.ipbase\_info \- Retrieve IP geolocation and other facts of a host\'s IP address using the ipbase\.com API
|
||||
* community\.general\.kdeconfig \- Manage KDE configuration files
|
||||
* community\.general\.keycloak\_authz\_authorization\_scope \- Allows administration of Keycloak client authorization scopes via Keycloak API
|
||||
* community\.general\.keycloak\_clientscope\_type \- Set the type of aclientscope in realm or client via Keycloak API
|
||||
* community\.general\.keycloak\_clientsecret\_info \- Retrieve client secret via Keycloak API
|
||||
* community\.general\.keycloak\_clientsecret\_regenerate \- Regenerate Keycloak client secret via Keycloak API
|
||||
* community\.general\.ocapi\_command \- Manages Out\-Of\-Band controllers using Open Composable API \(OCAPI\)
|
||||
* community\.general\.ocapi\_info \- Manages Out\-Of\-Band controllers using Open Composable API \(OCAPI\)
|
||||
|
||||
142
CHANGELOG.rst
142
CHANGELOG.rst
@@ -6,6 +6,84 @@ Community General Release Notes
|
||||
|
||||
This changelog describes changes after version 6.0.0.
|
||||
|
||||
v7.5.8
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix release.
|
||||
|
||||
Note that this is the last regular bugfix release. From now on, the 7.x.y release train
|
||||
will only receive major and security bugfixes.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- gitlab_deploy_key, gitlab_group_members, gitlab_group_variable, gitlab_hook, gitlab_instance_variable, gitlab_project_badge, gitlab_project_variable, gitlab_user - improve API pagination and compatibility with different versions of ``python-gitlab`` (https://github.com/ansible-collections/community.general/pull/7790).
|
||||
|
||||
Security Fixes
|
||||
--------------
|
||||
|
||||
- keycloak_identity_provider - the client secret was not correctly sanitized by the module. The return values ``proposed``, ``existing``, and ``end_state``, as well as the diff, did contain the client secret unmasked (https://github.com/ansible-collections/community.general/pull/8355).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- gitlab_runner - fix pagination when checking for existing runners (https://github.com/ansible-collections/community.general/pull/7790).
|
||||
- keycloak_user_federation - fix diff of empty ``krbPrincipalAttribute`` (https://github.com/ansible-collections/community.general/pull/8320).
|
||||
- opentelemetry callback plugin - close spans always (https://github.com/ansible-collections/community.general/pull/8367).
|
||||
- opentelemetry callback plugin - honour the ``disable_logs`` option to avoid storing task results since they are not used regardless (https://github.com/ansible-collections/community.general/pull/8373).
|
||||
|
||||
v7.5.7
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix release.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- aix_filesystem - fix ``_validate_vg`` not passing VG name to ``lsvg_cmd`` (https://github.com/ansible-collections/community.general/issues/8151).
|
||||
- apt_rpm - when checking whether packages were installed after running ``apt-get -y install <packages>``, only the last package name was checked (https://github.com/ansible-collections/community.general/pull/8263).
|
||||
- bitwarden_secrets_manager lookup plugin - implements retry with exponential backoff to avoid lookup errors when Bitwardn's API rate limiting is encountered (https://github.com/ansible-collections/community.general/issues/8230, https://github.com/ansible-collections/community.general/pull/8238).
|
||||
- haproxy - fix an issue where HAProxy could get stuck in DRAIN mode when the backend was unreachable (https://github.com/ansible-collections/community.general/issues/8092).
|
||||
- inventory plugins - add unsafe wrapper to avoid marking strings that do not contain ``{`` or ``}`` as unsafe, to work around a bug in AWX ((https://github.com/ansible-collections/community.general/issues/8212, https://github.com/ansible-collections/community.general/pull/8225).
|
||||
- ipa - fix get version regex in IPA module_utils (https://github.com/ansible-collections/community.general/pull/8175).
|
||||
- keycloak_client - add sorted ``defaultClientScopes`` and ``optionalClientScopes`` to normalizations (https://github.com/ansible-collections/community.general/pull/8223).
|
||||
- keycloak_realm - add normalizations for ``enabledEventTypes`` and ``supportedLocales`` (https://github.com/ansible-collections/community.general/pull/8224).
|
||||
- puppet - add option ``environment_lang`` to set the environment language encoding. Defaults to lang ``C``. It is recommended to set it to ``C.UTF-8`` or ``en_US.UTF-8`` depending on what is available on your system. (https://github.com/ansible-collections/community.general/issues/8000)
|
||||
- riak - support ``riak admin`` sub-command in newer Riak KV versions beside the legacy ``riak-admin`` main command (https://github.com/ansible-collections/community.general/pull/8211).
|
||||
- xml - make module work with lxml 5.1.1, which removed some internals that the module was relying on (https://github.com/ansible-collections/community.general/pull/8169).
|
||||
|
||||
v7.5.6
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix release with security fixes.
|
||||
|
||||
Security Fixes
|
||||
--------------
|
||||
|
||||
- cobbler, gitlab_runners, icinga2, linode, lxd, nmap, online, opennebula, proxmox, scaleway, stackpath_compute, virtualbox, and xen_orchestra inventory plugin - make sure all data received from the remote servers is marked as unsafe, so remote code execution by obtaining texts that can be evaluated as templates is not possible (https://www.die-welt.net/2024/03/remote-code-execution-in-ansible-dynamic-inventory-plugins/, https://github.com/ansible-collections/community.general/pull/8098).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- aix_filesystem - fix issue with empty list items in crfs logic and option order (https://github.com/ansible-collections/community.general/pull/8052).
|
||||
- homebrew - error returned from brew command was ignored and tried to parse empty JSON. Fix now checks for an error and raises it to give accurate error message to users (https://github.com/ansible-collections/community.general/issues/8047).
|
||||
- ipa_hbacrule - the module uses a string for ``ipaenabledflag`` for new FreeIPA versions while the returned value is a boolean (https://github.com/ansible-collections/community.general/pull/7880).
|
||||
- ipa_sudorule - the module uses a string for ``ipaenabledflag`` for new FreeIPA versions while the returned value is a boolean (https://github.com/ansible-collections/community.general/pull/7880).
|
||||
- iptables_state - fix idempotency issues when restoring incomplete iptables dumps (https://github.com/ansible-collections/community.general/issues/8029).
|
||||
- linode inventory plugin - add descriptive error message for linode inventory plugin (https://github.com/ansible-collections/community.general/pull/8133).
|
||||
- pacemaker_cluster - actually implement check mode, which the module claims to support. This means that until now the module also did changes in check mode (https://github.com/ansible-collections/community.general/pull/8081).
|
||||
- pam_limits - when the file does not exist, do not create it in check mode (https://github.com/ansible-collections/community.general/issues/8050, https://github.com/ansible-collections/community.general/pull/8057).
|
||||
- proxmox_kvm - fixed status check getting from node-specific API endpoint (https://github.com/ansible-collections/community.general/issues/7817).
|
||||
|
||||
v7.5.5
|
||||
======
|
||||
|
||||
@@ -173,11 +251,11 @@ Bugfixes
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- consul_role - Manipulate Consul roles
|
||||
- gio_mime - Set default handler for MIME type, for applications using Gnome GIO
|
||||
- keycloak_authz_custom_policy - Allows administration of Keycloak client custom Javascript policies via Keycloak API
|
||||
- keycloak_realm_key - Allows administration of Keycloak realm keys via Keycloak API
|
||||
- simpleinit_msb - Manage services on Source Mage GNU/Linux
|
||||
- community.general.consul_role - Manipulate Consul roles
|
||||
- community.general.gio_mime - Set default handler for MIME type, for applications using Gnome GIO
|
||||
- community.general.keycloak_authz_custom_policy - Allows administration of Keycloak client custom Javascript policies via Keycloak API
|
||||
- community.general.keycloak_realm_key - Allows administration of Keycloak realm keys via Keycloak API
|
||||
- community.general.simpleinit_msb - Manage services on Source Mage GNU/Linux
|
||||
|
||||
v7.4.0
|
||||
======
|
||||
@@ -217,8 +295,8 @@ Bugfixes
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- jenkins_build_info - Get information about Jenkins builds
|
||||
- pnpm - Manage node.js packages with pnpm
|
||||
- community.general.jenkins_build_info - Get information about Jenkins builds
|
||||
- community.general.pnpm - Manage node.js packages with pnpm
|
||||
|
||||
v7.3.0
|
||||
======
|
||||
@@ -367,15 +445,15 @@ New Plugins
|
||||
Lookup
|
||||
~~~~~~
|
||||
|
||||
- bitwarden_secrets_manager - Retrieve secrets from Bitwarden Secrets Manager
|
||||
- community.general.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
|
||||
- community.general.consul_policy - Manipulate Consul policies
|
||||
- community.general.keycloak_authz_permission - Allows administration of Keycloak client authorization permissions via Keycloak API
|
||||
- community.general.keycloak_authz_permission_info - Query Keycloak client authorization permissions information
|
||||
- community.general.proxmox_vm_info - Retrieve information about one or more Proxmox VE virtual machines
|
||||
|
||||
v7.1.0
|
||||
======
|
||||
@@ -489,13 +567,13 @@ Known Issues
|
||||
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
|
||||
- community.general.gitlab_instance_variable - Creates, updates, or deletes GitLab instance variables
|
||||
- community.general.gitlab_merge_request - Create, update, or delete GitLab merge requests
|
||||
- community.general.keycloak_authentication_required_actions - Allows administration of Keycloak authentication required actions
|
||||
- community.general.keycloak_user - Create and configure a user in Keycloak
|
||||
- community.general.lvg_rename - Renames LVM volume groups
|
||||
- community.general.proxmox_pool - Pool management for Proxmox VE cluster
|
||||
- community.general.proxmox_pool_member - Add or delete members from Proxmox VE cluster pools
|
||||
|
||||
v7.0.1
|
||||
======
|
||||
@@ -817,20 +895,20 @@ New Plugins
|
||||
Lookup
|
||||
~~~~~~
|
||||
|
||||
- merge_variables - merge variables with a certain suffix
|
||||
- community.general.merge_variables - merge variables with a certain suffix
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- btrfs_info - Query btrfs filesystem info
|
||||
- btrfs_subvolume - Manage btrfs subvolumes
|
||||
- gitlab_project_badge - Manage project badges on GitLab Server
|
||||
- ilo_redfish_command - Manages Out-Of-Band controllers using Redfish APIs
|
||||
- ipbase_info - Retrieve IP geolocation and other facts of a host's IP address using the ipbase.com API
|
||||
- kdeconfig - Manage KDE configuration files
|
||||
- keycloak_authz_authorization_scope - Allows administration of Keycloak client authorization scopes via Keycloak API
|
||||
- keycloak_clientscope_type - Set the type of aclientscope in realm or client via Keycloak API
|
||||
- keycloak_clientsecret_info - Retrieve client secret via Keycloak API
|
||||
- keycloak_clientsecret_regenerate - Regenerate Keycloak client secret via Keycloak API
|
||||
- ocapi_command - Manages Out-Of-Band controllers using Open Composable API (OCAPI)
|
||||
- ocapi_info - Manages Out-Of-Band controllers using Open Composable API (OCAPI)
|
||||
- community.general.btrfs_info - Query btrfs filesystem info
|
||||
- community.general.btrfs_subvolume - Manage btrfs subvolumes
|
||||
- community.general.gitlab_project_badge - Manage project badges on GitLab Server
|
||||
- community.general.ilo_redfish_command - Manages Out-Of-Band controllers using Redfish APIs
|
||||
- community.general.ipbase_info - Retrieve IP geolocation and other facts of a host's IP address using the ipbase.com API
|
||||
- community.general.kdeconfig - Manage KDE configuration files
|
||||
- community.general.keycloak_authz_authorization_scope - Allows administration of Keycloak client authorization scopes via Keycloak API
|
||||
- community.general.keycloak_clientscope_type - Set the type of aclientscope in realm or client via Keycloak API
|
||||
- community.general.keycloak_clientsecret_info - Retrieve client secret via Keycloak API
|
||||
- community.general.keycloak_clientsecret_regenerate - Regenerate Keycloak client secret via Keycloak API
|
||||
- community.general.ocapi_command - Manages Out-Of-Band controllers using Open Composable API (OCAPI)
|
||||
- community.general.ocapi_info - Manages Out-Of-Band controllers using Open Composable API (OCAPI)
|
||||
|
||||
@@ -31,7 +31,9 @@ Also, consider taking up a valuable, reviewed, but abandoned pull request which
|
||||
* Try committing your changes with an informative but short commit message.
|
||||
* Do not squash your commits and force-push to your branch if not needed. Reviews of your pull request are much easier with individual commits to comprehend the pull request history. All commits of your pull request branch will be squashed into one commit by GitHub upon merge.
|
||||
* Do not add merge commits to your PR. The bot will complain and you will have to rebase ([instructions for rebasing](https://docs.ansible.com/ansible/latest/dev_guide/developing_rebasing.html)) to remove them before your PR can be merged. To avoid that git automatically does merges during pulls, you can configure it to do rebases instead by running `git config pull.rebase true` inside the repository checkout.
|
||||
* Make sure your PR includes a [changelog fragment](https://docs.ansible.com/ansible/devel/community/development_process.html#creating-changelog-fragments). (You must not include a fragment for new modules or new plugins. Also you shouldn't include one for docs-only changes. If you're not sure, simply don't include one, we'll tell you whether one is needed or not :) )
|
||||
* Make sure your PR includes a [changelog fragment](https://docs.ansible.com/ansible/devel/community/collection_development_process.html#creating-a-changelog-fragment).
|
||||
* You must not include a fragment for new modules or new plugins. Also you shouldn't include one for docs-only changes. (If you're not sure, simply don't include one, we'll tell you whether one is needed or not :) )
|
||||
* Please always include a link to the pull request itself, and if the PR is about an issue, also a link to the issue. Also make sure the fragment ends with a period, and begins with a lower-case letter after `-`. (Again, if you don't do this, we'll add suggestions to fix it, so don't worry too much :) )
|
||||
* Avoid reformatting unrelated parts of the codebase in your PR. These types of changes will likely be requested for reversion, create additional work for reviewers, and may cause approval to be delayed.
|
||||
|
||||
You can also read [our Quick-start development guide](https://github.com/ansible/community-docs/blob/main/create_pr_quick_start_guide.rst).
|
||||
|
||||
@@ -9,6 +9,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
[](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
|
||||
[](https://github.com/ansible-collections/community.general/actions)
|
||||
[](https://codecov.io/gh/ansible-collections/community.general)
|
||||
[](https://api.reuse.software/info/github.com/ansible-collections/community.general)
|
||||
|
||||
This repository contains the `community.general` Ansible Collection. The collection is a part of the Ansible package and includes many modules and plugins supported by Ansible community which are not part of more specialized community collections.
|
||||
|
||||
@@ -24,7 +25,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, ansible-core 2.15, ansible-core 2.16 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, ansible-core 2.16, and ansible-core 2.17 releases. 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+.
|
||||
|
||||
|
||||
@@ -1746,3 +1746,121 @@ releases:
|
||||
- 8003-redfish-get-update-status-empty-response.yml
|
||||
- pkgin.yml
|
||||
release_date: '2024-02-25'
|
||||
7.5.6:
|
||||
changes:
|
||||
bugfixes:
|
||||
- aix_filesystem - fix issue with empty list items in crfs logic and option
|
||||
order (https://github.com/ansible-collections/community.general/pull/8052).
|
||||
- homebrew - error returned from brew command was ignored and tried to parse
|
||||
empty JSON. Fix now checks for an error and raises it to give accurate error
|
||||
message to users (https://github.com/ansible-collections/community.general/issues/8047).
|
||||
- ipa_hbacrule - the module uses a string for ``ipaenabledflag`` for new FreeIPA
|
||||
versions while the returned value is a boolean (https://github.com/ansible-collections/community.general/pull/7880).
|
||||
- ipa_sudorule - the module uses a string for ``ipaenabledflag`` for new FreeIPA
|
||||
versions while the returned value is a boolean (https://github.com/ansible-collections/community.general/pull/7880).
|
||||
- iptables_state - fix idempotency issues when restoring incomplete iptables
|
||||
dumps (https://github.com/ansible-collections/community.general/issues/8029).
|
||||
- linode inventory plugin - add descriptive error message for linode inventory
|
||||
plugin (https://github.com/ansible-collections/community.general/pull/8133).
|
||||
- pacemaker_cluster - actually implement check mode, which the module claims
|
||||
to support. This means that until now the module also did changes in check
|
||||
mode (https://github.com/ansible-collections/community.general/pull/8081).
|
||||
- pam_limits - when the file does not exist, do not create it in check mode
|
||||
(https://github.com/ansible-collections/community.general/issues/8050, https://github.com/ansible-collections/community.general/pull/8057).
|
||||
- proxmox_kvm - fixed status check getting from node-specific API endpoint (https://github.com/ansible-collections/community.general/issues/7817).
|
||||
release_summary: Regular bugfix release with security fixes.
|
||||
security_fixes:
|
||||
- cobbler, gitlab_runners, icinga2, linode, lxd, nmap, online, opennebula, proxmox,
|
||||
scaleway, stackpath_compute, virtualbox, and xen_orchestra inventory plugin
|
||||
- make sure all data received from the remote servers is marked as unsafe,
|
||||
so remote code execution by obtaining texts that can be evaluated as templates
|
||||
is not possible (https://www.die-welt.net/2024/03/remote-code-execution-in-ansible-dynamic-inventory-plugins/,
|
||||
https://github.com/ansible-collections/community.general/pull/8098).
|
||||
fragments:
|
||||
- 7.5.6.yml
|
||||
- 7880-ipa-fix-sudo-and-hbcalrule-idempotence.yml
|
||||
- 7953-proxmox_kvm-fix_status_check.yml
|
||||
- 8029-iptables-state-restore-check-mode.yml
|
||||
- 8048-fix-homebrew-module-error-reporting-on-become-true.yaml
|
||||
- 8057-pam_limits-check-mode.yml
|
||||
- 8133-add-error-message-for-linode-inventory-plugin.yaml
|
||||
- aix_filesystem-crfs-issue.yml
|
||||
- inventory-rce.yml
|
||||
- pacemaker-cluster.yml
|
||||
release_date: '2024-03-25'
|
||||
7.5.7:
|
||||
changes:
|
||||
bugfixes:
|
||||
- aix_filesystem - fix ``_validate_vg`` not passing VG name to ``lsvg_cmd``
|
||||
(https://github.com/ansible-collections/community.general/issues/8151).
|
||||
- apt_rpm - when checking whether packages were installed after running ``apt-get
|
||||
-y install <packages>``, only the last package name was checked (https://github.com/ansible-collections/community.general/pull/8263).
|
||||
- bitwarden_secrets_manager lookup plugin - implements retry with exponential
|
||||
backoff to avoid lookup errors when Bitwardn's API rate limiting is encountered
|
||||
(https://github.com/ansible-collections/community.general/issues/8230, https://github.com/ansible-collections/community.general/pull/8238).
|
||||
- haproxy - fix an issue where HAProxy could get stuck in DRAIN mode when the
|
||||
backend was unreachable (https://github.com/ansible-collections/community.general/issues/8092).
|
||||
- inventory plugins - add unsafe wrapper to avoid marking strings that do not
|
||||
contain ``{`` or ``}`` as unsafe, to work around a bug in AWX ((https://github.com/ansible-collections/community.general/issues/8212,
|
||||
https://github.com/ansible-collections/community.general/pull/8225).
|
||||
- ipa - fix get version regex in IPA module_utils (https://github.com/ansible-collections/community.general/pull/8175).
|
||||
- keycloak_client - add sorted ``defaultClientScopes`` and ``optionalClientScopes``
|
||||
to normalizations (https://github.com/ansible-collections/community.general/pull/8223).
|
||||
- keycloak_realm - add normalizations for ``enabledEventTypes`` and ``supportedLocales``
|
||||
(https://github.com/ansible-collections/community.general/pull/8224).
|
||||
- puppet - add option ``environment_lang`` to set the environment language encoding.
|
||||
Defaults to lang ``C``. It is recommended to set it to ``C.UTF-8`` or ``en_US.UTF-8``
|
||||
depending on what is available on your system. (https://github.com/ansible-collections/community.general/issues/8000)
|
||||
- riak - support ``riak admin`` sub-command in newer Riak KV versions beside
|
||||
the legacy ``riak-admin`` main command (https://github.com/ansible-collections/community.general/pull/8211).
|
||||
- xml - make module work with lxml 5.1.1, which removed some internals that
|
||||
the module was relying on (https://github.com/ansible-collections/community.general/pull/8169).
|
||||
release_summary: Regular bugfix release.
|
||||
fragments:
|
||||
- 7.5.7.yml
|
||||
- 8100-haproxy-drain-fails-on-down-backend.yml
|
||||
- 8151-fix-lsvg_cmd-failed.yml
|
||||
- 8169-lxml.yml
|
||||
- 8175-get_ipa_version_regex.yml
|
||||
- 8211-riak-admin-sub-command-support.yml
|
||||
- 8223-keycloak_client-additional-normalizations.yaml
|
||||
- 8224-keycloak_realm-add-normalizations.yaml
|
||||
- 8225-unsafe.yml
|
||||
- 8238-bitwarden-secrets-manager-rate-limit-retry-with-backoff.yml
|
||||
- 8263-apt_rpm-install-check.yml
|
||||
- puppet_lang_force.yml
|
||||
release_date: '2024-04-22'
|
||||
7.5.8:
|
||||
changes:
|
||||
bugfixes:
|
||||
- gitlab_runner - fix pagination when checking for existing runners (https://github.com/ansible-collections/community.general/pull/7790).
|
||||
- keycloak_user_federation - fix diff of empty ``krbPrincipalAttribute`` (https://github.com/ansible-collections/community.general/pull/8320).
|
||||
- opentelemetry callback plugin - close spans always (https://github.com/ansible-collections/community.general/pull/8367).
|
||||
- opentelemetry callback plugin - honour the ``disable_logs`` option to avoid
|
||||
storing task results since they are not used regardless (https://github.com/ansible-collections/community.general/pull/8373).
|
||||
minor_changes:
|
||||
- gitlab_deploy_key, gitlab_group_members, gitlab_group_variable, gitlab_hook,
|
||||
gitlab_instance_variable, gitlab_project_badge, gitlab_project_variable, gitlab_user
|
||||
- improve API pagination and compatibility with different versions of ``python-gitlab``
|
||||
(https://github.com/ansible-collections/community.general/pull/7790).
|
||||
release_summary: 'Regular bugfix release.
|
||||
|
||||
|
||||
Note that this is the last regular bugfix release. From now on, the 7.x.y
|
||||
release train
|
||||
|
||||
will only receive major and security bugfixes.
|
||||
|
||||
'
|
||||
security_fixes:
|
||||
- keycloak_identity_provider - the client secret was not correctly sanitized
|
||||
by the module. The return values ``proposed``, ``existing``, and ``end_state``,
|
||||
as well as the diff, did contain the client secret unmasked (https://github.com/ansible-collections/community.general/pull/8355).
|
||||
fragments:
|
||||
- 7.5.8.yml
|
||||
- 7790-gitlab-runner-api-pagination.yml
|
||||
- 8320-keycloak_user_federation-fix-diff-krbPrincipalAttribute.yaml
|
||||
- 8355-keycloak-idp-sanitize.yaml
|
||||
- 8367-fix-close-span-if-no-logs.yaml
|
||||
- 8373-honour-disable-logs.yaml
|
||||
release_date: '2024-05-20'
|
||||
|
||||
@@ -35,3 +35,6 @@ sections:
|
||||
- - known_issues
|
||||
- Known Issues
|
||||
title: Community General
|
||||
trivial_section_name: trivial
|
||||
use_fqcn: true
|
||||
add_plugin_period: true
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace: community
|
||||
name: general
|
||||
version: 7.5.5
|
||||
version: 7.5.8
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (https://github.com/ansible)
|
||||
|
||||
@@ -350,7 +350,8 @@ class OpenTelemetrySource(object):
|
||||
if not disable_logs:
|
||||
# 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)
|
||||
# Close span always
|
||||
span.end(end_time=host_data.finish)
|
||||
|
||||
def set_span_attributes(self, span, attributes):
|
||||
""" update the span attributes with the given attributes if not None """
|
||||
@@ -497,6 +498,12 @@ class CallbackModule(CallbackBase):
|
||||
# See https://github.com/open-telemetry/opentelemetry-specification/issues/740
|
||||
self.traceparent = self.get_option('traceparent')
|
||||
|
||||
def dump_results(self, result):
|
||||
""" dump the results if disable_logs is not enabled """
|
||||
if self.disable_logs:
|
||||
return ""
|
||||
return self._dump_results(result._result)
|
||||
|
||||
def v2_playbook_on_start(self, playbook):
|
||||
self.ansible_playbook = basename(playbook._file_name)
|
||||
|
||||
@@ -546,7 +553,7 @@ class CallbackModule(CallbackBase):
|
||||
self.tasks_data,
|
||||
status,
|
||||
result,
|
||||
self._dump_results(result._result)
|
||||
self.dump_results(result)
|
||||
)
|
||||
|
||||
def v2_runner_on_ok(self, result):
|
||||
@@ -554,7 +561,7 @@ class CallbackModule(CallbackBase):
|
||||
self.tasks_data,
|
||||
'ok',
|
||||
result,
|
||||
self._dump_results(result._result)
|
||||
self.dump_results(result)
|
||||
)
|
||||
|
||||
def v2_runner_on_skipped(self, result):
|
||||
@@ -562,7 +569,7 @@ class CallbackModule(CallbackBase):
|
||||
self.tasks_data,
|
||||
'skipped',
|
||||
result,
|
||||
self._dump_results(result._result)
|
||||
self.dump_results(result)
|
||||
)
|
||||
|
||||
def v2_playbook_on_include(self, included_file):
|
||||
|
||||
@@ -118,6 +118,8 @@ from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, to_safe_group_name
|
||||
from ansible.module_utils.six import text_type
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
# xmlrpc
|
||||
try:
|
||||
import xmlrpclib as xmlrpc_client
|
||||
@@ -274,9 +276,9 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||
for host in self._get_systems():
|
||||
# Get the FQDN for the host and add it to the right groups
|
||||
if self.inventory_hostname == 'system':
|
||||
hostname = host['name'] # None
|
||||
hostname = make_unsafe(host['name']) # None
|
||||
else:
|
||||
hostname = host['hostname'] # None
|
||||
hostname = make_unsafe(host['hostname']) # None
|
||||
interfaces = host['interfaces']
|
||||
|
||||
if set(host['mgmt_classes']) & set(self.include_mgmt_classes):
|
||||
@@ -296,7 +298,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||
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 != "":
|
||||
hostname = this_dns_name
|
||||
hostname = make_unsafe(this_dns_name)
|
||||
self.display.vvvv('Set hostname to %s from %s\n' % (hostname, iname))
|
||||
|
||||
if hostname == '':
|
||||
@@ -361,18 +363,18 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||
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)
|
||||
self.inventory.set_variable(hostname, 'cobbler_ipv4_address', make_unsafe(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)
|
||||
self.inventory.set_variable(hostname, 'cobbler_ipv6_address', make_unsafe(ipv6_address))
|
||||
|
||||
if self.get_option('want_facts'):
|
||||
try:
|
||||
self.inventory.set_variable(hostname, 'cobbler', host)
|
||||
self.inventory.set_variable(hostname, 'cobbler', make_unsafe(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)
|
||||
self.inventory.set_variable(self.group, 'cobbler_ipv4_addresses', make_unsafe(ip_addresses))
|
||||
self.inventory.set_variable(self.group, 'cobbler_ipv6_addresses', make_unsafe(ipv6_addresses))
|
||||
|
||||
@@ -85,6 +85,8 @@ from ansible.errors import AnsibleError, AnsibleParserError
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
try:
|
||||
import gitlab
|
||||
HAS_GITLAB = True
|
||||
@@ -106,11 +108,11 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
else:
|
||||
runners = gl.runners.all()
|
||||
for runner in runners:
|
||||
host = str(runner['id'])
|
||||
host = make_unsafe(str(runner['id']))
|
||||
ip_address = runner['ip_address']
|
||||
host_attrs = vars(gl.runners.get(runner['id']))['_attrs']
|
||||
host_attrs = make_unsafe(vars(gl.runners.get(runner['id']))['_attrs'])
|
||||
self.inventory.add_host(host, group='gitlab_runners')
|
||||
self.inventory.set_variable(host, 'ansible_host', ip_address)
|
||||
self.inventory.set_variable(host, 'ansible_host', make_unsafe(ip_address))
|
||||
if self.get_option('verbose_output', True):
|
||||
self.inventory.set_variable(host, 'gitlab_runner_attributes', host_attrs)
|
||||
|
||||
|
||||
@@ -97,6 +97,8 @@ from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.module_utils.six.moves.urllib.error import HTTPError
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
|
||||
class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
''' Host inventory parser for ansible using Icinga2 as source. '''
|
||||
@@ -233,15 +235,15 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
"""Convert Icinga2 API data to JSON format for Ansible"""
|
||||
groups_dict = {"_meta": {"hostvars": {}}}
|
||||
for entry in json_data:
|
||||
host_attrs = entry['attrs']
|
||||
host_attrs = make_unsafe(entry['attrs'])
|
||||
if self.inventory_attr == "name":
|
||||
host_name = entry.get('name')
|
||||
host_name = make_unsafe(entry.get('name'))
|
||||
if self.inventory_attr == "address":
|
||||
# When looking for address for inventory, if missing fallback to object name
|
||||
if host_attrs.get('address', '') != '':
|
||||
host_name = host_attrs.get('address')
|
||||
host_name = make_unsafe(host_attrs.get('address'))
|
||||
else:
|
||||
host_name = entry.get('name')
|
||||
host_name = make_unsafe(entry.get('name'))
|
||||
if self.inventory_attr == "display_name":
|
||||
host_name = host_attrs.get('display_name')
|
||||
if host_attrs['state'] == 0:
|
||||
@@ -257,7 +259,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
# If the address attribute is populated, override ansible_host with the value
|
||||
if host_attrs.get('address') != '':
|
||||
self.inventory.set_variable(host_name, 'ansible_host', host_attrs.get('address'))
|
||||
self.inventory.set_variable(host_name, 'hostname', entry.get('name'))
|
||||
self.inventory.set_variable(host_name, 'hostname', make_unsafe(entry.get('name')))
|
||||
self.inventory.set_variable(host_name, 'display_name', host_attrs.get('display_name'))
|
||||
self.inventory.set_variable(host_name, 'state',
|
||||
host_attrs['state'])
|
||||
|
||||
@@ -124,6 +124,8 @@ compose:
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
|
||||
try:
|
||||
from linode_api4 import LinodeClient
|
||||
@@ -199,20 +201,21 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
def _add_instances_to_groups(self):
|
||||
"""Add instance names to their dynamic inventory groups."""
|
||||
for instance in self.instances:
|
||||
self.inventory.add_host(instance.label, group=instance.group)
|
||||
self.inventory.add_host(make_unsafe(instance.label), group=instance.group)
|
||||
|
||||
def _add_hostvars_for_instances(self):
|
||||
"""Add hostvars for instances in the dynamic inventory."""
|
||||
ip_style = self.get_option('ip_style')
|
||||
for instance in self.instances:
|
||||
hostvars = instance._raw_json
|
||||
hostname = make_unsafe(instance.label)
|
||||
for hostvar_key in hostvars:
|
||||
if ip_style == 'api' and hostvar_key in ['ipv4', 'ipv6']:
|
||||
continue
|
||||
self.inventory.set_variable(
|
||||
instance.label,
|
||||
hostname,
|
||||
hostvar_key,
|
||||
hostvars[hostvar_key]
|
||||
make_unsafe(hostvars[hostvar_key])
|
||||
)
|
||||
if ip_style == 'api':
|
||||
ips = instance.ips.ipv4.public + instance.ips.ipv4.private
|
||||
@@ -221,9 +224,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
|
||||
for ip_type in set(ip.type for ip in ips):
|
||||
self.inventory.set_variable(
|
||||
instance.label,
|
||||
hostname,
|
||||
ip_type,
|
||||
self._ip_data([ip for ip in ips if ip.type == ip_type])
|
||||
make_unsafe(self._ip_data([ip for ip in ips if ip.type == ip_type]))
|
||||
)
|
||||
|
||||
def _ip_data(self, ip_list):
|
||||
@@ -254,30 +257,44 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
self._add_instances_to_groups()
|
||||
self._add_hostvars_for_instances()
|
||||
for instance in self.instances:
|
||||
variables = self.inventory.get_host(instance.label).get_vars()
|
||||
hostname = make_unsafe(instance.label)
|
||||
variables = self.inventory.get_host(hostname).get_vars()
|
||||
self._add_host_to_composed_groups(
|
||||
self.get_option('groups'),
|
||||
variables,
|
||||
instance.label,
|
||||
hostname,
|
||||
strict=strict)
|
||||
self._add_host_to_keyed_groups(
|
||||
self.get_option('keyed_groups'),
|
||||
variables,
|
||||
instance.label,
|
||||
hostname,
|
||||
strict=strict)
|
||||
self._set_composite_vars(
|
||||
self.get_option('compose'),
|
||||
variables,
|
||||
instance.label,
|
||||
hostname,
|
||||
strict=strict)
|
||||
|
||||
def verify_file(self, path):
|
||||
"""Verify the Linode configuration file."""
|
||||
"""Verify the Linode configuration file.
|
||||
|
||||
Return true/false if the config-file is valid for this plugin
|
||||
|
||||
Args:
|
||||
str(path): path to the config
|
||||
Kwargs:
|
||||
None
|
||||
Raises:
|
||||
None
|
||||
Returns:
|
||||
bool(valid): is valid config file"""
|
||||
valid = False
|
||||
if super(InventoryModule, self).verify_file(path):
|
||||
endings = ('linode.yaml', 'linode.yml')
|
||||
if any((path.endswith(ending) for ending in endings)):
|
||||
return True
|
||||
return False
|
||||
if path.endswith(("linode.yaml", "linode.yml")):
|
||||
valid = True
|
||||
else:
|
||||
self.display.vvv('Inventory source not ending in "linode.yaml" or "linode.yml"')
|
||||
return valid
|
||||
|
||||
def parse(self, inventory, loader, path, cache=True):
|
||||
"""Dynamically parse Linode the cloud inventory."""
|
||||
|
||||
@@ -161,6 +161,7 @@ from ansible.module_utils.six import raise_from
|
||||
from ansible.errors import AnsibleError, AnsibleParserError
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlencode
|
||||
from ansible_collections.community.general.plugins.module_utils.lxd import LXDClient, LXDClientException
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
try:
|
||||
import ipaddress
|
||||
@@ -656,7 +657,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||
|
||||
if self._get_data_entry('inventory/{0}/network_interfaces'.format(instance_name)): # instance have network interfaces
|
||||
self.inventory.set_variable(instance_name, 'ansible_connection', 'ssh')
|
||||
self.inventory.set_variable(instance_name, 'ansible_host', interface_selection(instance_name))
|
||||
self.inventory.set_variable(instance_name, 'ansible_host', make_unsafe(interface_selection(instance_name)))
|
||||
else:
|
||||
self.inventory.set_variable(instance_name, 'ansible_connection', 'local')
|
||||
|
||||
@@ -682,31 +683,39 @@ class InventoryModule(BaseInventoryPlugin):
|
||||
if self.filter.lower() != instance_state:
|
||||
continue
|
||||
# add instance
|
||||
instance_name = make_unsafe(instance_name)
|
||||
self.inventory.add_host(instance_name)
|
||||
# add network information
|
||||
self.build_inventory_network(instance_name)
|
||||
# add os
|
||||
v = self._get_data_entry('inventory/{0}/os'.format(instance_name))
|
||||
if v:
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_os', v.lower())
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_os', make_unsafe(v.lower()))
|
||||
# add release
|
||||
v = self._get_data_entry('inventory/{0}/release'.format(instance_name))
|
||||
if v:
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_release', v.lower())
|
||||
self.inventory.set_variable(
|
||||
instance_name, 'ansible_lxd_release', make_unsafe(v.lower()))
|
||||
# add profile
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_profile', self._get_data_entry('inventory/{0}/profile'.format(instance_name)))
|
||||
self.inventory.set_variable(
|
||||
instance_name, 'ansible_lxd_profile', make_unsafe(self._get_data_entry('inventory/{0}/profile'.format(instance_name))))
|
||||
# add state
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_state', instance_state)
|
||||
self.inventory.set_variable(
|
||||
instance_name, 'ansible_lxd_state', make_unsafe(instance_state))
|
||||
# add type
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_type', self._get_data_entry('inventory/{0}/type'.format(instance_name)))
|
||||
self.inventory.set_variable(
|
||||
instance_name, 'ansible_lxd_type', make_unsafe(self._get_data_entry('inventory/{0}/type'.format(instance_name))))
|
||||
# add location information
|
||||
if self._get_data_entry('inventory/{0}/location'.format(instance_name)) != "none": # wrong type by lxd 'none' != 'None'
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_location', self._get_data_entry('inventory/{0}/location'.format(instance_name)))
|
||||
self.inventory.set_variable(
|
||||
instance_name, 'ansible_lxd_location', make_unsafe(self._get_data_entry('inventory/{0}/location'.format(instance_name))))
|
||||
# add VLAN_ID information
|
||||
if self._get_data_entry('inventory/{0}/vlan_ids'.format(instance_name)):
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_vlan_ids', self._get_data_entry('inventory/{0}/vlan_ids'.format(instance_name)))
|
||||
self.inventory.set_variable(
|
||||
instance_name, 'ansible_lxd_vlan_ids', make_unsafe(self._get_data_entry('inventory/{0}/vlan_ids'.format(instance_name))))
|
||||
# add project
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_project', self._get_data_entry('inventory/{0}/project'.format(instance_name)))
|
||||
self.inventory.set_variable(
|
||||
instance_name, 'ansible_lxd_project', make_unsafe(self._get_data_entry('inventory/{0}/project'.format(instance_name))))
|
||||
|
||||
def build_inventory_groups_location(self, group_name):
|
||||
"""create group by attribute: location
|
||||
@@ -979,7 +988,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||
for group_name in self.groupby:
|
||||
if not group_name.isalnum():
|
||||
raise AnsibleParserError('Invalid character(s) in groupname: {0}'.format(to_native(group_name)))
|
||||
group_type(group_name)
|
||||
group_type(make_unsafe(group_name))
|
||||
|
||||
def build_inventory(self):
|
||||
"""Build dynamic inventory
|
||||
|
||||
@@ -127,6 +127,8 @@ from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
|
||||
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
|
||||
@@ -143,6 +145,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
strict = self.get_option('strict')
|
||||
|
||||
for host in hosts:
|
||||
host = make_unsafe(host)
|
||||
hostname = host['name']
|
||||
self.inventory.add_host(hostname)
|
||||
for var, value in host.items():
|
||||
|
||||
@@ -69,6 +69,8 @@ from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils.ansible_release import __version__ as ansible_version
|
||||
from ansible.module_utils.six.moves.urllib.parse import urljoin
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
|
||||
class InventoryModule(BaseInventoryPlugin):
|
||||
NAME = 'community.general.online'
|
||||
@@ -169,20 +171,20 @@ class InventoryModule(BaseInventoryPlugin):
|
||||
"support"
|
||||
)
|
||||
for attribute in targeted_attributes:
|
||||
self.inventory.set_variable(hostname, attribute, host_infos[attribute])
|
||||
self.inventory.set_variable(hostname, attribute, make_unsafe(host_infos[attribute]))
|
||||
|
||||
if self.extract_public_ipv4(host_infos=host_infos):
|
||||
self.inventory.set_variable(hostname, "public_ipv4", self.extract_public_ipv4(host_infos=host_infos))
|
||||
self.inventory.set_variable(hostname, "ansible_host", self.extract_public_ipv4(host_infos=host_infos))
|
||||
self.inventory.set_variable(hostname, "public_ipv4", make_unsafe(self.extract_public_ipv4(host_infos=host_infos)))
|
||||
self.inventory.set_variable(hostname, "ansible_host", make_unsafe(self.extract_public_ipv4(host_infos=host_infos)))
|
||||
|
||||
if self.extract_private_ipv4(host_infos=host_infos):
|
||||
self.inventory.set_variable(hostname, "public_ipv4", self.extract_private_ipv4(host_infos=host_infos))
|
||||
self.inventory.set_variable(hostname, "public_ipv4", make_unsafe(self.extract_private_ipv4(host_infos=host_infos)))
|
||||
|
||||
if self.extract_os_name(host_infos=host_infos):
|
||||
self.inventory.set_variable(hostname, "os_name", self.extract_os_name(host_infos=host_infos))
|
||||
self.inventory.set_variable(hostname, "os_name", make_unsafe(self.extract_os_name(host_infos=host_infos)))
|
||||
|
||||
if self.extract_os_version(host_infos=host_infos):
|
||||
self.inventory.set_variable(hostname, "os_version", self.extract_os_name(host_infos=host_infos))
|
||||
self.inventory.set_variable(hostname, "os_version", make_unsafe(self.extract_os_name(host_infos=host_infos)))
|
||||
|
||||
def _filter_host(self, host_infos, hostname_preferences):
|
||||
|
||||
@@ -201,6 +203,8 @@ class InventoryModule(BaseInventoryPlugin):
|
||||
if not hostname:
|
||||
return
|
||||
|
||||
hostname = make_unsafe(hostname)
|
||||
|
||||
self.inventory.add_host(host=hostname)
|
||||
self._fill_host_variables(hostname=hostname, host_infos=host_infos)
|
||||
|
||||
@@ -210,6 +214,8 @@ class InventoryModule(BaseInventoryPlugin):
|
||||
if not group:
|
||||
return
|
||||
|
||||
group = make_unsafe(group)
|
||||
|
||||
self.inventory.add_group(group=group)
|
||||
self.inventory.add_host(group=group, host=hostname)
|
||||
|
||||
|
||||
@@ -98,6 +98,8 @@ from ansible.errors import AnsibleError
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
from collections import namedtuple
|
||||
import os
|
||||
|
||||
@@ -215,6 +217,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
filter_by_label = self.get_option('filter_by_label')
|
||||
servers = self._retrieve_servers(filter_by_label)
|
||||
for server in servers:
|
||||
server = make_unsafe(server)
|
||||
hostname = server['name']
|
||||
# check for labels
|
||||
if group_by_labels and server['LABELS']:
|
||||
|
||||
@@ -224,6 +224,7 @@ from ansible.module_utils.six.moves.urllib.parse import urlencode
|
||||
from ansible.utils.display import Display
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
# 3rd party imports
|
||||
try:
|
||||
@@ -330,7 +331,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
|
||||
self._cache[self.cache_key][url] = data
|
||||
|
||||
return self._cache[self.cache_key][url]
|
||||
return make_unsafe(self._cache[self.cache_key][url])
|
||||
|
||||
def _get_nodes(self):
|
||||
return self._get_json("%s/api2/json/nodes" % self.proxmox_url)
|
||||
|
||||
@@ -121,6 +121,7 @@ else:
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||
from ansible_collections.community.general.plugins.module_utils.scaleway import SCALEWAY_LOCATION, parse_pagination_link
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.module_utils.six import raise_from
|
||||
@@ -279,7 +280,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
zone_info = SCALEWAY_LOCATION[zone]
|
||||
|
||||
url = _build_server_url(zone_info["api_endpoint"])
|
||||
raw_zone_hosts_infos = _fetch_information(url=url, token=token)
|
||||
raw_zone_hosts_infos = make_unsafe(_fetch_information(url=url, token=token))
|
||||
|
||||
for host_infos in raw_zone_hosts_infos:
|
||||
|
||||
@@ -341,4 +342,4 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
hostname_preference = self.get_option("hostnames")
|
||||
|
||||
for zone in self._get_zones(config_zones):
|
||||
self.do_zone_inventory(zone=zone, token=token, tags=tags, hostname_preferences=hostname_preference)
|
||||
self.do_zone_inventory(zone=make_unsafe(zone), token=token, tags=tags, hostname_preferences=hostname_preference)
|
||||
|
||||
@@ -73,6 +73,8 @@ from ansible.plugins.inventory import (
|
||||
)
|
||||
from ansible.utils.display import Display
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
|
||||
display = Display()
|
||||
|
||||
@@ -271,7 +273,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
if not cache or cache_needs_update:
|
||||
results = self._query()
|
||||
|
||||
self._populate(results)
|
||||
self._populate(make_unsafe(results))
|
||||
|
||||
# If the cache has expired/doesn't exist or
|
||||
# if refresh_inventory/flush cache is used
|
||||
|
||||
@@ -63,6 +63,8 @@ from ansible.module_utils.common._collections_compat import MutableMapping
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
|
||||
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
''' Host inventory parser for ansible using local virtualbox. '''
|
||||
@@ -116,6 +118,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
self._add_host_to_keyed_groups(self.get_option('keyed_groups'), hostvars[host], host, strict=strict)
|
||||
|
||||
def _populate_from_cache(self, source_data):
|
||||
source_data = make_unsafe(source_data)
|
||||
hostvars = source_data.pop('_meta', {}).get('hostvars', {})
|
||||
for group in source_data:
|
||||
if group == 'all':
|
||||
@@ -162,7 +165,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
v = v.strip()
|
||||
# found host
|
||||
if k.startswith('Name') and ',' not in v: # some setting strings appear in Name
|
||||
current_host = v
|
||||
current_host = make_unsafe(v)
|
||||
if current_host not in hostvars:
|
||||
hostvars[current_host] = {}
|
||||
self.inventory.add_host(current_host)
|
||||
@@ -170,12 +173,13 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
# try to get network info
|
||||
netdata = self._query_vbox_data(current_host, netinfo)
|
||||
if netdata:
|
||||
self.inventory.set_variable(current_host, 'ansible_host', netdata)
|
||||
self.inventory.set_variable(current_host, 'ansible_host', make_unsafe(netdata))
|
||||
|
||||
# found groups
|
||||
elif k == 'Groups':
|
||||
for group in v.split('/'):
|
||||
if group:
|
||||
group = make_unsafe(group)
|
||||
group = self.inventory.add_group(group)
|
||||
self.inventory.add_child(group, current_host)
|
||||
if group not in cacheable_results:
|
||||
@@ -185,17 +189,17 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
|
||||
else:
|
||||
# found vars, accumulate in hostvars for clean inventory set
|
||||
pref_k = 'vbox_' + k.strip().replace(' ', '_')
|
||||
pref_k = make_unsafe('vbox_' + k.strip().replace(' ', '_'))
|
||||
leading_spaces = len(k) - len(k.lstrip(' '))
|
||||
if 0 < leading_spaces <= 2:
|
||||
if prevkey not in hostvars[current_host] or not isinstance(hostvars[current_host][prevkey], dict):
|
||||
hostvars[current_host][prevkey] = {}
|
||||
hostvars[current_host][prevkey][pref_k] = v
|
||||
hostvars[current_host][prevkey][pref_k] = make_unsafe(v)
|
||||
elif leading_spaces > 2:
|
||||
continue
|
||||
else:
|
||||
if v != '':
|
||||
hostvars[current_host][pref_k] = v
|
||||
hostvars[current_host][pref_k] = make_unsafe(v)
|
||||
if self._ungrouped_host(current_host, cacheable_results):
|
||||
if 'ungrouped' not in cacheable_results:
|
||||
cacheable_results['ungrouped'] = {'hosts': []}
|
||||
|
||||
@@ -84,6 +84,7 @@ from ansible.errors import AnsibleError
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
# 3rd party imports
|
||||
try:
|
||||
@@ -347,4 +348,4 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
self.protocol = 'ws'
|
||||
|
||||
objects = self._get_objects()
|
||||
self._populate(objects)
|
||||
self._populate(make_unsafe(objects))
|
||||
|
||||
@@ -70,6 +70,7 @@ RETURN = """
|
||||
"""
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
from time import sleep
|
||||
|
||||
from ansible.errors import AnsibleLookupError
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
@@ -84,11 +85,29 @@ class BitwardenSecretsManagerException(AnsibleLookupError):
|
||||
class BitwardenSecretsManager(object):
|
||||
def __init__(self, path='bws'):
|
||||
self._cli_path = path
|
||||
self._max_retries = 3
|
||||
self._retry_delay = 1
|
||||
|
||||
@property
|
||||
def cli_path(self):
|
||||
return self._cli_path
|
||||
|
||||
def _run_with_retry(self, args, stdin=None, retries=0):
|
||||
out, err, rc = self._run(args, stdin)
|
||||
|
||||
if rc != 0:
|
||||
if retries >= self._max_retries:
|
||||
raise BitwardenSecretsManagerException("Max retries exceeded. Unable to retrieve secret.")
|
||||
|
||||
if "Too many requests" in err:
|
||||
delay = self._retry_delay * (2 ** retries)
|
||||
sleep(delay)
|
||||
return self._run_with_retry(args, stdin, retries + 1)
|
||||
else:
|
||||
raise BitwardenSecretsManagerException("Command failed with return code {rc}: {err}".format(rc=rc, err=err))
|
||||
|
||||
return out, err, rc
|
||||
|
||||
def _run(self, args, stdin=None):
|
||||
p = Popen([self.cli_path] + args, stdout=PIPE, stderr=PIPE, stdin=PIPE)
|
||||
out, err = p.communicate(stdin)
|
||||
@@ -107,7 +126,7 @@ class BitwardenSecretsManager(object):
|
||||
'get', 'secret', secret_id
|
||||
]
|
||||
|
||||
out, err, rc = self._run(params)
|
||||
out, err, rc = self._run_with_retry(params)
|
||||
if rc != 0:
|
||||
raise BitwardenSecretsManagerException(to_text(err))
|
||||
|
||||
|
||||
@@ -21,15 +21,30 @@ except ImportError:
|
||||
|
||||
import traceback
|
||||
|
||||
|
||||
def _determine_list_all_kwargs(version):
|
||||
gitlab_version = LooseVersion(version)
|
||||
if gitlab_version >= LooseVersion('4.0.0'):
|
||||
# 4.0.0 removed 'as_list'
|
||||
return {'iterator': True, 'per_page': 100}
|
||||
elif gitlab_version >= LooseVersion('3.7.0'):
|
||||
# 3.7.0 added 'get_all'
|
||||
return {'as_list': False, 'get_all': True, 'per_page': 100}
|
||||
else:
|
||||
return {'as_list': False, 'all': True, 'per_page': 100}
|
||||
|
||||
|
||||
GITLAB_IMP_ERR = None
|
||||
try:
|
||||
import gitlab
|
||||
import requests
|
||||
HAS_GITLAB_PACKAGE = True
|
||||
list_all_kwargs = _determine_list_all_kwargs(gitlab.__version__)
|
||||
except Exception:
|
||||
gitlab = None
|
||||
GITLAB_IMP_ERR = traceback.format_exc()
|
||||
HAS_GITLAB_PACKAGE = False
|
||||
list_all_kwargs = {}
|
||||
|
||||
|
||||
def auth_argument_spec(spec=None):
|
||||
|
||||
@@ -104,7 +104,7 @@ class IPAClient(object):
|
||||
|
||||
def get_ipa_version(self):
|
||||
response = self.ping()['summary']
|
||||
ipa_ver_regex = re.compile(r'IPA server version (\d\.\d\.\d).*')
|
||||
ipa_ver_regex = re.compile(r'IPA server version (\d+\.\d+\.\d+).*')
|
||||
version_match = ipa_ver_regex.match(response)
|
||||
ipa_version = None
|
||||
if version_match:
|
||||
|
||||
@@ -107,5 +107,6 @@ def puppet_runner(module):
|
||||
verbose=cmd_runner_fmt.as_bool("--verbose"),
|
||||
),
|
||||
check_rc=False,
|
||||
force_lang=module.params["environment_lang"],
|
||||
)
|
||||
return runner
|
||||
|
||||
@@ -38,8 +38,8 @@ options:
|
||||
type: list
|
||||
elements: str
|
||||
default:
|
||||
- agblksize='4096'
|
||||
- isnapshot='no'
|
||||
- agblksize=4096
|
||||
- isnapshot=no
|
||||
auto_mount:
|
||||
description:
|
||||
- File system is automatically mounted at system restart.
|
||||
@@ -242,7 +242,7 @@ def _validate_vg(module, vg):
|
||||
if rc != 0:
|
||||
module.fail_json(msg="Failed executing %s command." % lsvg_cmd)
|
||||
|
||||
rc, current_all_vgs, err = module.run_command([lsvg_cmd, "%s"])
|
||||
rc, current_all_vgs, err = module.run_command([lsvg_cmd])
|
||||
if rc != 0:
|
||||
module.fail_json(msg="Failed executing %s command." % lsvg_cmd)
|
||||
|
||||
@@ -365,7 +365,53 @@ def create_fs(
|
||||
# Creates a LVM file system.
|
||||
crfs_cmd = module.get_bin_path('crfs', True)
|
||||
if not module.check_mode:
|
||||
cmd = [crfs_cmd, "-v", fs_type, "-m", filesystem, vg, device, mount_group, auto_mount, account_subsystem, "-p", permissions, size, "-a", attributes]
|
||||
cmd = [crfs_cmd]
|
||||
|
||||
cmd.append("-v")
|
||||
cmd.append(fs_type)
|
||||
|
||||
if vg:
|
||||
(flag, value) = vg.split()
|
||||
cmd.append(flag)
|
||||
cmd.append(value)
|
||||
|
||||
if device:
|
||||
(flag, value) = device.split()
|
||||
cmd.append(flag)
|
||||
cmd.append(value)
|
||||
|
||||
cmd.append("-m")
|
||||
cmd.append(filesystem)
|
||||
|
||||
if mount_group:
|
||||
(flag, value) = mount_group.split()
|
||||
cmd.append(flag)
|
||||
cmd.append(value)
|
||||
|
||||
if auto_mount:
|
||||
(flag, value) = auto_mount.split()
|
||||
cmd.append(flag)
|
||||
cmd.append(value)
|
||||
|
||||
if account_subsystem:
|
||||
(flag, value) = account_subsystem.split()
|
||||
cmd.append(flag)
|
||||
cmd.append(value)
|
||||
|
||||
cmd.append("-p")
|
||||
cmd.append(permissions)
|
||||
|
||||
if size:
|
||||
(flag, value) = size.split()
|
||||
cmd.append(flag)
|
||||
cmd.append(value)
|
||||
|
||||
if attributes:
|
||||
splitted_attributes = attributes.split()
|
||||
cmd.append("-a")
|
||||
for value in splitted_attributes:
|
||||
cmd.append(value)
|
||||
|
||||
rc, crfs_out, err = module.run_command(cmd)
|
||||
|
||||
if rc == 10:
|
||||
@@ -461,7 +507,7 @@ def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
account_subsystem=dict(type='bool', default=False),
|
||||
attributes=dict(type='list', elements='str', default=["agblksize='4096'", "isnapshot='no'"]),
|
||||
attributes=dict(type='list', elements='str', default=["agblksize=4096", "isnapshot=no"]),
|
||||
auto_mount=dict(type='bool', default=True),
|
||||
device=dict(type='str'),
|
||||
filesystem=dict(type='str', required=True),
|
||||
|
||||
@@ -204,7 +204,7 @@ def install_packages(module, pkgspec):
|
||||
rc, out, err = module.run_command("%s -y install %s" % (APT_PATH, packages), environ_update={"LANG": "C"})
|
||||
|
||||
installed = True
|
||||
for packages in pkgspec:
|
||||
for package in pkgspec:
|
||||
if not query_package_provides(module, package):
|
||||
installed = False
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ class EjabberdUser(object):
|
||||
object manages user creation and deletion using ejabberdctl. The following
|
||||
commands are currently supported:
|
||||
* ejabberdctl register
|
||||
* ejabberdctl deregister
|
||||
* ejabberdctl unregister
|
||||
"""
|
||||
|
||||
def __init__(self, module):
|
||||
|
||||
@@ -121,7 +121,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, find_project, gitlab_authentication, gitlab, ensure_gitlab_package
|
||||
auth_argument_spec, find_project, gitlab_authentication, gitlab, ensure_gitlab_package, list_all_kwargs
|
||||
)
|
||||
|
||||
|
||||
@@ -209,8 +209,7 @@ class GitLabDeployKey(object):
|
||||
@param key_title Title of the key
|
||||
'''
|
||||
def find_deploy_key(self, project, key_title):
|
||||
deploy_keys = project.keys.list(all=True)
|
||||
for deploy_key in deploy_keys:
|
||||
for deploy_key in project.keys.list(**list_all_kwargs):
|
||||
if (deploy_key.title == key_title):
|
||||
return deploy_key
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, gitlab, ensure_gitlab_package
|
||||
auth_argument_spec, gitlab_authentication, gitlab, ensure_gitlab_package, list_all_kwargs
|
||||
)
|
||||
|
||||
|
||||
@@ -171,16 +171,20 @@ class GitLabGroup(object):
|
||||
|
||||
# get user id if the user exists
|
||||
def get_user_id(self, gitlab_user):
|
||||
user_exists = self._gitlab.users.list(username=gitlab_user, all=True)
|
||||
if user_exists:
|
||||
return user_exists[0].id
|
||||
return next(
|
||||
(u.id for u in self._gitlab.users.list(username=gitlab_user, **list_all_kwargs)),
|
||||
None
|
||||
)
|
||||
|
||||
# get group id if group exists
|
||||
def get_group_id(self, gitlab_group):
|
||||
groups = self._gitlab.groups.list(search=gitlab_group, all=True)
|
||||
for group in groups:
|
||||
if group.full_path == gitlab_group:
|
||||
return group.id
|
||||
return next(
|
||||
(
|
||||
g.id for g in self._gitlab.groups.list(search=gitlab_group, **list_all_kwargs)
|
||||
if g.full_path == gitlab_group
|
||||
),
|
||||
None
|
||||
)
|
||||
|
||||
# get all members in a group
|
||||
def get_members_in_a_group(self, gitlab_group_id):
|
||||
|
||||
@@ -207,7 +207,8 @@ group_variable:
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, ensure_gitlab_package, filter_returned_variables, vars_to_variables
|
||||
auth_argument_spec, gitlab_authentication, ensure_gitlab_package, filter_returned_variables, vars_to_variables,
|
||||
list_all_kwargs
|
||||
)
|
||||
|
||||
|
||||
@@ -222,14 +223,7 @@ class GitlabGroupVariables(object):
|
||||
return self.repo.groups.get(group_name)
|
||||
|
||||
def list_all_group_variables(self):
|
||||
page_nb = 1
|
||||
variables = []
|
||||
vars_page = self.group.variables.list(page=page_nb)
|
||||
while len(vars_page) > 0:
|
||||
variables += vars_page
|
||||
page_nb += 1
|
||||
vars_page = self.group.variables.list(page=page_nb)
|
||||
return variables
|
||||
return list(self.group.variables.list(**list_all_kwargs))
|
||||
|
||||
def create_variable(self, var_obj):
|
||||
if self._module.check_mode:
|
||||
|
||||
@@ -171,7 +171,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, find_project, gitlab_authentication, ensure_gitlab_package
|
||||
auth_argument_spec, find_project, gitlab_authentication, ensure_gitlab_package, list_all_kwargs
|
||||
)
|
||||
|
||||
|
||||
@@ -266,8 +266,7 @@ class GitLabHook(object):
|
||||
@param hook_url Url to call on event
|
||||
'''
|
||||
def find_hook(self, project, hook_url):
|
||||
hooks = project.hooks.list(all=True)
|
||||
for hook in hooks:
|
||||
for hook in project.hooks.list(**list_all_kwargs):
|
||||
if (hook.url == hook_url):
|
||||
return hook
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ instance_variable:
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, ensure_gitlab_package, filter_returned_variables
|
||||
auth_argument_spec, gitlab_authentication, ensure_gitlab_package, filter_returned_variables, list_all_kwargs
|
||||
)
|
||||
|
||||
|
||||
@@ -150,14 +150,7 @@ class GitlabInstanceVariables(object):
|
||||
self._module = module
|
||||
|
||||
def list_all_instance_variables(self):
|
||||
page_nb = 1
|
||||
variables = []
|
||||
gl_varibales_page = self.instance.variables.list(page=page_nb)
|
||||
while len(gl_varibales_page) > 0:
|
||||
variables += gl_varibales_page
|
||||
page_nb += 1
|
||||
gl_varibales_page = self.instance.variables.list(page=page_nb)
|
||||
return variables
|
||||
return list(self.instance.variables.list(**list_all_kwargs))
|
||||
|
||||
def create_variable(self, var_obj):
|
||||
if self._module.check_mode:
|
||||
|
||||
@@ -97,7 +97,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, find_project, ensure_gitlab_package
|
||||
auth_argument_spec, gitlab_authentication, find_project, ensure_gitlab_package, list_all_kwargs
|
||||
)
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ def present_strategy(module, gl, project, wished_badge):
|
||||
changed = False
|
||||
|
||||
existing_badge = None
|
||||
for badge in project.badges.list(iterator=True):
|
||||
for badge in project.badges.list(**list_all_kwargs):
|
||||
if badge.image_url == wished_badge["image_url"]:
|
||||
existing_badge = badge
|
||||
break
|
||||
@@ -135,7 +135,7 @@ def absent_strategy(module, gl, project, wished_badge):
|
||||
changed = False
|
||||
|
||||
existing_badge = None
|
||||
for badge in project.badges.list(iterator=True):
|
||||
for badge in project.badges.list(**list_all_kwargs):
|
||||
if badge.image_url == wished_badge["image_url"]:
|
||||
existing_badge = badge
|
||||
break
|
||||
|
||||
@@ -227,7 +227,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, ensure_gitlab_package, filter_returned_variables, vars_to_variables,
|
||||
HAS_GITLAB_PACKAGE, GITLAB_IMP_ERR
|
||||
list_all_kwargs, HAS_GITLAB_PACKAGE, GITLAB_IMP_ERR
|
||||
)
|
||||
|
||||
|
||||
@@ -242,14 +242,7 @@ class GitlabProjectVariables(object):
|
||||
return self.repo.projects.get(project_name)
|
||||
|
||||
def list_all_project_variables(self):
|
||||
page_nb = 1
|
||||
variables = []
|
||||
vars_page = self.project.variables.list(page=page_nb)
|
||||
while len(vars_page) > 0:
|
||||
variables += vars_page
|
||||
page_nb += 1
|
||||
vars_page = self.project.variables.list(page=page_nb)
|
||||
return variables
|
||||
return list(self.project.variables.list(**list_all_kwargs))
|
||||
|
||||
def create_variable(self, var_obj):
|
||||
if self._module.check_mode:
|
||||
|
||||
@@ -206,7 +206,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, gitlab, ensure_gitlab_package
|
||||
auth_argument_spec, gitlab_authentication, gitlab, ensure_gitlab_package, list_all_kwargs
|
||||
)
|
||||
|
||||
|
||||
@@ -309,7 +309,7 @@ class GitLabRunner(object):
|
||||
@param description Description of the runner
|
||||
'''
|
||||
def find_runner(self, description):
|
||||
runners = self._runners_endpoint(as_list=False)
|
||||
runners = self._runners_endpoint(**list_all_kwargs)
|
||||
|
||||
for runner in runners:
|
||||
# python-gitlab 2.2 through at least 2.5 returns a list of dicts for list() instead of a Runner
|
||||
|
||||
@@ -234,7 +234,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, find_group, gitlab_authentication, gitlab, ensure_gitlab_package
|
||||
auth_argument_spec, find_group, gitlab_authentication, gitlab, ensure_gitlab_package, list_all_kwargs
|
||||
)
|
||||
|
||||
|
||||
@@ -349,9 +349,10 @@ class GitLabUser(object):
|
||||
@param sshkey_name Name of the ssh key
|
||||
'''
|
||||
def ssh_key_exists(self, user, sshkey_name):
|
||||
keyList = map(lambda k: k.title, user.keys.list(all=True))
|
||||
|
||||
return sshkey_name in keyList
|
||||
return any(
|
||||
k.title == sshkey_name
|
||||
for k in user.keys.list(**list_all_kwargs)
|
||||
)
|
||||
|
||||
'''
|
||||
@param user User object
|
||||
@@ -519,10 +520,13 @@ class GitLabUser(object):
|
||||
@param username Username of the user
|
||||
'''
|
||||
def find_user(self, username):
|
||||
users = self._gitlab.users.list(search=username, all=True)
|
||||
for user in users:
|
||||
if (user.username == username):
|
||||
return user
|
||||
return next(
|
||||
(
|
||||
user for user in self._gitlab.users.list(search=username, **list_all_kwargs)
|
||||
if user.username == username
|
||||
),
|
||||
None
|
||||
)
|
||||
|
||||
'''
|
||||
@param username Username of the user
|
||||
|
||||
@@ -343,7 +343,7 @@ class HAProxy(object):
|
||||
|
||||
if state is not None:
|
||||
self.execute(Template(cmd).substitute(pxname=backend, svname=svname))
|
||||
if self.wait:
|
||||
if self.wait and not (wait_for_status == "DRAIN" and state == "DOWN"):
|
||||
self.wait_until_status(backend, svname, wait_for_status)
|
||||
|
||||
def get_state_for(self, pxname, svname):
|
||||
|
||||
@@ -488,6 +488,10 @@ class Homebrew(object):
|
||||
self.current_package,
|
||||
]
|
||||
rc, out, err = self.module.run_command(cmd)
|
||||
if err:
|
||||
self.failed = True
|
||||
self.message = err.strip()
|
||||
raise HomebrewException(self.message)
|
||||
data = json.loads(out)
|
||||
|
||||
return _check_package_in_json(data, "formulae") or _check_package_in_json(data, "casks")
|
||||
|
||||
@@ -70,7 +70,8 @@ options:
|
||||
does not exist it will fail.
|
||||
notes:
|
||||
- "This module depends on the C(passlib) Python library, which needs to be installed on all target systems."
|
||||
- "On Debian, Ubuntu, or Fedora: install C(python-passlib)."
|
||||
- "On Debian < 11, Ubuntu <= 20.04, or Fedora: install C(python-passlib)."
|
||||
- "On Debian, Ubuntu: install C(python3-passlib)."
|
||||
- "On RHEL or CentOS: Enable EPEL, then install C(python-passlib)."
|
||||
requirements: [ passlib>=1.6 ]
|
||||
author: "Ansible Core Team"
|
||||
|
||||
@@ -161,6 +161,7 @@ import traceback
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.general.plugins.module_utils.ipa import IPAClient, ipa_argument_spec
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
|
||||
class HBACRuleIPAClient(IPAClient):
|
||||
@@ -231,10 +232,17 @@ def ensure(module, client):
|
||||
name = module.params['cn']
|
||||
state = module.params['state']
|
||||
|
||||
ipa_version = client.get_ipa_version()
|
||||
if state in ['present', 'enabled']:
|
||||
ipaenabledflag = 'TRUE'
|
||||
if LooseVersion(ipa_version) < LooseVersion('4.9.10'):
|
||||
ipaenabledflag = 'TRUE'
|
||||
else:
|
||||
ipaenabledflag = True
|
||||
else:
|
||||
ipaenabledflag = 'FALSE'
|
||||
if LooseVersion(ipa_version) < LooseVersion('4.9.10'):
|
||||
ipaenabledflag = 'FALSE'
|
||||
else:
|
||||
ipaenabledflag = False
|
||||
|
||||
host = module.params['host']
|
||||
hostcategory = module.params['hostcategory']
|
||||
|
||||
@@ -186,6 +186,7 @@ import traceback
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.general.plugins.module_utils.ipa import IPAClient, ipa_argument_spec
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
|
||||
class SudoRuleIPAClient(IPAClient):
|
||||
@@ -310,10 +311,17 @@ def ensure(module, client):
|
||||
runasgroupcategory = module.params['runasgroupcategory']
|
||||
runasextusers = module.params['runasextusers']
|
||||
|
||||
ipa_version = client.get_ipa_version()
|
||||
if state in ['present', 'enabled']:
|
||||
ipaenabledflag = 'TRUE'
|
||||
if LooseVersion(ipa_version) < LooseVersion('4.9.10'):
|
||||
ipaenabledflag = 'TRUE'
|
||||
else:
|
||||
ipaenabledflag = True
|
||||
else:
|
||||
ipaenabledflag = 'FALSE'
|
||||
if LooseVersion(ipa_version) < LooseVersion('4.9.10'):
|
||||
ipaenabledflag = 'FALSE'
|
||||
else:
|
||||
ipaenabledflag = False
|
||||
|
||||
sudoopt = module.params['sudoopt']
|
||||
user = module.params['user']
|
||||
|
||||
@@ -207,7 +207,9 @@ saved:
|
||||
"# Completed"
|
||||
]
|
||||
tables:
|
||||
description: The iptables we have interest for when module starts.
|
||||
description:
|
||||
- The iptables on the system before the module has run, separated by table.
|
||||
- If the option O(table) is used, only this table is included.
|
||||
type: dict
|
||||
contains:
|
||||
table:
|
||||
@@ -346,20 +348,27 @@ def filter_and_format_state(string):
|
||||
return lines
|
||||
|
||||
|
||||
def per_table_state(command, state):
|
||||
def parse_per_table_state(all_states_dump):
|
||||
'''
|
||||
Convert raw iptables-save output into usable datastructure, for reliable
|
||||
comparisons between initial and final states.
|
||||
'''
|
||||
lines = filter_and_format_state(all_states_dump)
|
||||
tables = dict()
|
||||
for t in TABLES:
|
||||
COMMAND = list(command)
|
||||
if '*%s' % t in state.splitlines():
|
||||
COMMAND.extend(['--table', t])
|
||||
dummy, out, dummy = module.run_command(COMMAND, check_rc=True)
|
||||
out = re.sub(r'(^|\n)(# Generated|# Completed|[*]%s|COMMIT)[^\n]*' % t, r'', out)
|
||||
out = re.sub(r' *\[[0-9]+:[0-9]+\] *', r'', out)
|
||||
tables[t] = [tt for tt in out.splitlines() if tt != '']
|
||||
current_table = ''
|
||||
current_list = list()
|
||||
for line in lines:
|
||||
if re.match(r'^[*](filter|mangle|nat|raw|security)$', line):
|
||||
current_table = line[1:]
|
||||
continue
|
||||
if line == 'COMMIT':
|
||||
tables[current_table] = current_list
|
||||
current_table = ''
|
||||
current_list = list()
|
||||
continue
|
||||
if line.startswith('# '):
|
||||
continue
|
||||
current_list.append(line)
|
||||
return tables
|
||||
|
||||
|
||||
@@ -486,7 +495,7 @@ def main():
|
||||
# Depending on the value of 'table', initref_state may differ from
|
||||
# initial_state.
|
||||
(rc, stdout, stderr) = module.run_command(SAVECOMMAND, check_rc=True)
|
||||
tables_before = per_table_state(SAVECOMMAND, stdout)
|
||||
tables_before = parse_per_table_state(stdout)
|
||||
initref_state = filter_and_format_state(stdout)
|
||||
|
||||
if state == 'saved':
|
||||
@@ -583,14 +592,17 @@ def main():
|
||||
|
||||
(rc, stdout, stderr) = module.run_command(SAVECOMMAND, check_rc=True)
|
||||
restored_state = filter_and_format_state(stdout)
|
||||
|
||||
tables_after = parse_per_table_state('\n'.join(restored_state))
|
||||
if restored_state not in (initref_state, initial_state):
|
||||
if module.check_mode:
|
||||
changed = True
|
||||
else:
|
||||
tables_after = per_table_state(SAVECOMMAND, stdout)
|
||||
if tables_after != tables_before:
|
||||
for table_name, table_content in tables_after.items():
|
||||
if table_name not in tables_before:
|
||||
# Would initialize a table, which doesn't exist yet
|
||||
changed = True
|
||||
break
|
||||
if tables_before[table_name] != table_content:
|
||||
# Content of some table changes
|
||||
changed = True
|
||||
break
|
||||
|
||||
if _back is None or module.check_mode:
|
||||
module.exit_json(
|
||||
@@ -633,7 +645,7 @@ def main():
|
||||
os.remove(b_back)
|
||||
|
||||
(rc, stdout, stderr) = module.run_command(SAVECOMMAND, check_rc=True)
|
||||
tables_rollback = per_table_state(SAVECOMMAND, stdout)
|
||||
tables_rollback = parse_per_table_state(stdout)
|
||||
|
||||
msg = (
|
||||
"Failed to confirm state restored from %s after %ss. "
|
||||
|
||||
@@ -742,6 +742,12 @@ def normalise_cr(clientrep, remove_ids=False):
|
||||
if 'attributes' in clientrep:
|
||||
clientrep['attributes'] = list(sorted(clientrep['attributes']))
|
||||
|
||||
if 'defaultClientScopes' in clientrep:
|
||||
clientrep['defaultClientScopes'] = list(sorted(clientrep['defaultClientScopes']))
|
||||
|
||||
if 'optionalClientScopes' in clientrep:
|
||||
clientrep['optionalClientScopes'] = list(sorted(clientrep['optionalClientScopes']))
|
||||
|
||||
if 'redirectUris' in clientrep:
|
||||
clientrep['redirectUris'] = list(sorted(clientrep['redirectUris']))
|
||||
|
||||
|
||||
@@ -437,7 +437,7 @@ def sanitize(idp):
|
||||
idpcopy = deepcopy(idp)
|
||||
if 'config' in idpcopy:
|
||||
if 'clientSecret' in idpcopy['config']:
|
||||
idpcopy['clientSecret'] = '**********'
|
||||
idpcopy['config']['clientSecret'] = '**********'
|
||||
return idpcopy
|
||||
|
||||
|
||||
|
||||
@@ -582,6 +582,27 @@ from ansible_collections.community.general.plugins.module_utils.identity.keycloa
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
|
||||
def normalise_cr(realmrep):
|
||||
""" Re-sorts any properties where the order is important so that diff's is minimised and the change detection is more effective.
|
||||
|
||||
:param realmrep: the realmrep dict to be sanitized
|
||||
:return: normalised realmrep dict
|
||||
"""
|
||||
# Avoid the dict passed in to be modified
|
||||
realmrep = realmrep.copy()
|
||||
|
||||
if 'enabledEventTypes' in realmrep:
|
||||
realmrep['enabledEventTypes'] = list(sorted(realmrep['enabledEventTypes']))
|
||||
|
||||
if 'otpSupportedApplications' in realmrep:
|
||||
realmrep['otpSupportedApplications'] = list(sorted(realmrep['otpSupportedApplications']))
|
||||
|
||||
if 'supportedLocales' in realmrep:
|
||||
realmrep['supportedLocales'] = list(sorted(realmrep['supportedLocales']))
|
||||
|
||||
return realmrep
|
||||
|
||||
|
||||
def sanitize_cr(realmrep):
|
||||
""" Removes probably sensitive details from a realm representation.
|
||||
|
||||
@@ -595,7 +616,7 @@ def sanitize_cr(realmrep):
|
||||
if 'saml.signing.private.key' in result['attributes']:
|
||||
result['attributes'] = result['attributes'].copy()
|
||||
result['attributes']['saml.signing.private.key'] = '********'
|
||||
return result
|
||||
return normalise_cr(result)
|
||||
|
||||
|
||||
def main():
|
||||
@@ -777,9 +798,11 @@ def main():
|
||||
result['changed'] = True
|
||||
if module.check_mode:
|
||||
# We can only compare the current realm with the proposed updates we have
|
||||
before_norm = normalise_cr(before_realm)
|
||||
desired_norm = normalise_cr(desired_realm)
|
||||
if module._diff:
|
||||
result['diff'] = dict(before=before_realm_sanitized,
|
||||
after=sanitize_cr(desired_realm))
|
||||
result['diff'] = dict(before=sanitize_cr(before_norm),
|
||||
after=sanitize_cr(desired_norm))
|
||||
result['changed'] = (before_realm != desired_realm)
|
||||
|
||||
module.exit_json(**result)
|
||||
|
||||
@@ -712,6 +712,9 @@ def sanitize(comp):
|
||||
compcopy['config'] = dict((k, v[0]) for k, v in compcopy['config'].items())
|
||||
if 'bindCredential' in compcopy['config']:
|
||||
compcopy['config']['bindCredential'] = '**********'
|
||||
# an empty string is valid for krbPrincipalAttribute but is filtered out in diff
|
||||
if 'krbPrincipalAttribute' not in compcopy['config']:
|
||||
compcopy['config']['krbPrincipalAttribute'] = ''
|
||||
if 'mappers' in compcopy:
|
||||
for mapper in compcopy['mappers']:
|
||||
if 'config' in mapper:
|
||||
|
||||
@@ -44,6 +44,8 @@ options:
|
||||
type: str
|
||||
description:
|
||||
- The LDAP scope to use.
|
||||
- V(subordinate) requires the LDAPv3 subordinate feature extension.
|
||||
- V(children) is equivalent to a "subtree" scope.
|
||||
filter:
|
||||
default: '(objectClass=*)'
|
||||
type: str
|
||||
|
||||
@@ -86,8 +86,8 @@ options:
|
||||
source:
|
||||
description:
|
||||
- 'The source for the instance
|
||||
(for example V({ "type": "image", "mode": "pull", "server": "https://images.linuxcontainers.org",
|
||||
"protocol": "lxd", "alias": "ubuntu/xenial/amd64" })).'
|
||||
(for example V({ "type": "image", "mode": "pull", "server": "https://cloud-images.ubuntu.com/releases/",
|
||||
"protocol": "simplestreams", "alias": "22.04" })).'
|
||||
- 'See U(https://documentation.ubuntu.com/lxd/en/latest/api/) for complete API documentation.'
|
||||
- 'Note that C(protocol) accepts two choices: V(lxd) or V(simplestreams).'
|
||||
required: false
|
||||
@@ -205,6 +205,9 @@ notes:
|
||||
- You can copy a file in the created instance to the localhost
|
||||
with C(command=lxc file pull instance_name/dir/filename filename).
|
||||
See the first example below.
|
||||
- linuxcontainers.org has phased out LXC/LXD support with March 2024
|
||||
(U(https://discuss.linuxcontainers.org/t/important-notice-for-lxd-users-image-server/18479)).
|
||||
Currently only Ubuntu is still providing images.
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -220,9 +223,9 @@ EXAMPLES = '''
|
||||
source:
|
||||
type: image
|
||||
mode: pull
|
||||
server: https://images.linuxcontainers.org
|
||||
protocol: lxd # if you get a 404, try setting protocol: simplestreams
|
||||
alias: ubuntu/xenial/amd64
|
||||
server: https://cloud-images.ubuntu.com/releases/
|
||||
protocol: simplestreams
|
||||
alias: "22.04"
|
||||
profiles: ["default"]
|
||||
wait_for_ipv4_addresses: true
|
||||
timeout: 600
|
||||
@@ -264,6 +267,26 @@ EXAMPLES = '''
|
||||
wait_for_ipv4_addresses: true
|
||||
timeout: 600
|
||||
|
||||
# An example of creating a ubuntu-minial container
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
tasks:
|
||||
- name: Create a started container
|
||||
community.general.lxd_container:
|
||||
name: mycontainer
|
||||
ignore_volatile_options: true
|
||||
state: started
|
||||
source:
|
||||
type: image
|
||||
mode: pull
|
||||
# Provides Ubuntu minimal images
|
||||
server: https://cloud-images.ubuntu.com/minimal/releases/
|
||||
protocol: simplestreams
|
||||
alias: "22.04"
|
||||
profiles: ["default"]
|
||||
wait_for_ipv4_addresses: true
|
||||
timeout: 600
|
||||
|
||||
# An example for creating container in project other than default
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
@@ -278,8 +301,8 @@ EXAMPLES = '''
|
||||
protocol: simplestreams
|
||||
type: image
|
||||
mode: pull
|
||||
server: https://images.linuxcontainers.org
|
||||
alias: ubuntu/20.04/cloud
|
||||
server: https://cloud-images.ubuntu.com/releases/
|
||||
alias: "22.04"
|
||||
profiles: ["default"]
|
||||
wait_for_ipv4_addresses: true
|
||||
timeout: 600
|
||||
@@ -347,7 +370,7 @@ EXAMPLES = '''
|
||||
source:
|
||||
type: image
|
||||
mode: pull
|
||||
alias: ubuntu/xenial/amd64
|
||||
alias: "22.04"
|
||||
target: node01
|
||||
|
||||
- name: Create container on another node
|
||||
@@ -358,7 +381,7 @@ EXAMPLES = '''
|
||||
source:
|
||||
type: image
|
||||
mode: pull
|
||||
alias: ubuntu/xenial/amd64
|
||||
alias: "22.04"
|
||||
target: node02
|
||||
|
||||
# An example for creating a virtual machine
|
||||
|
||||
@@ -188,6 +188,8 @@ def main():
|
||||
if cluster_state == state:
|
||||
module.exit_json(changed=changed, out=cluster_state)
|
||||
else:
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=True)
|
||||
set_cluster(module, state, timeout, force)
|
||||
cluster_state = get_cluster_status(module)
|
||||
if cluster_state == state:
|
||||
@@ -201,12 +203,16 @@ def main():
|
||||
if node_state[1].strip().lower() == state:
|
||||
module.exit_json(changed=changed, out=cluster_state)
|
||||
else:
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=True)
|
||||
# Set cluster status if needed
|
||||
set_cluster(module, state, timeout, force)
|
||||
cluster_state = get_node_status(module, node)
|
||||
module.exit_json(changed=True, out=cluster_state)
|
||||
|
||||
if state in ['restart']:
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=True)
|
||||
set_cluster(module, 'offline', timeout, force)
|
||||
cluster_state = get_cluster_status(module)
|
||||
if cluster_state == 'offline':
|
||||
@@ -220,6 +226,8 @@ def main():
|
||||
module.fail_json(msg="Failed during the restart of the cluster, the cluster can't be stopped")
|
||||
|
||||
if state in ['cleanup']:
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=True)
|
||||
clean_cluster(module, timeout)
|
||||
cluster_state = get_cluster_status(module)
|
||||
module.exit_json(changed=True,
|
||||
|
||||
@@ -175,7 +175,6 @@ def main():
|
||||
limits_conf = '/etc/security/limits.conf'
|
||||
|
||||
module = AnsibleModule(
|
||||
# not checking because of daisy chain to file module
|
||||
argument_spec=dict(
|
||||
domain=dict(required=True, type='str'),
|
||||
limit_type=dict(required=True, type='str', choices=pam_types),
|
||||
@@ -201,6 +200,7 @@ def main():
|
||||
new_comment = module.params['comment']
|
||||
|
||||
changed = False
|
||||
does_not_exist = False
|
||||
|
||||
if os.path.isfile(limits_conf):
|
||||
if not os.access(limits_conf, os.W_OK):
|
||||
@@ -208,7 +208,7 @@ def main():
|
||||
else:
|
||||
limits_conf_dir = os.path.dirname(limits_conf)
|
||||
if os.path.isdir(limits_conf_dir) and os.access(limits_conf_dir, os.W_OK):
|
||||
open(limits_conf, 'a').close()
|
||||
does_not_exist = True
|
||||
changed = True
|
||||
else:
|
||||
module.fail_json(msg="directory %s is not writable (check presence, access rights, use sudo)" % limits_conf_dir)
|
||||
@@ -224,15 +224,20 @@ def main():
|
||||
|
||||
space_pattern = re.compile(r'\s+')
|
||||
|
||||
if does_not_exist:
|
||||
lines = []
|
||||
else:
|
||||
with open(limits_conf, 'rb') as f:
|
||||
lines = list(f)
|
||||
|
||||
message = ''
|
||||
f = open(limits_conf, 'rb')
|
||||
# Tempfile
|
||||
nf = tempfile.NamedTemporaryFile(mode='w+')
|
||||
|
||||
found = False
|
||||
new_value = value
|
||||
|
||||
for line in f:
|
||||
for line in lines:
|
||||
line = to_native(line, errors='surrogate_or_strict')
|
||||
if line.startswith('#'):
|
||||
nf.write(line)
|
||||
@@ -323,17 +328,17 @@ def main():
|
||||
message = new_limit
|
||||
nf.write(new_limit)
|
||||
|
||||
f.close()
|
||||
nf.flush()
|
||||
|
||||
with open(limits_conf, 'r') as content:
|
||||
content_current = content.read()
|
||||
|
||||
with open(nf.name, 'r') as content:
|
||||
content_new = content.read()
|
||||
|
||||
if not module.check_mode:
|
||||
# Copy tempfile to newfile
|
||||
if does_not_exist:
|
||||
with open(limits_conf, 'a'):
|
||||
pass
|
||||
|
||||
# Move tempfile to newfile
|
||||
module.atomic_move(nf.name, limits_conf)
|
||||
|
||||
try:
|
||||
@@ -344,7 +349,7 @@ def main():
|
||||
res_args = dict(
|
||||
changed=changed,
|
||||
msg=message,
|
||||
diff=dict(before=content_current, after=content_new),
|
||||
diff=dict(before=b''.join(lines), after=content_new),
|
||||
)
|
||||
|
||||
if backup:
|
||||
|
||||
@@ -325,7 +325,7 @@ EXAMPLES = r'''
|
||||
api_host: node1
|
||||
password: 123456
|
||||
hostname: example.org
|
||||
ostemplate: local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
|
||||
ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
|
||||
mounts: '{"mp0":"local:8,mp=/mnt/test/"}'
|
||||
|
||||
- name: Create new container with minimal options defining a cpu core limit
|
||||
@@ -337,7 +337,7 @@ EXAMPLES = r'''
|
||||
api_host: node1
|
||||
password: 123456
|
||||
hostname: example.org
|
||||
ostemplate: local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
|
||||
ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
|
||||
cores: 2
|
||||
|
||||
- name: Create new container with minimal options and same timezone as proxmox host
|
||||
@@ -361,7 +361,7 @@ EXAMPLES = r'''
|
||||
api_host: node1
|
||||
password: 123456
|
||||
hostname: example.org
|
||||
ostemplate: local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
|
||||
ostemplate: 'local:vztmpl/ubuntu-14.04-x86_64.tar.gz'
|
||||
features:
|
||||
- nesting=1
|
||||
- mount=cifs,nfs
|
||||
|
||||
@@ -1466,8 +1466,9 @@ def main():
|
||||
status = {}
|
||||
try:
|
||||
vm = proxmox.get_vm(vmid)
|
||||
status['status'] = vm['status']
|
||||
if vm['status'] == 'running':
|
||||
current = proxmox.proxmox_api.nodes(vm['node']).qemu(vmid).status.current.get()['status']
|
||||
status['status'] = current
|
||||
if current == 'running':
|
||||
module.exit_json(changed=False, vmid=vmid, msg="VM %s is already running" % vmid, **status)
|
||||
|
||||
if proxmox.start_vm(vm):
|
||||
@@ -1482,9 +1483,9 @@ def main():
|
||||
status = {}
|
||||
try:
|
||||
vm = proxmox.get_vm(vmid)
|
||||
|
||||
status['status'] = vm['status']
|
||||
if vm['status'] == 'stopped':
|
||||
current = proxmox.proxmox_api.nodes(vm['node']).qemu(vmid).status.current.get()['status']
|
||||
status['status'] = current
|
||||
if current == 'stopped':
|
||||
module.exit_json(changed=False, vmid=vmid, msg="VM %s is already stopped" % vmid, **status)
|
||||
|
||||
if proxmox.stop_vm(vm, force=module.params['force'], timeout=module.params['timeout']):
|
||||
@@ -1498,8 +1499,9 @@ def main():
|
||||
|
||||
status = {}
|
||||
vm = proxmox.get_vm(vmid)
|
||||
status['status'] = vm['status']
|
||||
if vm['status'] == 'stopped':
|
||||
current = proxmox.proxmox_api.nodes(vm['node']).qemu(vmid).status.current.get()['status']
|
||||
status['status'] = current
|
||||
if current == 'stopped':
|
||||
module.exit_json(changed=False, vmid=vmid, msg="VM %s is not running" % vmid, **status)
|
||||
|
||||
if proxmox.restart_vm(vm, force=module.params['force']):
|
||||
@@ -1516,8 +1518,9 @@ def main():
|
||||
module.exit_json(changed=False, vmid=vmid)
|
||||
|
||||
proxmox_node = proxmox.proxmox_api.nodes(vm['node'])
|
||||
status['status'] = vm['status']
|
||||
if vm['status'] == 'running':
|
||||
current = proxmox_node.qemu(vmid).status.current.get()['status']
|
||||
status['status'] = current
|
||||
if current == 'running':
|
||||
if module.params['force']:
|
||||
proxmox.stop_vm(vm, True, timeout=module.params['timeout'])
|
||||
else:
|
||||
|
||||
@@ -116,6 +116,15 @@ options:
|
||||
- Whether to print file changes details
|
||||
type: bool
|
||||
default: false
|
||||
environment_lang:
|
||||
description:
|
||||
- The lang environment to use when running the puppet agent.
|
||||
- The default value, V(C), is supported on every system, but can lead to encoding errors if UTF-8 is used in the output
|
||||
- Use V(C.UTF-8) or V(en_US.UTF-8) or similar UTF-8 supporting locales in case of problems. You need to make sure
|
||||
the selected locale is supported on the system the puppet agent runs on.
|
||||
type: str
|
||||
default: C
|
||||
version_added: 8.6.0
|
||||
requirements:
|
||||
- puppet
|
||||
author:
|
||||
@@ -208,6 +217,7 @@ def main():
|
||||
debug=dict(type='bool', default=False),
|
||||
verbose=dict(type='bool', default=False),
|
||||
use_srv_records=dict(type='bool'),
|
||||
environment_lang=dict(type='str', default='C'),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
mutually_exclusive=[
|
||||
|
||||
@@ -93,7 +93,7 @@ from ansible.module_utils.urls import fetch_url
|
||||
|
||||
|
||||
def ring_check(module, riak_admin_bin):
|
||||
cmd = '%s ringready' % riak_admin_bin
|
||||
cmd = riak_admin_bin + ['ringready']
|
||||
rc, out, err = module.run_command(cmd)
|
||||
if rc == 0 and 'TRUE All nodes agree on the ring' in out:
|
||||
return True
|
||||
@@ -127,6 +127,7 @@ def main():
|
||||
# make sure riak commands are on the path
|
||||
riak_bin = module.get_bin_path('riak')
|
||||
riak_admin_bin = module.get_bin_path('riak-admin')
|
||||
riak_admin_bin = [riak_admin_bin] if riak_admin_bin is not None else [riak_bin, 'admin']
|
||||
|
||||
timeout = time.time() + 120
|
||||
while True:
|
||||
@@ -164,7 +165,7 @@ def main():
|
||||
module.fail_json(msg=out)
|
||||
|
||||
elif command == 'kv_test':
|
||||
cmd = '%s test' % riak_admin_bin
|
||||
cmd = riak_admin_bin + ['test']
|
||||
rc, out, err = module.run_command(cmd)
|
||||
if rc == 0:
|
||||
result['kv_test'] = out
|
||||
@@ -175,7 +176,7 @@ def main():
|
||||
if nodes.count(node_name) == 1 and len(nodes) > 1:
|
||||
result['join'] = 'Node is already in cluster or staged to be in cluster.'
|
||||
else:
|
||||
cmd = '%s cluster join %s' % (riak_admin_bin, target_node)
|
||||
cmd = riak_admin_bin + ['cluster', 'join', target_node]
|
||||
rc, out, err = module.run_command(cmd)
|
||||
if rc == 0:
|
||||
result['join'] = out
|
||||
@@ -184,7 +185,7 @@ def main():
|
||||
module.fail_json(msg=out)
|
||||
|
||||
elif command == 'plan':
|
||||
cmd = '%s cluster plan' % riak_admin_bin
|
||||
cmd = riak_admin_bin + ['cluster', 'plan']
|
||||
rc, out, err = module.run_command(cmd)
|
||||
if rc == 0:
|
||||
result['plan'] = out
|
||||
@@ -194,7 +195,7 @@ def main():
|
||||
module.fail_json(msg=out)
|
||||
|
||||
elif command == 'commit':
|
||||
cmd = '%s cluster commit' % riak_admin_bin
|
||||
cmd = riak_admin_bin + ['cluster', 'commit']
|
||||
rc, out, err = module.run_command(cmd)
|
||||
if rc == 0:
|
||||
result['commit'] = out
|
||||
@@ -206,7 +207,7 @@ def main():
|
||||
if wait_for_handoffs:
|
||||
timeout = time.time() + wait_for_handoffs
|
||||
while True:
|
||||
cmd = '%s transfers' % riak_admin_bin
|
||||
cmd = riak_admin_bin + ['transfers']
|
||||
rc, out, err = module.run_command(cmd)
|
||||
if 'No transfers active' in out:
|
||||
result['handoffs'] = 'No transfers active.'
|
||||
@@ -216,7 +217,7 @@ def main():
|
||||
module.fail_json(msg='Timeout waiting for handoffs.')
|
||||
|
||||
if wait_for_service:
|
||||
cmd = [riak_admin_bin, 'wait_for_service', 'riak_%s' % wait_for_service, node_name]
|
||||
cmd = riak_admin_bin + ['wait_for_service', 'riak_%s' % wait_for_service, node_name]
|
||||
rc, out, err = module.run_command(cmd)
|
||||
result['service'] = out
|
||||
|
||||
|
||||
@@ -436,11 +436,16 @@ def is_attribute(tree, xpath, namespaces):
|
||||
""" Test if a given xpath matches and that match is an attribute
|
||||
|
||||
An xpath attribute search will only match one item"""
|
||||
|
||||
# lxml 5.1.1 removed etree._ElementStringResult, so we can no longer simply assume it's there
|
||||
# (https://github.com/lxml/lxml/commit/eba79343d0e7ad1ce40169f60460cdd4caa29eb3)
|
||||
ElementStringResult = getattr(etree, '_ElementStringResult', None)
|
||||
|
||||
if xpath_matches(tree, xpath, namespaces):
|
||||
match = tree.xpath(xpath, namespaces=namespaces)
|
||||
if isinstance(match[0], etree._ElementStringResult):
|
||||
if isinstance(match[0], etree._ElementUnicodeResult):
|
||||
return True
|
||||
elif isinstance(match[0], etree._ElementUnicodeResult):
|
||||
elif ElementStringResult is not None and isinstance(match[0], ElementStringResult):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
41
plugins/plugin_utils/unsafe.py
Normal file
41
plugins/plugin_utils/unsafe.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# Copyright (c) 2023, Felix Fontein <felix@fontein.de>
|
||||
# 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
|
||||
|
||||
import re
|
||||
|
||||
from ansible.module_utils.six import binary_type, text_type
|
||||
from ansible.module_utils.common._collections_compat import Mapping, Set
|
||||
from ansible.module_utils.common.collections import is_sequence
|
||||
from ansible.utils.unsafe_proxy import (
|
||||
AnsibleUnsafe,
|
||||
wrap_var as _make_unsafe,
|
||||
)
|
||||
|
||||
_RE_TEMPLATE_CHARS = re.compile(u'[{}]')
|
||||
_RE_TEMPLATE_CHARS_BYTES = re.compile(b'[{}]')
|
||||
|
||||
|
||||
def make_unsafe(value):
|
||||
if value is None or isinstance(value, AnsibleUnsafe):
|
||||
return value
|
||||
|
||||
if isinstance(value, Mapping):
|
||||
return dict((make_unsafe(key), make_unsafe(val)) for key, val in value.items())
|
||||
elif isinstance(value, Set):
|
||||
return set(make_unsafe(elt) for elt in value)
|
||||
elif is_sequence(value):
|
||||
return type(value)(make_unsafe(elt) for elt in value)
|
||||
elif isinstance(value, binary_type):
|
||||
if _RE_TEMPLATE_CHARS_BYTES.search(value):
|
||||
value = _make_unsafe(value)
|
||||
return value
|
||||
elif isinstance(value, text_type):
|
||||
if _RE_TEMPLATE_CHARS.search(value):
|
||||
value = _make_unsafe(value)
|
||||
return value
|
||||
|
||||
return value
|
||||
@@ -8,6 +8,14 @@
|
||||
# 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
|
||||
|
||||
- name: Help debugging
|
||||
debug:
|
||||
msg: >-
|
||||
distribution={{ ansible_distribution }},
|
||||
distribution major version={{ ansible_distribution_major_version }},
|
||||
os_family={{ ansible_os_family }},
|
||||
Python version={{ ansible_python.version.major }}
|
||||
|
||||
- name: test cloud-init
|
||||
# TODO: check for a workaround
|
||||
# install 'cloud-init'' failed: dpkg-divert: error: `diversion of /etc/init/ureadahead.conf
|
||||
@@ -15,10 +23,11 @@
|
||||
# /etc/init/ureadahead.conf to /etc/init/ureadahead.conf.distrib
|
||||
# https://bugs.launchpad.net/ubuntu/+source/ureadahead/+bug/997838
|
||||
# Will also have to skip on OpenSUSE when running on Python 2 on newer Leap versions
|
||||
# (!= 42 and >= 15) ascloud-init will install the Python 3 package, breaking our build on py2.
|
||||
# (!= 42 and >= 15) as cloud-init will install the Python 3 package, breaking our build on py2.
|
||||
when:
|
||||
- not (ansible_distribution == "Ubuntu" and ansible_distribution_major_version|int == 14)
|
||||
- not (ansible_os_family == "Suse" and ansible_distribution_major_version|int != 42 and ansible_python.version.major != 3)
|
||||
- not (ansible_os_family == "Suse" and ansible_distribution_major_version|int == 15)
|
||||
- not (ansible_distribution == "CentOS" and ansible_distribution_major_version|int == 8) # TODO: cannot start service
|
||||
- not (ansible_distribution == 'Archlinux') # TODO: package seems to be broken, cannot be downloaded from mirrors?
|
||||
- not (ansible_distribution == 'Alpine') # TODO: not sure what's wrong here, the module doesn't return what the tests expect
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
- name: bail out for non-supported platforms
|
||||
meta: end_play
|
||||
when:
|
||||
- (ansible_os_family != "RedHat" or ansible_distribution_major_version|int < 7)
|
||||
- (ansible_os_family != "RedHat" or ansible_distribution_major_version|int < 8) # TODO: bump back to 7
|
||||
- (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int < 8) # TODO: remove
|
||||
- ansible_os_family != "Debian"
|
||||
|
||||
- name: install perl development package for Red Hat family
|
||||
|
||||
@@ -43,6 +43,11 @@
|
||||
chdir: "{{ tmp_django_root.path }}/startproj"
|
||||
cmd: "{{ tmp_django_root.path }}/venv/bin/django-admin startapp app1"
|
||||
|
||||
- name: Make manage.py executable
|
||||
file:
|
||||
path: "{{ tmp_django_root.path }}/startproj/test_django_manage_1/manage.py"
|
||||
mode: "0755"
|
||||
|
||||
- name: Check
|
||||
community.general.django_manage:
|
||||
project_path: "{{ tmp_django_root.path }}/startproj/test_django_manage_1"
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
|
||||
- name: Bail out if not supported
|
||||
ansible.builtin.meta: end_play
|
||||
when: ansible_distribution in ('Alpine', 'openSUSE Leap', 'CentOS', 'Fedora')
|
||||
# TODO: remove Archlinux from the list
|
||||
when: ansible_distribution in ('Alpine', 'openSUSE Leap', 'CentOS', 'Fedora', 'Archlinux')
|
||||
|
||||
|
||||
- name: Remove ejabberd
|
||||
|
||||
@@ -5,3 +5,5 @@
|
||||
azp/posix/2
|
||||
skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
|
||||
skip/python2.7 # jc only supports python3.x
|
||||
skip/freebsd13.3 # FIXME - ruyaml compilation fails
|
||||
skip/freebsd14.0 # FIXME - ruyaml compilation fails
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
when:
|
||||
- xtables_lock is undefined
|
||||
|
||||
- name: include tasks to test partial restore files
|
||||
include_tasks: tests/02-partial-restore.yml
|
||||
when:
|
||||
- xtables_lock is undefined
|
||||
|
||||
|
||||
- name: include tasks to test rollbacks
|
||||
include_tasks: tests/10-rollback.yml
|
||||
when:
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- name: "Create initial rule set to use"
|
||||
copy:
|
||||
dest: "{{ iptables_tests }}"
|
||||
content: |
|
||||
*filter
|
||||
:INPUT ACCEPT [0:0]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
-A INPUT -m state --state NEW,ESTABLISHED -j ACCEPT
|
||||
COMMIT
|
||||
*nat
|
||||
:PREROUTING ACCEPT [151:17304]
|
||||
:INPUT ACCEPT [151:17304]
|
||||
:OUTPUT ACCEPT [151:17304]
|
||||
:POSTROUTING ACCEPT [151:17304]
|
||||
-A POSTROUTING -o eth0 -j MASQUERADE
|
||||
COMMIT
|
||||
|
||||
- name: "Restore initial state"
|
||||
iptables_state:
|
||||
path: "{{ iptables_tests }}"
|
||||
state: restored
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
|
||||
- name: "Create partial ruleset only specifying input"
|
||||
copy:
|
||||
dest: "{{ iptables_tests }}"
|
||||
content: |
|
||||
*filter
|
||||
:INPUT ACCEPT [0:0]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
-A INPUT -m state --state NEW,ESTABLISHED -j ACCEPT
|
||||
COMMIT
|
||||
|
||||
- name: "Check restoring partial state"
|
||||
iptables_state:
|
||||
path: "{{ iptables_tests }}"
|
||||
state: restored
|
||||
check_mode: true
|
||||
register: iptables_state
|
||||
|
||||
|
||||
- name: "assert that no changes are detected in check mode"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
|
||||
- name: "Restore partial state"
|
||||
iptables_state:
|
||||
path: "{{ iptables_tests }}"
|
||||
state: restored
|
||||
register: iptables_state
|
||||
async: "{{ ansible_timeout }}"
|
||||
poll: 0
|
||||
|
||||
- name: "assert that no changes are made"
|
||||
assert:
|
||||
that:
|
||||
- iptables_state is not changed
|
||||
@@ -13,3 +13,5 @@ skip/rhel9.2 # FIXME
|
||||
skip/rhel9.3 # FIXME
|
||||
skip/freebsd12.4 # FIXME
|
||||
skip/freebsd13.2 # FIXME
|
||||
skip/freebsd13.3 # FIXME
|
||||
skip/freebsd14.0 # FIXME
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
- result.existing == {}
|
||||
- result.end_state.alias == "{{ idp }}"
|
||||
- result.end_state.mappers != []
|
||||
- result.end_state.config.client_secret = "**********"
|
||||
|
||||
- name: Update existing identity provider (no change)
|
||||
community.general.keycloak_identity_provider:
|
||||
|
||||
@@ -7,11 +7,12 @@
|
||||
package_name: ansible-test-foo
|
||||
username: ansible-regular-user
|
||||
block:
|
||||
- name: Install fakeroot
|
||||
- name: Install dependencies
|
||||
pacman:
|
||||
state: present
|
||||
name:
|
||||
- fakeroot
|
||||
- debugedit
|
||||
|
||||
- name: Create user
|
||||
user:
|
||||
|
||||
@@ -515,11 +515,18 @@
|
||||
# NOTE: FreeBSD 13.2 fails to update the package catalogue for unknown reasons (someone with FreeBSD
|
||||
# knowledge has to take a look)
|
||||
#
|
||||
# NOTE: FreeBSD 13.3 fails to update the package catalogue for unknown reasons (someone with FreeBSD
|
||||
# knowledge has to take a look)
|
||||
#
|
||||
# NOTE: FreeBSD 14.0 fails to update the package catalogue for unknown reasons (someone with FreeBSD
|
||||
# knowledge has to take a look)
|
||||
#
|
||||
# See also
|
||||
# https://github.com/ansible-collections/community.general/issues/5795
|
||||
when: >-
|
||||
(ansible_distribution_version is version('12.01', '>=') and ansible_distribution_version is version('12.3', '<'))
|
||||
or ansible_distribution_version is version('13.3', '>=')
|
||||
or (ansible_distribution_version is version('13.4', '>=') and ansible_distribution_version is version('14.0', '<'))
|
||||
or ansible_distribution_version is version('14.1', '>=')
|
||||
block:
|
||||
- name: Setup testjail
|
||||
include_tasks: setup-testjail.yml
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
ansible.builtin.include_tasks: test.yml
|
||||
- name: Include test_channel
|
||||
ansible.builtin.include_tasks: test_channel.yml
|
||||
- name: Include test_dangerous
|
||||
ansible.builtin.include_tasks: test_dangerous.yml
|
||||
# TODO: Find better package to download and install from sources - cider 1.6.0 takes over 35 seconds to install
|
||||
# - name: Include test_dangerous
|
||||
# ansible.builtin.include_tasks: test_dangerous.yml
|
||||
- name: Include test_3dash
|
||||
ansible.builtin.include_tasks: test_3dash.yml
|
||||
- name: Include test_empty_list
|
||||
|
||||
@@ -3,47 +3,46 @@
|
||||
# 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
|
||||
|
||||
- name: Make sure package is not installed (microk8s)
|
||||
# NOTE This is currently disabled for performance reasons!
|
||||
|
||||
- name: Make sure package is not installed (wisdom)
|
||||
community.general.snap:
|
||||
name: microk8s
|
||||
name: wisdom
|
||||
state: absent
|
||||
|
||||
# Test for https://github.com/ansible-collections/community.general/issues/1606
|
||||
- name: Install package (microk8s)
|
||||
- name: Install package (wisdom)
|
||||
community.general.snap:
|
||||
name: microk8s
|
||||
classic: true
|
||||
name: wisdom
|
||||
state: present
|
||||
register: install_microk8s
|
||||
register: install_wisdom
|
||||
|
||||
- name: Install package with channel (microk8s)
|
||||
- name: Install package with channel (wisdom)
|
||||
community.general.snap:
|
||||
name: microk8s
|
||||
classic: true
|
||||
channel: 1.20/stable
|
||||
name: wisdom
|
||||
state: present
|
||||
register: install_microk8s_chan
|
||||
channel: latest/edge
|
||||
register: install_wisdom_chan
|
||||
|
||||
- name: Install package with channel (microk8s) again
|
||||
- name: Install package with channel (wisdom) again
|
||||
community.general.snap:
|
||||
name: microk8s
|
||||
classic: true
|
||||
channel: 1.20/stable
|
||||
name: wisdom
|
||||
state: present
|
||||
register: install_microk8s_chan_again
|
||||
channel: latest/edge
|
||||
register: install_wisdom_chan_again
|
||||
|
||||
- name: Remove package (microk8s)
|
||||
- name: Remove package (wisdom)
|
||||
community.general.snap:
|
||||
name: microk8s
|
||||
name: wisdom
|
||||
state: absent
|
||||
register: remove_microk8s
|
||||
register: remove_wisdom
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- install_microk8s is changed
|
||||
- install_microk8s_chan is changed
|
||||
- install_microk8s_chan_again is not changed
|
||||
- remove_microk8s is changed
|
||||
- install_wisdom is changed
|
||||
- install_wisdom_chan is changed
|
||||
- install_wisdom_chan_again is not changed
|
||||
- remove_wisdom is changed
|
||||
|
||||
- name: Install package (shellcheck)
|
||||
community.general.snap:
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# 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
|
||||
|
||||
# NOTE This is currently disabled for performance reasons!
|
||||
|
||||
- name: Make sure package is not installed (cider)
|
||||
community.general.snap:
|
||||
name: cider
|
||||
|
||||
@@ -21,4 +21,6 @@ plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice
|
||||
plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt'
|
||||
plugins/modules/udm_user.py import-3.12 # Uses deprecated stdlib library 'crypt'
|
||||
plugins/modules/xfconf.py validate-modules:return-syntax-error
|
||||
plugins/module_utils/univention_umc.py pylint:use-yield-from # suggested construct does not work with Python 2
|
||||
tests/unit/compat/mock.py pylint:use-yield-from # suggested construct does not work with Python 2
|
||||
tests/unit/plugins/modules/test_gio_mime.yaml no-smart-quotes
|
||||
|
||||
@@ -37,11 +37,25 @@ def test_missing_access_token_lookup(inventory):
|
||||
assert 'Could not retrieve Linode access token' in error_message
|
||||
|
||||
|
||||
def test_verify_file(tmp_path, inventory):
|
||||
def test_verify_file_yml(tmp_path, inventory):
|
||||
file = tmp_path / "foobar.linode.yml"
|
||||
file.touch()
|
||||
assert inventory.verify_file(str(file)) is True
|
||||
|
||||
|
||||
def test_verify_file_yaml(tmp_path, inventory):
|
||||
file = tmp_path / "foobar.linode.yaml"
|
||||
file.touch()
|
||||
assert inventory.verify_file(str(file)) is True
|
||||
|
||||
|
||||
def test_verify_file_bad_config_yml(inventory):
|
||||
assert inventory.verify_file("foobar.linode.yml") is False
|
||||
|
||||
|
||||
def test_verify_file_bad_config_yaml(inventory):
|
||||
assert inventory.verify_file("foobar.linode.yaml") is False
|
||||
|
||||
|
||||
def test_verify_file_bad_config(inventory):
|
||||
assert inventory.verify_file('foobar.linode.yml') is False
|
||||
assert inventory.verify_file("foobar.wrongcloud.yml") is False
|
||||
|
||||
133
tests/unit/plugins/plugin_utils/test_unsafe.py
Normal file
133
tests/unit/plugins/plugin_utils/test_unsafe.py
Normal file
@@ -0,0 +1,133 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2024, Felix Fontein <felix@fontein.de>
|
||||
# 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
|
||||
|
||||
# Make coding more python3-ish
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
import pytest
|
||||
|
||||
from ansible.utils.unsafe_proxy import AnsibleUnsafe
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import (
|
||||
make_unsafe,
|
||||
)
|
||||
|
||||
|
||||
TEST_MAKE_UNSAFE = [
|
||||
(
|
||||
u'text',
|
||||
[],
|
||||
[
|
||||
(),
|
||||
],
|
||||
),
|
||||
(
|
||||
u'{{text}}',
|
||||
[
|
||||
(),
|
||||
],
|
||||
[],
|
||||
),
|
||||
(
|
||||
b'text',
|
||||
[],
|
||||
[
|
||||
(),
|
||||
],
|
||||
),
|
||||
(
|
||||
b'{{text}}',
|
||||
[
|
||||
(),
|
||||
],
|
||||
[],
|
||||
),
|
||||
(
|
||||
{
|
||||
'skey': 'value',
|
||||
'ukey': '{{value}}',
|
||||
1: [
|
||||
'value',
|
||||
'{{value}}',
|
||||
{
|
||||
1.0: '{{value}}',
|
||||
2.0: 'value',
|
||||
},
|
||||
],
|
||||
},
|
||||
[
|
||||
('ukey', ),
|
||||
(1, 1),
|
||||
(1, 2, 1.0),
|
||||
],
|
||||
[
|
||||
('skey', ),
|
||||
(1, 0),
|
||||
(1, 2, 2.0),
|
||||
],
|
||||
),
|
||||
(
|
||||
['value', '{{value}}'],
|
||||
[
|
||||
(1, ),
|
||||
],
|
||||
[
|
||||
(0, ),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value, check_unsafe_paths, check_safe_paths", TEST_MAKE_UNSAFE)
|
||||
def test_make_unsafe(value, check_unsafe_paths, check_safe_paths):
|
||||
unsafe_value = make_unsafe(value)
|
||||
assert unsafe_value == value
|
||||
for check_path in check_unsafe_paths:
|
||||
obj = unsafe_value
|
||||
for elt in check_path:
|
||||
obj = obj[elt]
|
||||
assert isinstance(obj, AnsibleUnsafe)
|
||||
for check_path in check_safe_paths:
|
||||
obj = unsafe_value
|
||||
for elt in check_path:
|
||||
obj = obj[elt]
|
||||
assert not isinstance(obj, AnsibleUnsafe)
|
||||
|
||||
|
||||
def test_make_unsafe_dict_key():
|
||||
value = {
|
||||
b'test': 1,
|
||||
u'test': 2,
|
||||
}
|
||||
unsafe_value = make_unsafe(value)
|
||||
assert unsafe_value == value
|
||||
for obj in unsafe_value:
|
||||
assert not isinstance(obj, AnsibleUnsafe)
|
||||
|
||||
value = {
|
||||
b'{{test}}': 1,
|
||||
u'{{test}}': 2,
|
||||
}
|
||||
unsafe_value = make_unsafe(value)
|
||||
assert unsafe_value == value
|
||||
for obj in unsafe_value:
|
||||
assert isinstance(obj, AnsibleUnsafe)
|
||||
|
||||
|
||||
def test_make_unsafe_set():
|
||||
value = set([b'test', u'test'])
|
||||
unsafe_value = make_unsafe(value)
|
||||
assert unsafe_value == value
|
||||
for obj in unsafe_value:
|
||||
assert not isinstance(obj, AnsibleUnsafe)
|
||||
|
||||
value = set([b'{{test}}', u'{{test}}'])
|
||||
unsafe_value = make_unsafe(value)
|
||||
assert unsafe_value == value
|
||||
for obj in unsafe_value:
|
||||
assert isinstance(obj, AnsibleUnsafe)
|
||||
Reference in New Issue
Block a user