mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-30 02:16:50 +00:00
Compare commits
156 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
983b4d70e0 | ||
|
|
821ae9bc41 | ||
|
|
d5efd56dae | ||
|
|
88ef840750 | ||
|
|
08d04a7923 | ||
|
|
9d0b14b239 | ||
|
|
9e83a4cb34 | ||
|
|
dc5f012e52 | ||
|
|
210adc196e | ||
|
|
f30fcec398 | ||
|
|
0a904d60cd | ||
|
|
1ee2bba140 | ||
|
|
0aa9cd0e30 | ||
|
|
7009a768a4 | ||
|
|
2f5552da04 | ||
|
|
145686cfe0 | ||
|
|
08239919de | ||
|
|
1ab1f8f62b | ||
|
|
13c25154b5 | ||
|
|
d22199f82e | ||
|
|
82a07de870 | ||
|
|
895c1fe2a0 | ||
|
|
3e972990cb | ||
|
|
0ac6e44566 | ||
|
|
1308198eae | ||
|
|
d887985b46 | ||
|
|
7d6e7fa5fa | ||
|
|
b61b988b2e | ||
|
|
549c9e69ae | ||
|
|
fe35cff7a4 | ||
|
|
cef57b044b | ||
|
|
980a9817f3 | ||
|
|
778662921f | ||
|
|
a045d088d5 | ||
|
|
395fc1e77a | ||
|
|
42c65f32eb | ||
|
|
4776e7bed3 | ||
|
|
d423b27288 | ||
|
|
89c56631c8 | ||
|
|
2e34cba62c | ||
|
|
ce5417bb73 | ||
|
|
bf089294b4 | ||
|
|
87a079e93c | ||
|
|
2de375eaf8 | ||
|
|
3a946bf115 | ||
|
|
1e3ad7f189 | ||
|
|
8c386516eb | ||
|
|
058c918cad | ||
|
|
a7dac117e5 | ||
|
|
9fc447dedb | ||
|
|
fc70818ee3 | ||
|
|
a7bbf99448 | ||
|
|
718f88d2c7 | ||
|
|
c596558846 | ||
|
|
21a7159472 | ||
|
|
5dc20d9028 | ||
|
|
2f47748154 | ||
|
|
ddf6b13f18 | ||
|
|
293aee5648 | ||
|
|
f6603d552e | ||
|
|
26dfe96ad6 | ||
|
|
d7b89cde46 | ||
|
|
6808f77f1a | ||
|
|
ec9fd625fc | ||
|
|
b80d408a25 | ||
|
|
7db93a7dd3 | ||
|
|
c79073c687 | ||
|
|
09047058ce | ||
|
|
7de503a2a3 | ||
|
|
b746024c96 | ||
|
|
908a9836c0 | ||
|
|
adea41d773 | ||
|
|
2dd964cab3 | ||
|
|
410101a116 | ||
|
|
ec5dd70f8b | ||
|
|
3473cb504e | ||
|
|
c329192e82 | ||
|
|
7fe5e5f02c | ||
|
|
4482b04463 | ||
|
|
05608ea658 | ||
|
|
a43132ba93 | ||
|
|
33c5e17762 | ||
|
|
42efe21600 | ||
|
|
fc02a7c74e | ||
|
|
ef16e7ea4e | ||
|
|
dce0a65ffe | ||
|
|
ab2c0992e4 | ||
|
|
2c6b2e344b | ||
|
|
d87b91e279 | ||
|
|
505cde7e6b | ||
|
|
0fcf81dd18 | ||
|
|
e62a256724 | ||
|
|
ee7ba1a691 | ||
|
|
ee428ccd64 | ||
|
|
580f8b30a8 | ||
|
|
7204798479 | ||
|
|
59b1329337 | ||
|
|
e3eaeda81a | ||
|
|
b7e68f5b2d | ||
|
|
dcb38bece0 | ||
|
|
c82c375aef | ||
|
|
d5f6889f51 | ||
|
|
ff8e67840f | ||
|
|
c1d142f543 | ||
|
|
cb9be1349a | ||
|
|
59086813c1 | ||
|
|
12319f4a82 | ||
|
|
04b29342d2 | ||
|
|
0d23fa7a49 | ||
|
|
dbec1ebf7a | ||
|
|
feefec42df | ||
|
|
a60cba237f | ||
|
|
76d011ed4b | ||
|
|
3ba00d5a07 | ||
|
|
8eb3003894 | ||
|
|
89158ce325 | ||
|
|
7f8d77b9f3 | ||
|
|
3cf90b3e36 | ||
|
|
189b737c50 | ||
|
|
c4bd7c2b7b | ||
|
|
ea427d3c82 | ||
|
|
bc011c60e6 | ||
|
|
a76537b24f | ||
|
|
327777a1da | ||
|
|
d8ee97c7e9 | ||
|
|
52ffc4eb7c | ||
|
|
be8c05bf65 | ||
|
|
bf284a01cb | ||
|
|
c1f9aeaac8 | ||
|
|
1a5ad80589 | ||
|
|
f2e2157bcc | ||
|
|
20d2488f0f | ||
|
|
7d75bb3d7e | ||
|
|
c5f8719fe9 | ||
|
|
79cfc48dd5 | ||
|
|
e0489d738a | ||
|
|
3e1cbbb617 | ||
|
|
28d7c499b5 | ||
|
|
9f218be912 | ||
|
|
363936a544 | ||
|
|
a8351fa9df | ||
|
|
4b84127ef3 | ||
|
|
82e1f24d2e | ||
|
|
9e8b6ea803 | ||
|
|
db8a6609de | ||
|
|
5be75b8e43 | ||
|
|
71b1ae0aff | ||
|
|
9b2fa2cfd7 | ||
|
|
83193ffc1f | ||
|
|
4b955a3548 | ||
|
|
c7dbda3656 | ||
|
|
e98cf96499 | ||
|
|
8d52dc3f1d | ||
|
|
5f9ea0b7ac | ||
|
|
d125f5bee6 | ||
|
|
82c5970811 |
@@ -29,14 +29,14 @@ schedules:
|
||||
always: true
|
||||
branches:
|
||||
include:
|
||||
- stable-9
|
||||
- stable-8
|
||||
- stable-7
|
||||
- cron: 0 11 * * 0
|
||||
displayName: Weekly (old stable branches)
|
||||
always: true
|
||||
branches:
|
||||
include:
|
||||
- stable-7
|
||||
- stable-6
|
||||
|
||||
variables:
|
||||
- name: checkoutPath
|
||||
@@ -73,19 +73,6 @@ stages:
|
||||
- test: 3
|
||||
- test: 4
|
||||
- test: extra
|
||||
- stage: Sanity_2_17
|
||||
displayName: Sanity 2.17
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Test {0}
|
||||
testFormat: 2.17/sanity/{0}
|
||||
targets:
|
||||
- test: 1
|
||||
- test: 2
|
||||
- test: 3
|
||||
- test: 4
|
||||
- stage: Sanity_2_16
|
||||
displayName: Sanity 2.16
|
||||
dependsOn: []
|
||||
@@ -112,6 +99,19 @@ 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
|
||||
@@ -122,22 +122,12 @@ stages:
|
||||
nameFormat: Python {0}
|
||||
testFormat: devel/units/{0}/1
|
||||
targets:
|
||||
- test: 3.7
|
||||
- test: 3.8
|
||||
- test: 3.9
|
||||
- test: '3.10'
|
||||
- test: '3.11'
|
||||
- test: '3.12'
|
||||
- stage: Units_2_17
|
||||
displayName: Units 2.17
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: 2.17/units/{0}/1
|
||||
targets:
|
||||
- test: 3.7
|
||||
- test: "3.12"
|
||||
- stage: Units_2_16
|
||||
displayName: Units 2.16
|
||||
dependsOn: []
|
||||
@@ -161,6 +151,16 @@ 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
|
||||
@@ -171,8 +171,8 @@ stages:
|
||||
parameters:
|
||||
testFormat: devel/{0}
|
||||
targets:
|
||||
- name: Alpine 3.19
|
||||
test: alpine/3.19
|
||||
- name: Alpine 3.18
|
||||
test: alpine/3.18
|
||||
# - name: Fedora 39
|
||||
# test: fedora/39
|
||||
- name: Ubuntu 22.04
|
||||
@@ -187,26 +187,12 @@ stages:
|
||||
parameters:
|
||||
testFormat: devel/{0}
|
||||
targets:
|
||||
- name: macOS 14.3
|
||||
test: macos/14.3
|
||||
- name: macOS 13.2
|
||||
test: macos/13.2
|
||||
- name: RHEL 9.3
|
||||
test: rhel/9.3
|
||||
- name: FreeBSD 14.0
|
||||
test: freebsd/14.0
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- stage: Remote_2_17
|
||||
displayName: Remote 2.17
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: 2.17/{0}
|
||||
targets:
|
||||
- name: FreeBSD 13.3
|
||||
test: freebsd/13.3
|
||||
- name: FreeBSD 13.2
|
||||
test: freebsd/13.2
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
@@ -219,14 +205,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
|
||||
@@ -253,6 +239,24 @@ 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: macOS 12.0
|
||||
# test: macos/12.0
|
||||
- name: RHEL 9.0
|
||||
test: rhel/9.0
|
||||
#- name: FreeBSD 12.4
|
||||
# test: freebsd/12.4
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
|
||||
### Docker
|
||||
- stage: Docker_devel
|
||||
@@ -269,20 +273,8 @@ stages:
|
||||
test: ubuntu2004
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu2204
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- stage: Docker_2_17
|
||||
displayName: Docker 2.17
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: 2.17/linux/{0}
|
||||
targets:
|
||||
- name: Alpine 3.19
|
||||
test: alpine319
|
||||
- name: Alpine 3
|
||||
test: alpine3
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
@@ -299,8 +291,6 @@ stages:
|
||||
test: fedora38
|
||||
- name: openSUSE 15
|
||||
test: opensuse15
|
||||
- name: Alpine 3
|
||||
test: alpine3
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
@@ -321,6 +311,20 @@ 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
|
||||
@@ -336,7 +340,7 @@ stages:
|
||||
- name: Debian Bookworm
|
||||
test: debian-bookworm/3.11
|
||||
- name: ArchLinux
|
||||
test: archlinux/3.12
|
||||
test: archlinux/3.11
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
@@ -351,17 +355,6 @@ stages:
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: devel/generic/{0}/1
|
||||
targets:
|
||||
- test: '3.8'
|
||||
- test: '3.11'
|
||||
- stage: Generic_2_17
|
||||
displayName: Generic 2.17
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: 2.17/generic/{0}/1
|
||||
targets:
|
||||
- test: '3.7'
|
||||
- test: '3.12'
|
||||
@@ -387,32 +380,42 @@ 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
|
||||
- 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
|
||||
# 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
|
||||
|
||||
109
.github/BOTMETA.yml
vendored
109
.github/BOTMETA.yml
vendored
@@ -33,8 +33,6 @@ files:
|
||||
maintainers: $team_ansible_core
|
||||
$becomes/pmrun.py:
|
||||
maintainers: $team_ansible_core
|
||||
$becomes/run0.py:
|
||||
maintainers: konstruktoid
|
||||
$becomes/sesu.py:
|
||||
maintainers: nekonyuu
|
||||
$becomes/sudosu.py:
|
||||
@@ -52,8 +50,6 @@ files:
|
||||
$callbacks/cgroup_memory_recap.py: {}
|
||||
$callbacks/context_demo.py: {}
|
||||
$callbacks/counter_enabled.py: {}
|
||||
$callbacks/default_without_diff.py:
|
||||
maintainers: felixfontein
|
||||
$callbacks/dense.py:
|
||||
maintainers: dagwieers
|
||||
$callbacks/diy.py:
|
||||
@@ -91,8 +87,6 @@ files:
|
||||
maintainers: ryancurrah
|
||||
$callbacks/syslog_json.py:
|
||||
maintainers: imjoseangel
|
||||
$callbacks/timestamp.py:
|
||||
maintainers: kurokobo
|
||||
$callbacks/unixy.py:
|
||||
labels: unixy
|
||||
maintainers: akatch
|
||||
@@ -121,8 +115,6 @@ files:
|
||||
maintainers: $team_ansible_core
|
||||
$doc_fragments/:
|
||||
labels: docs_fragments
|
||||
$doc_fragments/django.py:
|
||||
maintainers: russoz
|
||||
$doc_fragments/hpe3par.py:
|
||||
labels: hpe3par
|
||||
maintainers: farhan7500 gautamphegde
|
||||
@@ -157,18 +149,8 @@ files:
|
||||
$filters/jc.py:
|
||||
maintainers: kellyjonbrazil
|
||||
$filters/json_query.py: {}
|
||||
$filters/lists.py:
|
||||
maintainers: cfiehe
|
||||
$filters/lists_difference.yml:
|
||||
maintainers: cfiehe
|
||||
$filters/lists_intersect.yml:
|
||||
maintainers: cfiehe
|
||||
$filters/lists_mergeby.py:
|
||||
maintainers: vbotka
|
||||
$filters/lists_symmetric_difference.yml:
|
||||
maintainers: cfiehe
|
||||
$filters/lists_union.yml:
|
||||
maintainers: cfiehe
|
||||
$filters/random_mac.py: {}
|
||||
$filters/time.py:
|
||||
maintainers: resmo
|
||||
@@ -218,7 +200,7 @@ files:
|
||||
labels: cloud opennebula
|
||||
maintainers: feldsam
|
||||
$inventories/proxmox.py:
|
||||
maintainers: $team_virt ilijamt krauthosting
|
||||
maintainers: $team_virt ilijamt
|
||||
$inventories/scaleway.py:
|
||||
labels: cloud scaleway
|
||||
maintainers: $team_scaleway
|
||||
@@ -271,7 +253,7 @@ files:
|
||||
labels: manifold
|
||||
maintainers: galanoff
|
||||
$lookups/merge_variables.py:
|
||||
maintainers: rlenferink m-a-r-k-e alpex8
|
||||
maintainers: rlenferink m-a-r-k-e
|
||||
$lookups/onepass:
|
||||
labels: onepassword
|
||||
maintainers: samdoran
|
||||
@@ -300,12 +282,8 @@ files:
|
||||
labels: module_utils
|
||||
$module_utils/btrfs.py:
|
||||
maintainers: gnfzdz
|
||||
$module_utils/cmd_runner.py:
|
||||
maintainers: russoz
|
||||
$module_utils/deps.py:
|
||||
maintainers: russoz
|
||||
$module_utils/django.py:
|
||||
maintainers: russoz
|
||||
$module_utils/gconftool2.py:
|
||||
labels: gconftool2
|
||||
maintainers: russoz
|
||||
@@ -349,8 +327,6 @@ files:
|
||||
$module_utils/pipx.py:
|
||||
labels: pipx
|
||||
maintainers: russoz
|
||||
$module_utils/python_runner.py:
|
||||
maintainers: russoz
|
||||
$module_utils/puppet.py:
|
||||
labels: puppet
|
||||
maintainers: russoz
|
||||
@@ -506,8 +482,6 @@ files:
|
||||
ignore: scottanderson42 tastychutney
|
||||
labels: django_manage
|
||||
maintainers: russoz
|
||||
$modules/django_command.py:
|
||||
maintainers: russoz
|
||||
$modules/dnf_versionlock.py:
|
||||
maintainers: moreda
|
||||
$modules/dnf_config_manager.py:
|
||||
@@ -546,6 +520,8 @@ files:
|
||||
maintainers: $team_flatpak
|
||||
$modules/flatpak_remote.py:
|
||||
maintainers: $team_flatpak
|
||||
$modules/flowdock.py:
|
||||
ignore: mcodd
|
||||
$modules/gandi_livedns.py:
|
||||
maintainers: gthiemonge
|
||||
$modules/gconftool2.py:
|
||||
@@ -600,10 +576,6 @@ files:
|
||||
maintainers: SamyCoenen
|
||||
$modules/gitlab_user.py:
|
||||
maintainers: LennertMertens stgrace
|
||||
$modules/gitlab_group_access_token.py:
|
||||
maintainers: pixslx
|
||||
$modules/gitlab_project_access_token.py:
|
||||
maintainers: pixslx
|
||||
$modules/grove.py:
|
||||
maintainers: zimbatm
|
||||
$modules/gunicorn.py:
|
||||
@@ -792,8 +764,6 @@ files:
|
||||
maintainers: laurpaum
|
||||
$modules/keycloak_component_info.py:
|
||||
maintainers: desand01
|
||||
$modules/keycloak_client_rolescope.py:
|
||||
maintainers: desand01
|
||||
$modules/keycloak_user_rolemapping.py:
|
||||
maintainers: bratwurzt
|
||||
$modules/keycloak_realm_rolemapping.py:
|
||||
@@ -1073,27 +1043,27 @@ files:
|
||||
$modules/proxmox:
|
||||
keywords: kvm libvirt proxmox qemu
|
||||
labels: proxmox virt
|
||||
maintainers: $team_virt UnderGreen krauthosting
|
||||
maintainers: $team_virt UnderGreen
|
||||
ignore: tleguern
|
||||
$modules/proxmox.py:
|
||||
ignore: skvidal
|
||||
maintainers: UnderGreen krauthosting
|
||||
maintainers: UnderGreen
|
||||
$modules/proxmox_disk.py:
|
||||
maintainers: castorsky krauthosting
|
||||
maintainers: castorsky
|
||||
$modules/proxmox_kvm.py:
|
||||
ignore: skvidal
|
||||
maintainers: helldorado krauthosting
|
||||
maintainers: helldorado
|
||||
$modules/proxmox_nic.py:
|
||||
maintainers: Kogelvis krauthosting
|
||||
maintainers: Kogelvis
|
||||
$modules/proxmox_node_info.py:
|
||||
maintainers: jwbernin krauthosting
|
||||
maintainers: jwbernin
|
||||
$modules/proxmox_storage_contents_info.py:
|
||||
maintainers: l00ptr krauthosting
|
||||
maintainers: l00ptr
|
||||
$modules/proxmox_tasks_info:
|
||||
maintainers: paginabianca krauthosting
|
||||
maintainers: paginabianca
|
||||
$modules/proxmox_template.py:
|
||||
ignore: skvidal
|
||||
maintainers: UnderGreen krauthosting
|
||||
maintainers: UnderGreen
|
||||
$modules/pubnub_blocks.py:
|
||||
maintainers: parfeon pubnub
|
||||
$modules/pulp_repo.py:
|
||||
@@ -1108,6 +1078,46 @@ files:
|
||||
$modules/python_requirements_info.py:
|
||||
ignore: ryansb
|
||||
maintainers: willthames
|
||||
$modules/rax:
|
||||
ignore: ryansb sivel
|
||||
$modules/rax.py:
|
||||
maintainers: omgjlk sivel
|
||||
$modules/rax_cbs.py:
|
||||
maintainers: claco
|
||||
$modules/rax_cbs_attachments.py:
|
||||
maintainers: claco
|
||||
$modules/rax_cdb.py:
|
||||
maintainers: jails
|
||||
$modules/rax_cdb_database.py:
|
||||
maintainers: jails
|
||||
$modules/rax_cdb_user.py:
|
||||
maintainers: jails
|
||||
$modules/rax_clb.py:
|
||||
maintainers: claco
|
||||
$modules/rax_clb_nodes.py:
|
||||
maintainers: neuroid
|
||||
$modules/rax_clb_ssl.py:
|
||||
maintainers: smashwilson
|
||||
$modules/rax_files.py:
|
||||
maintainers: angstwad
|
||||
$modules/rax_files_objects.py:
|
||||
maintainers: angstwad
|
||||
$modules/rax_identity.py:
|
||||
maintainers: claco
|
||||
$modules/rax_mon_alarm.py:
|
||||
maintainers: smashwilson
|
||||
$modules/rax_mon_check.py:
|
||||
maintainers: smashwilson
|
||||
$modules/rax_mon_entity.py:
|
||||
maintainers: smashwilson
|
||||
$modules/rax_mon_notification.py:
|
||||
maintainers: smashwilson
|
||||
$modules/rax_mon_notification_plan.py:
|
||||
maintainers: smashwilson
|
||||
$modules/rax_network.py:
|
||||
maintainers: claco omgjlk
|
||||
$modules/rax_queue.py:
|
||||
maintainers: claco
|
||||
$modules/read_csv.py:
|
||||
maintainers: dagwieers
|
||||
$modules/redfish_:
|
||||
@@ -1272,6 +1282,8 @@ files:
|
||||
maintainers: farhan7500 gautamphegde
|
||||
$modules/ssh_config.py:
|
||||
maintainers: gaqzi Akasurde
|
||||
$modules/stackdriver.py:
|
||||
maintainers: bwhaley
|
||||
$modules/stacki_host.py:
|
||||
labels: stacki_host
|
||||
maintainers: bsanders bbyhuy
|
||||
@@ -1326,8 +1338,6 @@ files:
|
||||
maintainers: nate-kingsley
|
||||
$modules/urpmi.py:
|
||||
maintainers: pmakowski
|
||||
$modules/usb_facts.py:
|
||||
maintainers: maxopoly
|
||||
$modules/utm_:
|
||||
keywords: sophos utm
|
||||
maintainers: $team_e_spirit
|
||||
@@ -1364,6 +1374,8 @@ files:
|
||||
maintainers: $team_wdc
|
||||
$modules/wdc_redfish_info.py:
|
||||
maintainers: $team_wdc
|
||||
$modules/webfaction_:
|
||||
maintainers: quentinsf
|
||||
$modules/xattr.py:
|
||||
labels: xattr
|
||||
maintainers: bcoca
|
||||
@@ -1415,8 +1427,6 @@ files:
|
||||
ignore: matze
|
||||
labels: zypper
|
||||
maintainers: $team_suse
|
||||
$plugin_utils/unsafe.py:
|
||||
maintainers: felixfontein
|
||||
$tests/a_module.py:
|
||||
maintainers: felixfontein
|
||||
$tests/fqdn_valid.py:
|
||||
@@ -1430,8 +1440,6 @@ files:
|
||||
maintainers: felixfontein giner
|
||||
docs/docsite/rst/filter_guide_abstract_informations_grouping.rst:
|
||||
maintainers: felixfontein
|
||||
docs/docsite/rst/filter_guide_abstract_informations_lists_helper.rst:
|
||||
maintainers: cfiehe
|
||||
docs/docsite/rst/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst:
|
||||
maintainers: vbotka
|
||||
docs/docsite/rst/filter_guide_conversions.rst:
|
||||
@@ -1473,6 +1481,7 @@ macros:
|
||||
becomes: plugins/become
|
||||
caches: plugins/cache
|
||||
callbacks: plugins/callback
|
||||
cliconfs: plugins/cliconf
|
||||
connections: plugins/connection
|
||||
doc_fragments: plugins/doc_fragments
|
||||
filters: plugins/filter
|
||||
@@ -1480,7 +1489,7 @@ macros:
|
||||
lookups: plugins/lookup
|
||||
module_utils: plugins/module_utils
|
||||
modules: plugins/modules
|
||||
plugin_utils: plugins/plugin_utils
|
||||
terminals: plugins/terminal
|
||||
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
@@ -30,7 +30,6 @@ jobs:
|
||||
matrix:
|
||||
ansible:
|
||||
- '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
|
||||
@@ -42,7 +41,6 @@ jobs:
|
||||
uses: felixfontein/ansible-test-gh-action@main
|
||||
with:
|
||||
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
|
||||
@@ -74,8 +72,6 @@ jobs:
|
||||
python: '2.7'
|
||||
- ansible: '2.13'
|
||||
python: '3.8'
|
||||
- ansible: '2.14'
|
||||
python: '3.9'
|
||||
|
||||
steps:
|
||||
- name: >-
|
||||
@@ -84,7 +80,6 @@ jobs:
|
||||
uses: felixfontein/ansible-test-gh-action@main
|
||||
with:
|
||||
ansible-core-version: stable-${{ matrix.ansible }}
|
||||
codecov-token: ${{ secrets.CODECOV_TOKEN }}
|
||||
coverage: ${{ github.event_name == 'schedule' && 'always' || 'never' }}
|
||||
pre-test-cmd: >-
|
||||
mkdir -p ../../ansible
|
||||
@@ -153,29 +148,11 @@ jobs:
|
||||
docker: alpine3
|
||||
python: ''
|
||||
target: azp/posix/3/
|
||||
# 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.13'
|
||||
# docker: default
|
||||
# python: '3.9'
|
||||
# target: azp/generic/1/
|
||||
# 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: >-
|
||||
@@ -185,7 +162,6 @@ jobs:
|
||||
uses: felixfontein/ansible-test-gh-action@main
|
||||
with:
|
||||
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@v3
|
||||
uses: fsfe/reuse-action@v2
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -512,7 +512,3 @@ $RECYCLE.BIN/
|
||||
|
||||
# Integration tests cloud configs
|
||||
tests/integration/cloud-config-*.ini
|
||||
|
||||
|
||||
# VSCode specific extensions
|
||||
.vscode/settings.json
|
||||
|
||||
337
CHANGELOG.md
337
CHANGELOG.md
@@ -1,337 +0,0 @@
|
||||
# Community General Release Notes
|
||||
|
||||
**Topics**
|
||||
|
||||
- <a href="#v9-0-0">v9\.0\.0</a>
|
||||
- <a href="#release-summary">Release Summary</a>
|
||||
- <a href="#minor-changes">Minor Changes</a>
|
||||
- <a href="#breaking-changes--porting-guide">Breaking Changes / Porting Guide</a>
|
||||
- <a href="#deprecated-features">Deprecated Features</a>
|
||||
- <a href="#removed-features-previously-deprecated">Removed Features \(previously deprecated\)</a>
|
||||
- <a href="#security-fixes">Security Fixes</a>
|
||||
- <a href="#bugfixes">Bugfixes</a>
|
||||
- <a href="#new-plugins">New Plugins</a>
|
||||
- <a href="#become">Become</a>
|
||||
- <a href="#callback">Callback</a>
|
||||
- <a href="#connection">Connection</a>
|
||||
- <a href="#filter">Filter</a>
|
||||
- <a href="#lookup">Lookup</a>
|
||||
- <a href="#test">Test</a>
|
||||
- <a href="#new-modules">New Modules</a>
|
||||
This changelog describes changes after version 8\.0\.0\.
|
||||
|
||||
<a id="v9-0-0"></a>
|
||||
## v9\.0\.0
|
||||
|
||||
<a id="release-summary"></a>
|
||||
### Release Summary
|
||||
|
||||
This is release 9\.0\.0 of <code>community\.general</code>\, released on 2024\-05\-20\.
|
||||
|
||||
<a id="minor-changes"></a>
|
||||
### Minor Changes
|
||||
|
||||
* PythonRunner module utils \- specialisation of <code>CmdRunner</code> to execute Python scripts \([https\://github\.com/ansible\-collections/community\.general/pull/8289](https\://github\.com/ansible\-collections/community\.general/pull/8289)\)\.
|
||||
* Use offset\-aware <code>datetime\.datetime</code> objects \(with timezone UTC\) instead of offset\-naive UTC timestamps\, which are deprecated in Python 3\.12 \([https\://github\.com/ansible\-collections/community\.general/pull/8222](https\://github\.com/ansible\-collections/community\.general/pull/8222)\)\.
|
||||
* aix\_lvol \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
|
||||
* apt\_rpm \- add new states <code>latest</code> and <code>present\_not\_latest</code>\. The value <code>latest</code> is equivalent to the current behavior of <code>present</code>\, which will upgrade a package if a newer version exists\. <code>present\_not\_latest</code> does what most users would expect <code>present</code> to do\: it does not upgrade if the package is already installed\. The current behavior of <code>present</code> will be deprecated in a later version\, and eventually changed to that of <code>present\_not\_latest</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8217](https\://github\.com/ansible\-collections/community\.general/issues/8217)\, [https\://github\.com/ansible\-collections/community\.general/pull/8247](https\://github\.com/ansible\-collections/community\.general/pull/8247)\)\.
|
||||
* apt\_rpm \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
|
||||
* bitwarden lookup plugin \- add <code>bw\_session</code> option\, to pass session key instead of reading from env \([https\://github\.com/ansible\-collections/community\.general/pull/7994](https\://github\.com/ansible\-collections/community\.general/pull/7994)\)\.
|
||||
* bitwarden lookup plugin \- add support to filter by organization ID \([https\://github\.com/ansible\-collections/community\.general/pull/8188](https\://github\.com/ansible\-collections/community\.general/pull/8188)\)\.
|
||||
* bitwarden lookup plugin \- allows to fetch all records of a given collection ID\, by allowing to pass an empty value for <code>search\_value</code> when <code>collection\_id</code> is provided \([https\://github\.com/ansible\-collections/community\.general/pull/8013](https\://github\.com/ansible\-collections/community\.general/pull/8013)\)\.
|
||||
* bitwarden lookup plugin \- when looking for items using an item ID\, the item is now accessed directly with <code>bw get item</code> instead of searching through all items\. This doubles the lookup speed \([https\://github\.com/ansible\-collections/community\.general/pull/7468](https\://github\.com/ansible\-collections/community\.general/pull/7468)\)\.
|
||||
* btrfs\_subvolume \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
|
||||
* cmd\_runner module\_utils \- add validation for minimum and maximum length in the value passed to <code>cmd\_runner\_fmt\.as\_list\(\)</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8288](https\://github\.com/ansible\-collections/community\.general/pull/8288)\)\.
|
||||
* consul\_auth\_method\, consul\_binding\_rule\, consul\_policy\, consul\_role\, consul\_session\, consul\_token \- added action group <code>community\.general\.consul</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7897](https\://github\.com/ansible\-collections/community\.general/pull/7897)\)\.
|
||||
* consul\_policy \- added support for diff and check mode \([https\://github\.com/ansible\-collections/community\.general/pull/7878](https\://github\.com/ansible\-collections/community\.general/pull/7878)\)\.
|
||||
* consul\_policy\, consul\_role\, consul\_session \- removed dependency on <code>requests</code> and factored out common parts \([https\://github\.com/ansible\-collections/community\.general/pull/7826](https\://github\.com/ansible\-collections/community\.general/pull/7826)\, [https\://github\.com/ansible\-collections/community\.general/pull/7878](https\://github\.com/ansible\-collections/community\.general/pull/7878)\)\.
|
||||
* consul\_role \- <code>node\_identities</code> now expects a <code>node\_name</code> option to match the Consul API\, the old <code>name</code> is still supported as alias \([https\://github\.com/ansible\-collections/community\.general/pull/7878](https\://github\.com/ansible\-collections/community\.general/pull/7878)\)\.
|
||||
* consul\_role \- <code>service\_identities</code> now expects a <code>service\_name</code> option to match the Consul API\, the old <code>name</code> is still supported as alias \([https\://github\.com/ansible\-collections/community\.general/pull/7878](https\://github\.com/ansible\-collections/community\.general/pull/7878)\)\.
|
||||
* consul\_role \- added support for diff mode \([https\://github\.com/ansible\-collections/community\.general/pull/7878](https\://github\.com/ansible\-collections/community\.general/pull/7878)\)\.
|
||||
* consul\_role \- added support for templated policies \([https\://github\.com/ansible\-collections/community\.general/pull/7878](https\://github\.com/ansible\-collections/community\.general/pull/7878)\)\.
|
||||
* 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)\)\.
|
||||
* filesystem \- add bcachefs support \([https\://github\.com/ansible\-collections/community\.general/pull/8126](https\://github\.com/ansible\-collections/community\.general/pull/8126)\)\.
|
||||
* gandi\_livedns \- adds support for personal access tokens \([https\://github\.com/ansible\-collections/community\.general/issues/7639](https\://github\.com/ansible\-collections/community\.general/issues/7639)\, [https\://github\.com/ansible\-collections/community\.general/pull/8337](https\://github\.com/ansible\-collections/community\.general/pull/8337)\)\.
|
||||
* gconftool2 \- use <code>ModuleHelper</code> with <code>VarDict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
|
||||
* git\_config \- allow multiple git configs for the same name with the new <code>add\_mode</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7260](https\://github\.com/ansible\-collections/community\.general/pull/7260)\)\.
|
||||
* git\_config \- the <code>after</code> and <code>before</code> fields in the <code>diff</code> of the return value can be a list instead of a string in case more configs with the same key are affected \([https\://github\.com/ansible\-collections/community\.general/pull/7260](https\://github\.com/ansible\-collections/community\.general/pull/7260)\)\.
|
||||
* git\_config \- when a value is unset\, all configs with the same key are unset \([https\://github\.com/ansible\-collections/community\.general/pull/7260](https\://github\.com/ansible\-collections/community\.general/pull/7260)\)\.
|
||||
* gitlab modules \- add <code>ca\_path</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7472](https\://github\.com/ansible\-collections/community\.general/pull/7472)\)\.
|
||||
* gitlab modules \- remove duplicate <code>gitlab</code> package check \([https\://github\.com/ansible\-collections/community\.general/pull/7486](https\://github\.com/ansible\-collections/community\.general/pull/7486)\)\.
|
||||
* 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)\)\.
|
||||
* gitlab\_hook \- adds <code>releases\_events</code> parameter for supporting Releases events triggers on GitLab hooks \([https\://github\.com/ansible\-collections/community\.general/pull/7956](https\://github\.com/ansible\-collections/community\.general/pull/7956)\)\.
|
||||
* gitlab\_runner \- add support for new runner creation workflow \([https\://github\.com/ansible\-collections/community\.general/pull/7199](https\://github\.com/ansible\-collections/community\.general/pull/7199)\)\.
|
||||
* homebrew \- adds <code>force\_formula</code> parameter to disambiguate a formula from a cask of the same name \([https\://github\.com/ansible\-collections/community\.general/issues/8274](https\://github\.com/ansible\-collections/community\.general/issues/8274)\)\.
|
||||
* homebrew\, homebrew\_cask \- refactor common argument validation logic into a dedicated <code>homebrew</code> module utils \([https\://github\.com/ansible\-collections/community\.general/issues/8323](https\://github\.com/ansible\-collections/community\.general/issues/8323)\, [https\://github\.com/ansible\-collections/community\.general/pull/8324](https\://github\.com/ansible\-collections/community\.general/pull/8324)\)\.
|
||||
* icinga2 inventory plugin \- add Jinja2 templating support to <code>url</code>\, <code>user</code>\, and <code>password</code> paramenters \([https\://github\.com/ansible\-collections/community\.general/issues/7074](https\://github\.com/ansible\-collections/community\.general/issues/7074)\, [https\://github\.com/ansible\-collections/community\.general/pull/7996](https\://github\.com/ansible\-collections/community\.general/pull/7996)\)\.
|
||||
* icinga2 inventory plugin \- adds new parameter <code>group\_by\_hostgroups</code> in order to make grouping by Icinga2 hostgroups optional \([https\://github\.com/ansible\-collections/community\.general/pull/7998](https\://github\.com/ansible\-collections/community\.general/pull/7998)\)\.
|
||||
* ini\_file \- add an optional parameter <code>section\_has\_values</code>\. If the target ini file contains more than one <code>section</code>\, use <code>section\_has\_values</code> to specify which one should be updated \([https\://github\.com/ansible\-collections/community\.general/pull/7505](https\://github\.com/ansible\-collections/community\.general/pull/7505)\)\.
|
||||
* ini\_file \- support optional spaces between section names and their surrounding brackets \([https\://github\.com/ansible\-collections/community\.general/pull/8075](https\://github\.com/ansible\-collections/community\.general/pull/8075)\)\.
|
||||
* installp \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
|
||||
* ipa\_config \- adds <code>passkey</code> choice to <code>ipauserauthtype</code> parameter\'s choices \([https\://github\.com/ansible\-collections/community\.general/pull/7588](https\://github\.com/ansible\-collections/community\.general/pull/7588)\)\.
|
||||
* ipa\_dnsrecord \- adds ability to manage NS record types \([https\://github\.com/ansible\-collections/community\.general/pull/7737](https\://github\.com/ansible\-collections/community\.general/pull/7737)\)\.
|
||||
* ipa\_pwpolicy \- refactor module and exchange a sequence <code>if</code> statements with a <code>for</code> loop \([https\://github\.com/ansible\-collections/community\.general/pull/7723](https\://github\.com/ansible\-collections/community\.general/pull/7723)\)\.
|
||||
* ipa\_pwpolicy \- update module to support <code>maxrepeat</code>\, <code>maxsequence</code>\, <code>dictcheck</code>\, <code>usercheck</code>\, <code>gracelimit</code> parameters in FreeIPA password policies \([https\://github\.com/ansible\-collections/community\.general/pull/7723](https\://github\.com/ansible\-collections/community\.general/pull/7723)\)\.
|
||||
* ipa\_sudorule \- adds options to include denied commands or command groups \([https\://github\.com/ansible\-collections/community\.general/pull/7415](https\://github\.com/ansible\-collections/community\.general/pull/7415)\)\.
|
||||
* ipa\_user \- adds <code>idp</code> and <code>passkey</code> choice to <code>ipauserauthtype</code> parameter\'s choices \([https\://github\.com/ansible\-collections/community\.general/pull/7589](https\://github\.com/ansible\-collections/community\.general/pull/7589)\)\.
|
||||
* irc \- add <code>validate\_certs</code> option\, and rename <code>use\_ssl</code> to <code>use\_tls</code>\, while keeping <code>use\_ssl</code> as an alias\. The default value for <code>validate\_certs</code> is <code>false</code> for backwards compatibility\. We recommend to every user of this module to explicitly set <code>use\_tls\=true</code> and <em class="title-reference">validate\_certs\=true\`</em> whenever possible\, especially when communicating to IRC servers over the internet \([https\://github\.com/ansible\-collections/community\.general/pull/7550](https\://github\.com/ansible\-collections/community\.general/pull/7550)\)\.
|
||||
* java\_cert \- add <code>cert\_content</code> argument \([https\://github\.com/ansible\-collections/community\.general/pull/8153](https\://github\.com/ansible\-collections/community\.general/pull/8153)\)\.
|
||||
* java\_cert \- enable <code>owner</code>\, <code>group</code>\, <code>mode</code>\, and other generic file arguments \([https\://github\.com/ansible\-collections/community\.general/pull/8116](https\://github\.com/ansible\-collections/community\.general/pull/8116)\)\.
|
||||
* kernel\_blacklist \- use <code>ModuleHelper</code> with <code>VarDict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
|
||||
* keycloak module utils \- expose error message from Keycloak server for HTTP errors in some specific situations \([https\://github\.com/ansible\-collections/community\.general/pull/7645](https\://github\.com/ansible\-collections/community\.general/pull/7645)\)\.
|
||||
* keycloak\_client\, keycloak\_clientscope\, keycloak\_clienttemplate \- added <code>docker\-v2</code> protocol support\, enhancing alignment with Keycloak\'s protocol options \([https\://github\.com/ansible\-collections/community\.general/issues/8215](https\://github\.com/ansible\-collections/community\.general/issues/8215)\, [https\://github\.com/ansible\-collections/community\.general/pull/8216](https\://github\.com/ansible\-collections/community\.general/pull/8216)\)\.
|
||||
* keycloak\_realm\_key \- the <code>config\.algorithm</code> option now supports 8 additional key algorithms \([https\://github\.com/ansible\-collections/community\.general/pull/7698](https\://github\.com/ansible\-collections/community\.general/pull/7698)\)\.
|
||||
* keycloak\_realm\_key \- the <code>config\.certificate</code> option value is no longer defined with <code>no\_log\=True</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7698](https\://github\.com/ansible\-collections/community\.general/pull/7698)\)\.
|
||||
* keycloak\_realm\_key \- the <code>provider\_id</code> option now supports RSA encryption key usage \(value <code>rsa\-enc</code>\) \([https\://github\.com/ansible\-collections/community\.general/pull/7698](https\://github\.com/ansible\-collections/community\.general/pull/7698)\)\.
|
||||
* keycloak\_user\_federation \- add option for <code>krbPrincipalAttribute</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7538](https\://github\.com/ansible\-collections/community\.general/pull/7538)\)\.
|
||||
* keycloak\_user\_federation \- allow custom user storage providers to be set through <code>provider\_id</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7789](https\://github\.com/ansible\-collections/community\.general/pull/7789)\)\.
|
||||
* ldap\_attrs \- module now supports diff mode\, showing which attributes are changed within an operation \([https\://github\.com/ansible\-collections/community\.general/pull/8073](https\://github\.com/ansible\-collections/community\.general/pull/8073)\)\.
|
||||
* lvg \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
|
||||
* lvol \- change <code>pvs</code> argument type to list of strings \([https\://github\.com/ansible\-collections/community\.general/pull/7676](https\://github\.com/ansible\-collections/community\.general/pull/7676)\, [https\://github\.com/ansible\-collections/community\.general/issues/7504](https\://github\.com/ansible\-collections/community\.general/issues/7504)\)\.
|
||||
* lvol \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
|
||||
* lxd connection plugin \- tighten the detection logic for lxd <code>Instance not found</code> errors\, to avoid false detection on unrelated errors such as <code>/usr/bin/python3\: not found</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7521](https\://github\.com/ansible\-collections/community\.general/pull/7521)\)\.
|
||||
* lxd\_container \- uses <code>/1\.0/instances</code> API endpoint\, if available\. Falls back to <code>/1\.0/containers</code> or <code>/1\.0/virtual\-machines</code>\. Fixes issue when using Incus or LXD 5\.19 due to migrating to <code>/1\.0/instances</code> endpoint \([https\://github\.com/ansible\-collections/community\.general/pull/7980](https\://github\.com/ansible\-collections/community\.general/pull/7980)\)\.
|
||||
* macports \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
|
||||
* mail \- add <code>Message\-ID</code> header\; which is required by some mail servers \([https\://github\.com/ansible\-collections/community\.general/pull/7740](https\://github\.com/ansible\-collections/community\.general/pull/7740)\)\.
|
||||
* mail module\, mail callback plugin \- allow to configure the domain name of the Message\-ID header with a new <code>message\_id\_domain</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/7765](https\://github\.com/ansible\-collections/community\.general/pull/7765)\)\.
|
||||
* mssql\_script \- adds transactional \(rollback/commit\) support via optional boolean param <code>transaction</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7976](https\://github\.com/ansible\-collections/community\.general/pull/7976)\)\.
|
||||
* netcup\_dns \- adds support for record types <code>OPENPGPKEY</code>\, <code>SMIMEA</code>\, and <code>SSHFP</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7489](https\://github\.com/ansible\-collections/community\.general/pull/7489)\)\.
|
||||
* nmcli \- add support for new connection type <code>loopback</code> \([https\://github\.com/ansible\-collections/community\.general/issues/6572](https\://github\.com/ansible\-collections/community\.general/issues/6572)\)\.
|
||||
* nmcli \- adds OpenvSwitch support with new <code>type</code> values <code>ovs\-port</code>\, <code>ovs\-interface</code>\, and <code>ovs\-bridge</code>\, and new <code>slave\_type</code> value <code>ovs\-port</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8154](https\://github\.com/ansible\-collections/community\.general/pull/8154)\)\.
|
||||
* nmcli \- allow for <code>infiniband</code> slaves of <code>bond</code> interface types \([https\://github\.com/ansible\-collections/community\.general/pull/7569](https\://github\.com/ansible\-collections/community\.general/pull/7569)\)\.
|
||||
* nmcli \- allow for the setting of <code>MTU</code> for <code>infiniband</code> and <code>bond</code> interface types \([https\://github\.com/ansible\-collections/community\.general/pull/7499](https\://github\.com/ansible\-collections/community\.general/pull/7499)\)\.
|
||||
* nmcli \- allow setting <code>MTU</code> for <code>bond\-slave</code> interface types \([https\://github\.com/ansible\-collections/community\.general/pull/8118](https\://github\.com/ansible\-collections/community\.general/pull/8118)\)\.
|
||||
* onepassword lookup plugin \- support 1Password Connect with the opv2 client by setting the connect\_host and connect\_token parameters \([https\://github\.com/ansible\-collections/community\.general/pull/7116](https\://github\.com/ansible\-collections/community\.general/pull/7116)\)\.
|
||||
* onepassword\_raw lookup plugin \- support 1Password Connect with the opv2 client by setting the connect\_host and connect\_token parameters \([https\://github\.com/ansible\-collections/community\.general/pull/7116](https\://github\.com/ansible\-collections/community\.general/pull/7116)\)
|
||||
* opentelemetry \- add support for HTTP trace\_exporter and configures the behavior via <code>OTEL\_EXPORTER\_OTLP\_TRACES\_PROTOCOL</code> \([https\://github\.com/ansible\-collections/community\.general/issues/7888](https\://github\.com/ansible\-collections/community\.general/issues/7888)\, [https\://github\.com/ansible\-collections/community\.general/pull/8321](https\://github\.com/ansible\-collections/community\.general/pull/8321)\)\.
|
||||
* opentelemetry \- add support for exporting spans in a file via <code>ANSIBLE\_OPENTELEMETRY\_STORE\_SPANS\_IN\_FILE</code> \([https\://github\.com/ansible\-collections/community\.general/issues/7888](https\://github\.com/ansible\-collections/community\.general/issues/7888)\, [https\://github\.com/ansible\-collections/community\.general/pull/8363](https\://github\.com/ansible\-collections/community\.general/pull/8363)\)\.
|
||||
* opkg \- use <code>ModuleHelper</code> with <code>VarDict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
|
||||
* osx\_defaults \- add option <code>check\_types</code> to enable changing the type of existing defaults on the fly \([https\://github\.com/ansible\-collections/community\.general/pull/8173](https\://github\.com/ansible\-collections/community\.general/pull/8173)\)\.
|
||||
* parted \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
|
||||
* passwordstore \- adds <code>timestamp</code> and <code>preserve</code> parameters to modify the stored password format \([https\://github\.com/ansible\-collections/community\.general/pull/7426](https\://github\.com/ansible\-collections/community\.general/pull/7426)\)\.
|
||||
* passwordstore lookup \- add <code>missing\_subkey</code> parameter defining the behavior of the lookup when a passwordstore subkey is missing \([https\://github\.com/ansible\-collections/community\.general/pull/8166](https\://github\.com/ansible\-collections/community\.general/pull/8166)\)\.
|
||||
* pipx \- use <code>ModuleHelper</code> with <code>VarDict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
|
||||
* pkg5 \- add support for non\-silent execution \([https\://github\.com/ansible\-collections/community\.general/issues/8379](https\://github\.com/ansible\-collections/community\.general/issues/8379)\, [https\://github\.com/ansible\-collections/community\.general/pull/8382](https\://github\.com/ansible\-collections/community\.general/pull/8382)\)\.
|
||||
* pkgin \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
|
||||
* portage \- adds the possibility to explicitely tell portage to write packages to world file \([https\://github\.com/ansible\-collections/community\.general/issues/6226](https\://github\.com/ansible\-collections/community\.general/issues/6226)\, [https\://github\.com/ansible\-collections/community\.general/pull/8236](https\://github\.com/ansible\-collections/community\.general/pull/8236)\)\.
|
||||
* portinstall \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
|
||||
* proxmox \- adds <code>startup</code> parameters to configure startup order\, startup delay and shutdown delay \([https\://github\.com/ansible\-collections/community\.general/pull/8038](https\://github\.com/ansible\-collections/community\.general/pull/8038)\)\.
|
||||
* proxmox \- adds <code>template</code> value to the <code>state</code> parameter\, allowing conversion of container to a template \([https\://github\.com/ansible\-collections/community\.general/pull/7143](https\://github\.com/ansible\-collections/community\.general/pull/7143)\)\.
|
||||
* proxmox \- adds <code>update</code> parameter\, allowing update of an already existing containers configuration \([https\://github\.com/ansible\-collections/community\.general/pull/7540](https\://github\.com/ansible\-collections/community\.general/pull/7540)\)\.
|
||||
* proxmox inventory plugin \- adds an option to exclude nodes from the dynamic inventory generation\. The new setting is optional\, not using this option will behave as usual \([https\://github\.com/ansible\-collections/community\.general/issues/6714](https\://github\.com/ansible\-collections/community\.general/issues/6714)\, [https\://github\.com/ansible\-collections/community\.general/pull/7461](https\://github\.com/ansible\-collections/community\.general/pull/7461)\)\.
|
||||
* proxmox\* modules \- there is now a <code>community\.general\.proxmox</code> module defaults group that can be used to set default options for all Proxmox modules \([https\://github\.com/ansible\-collections/community\.general/pull/8334](https\://github\.com/ansible\-collections/community\.general/pull/8334)\)\.
|
||||
* proxmox\_disk \- add ability to manipulate CD\-ROM drive \([https\://github\.com/ansible\-collections/community\.general/pull/7495](https\://github\.com/ansible\-collections/community\.general/pull/7495)\)\.
|
||||
* proxmox\_kvm \- add parameter <code>update\_unsafe</code> to avoid limitations when updating dangerous values \([https\://github\.com/ansible\-collections/community\.general/pull/7843](https\://github\.com/ansible\-collections/community\.general/pull/7843)\)\.
|
||||
* proxmox\_kvm \- adds <code>template</code> value to the <code>state</code> parameter\, allowing conversion of a VM to a template \([https\://github\.com/ansible\-collections/community\.general/pull/7143](https\://github\.com/ansible\-collections/community\.general/pull/7143)\)\.
|
||||
* proxmox\_kvm \- adds\`\`usb\`\` parameter for setting USB devices on proxmox KVM VMs \([https\://github\.com/ansible\-collections/community\.general/pull/8199](https\://github\.com/ansible\-collections/community\.general/pull/8199)\)\.
|
||||
* proxmox\_kvm \- support the <code>hookscript</code> parameter \([https\://github\.com/ansible\-collections/community\.general/issues/7600](https\://github\.com/ansible\-collections/community\.general/issues/7600)\)\.
|
||||
* proxmox\_ostype \- it is now possible to specify the <code>ostype</code> when creating an LXC container \([https\://github\.com/ansible\-collections/community\.general/pull/7462](https\://github\.com/ansible\-collections/community\.general/pull/7462)\)\.
|
||||
* proxmox\_vm\_info \- add ability to retrieve configuration info \([https\://github\.com/ansible\-collections/community\.general/pull/7485](https\://github\.com/ansible\-collections/community\.general/pull/7485)\)\.
|
||||
* puppet \- new feature to set <code>\-\-waitforlock</code> option \([https\://github\.com/ansible\-collections/community\.general/pull/8282](https\://github\.com/ansible\-collections/community\.general/pull/8282)\)\.
|
||||
* redfish\_command \- add command <code>ResetToDefaults</code> to reset manager to default state \([https\://github\.com/ansible\-collections/community\.general/issues/8163](https\://github\.com/ansible\-collections/community\.general/issues/8163)\)\.
|
||||
* redfish\_config \- add command <code>SetServiceIdentification</code> to set service identification \([https\://github\.com/ansible\-collections/community\.general/issues/7916](https\://github\.com/ansible\-collections/community\.general/issues/7916)\)\.
|
||||
* redfish\_info \- add boolean return value <code>MultipartHttpPush</code> to <code>GetFirmwareUpdateCapabilities</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8194](https\://github\.com/ansible\-collections/community\.general/issues/8194)\, [https\://github\.com/ansible\-collections/community\.general/pull/8195](https\://github\.com/ansible\-collections/community\.general/pull/8195)\)\.
|
||||
* redfish\_info \- add command <code>GetServiceIdentification</code> to get service identification \([https\://github\.com/ansible\-collections/community\.general/issues/7882](https\://github\.com/ansible\-collections/community\.general/issues/7882)\)\.
|
||||
* redfish\_info \- adding the <code>BootProgress</code> property when getting <code>Systems</code> info \([https\://github\.com/ansible\-collections/community\.general/pull/7626](https\://github\.com/ansible\-collections/community\.general/pull/7626)\)\.
|
||||
* revbitspss lookup plugin \- removed a redundant unicode prefix\. The prefix was not necessary for Python 3 and has been cleaned up to streamline the code \([https\://github\.com/ansible\-collections/community\.general/pull/8087](https\://github\.com/ansible\-collections/community\.general/pull/8087)\)\.
|
||||
* rundeck module utils \- allow to pass <code>Content\-Type</code> to API requests \([https\://github\.com/ansible\-collections/community\.general/pull/7684](https\://github\.com/ansible\-collections/community\.general/pull/7684)\)\.
|
||||
* slackpkg \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
|
||||
* ssh\_config \- adds <code>controlmaster</code>\, <code>controlpath</code> and <code>controlpersist</code> parameters \([https\://github\.com/ansible\-collections/community\.general/pull/7456](https\://github\.com/ansible\-collections/community\.general/pull/7456)\)\.
|
||||
* ssh\_config \- allow <code>accept\-new</code> as valid value for <code>strict\_host\_key\_checking</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8257](https\://github\.com/ansible\-collections/community\.general/pull/8257)\)\.
|
||||
* ssh\_config \- new feature to set <code>AddKeysToAgent</code> option to <code>yes</code> or <code>no</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7703](https\://github\.com/ansible\-collections/community\.general/pull/7703)\)\.
|
||||
* ssh\_config \- new feature to set <code>IdentitiesOnly</code> option to <code>yes</code> or <code>no</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7704](https\://github\.com/ansible\-collections/community\.general/pull/7704)\)\.
|
||||
* sudoers \- add support for the <code>NOEXEC</code> tag in sudoers rules \([https\://github\.com/ansible\-collections/community\.general/pull/7983](https\://github\.com/ansible\-collections/community\.general/pull/7983)\)\.
|
||||
* svr4pkg \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
|
||||
* swdepot \- refactor module to pass list of arguments to <code>module\.run\_command\(\)</code> instead of relying on interpretation by a shell \([https\://github\.com/ansible\-collections/community\.general/pull/8264](https\://github\.com/ansible\-collections/community\.general/pull/8264)\)\.
|
||||
* terraform \- add support for <code>diff\_mode</code> for terraform resource\_changes \([https\://github\.com/ansible\-collections/community\.general/pull/7896](https\://github\.com/ansible\-collections/community\.general/pull/7896)\)\.
|
||||
* terraform \- fix <code>diff\_mode</code> in state <code>absent</code> and when terraform <code>resource\_changes</code> does not exist \([https\://github\.com/ansible\-collections/community\.general/pull/7963](https\://github\.com/ansible\-collections/community\.general/pull/7963)\)\.
|
||||
* xcc\_redfish\_command \- added support for raw POSTs \(<code>command\=PostResource</code> in <code>category\=Raw</code>\) without a specific action info \([https\://github\.com/ansible\-collections/community\.general/pull/7746](https\://github\.com/ansible\-collections/community\.general/pull/7746)\)\.
|
||||
* xfconf \- use <code>ModuleHelper</code> with <code>VarDict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
|
||||
* xfconf\_info \- use <code>ModuleHelper</code> with <code>VarDict</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
|
||||
|
||||
<a id="breaking-changes--porting-guide"></a>
|
||||
### Breaking Changes / Porting Guide
|
||||
|
||||
* cpanm \- the default of the <code>mode</code> option changed from <code>compatibility</code> to <code>new</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
* django\_manage \- the module now requires Django \>\= 4\.1 \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
* django\_manage \- the module will now fail if <code>virtualenv</code> is specified but no virtual environment exists at that location \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
* redfish\_command\, redfish\_config\, redfish\_info \- change the default for <code>timeout</code> from 10 to 60 \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
|
||||
<a id="deprecated-features"></a>
|
||||
### Deprecated Features
|
||||
|
||||
* MH DependencyCtxMgr module\_utils \- deprecate <code>module\_utils\.mh\.mixin\.deps\.DependencyCtxMgr</code> in favour of <code>module\_utils\.deps</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
|
||||
* ModuleHelper module\_utils \- deprecate <code>plugins\.module\_utils\.module\_helper\.AnsibleModule</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
|
||||
* ModuleHelper module\_utils \- deprecate <code>plugins\.module\_utils\.module\_helper\.DependencyCtxMgr</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
|
||||
* ModuleHelper module\_utils \- deprecate <code>plugins\.module\_utils\.module\_helper\.StateMixin</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
|
||||
* ModuleHelper module\_utils \- deprecate <code>plugins\.module\_utils\.module\_helper\.VarDict\,</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
|
||||
* ModuleHelper module\_utils \- deprecate <code>plugins\.module\_utils\.module\_helper\.VarMeta</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
|
||||
* ModuleHelper module\_utils \- deprecate <code>plugins\.module\_utils\.module\_helper\.VarsMixin</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8280](https\://github\.com/ansible\-collections/community\.general/pull/8280)\)\.
|
||||
* ModuleHelper module\_utils \- deprecate use of <code>VarsMixin</code> in favor of using the <code>VardDict</code> module\_utils \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
|
||||
* ModuleHelper vars module\_utils \- bump deprecation of <code>VarMeta</code>\, <code>VarDict</code> and <code>VarsMixin</code> to version 11\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/8226](https\://github\.com/ansible\-collections/community\.general/pull/8226)\)\.
|
||||
* apt\_rpm \- the behavior of <code>state\=present</code> and <code>state\=installed</code> is deprecated and will change in community\.general 11\.0\.0\. Right now the module will upgrade a package to the latest version if one of these two states is used\. You should explicitly use <code>state\=latest</code> if you want this behavior\, and switch to <code>state\=present\_not\_latest</code> if you do not want to upgrade the package if it is already installed\. In community\.general 11\.0\.0 the behavior of <code>state\=present</code> and <code>state\=installed</code> will change to that of <code>state\=present\_not\_latest</code> \([https\://github\.com/ansible\-collections/community\.general/issues/8217](https\://github\.com/ansible\-collections/community\.general/issues/8217)\, [https\://github\.com/ansible\-collections/community\.general/pull/8285](https\://github\.com/ansible\-collections/community\.general/pull/8285)\)\.
|
||||
* consul\_acl \- the module has been deprecated and will be removed in community\.general 10\.0\.0\. <code>consul\_token</code> and <code>consul\_policy</code> can be used instead \([https\://github\.com/ansible\-collections/community\.general/pull/7901](https\://github\.com/ansible\-collections/community\.general/pull/7901)\)\.
|
||||
* django\_manage \- the <code>ack\_venv\_creation\_deprecation</code> option has no more effect and will be removed from community\.general 11\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
* gitlab modules \- the basic auth method on GitLab API have been deprecated and will be removed in community\.general 10\.0\.0 \([https\://github\.com/ansible\-collections/community\.general/pull/8383](https\://github\.com/ansible\-collections/community\.general/pull/8383)\)\.
|
||||
* hipchat callback plugin \- the hipchat service has been discontinued and the self\-hosted variant has been End of Life since 2020\. The callback plugin is therefore deprecated and will be removed from community\.general 10\.0\.0 if nobody provides compelling reasons to still keep it \([https\://github\.com/ansible\-collections/community\.general/issues/8184](https\://github\.com/ansible\-collections/community\.general/issues/8184)\, [https\://github\.com/ansible\-collections/community\.general/pull/8189](https\://github\.com/ansible\-collections/community\.general/pull/8189)\)\.
|
||||
* irc \- the defaults <code>false</code> for <code>use\_tls</code> and <code>validate\_certs</code> have been deprecated and will change to <code>true</code> in community\.general 10\.0\.0 to improve security\. You can already improve security now by explicitly setting them to <code>true</code>\. Specifying values now disables the deprecation warning \([https\://github\.com/ansible\-collections/community\.general/pull/7578](https\://github\.com/ansible\-collections/community\.general/pull/7578)\)\.
|
||||
|
||||
<a id="removed-features-previously-deprecated"></a>
|
||||
### Removed Features \(previously deprecated\)
|
||||
|
||||
* The deprecated redirects for internal module names have been removed\. These internal redirects were extra\-long FQCNs like <code>community\.general\.packaging\.os\.apt\_rpm</code> that redirect to the short FQCN <code>community\.general\.apt\_rpm</code>\. They were originally needed to implement flatmapping\; as various tooling started to recommend users to use the long names flatmapping was removed from the collection and redirects were added for users who already followed these incorrect recommendations \([https\://github\.com/ansible\-collections/community\.general/pull/7835](https\://github\.com/ansible\-collections/community\.general/pull/7835)\)\.
|
||||
* ansible\_galaxy\_install \- the <code>ack\_ansible29</code> and <code>ack\_min\_ansiblecore211</code> options have been removed\. They no longer had any effect \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
* cloudflare\_dns \- remove support for SPF records\. These are no longer supported by CloudFlare \([https\://github\.com/ansible\-collections/community\.general/pull/7782](https\://github\.com/ansible\-collections/community\.general/pull/7782)\)\.
|
||||
* django\_manage \- support for the <code>command</code> values <code>cleanup</code>\, <code>syncdb</code>\, and <code>validate</code> were removed\. Use <code>clearsessions</code>\, <code>migrate</code>\, and <code>check</code> instead\, respectively \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
* flowdock \- this module relied on HTTPS APIs that do not exist anymore and was thus removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
* mh\.mixins\.deps module utils \- the <code>DependencyMixin</code> has been removed\. Use the <code>deps</code> module utils instead \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
* proxmox \- the <code>proxmox\_default\_behavior</code> option has been removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
* rax\* modules\, rax module utils\, rax docs fragment \- the Rackspace modules relied on the deprecated package <code>pyrax</code> and were thus removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
* redhat module utils \- the classes <code>Rhsm</code>\, <code>RhsmPool</code>\, and <code>RhsmPools</code> have been removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
* redhat\_subscription \- the alias <code>autosubscribe</code> of the <code>auto\_attach</code> option was removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
* stackdriver \- this module relied on HTTPS APIs that do not exist anymore and was thus removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
* webfaction\_\* modules \- these modules relied on HTTPS APIs that do not exist anymore and were thus removed \([https\://github\.com/ansible\-collections/community\.general/pull/8198](https\://github\.com/ansible\-collections/community\.general/pull/8198)\)\.
|
||||
|
||||
<a id="security-fixes"></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)\)\.
|
||||
* 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
|
||||
|
||||
* 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)\)\.
|
||||
* 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)\)\.
|
||||
* apt\-rpm \- the module did not upgrade packages if a newer version exists\. Now the package will be reinstalled if the candidate is newer than the installed version \([https\://github\.com/ansible\-collections/community\.general/issues/7414](https\://github\.com/ansible\-collections/community\.general/issues/7414)\)\.
|
||||
* 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)\)\.
|
||||
* 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)\)\.
|
||||
* 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)\)\.
|
||||
* consul\_token \- fix token creation without <code>accessor\_id</code> \([https\://github\.com/ansible\-collections/community\.general/pull/8091](https\://github\.com/ansible\-collections/community\.general/pull/8091)\)\.
|
||||
* from\_ini filter plugin \- disabling interpolation of <code>ConfigParser</code> to allow converting values with a <code>\%</code> sign \([https\://github\.com/ansible\-collections/community\.general/issues/8183](https\://github\.com/ansible\-collections/community\.general/issues/8183)\, [https\://github\.com/ansible\-collections/community\.general/pull/8185](https\://github\.com/ansible\-collections/community\.general/pull/8185)\)\.
|
||||
* gitlab\_group\_members \- fix gitlab constants call in <code>gitlab\_group\_members</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
|
||||
* gitlab\_issue \- fix behavior to search GitLab issue\, using <code>search</code> keyword instead of <code>title</code> \([https\://github\.com/ansible\-collections/community\.general/issues/7846](https\://github\.com/ansible\-collections/community\.general/issues/7846)\)\.
|
||||
* gitlab\_issue\, gitlab\_label\, gitlab\_milestone \- avoid crash during version comparison when the python\-gitlab Python module is not installed \([https\://github\.com/ansible\-collections/community\.general/pull/8158](https\://github\.com/ansible\-collections/community\.general/pull/8158)\)\.
|
||||
* gitlab\_project\_members \- fix gitlab constants call in <code>gitlab\_project\_members</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
|
||||
* gitlab\_protected\_branches \- fix gitlab constants call in <code>gitlab\_protected\_branches</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
|
||||
* 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)\)\.
|
||||
* gitlab\_user \- fix gitlab constants call in <code>gitlab\_user</code> module \([https\://github\.com/ansible\-collections/community\.general/issues/7467](https\://github\.com/ansible\-collections/community\.general/issues/7467)\)\.
|
||||
* 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)\)\.
|
||||
* 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)\)\.
|
||||
* 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)\)\.
|
||||
* incus connection plugin \- treats <code>inventory\_hostname</code> as a variable instead of a literal in remote connections \([https\://github\.com/ansible\-collections/community\.general/issues/7874](https\://github\.com/ansible\-collections/community\.general/issues/7874)\)\.
|
||||
* interface\_files \- also consider <code>address\_family</code> when changing <code>option\=method</code> \([https\://github\.com/ansible\-collections/community\.general/issues/7610](https\://github\.com/ansible\-collections/community\.general/issues/7610)\, [https\://github\.com/ansible\-collections/community\.general/pull/7612](https\://github\.com/ansible\-collections/community\.general/pull/7612)\)\.
|
||||
* 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)\)\.
|
||||
* 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\_otptoken \- the module expect <code>ipatokendisabled</code> as string but the <code>ipatokendisabled</code> value is returned as a boolean \([https\://github\.com/ansible\-collections/community\.general/pull/7795](https\://github\.com/ansible\-collections/community\.general/pull/7795)\)\.
|
||||
* 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)\)\.
|
||||
* irc \- replace <code>ssl\.wrap\_socket</code> that was removed from Python 3\.12 with code for creating a proper SSL context \([https\://github\.com/ansible\-collections/community\.general/pull/7542](https\://github\.com/ansible\-collections/community\.general/pull/7542)\)\.
|
||||
* keycloak\_\* \- fix Keycloak API client to quote <code>/</code> properly \([https\://github\.com/ansible\-collections/community\.general/pull/7641](https\://github\.com/ansible\-collections/community\.general/pull/7641)\)\.
|
||||
* keycloak\_authz\_permission \- resource payload variable for scope\-based permission was constructed as a string\, when it needs to be a list\, even for a single item \([https\://github\.com/ansible\-collections/community\.general/issues/7151](https\://github\.com/ansible\-collections/community\.general/issues/7151)\)\.
|
||||
* 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\_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)\)\.
|
||||
* 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)\)\.
|
||||
* keycloak\_identity\_provider \- it was not possible to reconfigure \(add\, remove\) <code>mappers</code> once they were created initially\. Removal was ignored\, adding new ones resulted in dropping the pre\-existing unmodified mappers\. Fix resolves the issue by supplying correct input to the internal update call \([https\://github\.com/ansible\-collections/community\.general/pull/7418](https\://github\.com/ansible\-collections/community\.general/pull/7418)\)\.
|
||||
* 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)\)\.
|
||||
* keycloak\_user \- when <code>force</code> is set\, but user does not exist\, do not try to delete it \([https\://github\.com/ansible\-collections/community\.general/pull/7696](https\://github\.com/ansible\-collections/community\.general/pull/7696)\)\.
|
||||
* 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)\)\.
|
||||
* ldap \- previously the order number \(if present\) was expected to follow an equals sign in the DN\. This makes it so the order number string is identified correctly anywhere within the DN \([https\://github\.com/ansible\-collections/community\.general/issues/7646](https\://github\.com/ansible\-collections/community\.general/issues/7646)\)\.
|
||||
* 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)\)\.
|
||||
* log\_entries callback plugin \- replace <code>ssl\.wrap\_socket</code> that was removed from Python 3\.12 with code for creating a proper SSL context \([https\://github\.com/ansible\-collections/community\.general/pull/7542](https\://github\.com/ansible\-collections/community\.general/pull/7542)\)\.
|
||||
* lvol \- test for output messages in both <code>stdout</code> and <code>stderr</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7601](https\://github\.com/ansible\-collections/community\.general/pull/7601)\, [https\://github\.com/ansible\-collections/community\.general/issues/7182](https\://github\.com/ansible\-collections/community\.general/issues/7182)\)\.
|
||||
* merge\_variables lookup plugin \- fixing cross host merge\: providing access to foreign hosts variables to the perspective of the host that is performing the merge \([https\://github\.com/ansible\-collections/community\.general/pull/8303](https\://github\.com/ansible\-collections/community\.general/pull/8303)\)\.
|
||||
* 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)\)\.
|
||||
* mssql\_script \- make the module work with Python 2 \([https\://github\.com/ansible\-collections/community\.general/issues/7818](https\://github\.com/ansible\-collections/community\.general/issues/7818)\, [https\://github\.com/ansible\-collections/community\.general/pull/7821](https\://github\.com/ansible\-collections/community\.general/pull/7821)\)\.
|
||||
* nmcli \- fix <code>connection\.slave\-type</code> wired to <code>bond</code> and not with parameter <code>slave\_type</code> in case of connection type <code>wifi</code> \([https\://github\.com/ansible\-collections/community\.general/issues/7389](https\://github\.com/ansible\-collections/community\.general/issues/7389)\)\.
|
||||
* ocapi\_utils\, oci\_utils\, redfish\_utils module utils \- replace <code>type\(\)</code> calls with <code>isinstance\(\)</code> calls \([https\://github\.com/ansible\-collections/community\.general/pull/7501](https\://github\.com/ansible\-collections/community\.general/pull/7501)\)\.
|
||||
* onepassword lookup plugin \- failed for fields that were in sections and had uppercase letters in the label/ID\. Field lookups are now case insensitive in all cases \([https\://github\.com/ansible\-collections/community\.general/pull/7919](https\://github\.com/ansible\-collections/community\.general/pull/7919)\)\.
|
||||
* onepassword lookup plugin \- field and section titles are now case insensitive when using op CLI version two or later\. This matches the behavior of version one \([https\://github\.com/ansible\-collections/community\.general/pull/7564](https\://github\.com/ansible\-collections/community\.general/pull/7564)\)\.
|
||||
* 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)\)\.
|
||||
* 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)\)\.
|
||||
* pipx module utils \- change the CLI argument formatter for the <code>pip\_args</code> parameter \([https\://github\.com/ansible\-collections/community\.general/issues/7497](https\://github\.com/ansible\-collections/community\.general/issues/7497)\, [https\://github\.com/ansible\-collections/community\.general/pull/7506](https\://github\.com/ansible\-collections/community\.general/pull/7506)\)\.
|
||||
* pkgin \- pkgin \(pkgsrc package manager used by SmartOS\) raises erratic exceptions and spurious <code>changed\=true</code> \([https\://github\.com/ansible\-collections/community\.general/pull/7971](https\://github\.com/ansible\-collections/community\.general/pull/7971)\)\.
|
||||
* proxmox \- fix updating a container config if the setting does not already exist \([https\://github\.com/ansible\-collections/community\.general/pull/7872](https\://github\.com/ansible\-collections/community\.general/pull/7872)\)\.
|
||||
* 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)\)\.
|
||||
* proxmox\_kvm \- running <code>state\=template</code> will first check whether VM is already a template \([https\://github\.com/ansible\-collections/community\.general/pull/7792](https\://github\.com/ansible\-collections/community\.general/pull/7792)\)\.
|
||||
* proxmox\_pool\_member \- absent state for type VM did not delete VMs from the pools \([https\://github\.com/ansible\-collections/community\.general/pull/7464](https\://github\.com/ansible\-collections/community\.general/pull/7464)\)\.
|
||||
* 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)\)
|
||||
* redfish\_command \- fix usage of message parsing in <code>SimpleUpdate</code> and <code>MultipartHTTPPushUpdate</code> commands to treat the lack of a <code>MessageId</code> as no message \([https\://github\.com/ansible\-collections/community\.general/issues/7465](https\://github\.com/ansible\-collections/community\.general/issues/7465)\, [https\://github\.com/ansible\-collections/community\.general/pull/7471](https\://github\.com/ansible\-collections/community\.general/pull/7471)\)\.
|
||||
* redfish\_info \- allow for a GET operation invoked by <code>GetUpdateStatus</code> to allow for an empty response body for cases where a service returns 204 No Content \([https\://github\.com/ansible\-collections/community\.general/issues/8003](https\://github\.com/ansible\-collections/community\.general/issues/8003)\)\.
|
||||
* redfish\_info \- correct uncaught exception when attempting to retrieve <code>Chassis</code> information \([https\://github\.com/ansible\-collections/community\.general/pull/7952](https\://github\.com/ansible\-collections/community\.general/pull/7952)\)\.
|
||||
* redhat\_subscription \- use the D\-Bus registration on RHEL 7 only on 7\.4 and
|
||||
greater\; older versions of RHEL 7 do not have it
|
||||
\([https\://github\.com/ansible\-collections/community\.general/issues/7622](https\://github\.com/ansible\-collections/community\.general/issues/7622)\,
|
||||
[https\://github\.com/ansible\-collections/community\.general/pull/7624](https\://github\.com/ansible\-collections/community\.general/pull/7624)\)\.
|
||||
* 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)\)\.
|
||||
* statusio\_maintenance \- fix error caused by incorrectly formed API data payload\. Was raising \"Failed to create maintenance HTTP Error 400 Bad Request\" caused by bad data type for date/time and deprecated dict keys \([https\://github\.com/ansible\-collections/community\.general/pull/7754](https\://github\.com/ansible\-collections/community\.general/pull/7754)\)\.
|
||||
* terraform \- fix multiline string handling in complex variables \([https\://github\.com/ansible\-collections/community\.general/pull/7535](https\://github\.com/ansible\-collections/community\.general/pull/7535)\)\.
|
||||
* to\_ini filter plugin \- disabling interpolation of <code>ConfigParser</code> to allow converting values with a <code>\%</code> sign \([https\://github\.com/ansible\-collections/community\.general/issues/8183](https\://github\.com/ansible\-collections/community\.general/issues/8183)\, [https\://github\.com/ansible\-collections/community\.general/pull/8185](https\://github\.com/ansible\-collections/community\.general/pull/8185)\)\.
|
||||
* 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="new-plugins"></a>
|
||||
### New Plugins
|
||||
|
||||
<a id="become"></a>
|
||||
#### Become
|
||||
|
||||
* community\.general\.run0 \- Systemd\'s run0\.
|
||||
|
||||
<a id="callback"></a>
|
||||
#### Callback
|
||||
|
||||
* community\.general\.default\_without\_diff \- The default ansible callback without diff output\.
|
||||
* community\.general\.timestamp \- Adds simple timestamp for each header\.
|
||||
|
||||
<a id="connection"></a>
|
||||
#### Connection
|
||||
|
||||
* community\.general\.incus \- Run tasks in Incus instances via the Incus CLI\.
|
||||
|
||||
<a id="filter"></a>
|
||||
#### Filter
|
||||
|
||||
* community\.general\.from\_ini \- Converts INI text input into a dictionary\.
|
||||
* community\.general\.lists\_difference \- Difference of lists with a predictive order\.
|
||||
* community\.general\.lists\_intersect \- Intersection of lists with a predictive order\.
|
||||
* community\.general\.lists\_symmetric\_difference \- Symmetric Difference of lists with a predictive order\.
|
||||
* community\.general\.lists\_union \- Union of lists with a predictive order\.
|
||||
* community\.general\.to\_ini \- Converts a dictionary to the INI file format\.
|
||||
|
||||
<a id="lookup"></a>
|
||||
#### Lookup
|
||||
|
||||
* community\.general\.github\_app\_access\_token \- Obtain short\-lived Github App Access tokens\.
|
||||
* community\.general\.onepassword\_doc \- Fetch documents stored in 1Password\.
|
||||
|
||||
<a id="test"></a>
|
||||
#### Test
|
||||
|
||||
* community\.general\.fqdn\_valid \- Validates fully\-qualified domain names against RFC 1123\.
|
||||
|
||||
<a id="new-modules"></a>
|
||||
### New Modules
|
||||
|
||||
* community\.general\.consul\_acl\_bootstrap \- Bootstrap ACLs in Consul\.
|
||||
* community\.general\.consul\_auth\_method \- Manipulate Consul auth methods\.
|
||||
* community\.general\.consul\_binding\_rule \- Manipulate Consul binding rules\.
|
||||
* community\.general\.consul\_token \- Manipulate Consul tokens\.
|
||||
* community\.general\.django\_command \- Run Django admin commands\.
|
||||
* community\.general\.dnf\_config\_manager \- Enable or disable dnf repositories using config\-manager\.
|
||||
* community\.general\.git\_config\_info \- Read git configuration\.
|
||||
* community\.general\.gitlab\_group\_access\_token \- Manages GitLab group access tokens\.
|
||||
* community\.general\.gitlab\_issue \- Create\, update\, or delete GitLab issues\.
|
||||
* community\.general\.gitlab\_label \- Creates/updates/deletes GitLab Labels belonging to project or group\.
|
||||
* community\.general\.gitlab\_milestone \- Creates/updates/deletes GitLab Milestones belonging to project or group\.
|
||||
* community\.general\.gitlab\_project\_access\_token \- Manages GitLab project access tokens\.
|
||||
* community\.general\.keycloak\_client\_rolescope \- Allows administration of Keycloak client roles scope to restrict the usage of certain roles to a other specific client applications\.
|
||||
* community\.general\.keycloak\_component\_info \- Retrive component info in Keycloak\.
|
||||
* community\.general\.keycloak\_realm\_rolemapping \- Allows administration of Keycloak realm role mappings into groups with the Keycloak API\.
|
||||
* community\.general\.nomad\_token \- Manage Nomad ACL tokens\.
|
||||
* community\.general\.proxmox\_node\_info \- Retrieve information about one or more Proxmox VE nodes\.
|
||||
* community\.general\.proxmox\_storage\_contents\_info \- List content from a Proxmox VE storage\.
|
||||
* community\.general\.usb\_facts \- Allows listing information about USB devices\.
|
||||
@@ -1,3 +0,0 @@
|
||||
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
|
||||
SPDX-FileCopyrightText: Ansible Project
|
||||
702
CHANGELOG.rst
702
CHANGELOG.rst
@@ -4,30 +4,19 @@ Community General Release Notes
|
||||
|
||||
.. contents:: Topics
|
||||
|
||||
This changelog describes changes after version 8.0.0.
|
||||
This changelog describes changes after version 7.0.0.
|
||||
|
||||
v9.0.0
|
||||
v8.3.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This is release 9.0.0 of ``community.general``, released on 2024-05-20.
|
||||
Regular bugfix and feature release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- PythonRunner module utils - specialisation of ``CmdRunner`` to execute Python scripts (https://github.com/ansible-collections/community.general/pull/8289).
|
||||
- Use offset-aware ``datetime.datetime`` objects (with timezone UTC) instead of offset-naive UTC timestamps, which are deprecated in Python 3.12 (https://github.com/ansible-collections/community.general/pull/8222).
|
||||
- aix_lvol - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
|
||||
- apt_rpm - add new states ``latest`` and ``present_not_latest``. The value ``latest`` is equivalent to the current behavior of ``present``, which will upgrade a package if a newer version exists. ``present_not_latest`` does what most users would expect ``present`` to do: it does not upgrade if the package is already installed. The current behavior of ``present`` will be deprecated in a later version, and eventually changed to that of ``present_not_latest`` (https://github.com/ansible-collections/community.general/issues/8217, https://github.com/ansible-collections/community.general/pull/8247).
|
||||
- apt_rpm - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
|
||||
- bitwarden lookup plugin - add ``bw_session`` option, to pass session key instead of reading from env (https://github.com/ansible-collections/community.general/pull/7994).
|
||||
- bitwarden lookup plugin - add support to filter by organization ID (https://github.com/ansible-collections/community.general/pull/8188).
|
||||
- bitwarden lookup plugin - allows to fetch all records of a given collection ID, by allowing to pass an empty value for ``search_value`` when ``collection_id`` is provided (https://github.com/ansible-collections/community.general/pull/8013).
|
||||
- bitwarden lookup plugin - when looking for items using an item ID, the item is now accessed directly with ``bw get item`` instead of searching through all items. This doubles the lookup speed (https://github.com/ansible-collections/community.general/pull/7468).
|
||||
- btrfs_subvolume - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
|
||||
- cmd_runner module_utils - add validation for minimum and maximum length in the value passed to ``cmd_runner_fmt.as_list()`` (https://github.com/ansible-collections/community.general/pull/8288).
|
||||
- consul_auth_method, consul_binding_rule, consul_policy, consul_role, consul_session, consul_token - added action group ``community.general.consul`` (https://github.com/ansible-collections/community.general/pull/7897).
|
||||
- consul_policy - added support for diff and check mode (https://github.com/ansible-collections/community.general/pull/7878).
|
||||
- consul_policy, consul_role, consul_session - removed dependency on ``requests`` and factored out common parts (https://github.com/ansible-collections/community.general/pull/7826, https://github.com/ansible-collections/community.general/pull/7878).
|
||||
@@ -35,289 +24,532 @@ Minor Changes
|
||||
- consul_role - ``service_identities`` now expects a ``service_name`` option to match the Consul API, the old ``name`` is still supported as alias (https://github.com/ansible-collections/community.general/pull/7878).
|
||||
- consul_role - added support for diff mode (https://github.com/ansible-collections/community.general/pull/7878).
|
||||
- consul_role - added support for templated policies (https://github.com/ansible-collections/community.general/pull/7878).
|
||||
- redfish_info - add command ``GetServiceIdentification`` to get service identification (https://github.com/ansible-collections/community.general/issues/7882).
|
||||
- terraform - add support for ``diff_mode`` for terraform resource_changes (https://github.com/ansible-collections/community.general/pull/7896).
|
||||
|
||||
Deprecated Features
|
||||
-------------------
|
||||
|
||||
- consul_acl - the module has been deprecated and will be removed in community.general 10.0.0. ``consul_token`` and ``consul_policy`` can be used instead (https://github.com/ansible-collections/community.general/pull/7901).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- homebrew - detect already installed formulae and casks using JSON output from ``brew info`` (https://github.com/ansible-collections/community.general/issues/864).
|
||||
- incus connection plugin - treats ``inventory_hostname`` as a variable instead of a literal in remote connections (https://github.com/ansible-collections/community.general/issues/7874).
|
||||
- ipa_otptoken - the module expect ``ipatokendisabled`` as string but the ``ipatokendisabled`` value is returned as a boolean (https://github.com/ansible-collections/community.general/pull/7795).
|
||||
- ldap - previously the order number (if present) was expected to follow an equals sign in the DN. This makes it so the order number string is identified correctly anywhere within the DN (https://github.com/ansible-collections/community.general/issues/7646).
|
||||
- mssql_script - make the module work with Python 2 (https://github.com/ansible-collections/community.general/issues/7818, https://github.com/ansible-collections/community.general/pull/7821).
|
||||
- nmcli - fix ``connection.slave-type`` wired to ``bond`` and not with parameter ``slave_type`` in case of connection type ``wifi`` (https://github.com/ansible-collections/community.general/issues/7389).
|
||||
- proxmox - fix updating a container config if the setting does not already exist (https://github.com/ansible-collections/community.general/pull/7872).
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- consul_acl_bootstrap - Bootstrap ACLs in Consul
|
||||
- consul_auth_method - Manipulate Consul auth methods
|
||||
- consul_binding_rule - Manipulate Consul binding rules
|
||||
- consul_token - Manipulate Consul tokens
|
||||
- gitlab_label - Creates/updates/deletes GitLab Labels belonging to project or group.
|
||||
- gitlab_milestone - Creates/updates/deletes GitLab Milestones belonging to project or group
|
||||
|
||||
v8.2.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix and feature release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- ipa_dnsrecord - adds ability to manage NS record types (https://github.com/ansible-collections/community.general/pull/7737).
|
||||
- ipa_pwpolicy - refactor module and exchange a sequence ``if`` statements with a ``for`` loop (https://github.com/ansible-collections/community.general/pull/7723).
|
||||
- ipa_pwpolicy - update module to support ``maxrepeat``, ``maxsequence``, ``dictcheck``, ``usercheck``, ``gracelimit`` parameters in FreeIPA password policies (https://github.com/ansible-collections/community.general/pull/7723).
|
||||
- keycloak_realm_key - the ``config.algorithm`` option now supports 8 additional key algorithms (https://github.com/ansible-collections/community.general/pull/7698).
|
||||
- keycloak_realm_key - the ``config.certificate`` option value is no longer defined with ``no_log=True`` (https://github.com/ansible-collections/community.general/pull/7698).
|
||||
- keycloak_realm_key - the ``provider_id`` option now supports RSA encryption key usage (value ``rsa-enc``) (https://github.com/ansible-collections/community.general/pull/7698).
|
||||
- keycloak_user_federation - allow custom user storage providers to be set through ``provider_id`` (https://github.com/ansible-collections/community.general/pull/7789).
|
||||
- mail - add ``Message-ID`` header; which is required by some mail servers (https://github.com/ansible-collections/community.general/pull/7740).
|
||||
- mail module, mail callback plugin - allow to configure the domain name of the Message-ID header with a new ``message_id_domain`` option (https://github.com/ansible-collections/community.general/pull/7765).
|
||||
- ssh_config - new feature to set ``AddKeysToAgent`` option to ``yes`` or ``no`` (https://github.com/ansible-collections/community.general/pull/7703).
|
||||
- ssh_config - new feature to set ``IdentitiesOnly`` option to ``yes`` or ``no`` (https://github.com/ansible-collections/community.general/pull/7704).
|
||||
- xcc_redfish_command - added support for raw POSTs (``command=PostResource`` in ``category=Raw``) without a specific action info (https://github.com/ansible-collections/community.general/pull/7746).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- keycloak_identity_provider - ``mappers`` 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).
|
||||
- keycloak_identity_provider - it was not possible to reconfigure (add, remove) ``mappers`` once they were created initially. Removal was ignored, adding new ones resulted in dropping the pre-existing unmodified mappers. Fix resolves the issue by supplying correct input to the internal update call (https://github.com/ansible-collections/community.general/pull/7418).
|
||||
- keycloak_user - when ``force`` is set, but user does not exist, do not try to delete it (https://github.com/ansible-collections/community.general/pull/7696).
|
||||
- proxmox_kvm - running ``state=template`` will first check whether VM is already a template (https://github.com/ansible-collections/community.general/pull/7792).
|
||||
- statusio_maintenance - fix error caused by incorrectly formed API data payload. Was raising "Failed to create maintenance HTTP Error 400 Bad Request" caused by bad data type for date/time and deprecated dict keys (https://github.com/ansible-collections/community.general/pull/7754).
|
||||
|
||||
New Plugins
|
||||
-----------
|
||||
|
||||
Connection
|
||||
~~~~~~~~~~
|
||||
|
||||
- incus - Run tasks in Incus instances via the Incus CLI.
|
||||
|
||||
Filter
|
||||
~~~~~~
|
||||
|
||||
- from_ini - Converts INI text input into a dictionary
|
||||
- to_ini - Converts a dictionary to the INI file format
|
||||
|
||||
Lookup
|
||||
~~~~~~
|
||||
|
||||
- github_app_access_token - Obtain short-lived Github App Access tokens
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- dnf_config_manager - Enable or disable dnf repositories using config-manager
|
||||
- keycloak_component_info - Retrive component info in Keycloak
|
||||
- keycloak_realm_rolemapping - Allows administration of Keycloak realm role mappings into groups with the Keycloak API
|
||||
- proxmox_node_info - Retrieve information about one or more Proxmox VE nodes
|
||||
- proxmox_storage_contents_info - List content from a Proxmox VE storage
|
||||
|
||||
v8.1.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix and feature release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- bitwarden lookup plugin - when looking for items using an item ID, the item is now accessed directly with ``bw get item`` instead of searching through all items. This doubles the lookup speed (https://github.com/ansible-collections/community.general/pull/7468).
|
||||
- elastic callback plugin - close elastic client to not leak resources (https://github.com/ansible-collections/community.general/pull/7517).
|
||||
- filesystem - add bcachefs support (https://github.com/ansible-collections/community.general/pull/8126).
|
||||
- gandi_livedns - adds support for personal access tokens (https://github.com/ansible-collections/community.general/issues/7639, https://github.com/ansible-collections/community.general/pull/8337).
|
||||
- gconftool2 - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
|
||||
- git_config - allow multiple git configs for the same name with the new ``add_mode`` option (https://github.com/ansible-collections/community.general/pull/7260).
|
||||
- git_config - the ``after`` and ``before`` fields in the ``diff`` of the return value can be a list instead of a string in case more configs with the same key are affected (https://github.com/ansible-collections/community.general/pull/7260).
|
||||
- git_config - when a value is unset, all configs with the same key are unset (https://github.com/ansible-collections/community.general/pull/7260).
|
||||
- gitlab modules - add ``ca_path`` option (https://github.com/ansible-collections/community.general/pull/7472).
|
||||
- gitlab modules - remove duplicate ``gitlab`` package check (https://github.com/ansible-collections/community.general/pull/7486).
|
||||
- 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).
|
||||
- gitlab_hook - adds ``releases_events`` parameter for supporting Releases events triggers on GitLab hooks (https://github.com/ansible-collections/community.general/pull/7956).
|
||||
- gitlab_runner - add support for new runner creation workflow (https://github.com/ansible-collections/community.general/pull/7199).
|
||||
- homebrew - adds ``force_formula`` parameter to disambiguate a formula from a cask of the same name (https://github.com/ansible-collections/community.general/issues/8274).
|
||||
- homebrew, homebrew_cask - refactor common argument validation logic into a dedicated ``homebrew`` module utils (https://github.com/ansible-collections/community.general/issues/8323, https://github.com/ansible-collections/community.general/pull/8324).
|
||||
- icinga2 inventory plugin - add Jinja2 templating support to ``url``, ``user``, and ``password`` paramenters (https://github.com/ansible-collections/community.general/issues/7074, https://github.com/ansible-collections/community.general/pull/7996).
|
||||
- icinga2 inventory plugin - adds new parameter ``group_by_hostgroups`` in order to make grouping by Icinga2 hostgroups optional (https://github.com/ansible-collections/community.general/pull/7998).
|
||||
- ini_file - add an optional parameter ``section_has_values``. If the target ini file contains more than one ``section``, use ``section_has_values`` to specify which one should be updated (https://github.com/ansible-collections/community.general/pull/7505).
|
||||
- ini_file - support optional spaces between section names and their surrounding brackets (https://github.com/ansible-collections/community.general/pull/8075).
|
||||
- installp - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
|
||||
- ipa_config - adds ``passkey`` choice to ``ipauserauthtype`` parameter's choices (https://github.com/ansible-collections/community.general/pull/7588).
|
||||
- ipa_dnsrecord - adds ability to manage NS record types (https://github.com/ansible-collections/community.general/pull/7737).
|
||||
- ipa_pwpolicy - refactor module and exchange a sequence ``if`` statements with a ``for`` loop (https://github.com/ansible-collections/community.general/pull/7723).
|
||||
- ipa_pwpolicy - update module to support ``maxrepeat``, ``maxsequence``, ``dictcheck``, ``usercheck``, ``gracelimit`` parameters in FreeIPA password policies (https://github.com/ansible-collections/community.general/pull/7723).
|
||||
- ipa_sudorule - adds options to include denied commands or command groups (https://github.com/ansible-collections/community.general/pull/7415).
|
||||
- ipa_user - adds ``idp`` and ``passkey`` choice to ``ipauserauthtype`` parameter's choices (https://github.com/ansible-collections/community.general/pull/7589).
|
||||
- irc - add ``validate_certs`` option, and rename ``use_ssl`` to ``use_tls``, while keeping ``use_ssl`` as an alias. The default value for ``validate_certs`` is ``false`` for backwards compatibility. We recommend to every user of this module to explicitly set ``use_tls=true`` and `validate_certs=true`` whenever possible, especially when communicating to IRC servers over the internet (https://github.com/ansible-collections/community.general/pull/7550).
|
||||
- java_cert - add ``cert_content`` argument (https://github.com/ansible-collections/community.general/pull/8153).
|
||||
- java_cert - enable ``owner``, ``group``, ``mode``, and other generic file arguments (https://github.com/ansible-collections/community.general/pull/8116).
|
||||
- kernel_blacklist - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
|
||||
- keycloak module utils - expose error message from Keycloak server for HTTP errors in some specific situations (https://github.com/ansible-collections/community.general/pull/7645).
|
||||
- keycloak_client, keycloak_clientscope, keycloak_clienttemplate - added ``docker-v2`` protocol support, enhancing alignment with Keycloak's protocol options (https://github.com/ansible-collections/community.general/issues/8215, https://github.com/ansible-collections/community.general/pull/8216).
|
||||
- keycloak_realm_key - the ``config.algorithm`` option now supports 8 additional key algorithms (https://github.com/ansible-collections/community.general/pull/7698).
|
||||
- keycloak_realm_key - the ``config.certificate`` option value is no longer defined with ``no_log=True`` (https://github.com/ansible-collections/community.general/pull/7698).
|
||||
- keycloak_realm_key - the ``provider_id`` option now supports RSA encryption key usage (value ``rsa-enc``) (https://github.com/ansible-collections/community.general/pull/7698).
|
||||
- keycloak_user_federation - add option for ``krbPrincipalAttribute`` (https://github.com/ansible-collections/community.general/pull/7538).
|
||||
- keycloak_user_federation - allow custom user storage providers to be set through ``provider_id`` (https://github.com/ansible-collections/community.general/pull/7789).
|
||||
- ldap_attrs - module now supports diff mode, showing which attributes are changed within an operation (https://github.com/ansible-collections/community.general/pull/8073).
|
||||
- lvg - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
|
||||
- lvol - change ``pvs`` argument type to list of strings (https://github.com/ansible-collections/community.general/pull/7676, https://github.com/ansible-collections/community.general/issues/7504).
|
||||
- lvol - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
|
||||
- lxd connection plugin - tighten the detection logic for lxd ``Instance not found`` errors, to avoid false detection on unrelated errors such as ``/usr/bin/python3: not found`` (https://github.com/ansible-collections/community.general/pull/7521).
|
||||
- lxd_container - uses ``/1.0/instances`` API endpoint, if available. Falls back to ``/1.0/containers`` or ``/1.0/virtual-machines``. Fixes issue when using Incus or LXD 5.19 due to migrating to ``/1.0/instances`` endpoint (https://github.com/ansible-collections/community.general/pull/7980).
|
||||
- macports - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
|
||||
- mail - add ``Message-ID`` header; which is required by some mail servers (https://github.com/ansible-collections/community.general/pull/7740).
|
||||
- mail module, mail callback plugin - allow to configure the domain name of the Message-ID header with a new ``message_id_domain`` option (https://github.com/ansible-collections/community.general/pull/7765).
|
||||
- mssql_script - adds transactional (rollback/commit) support via optional boolean param ``transaction`` (https://github.com/ansible-collections/community.general/pull/7976).
|
||||
- netcup_dns - adds support for record types ``OPENPGPKEY``, ``SMIMEA``, and ``SSHFP`` (https://github.com/ansible-collections/community.general/pull/7489).
|
||||
- nmcli - add support for new connection type ``loopback`` (https://github.com/ansible-collections/community.general/issues/6572).
|
||||
- nmcli - adds OpenvSwitch support with new ``type`` values ``ovs-port``, ``ovs-interface``, and ``ovs-bridge``, and new ``slave_type`` value ``ovs-port`` (https://github.com/ansible-collections/community.general/pull/8154).
|
||||
- nmcli - allow for ``infiniband`` slaves of ``bond`` interface types (https://github.com/ansible-collections/community.general/pull/7569).
|
||||
- nmcli - allow for the setting of ``MTU`` for ``infiniband`` and ``bond`` interface types (https://github.com/ansible-collections/community.general/pull/7499).
|
||||
- nmcli - allow setting ``MTU`` for ``bond-slave`` interface types (https://github.com/ansible-collections/community.general/pull/8118).
|
||||
- onepassword lookup plugin - support 1Password Connect with the opv2 client by setting the connect_host and connect_token parameters (https://github.com/ansible-collections/community.general/pull/7116).
|
||||
- onepassword_raw lookup plugin - support 1Password Connect with the opv2 client by setting the connect_host and connect_token parameters (https://github.com/ansible-collections/community.general/pull/7116)
|
||||
- opentelemetry - add support for HTTP trace_exporter and configures the behavior via ``OTEL_EXPORTER_OTLP_TRACES_PROTOCOL`` (https://github.com/ansible-collections/community.general/issues/7888, https://github.com/ansible-collections/community.general/pull/8321).
|
||||
- opentelemetry - add support for exporting spans in a file via ``ANSIBLE_OPENTELEMETRY_STORE_SPANS_IN_FILE`` (https://github.com/ansible-collections/community.general/issues/7888, https://github.com/ansible-collections/community.general/pull/8363).
|
||||
- opkg - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
|
||||
- osx_defaults - add option ``check_types`` to enable changing the type of existing defaults on the fly (https://github.com/ansible-collections/community.general/pull/8173).
|
||||
- parted - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
|
||||
- passwordstore - adds ``timestamp`` and ``preserve`` parameters to modify the stored password format (https://github.com/ansible-collections/community.general/pull/7426).
|
||||
- passwordstore lookup - add ``missing_subkey`` parameter defining the behavior of the lookup when a passwordstore subkey is missing (https://github.com/ansible-collections/community.general/pull/8166).
|
||||
- pipx - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
|
||||
- pkg5 - add support for non-silent execution (https://github.com/ansible-collections/community.general/issues/8379, https://github.com/ansible-collections/community.general/pull/8382).
|
||||
- pkgin - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
|
||||
- portage - adds the possibility to explicitely tell portage to write packages to world file (https://github.com/ansible-collections/community.general/issues/6226, https://github.com/ansible-collections/community.general/pull/8236).
|
||||
- portinstall - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
|
||||
- proxmox - adds ``startup`` parameters to configure startup order, startup delay and shutdown delay (https://github.com/ansible-collections/community.general/pull/8038).
|
||||
- proxmox - adds ``template`` value to the ``state`` parameter, allowing conversion of container to a template (https://github.com/ansible-collections/community.general/pull/7143).
|
||||
- proxmox - adds ``update`` parameter, allowing update of an already existing containers configuration (https://github.com/ansible-collections/community.general/pull/7540).
|
||||
- proxmox inventory plugin - adds an option to exclude nodes from the dynamic inventory generation. The new setting is optional, not using this option will behave as usual (https://github.com/ansible-collections/community.general/issues/6714, https://github.com/ansible-collections/community.general/pull/7461).
|
||||
- proxmox* modules - there is now a ``community.general.proxmox`` module defaults group that can be used to set default options for all Proxmox modules (https://github.com/ansible-collections/community.general/pull/8334).
|
||||
- proxmox_disk - add ability to manipulate CD-ROM drive (https://github.com/ansible-collections/community.general/pull/7495).
|
||||
- proxmox_kvm - add parameter ``update_unsafe`` to avoid limitations when updating dangerous values (https://github.com/ansible-collections/community.general/pull/7843).
|
||||
- proxmox_kvm - adds ``template`` value to the ``state`` parameter, allowing conversion of a VM to a template (https://github.com/ansible-collections/community.general/pull/7143).
|
||||
- proxmox_kvm - adds``usb`` parameter for setting USB devices on proxmox KVM VMs (https://github.com/ansible-collections/community.general/pull/8199).
|
||||
- proxmox_kvm - support the ``hookscript`` parameter (https://github.com/ansible-collections/community.general/issues/7600).
|
||||
- proxmox_ostype - it is now possible to specify the ``ostype`` when creating an LXC container (https://github.com/ansible-collections/community.general/pull/7462).
|
||||
- proxmox_vm_info - add ability to retrieve configuration info (https://github.com/ansible-collections/community.general/pull/7485).
|
||||
- puppet - new feature to set ``--waitforlock`` option (https://github.com/ansible-collections/community.general/pull/8282).
|
||||
- redfish_command - add command ``ResetToDefaults`` to reset manager to default state (https://github.com/ansible-collections/community.general/issues/8163).
|
||||
- redfish_config - add command ``SetServiceIdentification`` to set service identification (https://github.com/ansible-collections/community.general/issues/7916).
|
||||
- redfish_info - add boolean return value ``MultipartHttpPush`` to ``GetFirmwareUpdateCapabilities`` (https://github.com/ansible-collections/community.general/issues/8194, https://github.com/ansible-collections/community.general/pull/8195).
|
||||
- redfish_info - add command ``GetServiceIdentification`` to get service identification (https://github.com/ansible-collections/community.general/issues/7882).
|
||||
- redfish_info - adding the ``BootProgress`` property when getting ``Systems`` info (https://github.com/ansible-collections/community.general/pull/7626).
|
||||
- revbitspss lookup plugin - removed a redundant unicode prefix. The prefix was not necessary for Python 3 and has been cleaned up to streamline the code (https://github.com/ansible-collections/community.general/pull/8087).
|
||||
- rundeck module utils - allow to pass ``Content-Type`` to API requests (https://github.com/ansible-collections/community.general/pull/7684).
|
||||
- slackpkg - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
|
||||
- ssh_config - adds ``controlmaster``, ``controlpath`` and ``controlpersist`` parameters (https://github.com/ansible-collections/community.general/pull/7456).
|
||||
- ssh_config - allow ``accept-new`` as valid value for ``strict_host_key_checking`` (https://github.com/ansible-collections/community.general/pull/8257).
|
||||
- ssh_config - new feature to set ``AddKeysToAgent`` option to ``yes`` or ``no`` (https://github.com/ansible-collections/community.general/pull/7703).
|
||||
- ssh_config - new feature to set ``IdentitiesOnly`` option to ``yes`` or ``no`` (https://github.com/ansible-collections/community.general/pull/7704).
|
||||
- sudoers - add support for the ``NOEXEC`` tag in sudoers rules (https://github.com/ansible-collections/community.general/pull/7983).
|
||||
- svr4pkg - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
|
||||
- swdepot - refactor module to pass list of arguments to ``module.run_command()`` instead of relying on interpretation by a shell (https://github.com/ansible-collections/community.general/pull/8264).
|
||||
- terraform - add support for ``diff_mode`` for terraform resource_changes (https://github.com/ansible-collections/community.general/pull/7896).
|
||||
- terraform - fix ``diff_mode`` in state ``absent`` and when terraform ``resource_changes`` does not exist (https://github.com/ansible-collections/community.general/pull/7963).
|
||||
- xcc_redfish_command - added support for raw POSTs (``command=PostResource`` in ``category=Raw``) without a specific action info (https://github.com/ansible-collections/community.general/pull/7746).
|
||||
- xfconf - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
|
||||
- xfconf_info - use ``ModuleHelper`` with ``VarDict`` (https://github.com/ansible-collections/community.general/pull/8226).
|
||||
|
||||
Breaking Changes / Porting Guide
|
||||
--------------------------------
|
||||
|
||||
- cpanm - the default of the ``mode`` option changed from ``compatibility`` to ``new`` (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
- django_manage - the module now requires Django >= 4.1 (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
- django_manage - the module will now fail if ``virtualenv`` is specified but no virtual environment exists at that location (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
- redfish_command, redfish_config, redfish_info - change the default for ``timeout`` from 10 to 60 (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
|
||||
Deprecated Features
|
||||
-------------------
|
||||
|
||||
- MH DependencyCtxMgr module_utils - deprecate ``module_utils.mh.mixin.deps.DependencyCtxMgr`` in favour of ``module_utils.deps`` (https://github.com/ansible-collections/community.general/pull/8280).
|
||||
- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.AnsibleModule`` (https://github.com/ansible-collections/community.general/pull/8280).
|
||||
- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.DependencyCtxMgr`` (https://github.com/ansible-collections/community.general/pull/8280).
|
||||
- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.StateMixin`` (https://github.com/ansible-collections/community.general/pull/8280).
|
||||
- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.VarDict,`` (https://github.com/ansible-collections/community.general/pull/8280).
|
||||
- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.VarMeta`` (https://github.com/ansible-collections/community.general/pull/8280).
|
||||
- ModuleHelper module_utils - deprecate ``plugins.module_utils.module_helper.VarsMixin`` (https://github.com/ansible-collections/community.general/pull/8280).
|
||||
- ModuleHelper module_utils - deprecate use of ``VarsMixin`` in favor of using the ``VardDict`` module_utils (https://github.com/ansible-collections/community.general/pull/8226).
|
||||
- ModuleHelper vars module_utils - bump deprecation of ``VarMeta``, ``VarDict`` and ``VarsMixin`` to version 11.0.0 (https://github.com/ansible-collections/community.general/pull/8226).
|
||||
- apt_rpm - the behavior of ``state=present`` and ``state=installed`` is deprecated and will change in community.general 11.0.0. Right now the module will upgrade a package to the latest version if one of these two states is used. You should explicitly use ``state=latest`` if you want this behavior, and switch to ``state=present_not_latest`` if you do not want to upgrade the package if it is already installed. In community.general 11.0.0 the behavior of ``state=present`` and ``state=installed`` will change to that of ``state=present_not_latest`` (https://github.com/ansible-collections/community.general/issues/8217, https://github.com/ansible-collections/community.general/pull/8285).
|
||||
- consul_acl - the module has been deprecated and will be removed in community.general 10.0.0. ``consul_token`` and ``consul_policy`` can be used instead (https://github.com/ansible-collections/community.general/pull/7901).
|
||||
- django_manage - the ``ack_venv_creation_deprecation`` option has no more effect and will be removed from community.general 11.0.0 (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
- gitlab modules - the basic auth method on GitLab API have been deprecated and will be removed in community.general 10.0.0 (https://github.com/ansible-collections/community.general/pull/8383).
|
||||
- hipchat callback plugin - the hipchat service has been discontinued and the self-hosted variant has been End of Life since 2020. The callback plugin is therefore deprecated and will be removed from community.general 10.0.0 if nobody provides compelling reasons to still keep it (https://github.com/ansible-collections/community.general/issues/8184, https://github.com/ansible-collections/community.general/pull/8189).
|
||||
- irc - the defaults ``false`` for ``use_tls`` and ``validate_certs`` have been deprecated and will change to ``true`` in community.general 10.0.0 to improve security. You can already improve security now by explicitly setting them to ``true``. Specifying values now disables the deprecation warning (https://github.com/ansible-collections/community.general/pull/7578).
|
||||
|
||||
Removed Features (previously deprecated)
|
||||
----------------------------------------
|
||||
|
||||
- The deprecated redirects for internal module names have been removed. These internal redirects were extra-long FQCNs like ``community.general.packaging.os.apt_rpm`` that redirect to the short FQCN ``community.general.apt_rpm``. They were originally needed to implement flatmapping; as various tooling started to recommend users to use the long names flatmapping was removed from the collection and redirects were added for users who already followed these incorrect recommendations (https://github.com/ansible-collections/community.general/pull/7835).
|
||||
- ansible_galaxy_install - the ``ack_ansible29`` and ``ack_min_ansiblecore211`` options have been removed. They no longer had any effect (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
- cloudflare_dns - remove support for SPF records. These are no longer supported by CloudFlare (https://github.com/ansible-collections/community.general/pull/7782).
|
||||
- django_manage - support for the ``command`` values ``cleanup``, ``syncdb``, and ``validate`` were removed. Use ``clearsessions``, ``migrate``, and ``check`` instead, respectively (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
- flowdock - this module relied on HTTPS APIs that do not exist anymore and was thus removed (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
- mh.mixins.deps module utils - the ``DependencyMixin`` has been removed. Use the ``deps`` module utils instead (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
- proxmox - the ``proxmox_default_behavior`` option has been removed (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
- rax* modules, rax module utils, rax docs fragment - the Rackspace modules relied on the deprecated package ``pyrax`` and were thus removed (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
- redhat module utils - the classes ``Rhsm``, ``RhsmPool``, and ``RhsmPools`` have been removed (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
- redhat_subscription - the alias ``autosubscribe`` of the ``auto_attach`` option was removed (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
- stackdriver - this module relied on HTTPS APIs that do not exist anymore and was thus removed (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
- webfaction_* modules - these modules relied on HTTPS APIs that do not exist anymore and were thus removed (https://github.com/ansible-collections/community.general/pull/8198).
|
||||
|
||||
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).
|
||||
- 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
|
||||
--------
|
||||
|
||||
- aix_filesystem - fix ``_validate_vg`` not passing VG name to ``lsvg_cmd`` (https://github.com/ansible-collections/community.general/issues/8151).
|
||||
- aix_filesystem - fix issue with empty list items in crfs logic and option order (https://github.com/ansible-collections/community.general/pull/8052).
|
||||
- apt-rpm - the module did not upgrade packages if a newer version exists. Now the package will be reinstalled if the candidate is newer than the installed version (https://github.com/ansible-collections/community.general/issues/7414).
|
||||
- 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).
|
||||
- cargo - fix idempotency issues when using a custom installation path for packages (using the ``--path`` parameter). The initial installation runs fine, but subsequent runs use the ``get_installed()`` function which did not check the given installation location, before running ``cargo install``. This resulted in a false ``changed`` state. Also the removal of packeges using ``state: absent`` failed, as the installation check did not use the given parameter (https://github.com/ansible-collections/community.general/pull/7970).
|
||||
- cloudflare_dns - fix Cloudflare lookup of SHFP records (https://github.com/ansible-collections/community.general/issues/7652).
|
||||
- consul_token - fix token creation without ``accessor_id`` (https://github.com/ansible-collections/community.general/pull/8091).
|
||||
- from_ini filter plugin - disabling interpolation of ``ConfigParser`` to allow converting values with a ``%`` sign (https://github.com/ansible-collections/community.general/issues/8183, https://github.com/ansible-collections/community.general/pull/8185).
|
||||
- gitlab_group_members - fix gitlab constants call in ``gitlab_group_members`` module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- gitlab_issue - fix behavior to search GitLab issue, using ``search`` keyword instead of ``title`` (https://github.com/ansible-collections/community.general/issues/7846).
|
||||
- gitlab_issue, gitlab_label, gitlab_milestone - avoid crash during version comparison when the python-gitlab Python module is not installed (https://github.com/ansible-collections/community.general/pull/8158).
|
||||
- gitlab_project_members - fix gitlab constants call in ``gitlab_project_members`` module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- gitlab_protected_branches - fix gitlab constants call in ``gitlab_protected_branches`` module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- gitlab_runner - fix pagination when checking for existing runners (https://github.com/ansible-collections/community.general/pull/7790).
|
||||
- gitlab_user - fix gitlab constants call in ``gitlab_user`` module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- 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).
|
||||
- homebrew - detect already installed formulae and casks using JSON output from ``brew info`` (https://github.com/ansible-collections/community.general/issues/864).
|
||||
- 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).
|
||||
- incus connection plugin - treats ``inventory_hostname`` as a variable instead of a literal in remote connections (https://github.com/ansible-collections/community.general/issues/7874).
|
||||
- interface_files - also consider ``address_family`` when changing ``option=method`` (https://github.com/ansible-collections/community.general/issues/7610, https://github.com/ansible-collections/community.general/pull/7612).
|
||||
- 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).
|
||||
- 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_otptoken - the module expect ``ipatokendisabled`` as string but the ``ipatokendisabled`` value is returned as a boolean (https://github.com/ansible-collections/community.general/pull/7795).
|
||||
- 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).
|
||||
- irc - replace ``ssl.wrap_socket`` that was removed from Python 3.12 with code for creating a proper SSL context (https://github.com/ansible-collections/community.general/pull/7542).
|
||||
- keycloak_* - fix Keycloak API client to quote ``/`` properly (https://github.com/ansible-collections/community.general/pull/7641).
|
||||
- keycloak_authz_permission - resource payload variable for scope-based permission was constructed as a string, when it needs to be a list, even for a single item (https://github.com/ansible-collections/community.general/issues/7151).
|
||||
- keycloak_client - add sorted ``defaultClientScopes`` and ``optionalClientScopes`` to normalizations (https://github.com/ansible-collections/community.general/pull/8223).
|
||||
- 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/pull/7881).
|
||||
- keycloak_identity_provider - ``mappers`` 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).
|
||||
- keycloak_identity_provider - it was not possible to reconfigure (add, remove) ``mappers`` once they were created initially. Removal was ignored, adding new ones resulted in dropping the pre-existing unmodified mappers. Fix resolves the issue by supplying correct input to the internal update call (https://github.com/ansible-collections/community.general/pull/7418).
|
||||
- keycloak_realm - add normalizations for ``enabledEventTypes`` and ``supportedLocales`` (https://github.com/ansible-collections/community.general/pull/8224).
|
||||
- keycloak_user - when ``force`` is set, but user does not exist, do not try to delete it (https://github.com/ansible-collections/community.general/pull/7696).
|
||||
- keycloak_user_federation - fix diff of empty ``krbPrincipalAttribute`` (https://github.com/ansible-collections/community.general/pull/8320).
|
||||
- ldap - previously the order number (if present) was expected to follow an equals sign in the DN. This makes it so the order number string is identified correctly anywhere within the DN (https://github.com/ansible-collections/community.general/issues/7646).
|
||||
- linode inventory plugin - add descriptive error message for linode inventory plugin (https://github.com/ansible-collections/community.general/pull/8133).
|
||||
- log_entries callback plugin - replace ``ssl.wrap_socket`` that was removed from Python 3.12 with code for creating a proper SSL context (https://github.com/ansible-collections/community.general/pull/7542).
|
||||
- lvol - test for output messages in both ``stdout`` and ``stderr`` (https://github.com/ansible-collections/community.general/pull/7601, https://github.com/ansible-collections/community.general/issues/7182).
|
||||
- merge_variables lookup plugin - fixing cross host merge: providing access to foreign hosts variables to the perspective of the host that is performing the merge (https://github.com/ansible-collections/community.general/pull/8303).
|
||||
- modprobe - listing modules files or modprobe files could trigger a FileNotFoundError if ``/etc/modprobe.d`` or ``/etc/modules-load.d`` 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).
|
||||
- mssql_script - make the module work with Python 2 (https://github.com/ansible-collections/community.general/issues/7818, https://github.com/ansible-collections/community.general/pull/7821).
|
||||
- nmcli - fix ``connection.slave-type`` wired to ``bond`` and not with parameter ``slave_type`` in case of connection type ``wifi`` (https://github.com/ansible-collections/community.general/issues/7389).
|
||||
- ocapi_utils, oci_utils, redfish_utils module utils - replace ``type()`` calls with ``isinstance()`` calls (https://github.com/ansible-collections/community.general/pull/7501).
|
||||
- onepassword lookup plugin - failed for fields that were in sections and had uppercase letters in the label/ID. Field lookups are now case insensitive in all cases (https://github.com/ansible-collections/community.general/pull/7919).
|
||||
- onepassword lookup plugin - field and section titles are now case insensitive when using op CLI version two or later. This matches the behavior of version one (https://github.com/ansible-collections/community.general/pull/7564).
|
||||
- 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).
|
||||
- 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).
|
||||
- pipx module utils - change the CLI argument formatter for the ``pip_args`` parameter (https://github.com/ansible-collections/community.general/issues/7497, https://github.com/ansible-collections/community.general/pull/7506).
|
||||
- pkgin - pkgin (pkgsrc package manager used by SmartOS) raises erratic exceptions and spurious ``changed=true`` (https://github.com/ansible-collections/community.general/pull/7971).
|
||||
- proxmox - fix updating a container config if the setting does not already exist (https://github.com/ansible-collections/community.general/pull/7872).
|
||||
- proxmox_kvm - fixed status check getting from node-specific API endpoint (https://github.com/ansible-collections/community.general/issues/7817).
|
||||
- proxmox_kvm - running ``state=template`` will first check whether VM is already a template (https://github.com/ansible-collections/community.general/pull/7792).
|
||||
- proxmox_pool_member - absent state for type VM did not delete VMs from the pools (https://github.com/ansible-collections/community.general/pull/7464).
|
||||
- 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)
|
||||
- redfish_command - fix usage of message parsing in ``SimpleUpdate`` and ``MultipartHTTPPushUpdate`` commands to treat the lack of a ``MessageId`` as no message (https://github.com/ansible-collections/community.general/issues/7465, https://github.com/ansible-collections/community.general/pull/7471).
|
||||
- redfish_info - allow for a GET operation invoked by ``GetUpdateStatus`` to allow for an empty response body for cases where a service returns 204 No Content (https://github.com/ansible-collections/community.general/issues/8003).
|
||||
- redfish_info - correct uncaught exception when attempting to retrieve ``Chassis`` information (https://github.com/ansible-collections/community.general/pull/7952).
|
||||
- redhat_subscription - use the D-Bus registration on RHEL 7 only on 7.4 and
|
||||
greater; older versions of RHEL 7 do not have it
|
||||
(https://github.com/ansible-collections/community.general/issues/7622,
|
||||
https://github.com/ansible-collections/community.general/pull/7624).
|
||||
- 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).
|
||||
- statusio_maintenance - fix error caused by incorrectly formed API data payload. Was raising "Failed to create maintenance HTTP Error 400 Bad Request" caused by bad data type for date/time and deprecated dict keys (https://github.com/ansible-collections/community.general/pull/7754).
|
||||
- terraform - fix multiline string handling in complex variables (https://github.com/ansible-collections/community.general/pull/7535).
|
||||
- to_ini filter plugin - disabling interpolation of ``ConfigParser`` to allow converting values with a ``%`` sign (https://github.com/ansible-collections/community.general/issues/8183, https://github.com/ansible-collections/community.general/pull/8185).
|
||||
- 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).
|
||||
|
||||
New Plugins
|
||||
-----------
|
||||
|
||||
Become
|
||||
~~~~~~
|
||||
|
||||
- community.general.run0 - Systemd's run0.
|
||||
|
||||
Callback
|
||||
~~~~~~~~
|
||||
|
||||
- community.general.default_without_diff - The default ansible callback without diff output.
|
||||
- community.general.timestamp - Adds simple timestamp for each header.
|
||||
|
||||
Connection
|
||||
~~~~~~~~~~
|
||||
|
||||
- community.general.incus - Run tasks in Incus instances via the Incus CLI.
|
||||
|
||||
Filter
|
||||
~~~~~~
|
||||
|
||||
- community.general.from_ini - Converts INI text input into a dictionary.
|
||||
- community.general.lists_difference - Difference of lists with a predictive order.
|
||||
- community.general.lists_intersect - Intersection of lists with a predictive order.
|
||||
- community.general.lists_symmetric_difference - Symmetric Difference of lists with a predictive order.
|
||||
- community.general.lists_union - Union of lists with a predictive order.
|
||||
- community.general.to_ini - Converts a dictionary to the INI file format.
|
||||
|
||||
Lookup
|
||||
~~~~~~
|
||||
|
||||
- community.general.github_app_access_token - Obtain short-lived Github App Access tokens.
|
||||
- community.general.onepassword_doc - Fetch documents stored in 1Password.
|
||||
- onepassword_doc - Fetch documents stored in 1Password
|
||||
|
||||
Test
|
||||
~~~~
|
||||
|
||||
- community.general.fqdn_valid - Validates fully-qualified domain names against RFC 1123.
|
||||
- fqdn_valid - Validates fully-qualified domain names against RFC 1123
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- community.general.consul_acl_bootstrap - Bootstrap ACLs in Consul.
|
||||
- community.general.consul_auth_method - Manipulate Consul auth methods.
|
||||
- community.general.consul_binding_rule - Manipulate Consul binding rules.
|
||||
- community.general.consul_token - Manipulate Consul tokens.
|
||||
- community.general.django_command - Run Django admin commands.
|
||||
- community.general.dnf_config_manager - Enable or disable dnf repositories using config-manager.
|
||||
- community.general.git_config_info - Read git configuration.
|
||||
- community.general.gitlab_group_access_token - Manages GitLab group access tokens.
|
||||
- community.general.gitlab_issue - Create, update, or delete GitLab issues.
|
||||
- community.general.gitlab_label - Creates/updates/deletes GitLab Labels belonging to project or group.
|
||||
- community.general.gitlab_milestone - Creates/updates/deletes GitLab Milestones belonging to project or group.
|
||||
- community.general.gitlab_project_access_token - Manages GitLab project access tokens.
|
||||
- community.general.keycloak_client_rolescope - Allows administration of Keycloak client roles scope to restrict the usage of certain roles to a other specific client applications.
|
||||
- community.general.keycloak_component_info - Retrive component info in Keycloak.
|
||||
- community.general.keycloak_realm_rolemapping - Allows administration of Keycloak realm role mappings into groups with the Keycloak API.
|
||||
- community.general.nomad_token - Manage Nomad ACL tokens.
|
||||
- community.general.proxmox_node_info - Retrieve information about one or more Proxmox VE nodes.
|
||||
- community.general.proxmox_storage_contents_info - List content from a Proxmox VE storage.
|
||||
- community.general.usb_facts - Allows listing information about USB devices.
|
||||
- git_config_info - Read git configuration
|
||||
- gitlab_issue - Create, update, or delete GitLab issues
|
||||
- nomad_token - Manage Nomad ACL tokens
|
||||
|
||||
v8.0.2
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Bugfix release for inclusion in Ansible 9.0.0rc1.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- ocapi_utils, oci_utils, redfish_utils module utils - replace ``type()`` calls with ``isinstance()`` calls (https://github.com/ansible-collections/community.general/pull/7501).
|
||||
- pipx module utils - change the CLI argument formatter for the ``pip_args`` parameter (https://github.com/ansible-collections/community.general/issues/7497, https://github.com/ansible-collections/community.general/pull/7506).
|
||||
|
||||
v8.0.1
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Bugfix release for inclusion in Ansible 9.0.0b1.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- gitlab_group_members - fix gitlab constants call in ``gitlab_group_members`` module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- gitlab_project_members - fix gitlab constants call in ``gitlab_project_members`` module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- gitlab_protected_branches - fix gitlab constants call in ``gitlab_protected_branches`` module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- gitlab_user - fix gitlab constants call in ``gitlab_user`` module (https://github.com/ansible-collections/community.general/issues/7467).
|
||||
- proxmox_pool_member - absent state for type VM did not delete VMs from the pools (https://github.com/ansible-collections/community.general/pull/7464).
|
||||
- redfish_command - fix usage of message parsing in ``SimpleUpdate`` and ``MultipartHTTPPushUpdate`` commands to treat the lack of a ``MessageId`` as no message (https://github.com/ansible-collections/community.general/issues/7465, https://github.com/ansible-collections/community.general/pull/7471).
|
||||
|
||||
v8.0.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This is release 8.0.0 of ``community.general``, released on 2023-11-01.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- The collection will start using semantic markup (https://github.com/ansible-collections/community.general/pull/6539).
|
||||
- VarDict module utils - add method ``VarDict.as_dict()`` to convert to a plain ``dict`` object (https://github.com/ansible-collections/community.general/pull/6602).
|
||||
- apt_rpm - extract package name from local ``.rpm`` path when verifying
|
||||
installation success. Allows installing packages from local ``.rpm`` files
|
||||
(https://github.com/ansible-collections/community.general/pull/7396).
|
||||
- cargo - add option ``executable``, which allows user to specify path to the cargo binary (https://github.com/ansible-collections/community.general/pull/7352).
|
||||
- cargo - add option ``locked`` which allows user to specify install the locked version of dependency instead of latest compatible version (https://github.com/ansible-collections/community.general/pull/6134).
|
||||
- chroot connection plugin - add ``disable_root_check`` option (https://github.com/ansible-collections/community.general/pull/7099).
|
||||
- cloudflare_dns - add CAA record support (https://github.com/ansible-collections/community.general/pull/7399).
|
||||
- cobbler inventory plugin - add ``exclude_mgmt_classes`` and ``include_mgmt_classes`` options to exclude or include hosts based on management classes (https://github.com/ansible-collections/community.general/pull/7184).
|
||||
- cobbler inventory plugin - add ``inventory_hostname`` option to allow using the system name for the inventory hostname (https://github.com/ansible-collections/community.general/pull/6502).
|
||||
- cobbler inventory plugin - add ``want_ip_addresses`` option to collect all interface DNS name to IP address mapping (https://github.com/ansible-collections/community.general/pull/6711).
|
||||
- cobbler inventory plugin - add primary IP addess to ``cobbler_ipv4_address`` and IPv6 address to ``cobbler_ipv6_address`` host variable (https://github.com/ansible-collections/community.general/pull/6711).
|
||||
- cobbler inventory plugin - add warning for systems with empty profiles (https://github.com/ansible-collections/community.general/pull/6502).
|
||||
- cobbler inventory plugin - convert Ansible unicode strings to native Python unicode strings before passing user/password to XMLRPC client (https://github.com/ansible-collections/community.general/pull/6923).
|
||||
- consul_session - drops requirement for the ``python-consul`` library to communicate with the Consul API, instead relying on the existing ``requests`` library requirement (https://github.com/ansible-collections/community.general/pull/6755).
|
||||
- copr - respawn module to use the system python interpreter when the ``dnf`` python module is not available in ``ansible_python_interpreter`` (https://github.com/ansible-collections/community.general/pull/6522).
|
||||
- cpanm - minor refactor when creating the ``CmdRunner`` object (https://github.com/ansible-collections/community.general/pull/7231).
|
||||
- datadog_monitor - adds ``notification_preset_name``, ``renotify_occurrences`` and ``renotify_statuses`` parameters (https://github.com/ansible-collections/community.general/issues/6521,https://github.com/ansible-collections/community.general/issues/5823).
|
||||
- dig lookup plugin - add TCP option to enable the use of TCP connection during DNS lookup (https://github.com/ansible-collections/community.general/pull/7343).
|
||||
- ejabberd_user - module now using ``CmdRunner`` to execute external command (https://github.com/ansible-collections/community.general/pull/7075).
|
||||
- filesystem - add ``uuid`` parameter for UUID change feature (https://github.com/ansible-collections/community.general/pull/6680).
|
||||
- gitlab_group - add option ``force_delete`` (default: false) which allows delete group even if projects exists in it (https://github.com/ansible-collections/community.general/pull/7364).
|
||||
- gitlab_group_variable - add support for ``raw`` variables suboption (https://github.com/ansible-collections/community.general/pull/7132).
|
||||
- gitlab_project_variable - add support for ``raw`` variables suboption (https://github.com/ansible-collections/community.general/pull/7132).
|
||||
- gitlab_project_variable - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- gitlab_runner - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6927).
|
||||
- htpasswd - minor code improvements in the module (https://github.com/ansible-collections/community.general/pull/6901).
|
||||
- htpasswd - the parameter ``crypt_scheme`` is being renamed as ``hash_scheme`` and added as an alias to it (https://github.com/ansible-collections/community.general/pull/6841).
|
||||
- icinga2_host - the ``ip`` option is no longer required, since Icinga 2 allows for an empty address attribute (https://github.com/ansible-collections/community.general/pull/7452).
|
||||
- ini_file - add ``ignore_spaces`` option (https://github.com/ansible-collections/community.general/pull/7273).
|
||||
- ini_file - add ``modify_inactive_option`` option (https://github.com/ansible-collections/community.general/pull/7401).
|
||||
- ipa_config - add module parameters to manage FreeIPA user and group objectclasses (https://github.com/ansible-collections/community.general/pull/7019).
|
||||
- ipa_config - adds ``idp`` choice to ``ipauserauthtype`` parameter's choices (https://github.com/ansible-collections/community.general/pull/7051).
|
||||
- jenkins_build - add new ``detach`` option, which allows the module to exit successfully as long as the build is created (default functionality is still waiting for the build to end before exiting) (https://github.com/ansible-collections/community.general/pull/7204).
|
||||
- jenkins_build - add new ``time_between_checks`` option, which allows to configure the wait time between requests to the Jenkins server (https://github.com/ansible-collections/community.general/pull/7204).
|
||||
- keycloak_authentication - added provider ID choices, since Keycloak supports only those two specific ones (https://github.com/ansible-collections/community.general/pull/6763).
|
||||
- keycloak_client_rolemapping - adds support for subgroups with additional parameter ``parents`` (https://github.com/ansible-collections/community.general/pull/6687).
|
||||
- keycloak_role - add composite roles support for realm and client roles (https://github.com/ansible-collections/community.general/pull/6469).
|
||||
- keyring - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6927).
|
||||
- ldap_* - add new arguments ``client_cert`` and ``client_key`` to the LDAP modules in order to allow certificate authentication (https://github.com/ansible-collections/community.general/pull/6668).
|
||||
- ldap_search - add a new ``page_size`` option to enable paged searches (https://github.com/ansible-collections/community.general/pull/6648).
|
||||
- locale_gen - module has been refactored to use ``ModuleHelper`` and ``CmdRunner`` (https://github.com/ansible-collections/community.general/pull/6903).
|
||||
- locale_gen - module now using ``CmdRunner`` to execute external commands (https://github.com/ansible-collections/community.general/pull/6820).
|
||||
- lvg - add ``active`` and ``inactive`` values to the ``state`` option for active state management feature (https://github.com/ansible-collections/community.general/pull/6682).
|
||||
- lvg - add ``reset_vg_uuid``, ``reset_pv_uuid`` options for UUID reset feature (https://github.com/ansible-collections/community.general/pull/6682).
|
||||
- lxc connection plugin - properly handle a change of the ``remote_addr`` option (https://github.com/ansible-collections/community.general/pull/7373).
|
||||
- lxd connection plugin - automatically translate ``remote_addr`` from FQDN to (short) hostname (https://github.com/ansible-collections/community.general/pull/7360).
|
||||
- lxd connection plugin - update error parsing to work with newer messages mentioning instances (https://github.com/ansible-collections/community.general/pull/7360).
|
||||
- lxd inventory plugin - add ``server_cert`` option for trust anchor to use for TLS verification of server certificates (https://github.com/ansible-collections/community.general/pull/7392).
|
||||
- lxd inventory plugin - add ``server_check_hostname`` option to disable hostname verification of server certificates (https://github.com/ansible-collections/community.general/pull/7392).
|
||||
- make - add new ``targets`` parameter allowing multiple targets to be used with ``make`` (https://github.com/ansible-collections/community.general/pull/6882, https://github.com/ansible-collections/community.general/issues/4919).
|
||||
- make - allows ``params`` to be used without value (https://github.com/ansible-collections/community.general/pull/7180).
|
||||
- mas - disable sign-in check for macOS 12+ as ``mas account`` is non-functional (https://github.com/ansible-collections/community.general/pull/6520).
|
||||
- newrelic_deployment - add option ``app_name_exact_match``, which filters results for the exact app_name provided (https://github.com/ansible-collections/community.general/pull/7355).
|
||||
- nmap inventory plugin - now has a ``use_arp_ping`` option to allow the user to disable the default ARP ping query for a more reliable form (https://github.com/ansible-collections/community.general/pull/7119).
|
||||
- nmcli - add support for ``ipv4.dns-options`` and ``ipv6.dns-options`` (https://github.com/ansible-collections/community.general/pull/6902).
|
||||
- nomad_job, nomad_job_info - add ``port`` parameter (https://github.com/ansible-collections/community.general/pull/7412).
|
||||
- npm - minor improvement on parameter validation (https://github.com/ansible-collections/community.general/pull/6848).
|
||||
- npm - module now using ``CmdRunner`` to execute external commands (https://github.com/ansible-collections/community.general/pull/6989).
|
||||
- onepassword lookup plugin - add service account support (https://github.com/ansible-collections/community.general/issues/6635, https://github.com/ansible-collections/community.general/pull/6660).
|
||||
- onepassword lookup plugin - introduce ``account_id`` option which allows specifying which account to use (https://github.com/ansible-collections/community.general/pull/7308).
|
||||
- onepassword_raw lookup plugin - add service account support (https://github.com/ansible-collections/community.general/issues/6635, https://github.com/ansible-collections/community.general/pull/6660).
|
||||
- onepassword_raw lookup plugin - introduce ``account_id`` option which allows specifying which account to use (https://github.com/ansible-collections/community.general/pull/7308).
|
||||
- opentelemetry callback plugin - add span attributes in the span event (https://github.com/ansible-collections/community.general/pull/6531).
|
||||
- opkg - add ``executable`` parameter allowing to specify the path of the ``opkg`` command (https://github.com/ansible-collections/community.general/pull/6862).
|
||||
- opkg - remove default value ``""`` for parameter ``force`` as it causes the same behaviour of not having that parameter (https://github.com/ansible-collections/community.general/pull/6513).
|
||||
- pagerduty - adds in option to use v2 API for creating pagerduty incidents (https://github.com/ansible-collections/community.general/issues/6151)
|
||||
- parted - on resize, use ``--fix`` option if available (https://github.com/ansible-collections/community.general/pull/7304).
|
||||
- pnpm - set correct version when state is latest or version is not mentioned. Resolves previous idempotency problem (https://github.com/ansible-collections/community.general/pull/7339).
|
||||
- pritunl module utils - ensure ``validate_certs`` parameter is honoured in all methods (https://github.com/ansible-collections/community.general/pull/7156).
|
||||
- proxmox - add ``vmid`` (and ``taskid`` when possible) to return values (https://github.com/ansible-collections/community.general/pull/7263).
|
||||
- proxmox - support ``timezone`` parameter at container creation (https://github.com/ansible-collections/community.general/pull/6510).
|
||||
- proxmox inventory plugin - add composite variables support for Proxmox nodes (https://github.com/ansible-collections/community.general/issues/6640).
|
||||
- proxmox_kvm - added support for ``tpmstate0`` parameter to configure TPM (Trusted Platform Module) disk. TPM is required for Windows 11 installations (https://github.com/ansible-collections/community.general/pull/6533).
|
||||
- proxmox_kvm - enabled force restart of VM, bringing the ``force`` parameter functionality in line with what is described in the docs (https://github.com/ansible-collections/community.general/pull/6914).
|
||||
- proxmox_kvm - re-use ``timeout`` module param to forcefully shutdown a virtual machine when ``state`` is ``stopped`` (https://github.com/ansible-collections/community.general/issues/6257).
|
||||
- proxmox_snap - add ``retention`` parameter to delete old snapshots (https://github.com/ansible-collections/community.general/pull/6576).
|
||||
- proxmox_vm_info - ``node`` parameter is no longer required. Information can be obtained for the whole cluster (https://github.com/ansible-collections/community.general/pull/6976).
|
||||
- proxmox_vm_info - non-existing provided by name/vmid VM would return empty results instead of failing (https://github.com/ansible-collections/community.general/pull/7049).
|
||||
- pubnub_blocks - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- random_string - added new ``ignore_similar_chars`` and ``similar_chars`` option to ignore certain chars (https://github.com/ansible-collections/community.general/pull/7242).
|
||||
- redfish_command - add ``MultipartHTTPPushUpdate`` command (https://github.com/ansible-collections/community.general/issues/6471, https://github.com/ansible-collections/community.general/pull/6612).
|
||||
- redfish_command - add ``account_types`` and ``oem_account_types`` as optional inputs to ``AddUser`` (https://github.com/ansible-collections/community.general/issues/6823, https://github.com/ansible-collections/community.general/pull/6871).
|
||||
- redfish_command - add new option ``update_oem_params`` for the ``MultipartHTTPPushUpdate`` command (https://github.com/ansible-collections/community.general/issues/7331).
|
||||
- redfish_config - add ``CreateVolume`` command to allow creation of volumes on servers (https://github.com/ansible-collections/community.general/pull/6813).
|
||||
- redfish_config - add ``DeleteAllVolumes`` command to allow deletion of all volumes on servers (https://github.com/ansible-collections/community.general/pull/6814).
|
||||
- redfish_config - adding ``SetSecureBoot`` command (https://github.com/ansible-collections/community.general/pull/7129).
|
||||
- redfish_info - add ``AccountTypes`` and ``OEMAccountTypes`` to the output of ``ListUsers`` (https://github.com/ansible-collections/community.general/issues/6823, https://github.com/ansible-collections/community.general/pull/6871).
|
||||
- redfish_info - add support for ``GetBiosRegistries`` command (https://github.com/ansible-collections/community.general/pull/7144).
|
||||
- redfish_info - adds ``LinkStatus`` to NIC inventory (https://github.com/ansible-collections/community.general/pull/7318).
|
||||
- redfish_info - adds ``ProcessorArchitecture`` to CPU inventory (https://github.com/ansible-collections/community.general/pull/6864).
|
||||
- redfish_info - fix for ``GetVolumeInventory``, Controller name was getting populated incorrectly and duplicates were seen in the volumes retrieved (https://github.com/ansible-collections/community.general/pull/6719).
|
||||
- redfish_info - report ``Id`` in the output of ``GetManagerInventory`` (https://github.com/ansible-collections/community.general/pull/7140).
|
||||
- redfish_utils - use ``Controllers`` key in redfish data to obtain Storage controllers properties (https://github.com/ansible-collections/community.general/pull/7081).
|
||||
- redfish_utils module utils - add support for ``PowerCycle`` reset type for ``redfish_command`` responses feature (https://github.com/ansible-collections/community.general/issues/7083).
|
||||
- redfish_utils module utils - add support for following ``@odata.nextLink`` pagination in ``software_inventory`` responses feature (https://github.com/ansible-collections/community.general/pull/7020).
|
||||
- redfish_utils module utils - support ``Volumes`` in response for ``GetDiskInventory`` (https://github.com/ansible-collections/community.general/pull/6819).
|
||||
- redhat_subscription - the internal ``RegistrationBase`` class was folded
|
||||
into the other internal ``Rhsm`` class, as the separation had no purpose
|
||||
anymore
|
||||
(https://github.com/ansible-collections/community.general/pull/6658).
|
||||
- redis_info - refactor the redis_info module to use the redis module_utils enabling to pass TLS parameters to the Redis client (https://github.com/ansible-collections/community.general/pull/7267).
|
||||
- rhsm_release - improve/harden the way ``subscription-manager`` is run;
|
||||
no behaviour change is expected
|
||||
(https://github.com/ansible-collections/community.general/pull/6669).
|
||||
- rhsm_repository - the interaction with ``subscription-manager`` was
|
||||
refactored by grouping things together, removing unused bits, and hardening
|
||||
the way it is run; also, the parsing of ``subscription-manager repos --list``
|
||||
was improved and made slightly faster; no behaviour change is expected
|
||||
(https://github.com/ansible-collections/community.general/pull/6783,
|
||||
https://github.com/ansible-collections/community.general/pull/6837).
|
||||
- scaleway_security_group_rule - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- shutdown - use ``shutdown -p ...`` with FreeBSD to halt and power off machine (https://github.com/ansible-collections/community.general/pull/7102).
|
||||
- snap - add option ``dangerous`` to the module, that will map into the command line argument ``--dangerous``, allowing unsigned snap files to be installed (https://github.com/ansible-collections/community.general/pull/6908, https://github.com/ansible-collections/community.general/issues/5715).
|
||||
- snap - module is now aware of channel when deciding whether to install or refresh the snap (https://github.com/ansible-collections/community.general/pull/6435, https://github.com/ansible-collections/community.general/issues/1606).
|
||||
- sorcery - add grimoire (repository) management support (https://github.com/ansible-collections/community.general/pull/7012).
|
||||
- sorcery - minor refactor (https://github.com/ansible-collections/community.general/pull/6525).
|
||||
- supervisorctl - allow to stop matching running processes before removing them with ``stop_before_removing=true`` (https://github.com/ansible-collections/community.general/pull/7284).
|
||||
- tss lookup plugin - allow to fetch secret IDs which are in a folder based on folder ID. Previously, we could not fetch secrets based on folder ID but now use ``fetch_secret_ids_from_folder`` option to indicate to fetch secret IDs based on folder ID (https://github.com/ansible-collections/community.general/issues/6223).
|
||||
- tss lookup plugin - allow to fetch secret by path. Previously, we could not fetch secret by path but now use ``secret_path`` option to indicate to fetch secret by secret path (https://github.com/ansible-collections/community.general/pull/6881).
|
||||
- unixy callback plugin - add support for ``check_mode_markers`` option (https://github.com/ansible-collections/community.general/pull/7179).
|
||||
- vardict module utils - added convenience methods to ``VarDict`` (https://github.com/ansible-collections/community.general/pull/6647).
|
||||
- xenserver_guest_info - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- xenserver_guest_powerstate - minor refactor removing unnecessary code statements (https://github.com/ansible-collections/community.general/pull/6928).
|
||||
- yum_versionlock - add support to pin specific package versions instead of only the package itself (https://github.com/ansible-collections/community.general/pull/6861, https://github.com/ansible-collections/community.general/issues/4470).
|
||||
|
||||
Breaking Changes / Porting Guide
|
||||
--------------------------------
|
||||
|
||||
- collection_version lookup plugin - remove compatibility code for ansible-base 2.10 and ansible-core 2.11 (https://github.com/ansible-collections/community.general/pull/7269).
|
||||
- gitlab_project - add ``default_branch`` support for project update. If you used the module so far with ``default_branch`` to update a project, the value of ``default_branch`` was ignored. Make sure that you either do not pass a value if you are not sure whether it is the one you want to have to avoid unexpected breaking changes (https://github.com/ansible-collections/community.general/pull/7158).
|
||||
- selective callback plugin - remove compatibility code for Ansible 2.9 and ansible-core 2.10 (https://github.com/ansible-collections/community.general/pull/7269).
|
||||
- vardict module utils - ``VarDict`` will no longer accept variables named ``_var``, ``get_meta``, and ``as_dict`` (https://github.com/ansible-collections/community.general/pull/6647).
|
||||
- version module util - remove fallback for ansible-core 2.11. All modules and plugins that do version collections no longer work with ansible-core 2.11 (https://github.com/ansible-collections/community.general/pull/7269).
|
||||
|
||||
Deprecated Features
|
||||
-------------------
|
||||
|
||||
- CmdRunner module utils - deprecate ``cmd_runner_fmt.as_default_type()`` formatter (https://github.com/ansible-collections/community.general/pull/6601).
|
||||
- MH VarsMixin module utils - deprecates ``VarsMixin`` and supporting classes in favor of plain ``vardict`` module util (https://github.com/ansible-collections/community.general/pull/6649).
|
||||
- ansible_galaxy_install - the ``ack_ansible29`` and ``ack_min_ansiblecore211`` options have been deprecated and will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/7358).
|
||||
- consul - the ``ack_params_state_absent`` option has been deprecated and will be removed in community.general 10.0.0 (https://github.com/ansible-collections/community.general/pull/7358).
|
||||
- cpanm - value ``compatibility`` is deprecated as default for parameter ``mode`` (https://github.com/ansible-collections/community.general/pull/6512).
|
||||
- ejabberd_user - deprecate the parameter ``logging`` in favour of producing more detailed information in the module output (https://github.com/ansible-collections/community.general/pull/7043).
|
||||
- flowdock - module relies entirely on no longer responsive API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6930).
|
||||
- proxmox - old feature flag ``proxmox_default_behavior`` will be removed in community.general 10.0.0 (https://github.com/ansible-collections/community.general/pull/6836).
|
||||
- proxmox_kvm - deprecate the option ``proxmox_default_behavior`` (https://github.com/ansible-collections/community.general/pull/7377).
|
||||
- redfish_info, redfish_config, redfish_command - the default value ``10`` for the ``timeout`` option is deprecated and will change to ``60`` in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/7295).
|
||||
- redhat module utils - the ``module_utils.redhat`` module is deprecated, as
|
||||
effectively unused: the ``Rhsm``, ``RhsmPool``, and ``RhsmPools`` classes
|
||||
will be removed in community.general 9.0.0; the ``RegistrationBase`` class
|
||||
will be removed in community.general 10.0.0 together with the
|
||||
``rhn_register`` module, as it is the only user of this class; this means
|
||||
that the whole ``module_utils.redhat`` module will be dropped in
|
||||
community.general 10.0.0, so importing it without even using anything of it
|
||||
will fail
|
||||
(https://github.com/ansible-collections/community.general/pull/6663).
|
||||
- redhat_subscription - the ``autosubscribe`` alias for the ``auto_attach`` option has been
|
||||
deprecated for many years, although only in the documentation. Officially mark this alias
|
||||
as deprecated, and it will be removed in community.general 9.0.0
|
||||
(https://github.com/ansible-collections/community.general/pull/6646).
|
||||
- redhat_subscription - the ``pool`` option is deprecated in favour of the
|
||||
more precise and flexible ``pool_ids`` option
|
||||
(https://github.com/ansible-collections/community.general/pull/6650).
|
||||
- rhsm_repository - ``state=present`` has not been working as expected for many years,
|
||||
and it seems it was not noticed so far; also, "presence" is not really a valid concept
|
||||
for subscription repositories, which can only be enabled or disabled. Hence, mark the
|
||||
``present`` and ``absent`` values of the ``state`` option as deprecated, slating them
|
||||
for removal in community.general 10.0.0
|
||||
(https://github.com/ansible-collections/community.general/pull/6673).
|
||||
- stackdriver - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6887).
|
||||
- webfaction_app - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
- webfaction_db - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
- webfaction_domain - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
- webfaction_mailbox - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
- webfaction_site - module relies entirely on no longer existent API endpoints, and it will be removed in community.general 9.0.0 (https://github.com/ansible-collections/community.general/pull/6909).
|
||||
|
||||
Removed Features (previously deprecated)
|
||||
----------------------------------------
|
||||
|
||||
- The collection no longer supports ansible-core 2.11 and ansible-core 2.12. Parts of the collection might still work on these ansible-core versions, but others might not (https://github.com/ansible-collections/community.general/pull/7269).
|
||||
- ansible_galaxy_install - support for Ansible 2.9 and ansible-base 2.10 has been removed (https://github.com/ansible-collections/community.general/pull/7358).
|
||||
- consul - when ``state=absent``, the options ``script``, ``ttl``, ``tcp``, ``http``, and ``interval`` can no longer be specified (https://github.com/ansible-collections/community.general/pull/7358).
|
||||
- gconftool2 - ``state=get`` has been removed. Use the module ``community.general.gconftool2_info`` instead (https://github.com/ansible-collections/community.general/pull/7358).
|
||||
- gitlab_runner - remove the default value for the ``access_level`` option. To restore the previous behavior, explicitly set it to ``ref_protected`` (https://github.com/ansible-collections/community.general/pull/7358).
|
||||
- htpasswd - removed code for passlib <1.6 (https://github.com/ansible-collections/community.general/pull/6901).
|
||||
- manageiq_polices - ``state=list`` has been removed. Use the module ``community.general.manageiq_policies_info`` instead (https://github.com/ansible-collections/community.general/pull/7358).
|
||||
- manageiq_tags - ``state=list`` has been removed. Use the module ``community.general.manageiq_tags_info`` instead (https://github.com/ansible-collections/community.general/pull/7358).
|
||||
- mh.mixins.cmd module utils - the ``ArgFormat`` class has been removed (https://github.com/ansible-collections/community.general/pull/7358).
|
||||
- mh.mixins.cmd module utils - the ``CmdMixin`` mixin has been removed. Use ``community.general.plugins.module_utils.cmd_runner.CmdRunner`` instead (https://github.com/ansible-collections/community.general/pull/7358).
|
||||
- mh.mixins.cmd module utils - the mh.mixins.cmd module utils has been removed after all its contents were removed (https://github.com/ansible-collections/community.general/pull/7358).
|
||||
- mh.module_helper module utils - the ``CmdModuleHelper`` and ``CmdStateModuleHelper`` classes have been removed. Use ``community.general.plugins.module_utils.cmd_runner.CmdRunner`` instead (https://github.com/ansible-collections/community.general/pull/7358).
|
||||
- proxmox module utils - removed unused imports (https://github.com/ansible-collections/community.general/pull/6873).
|
||||
- xfconf - the deprecated ``disable_facts`` option was removed (https://github.com/ansible-collections/community.general/pull/7358).
|
||||
|
||||
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).
|
||||
- MH DependencyMixin module utils - deprecation notice was popping up for modules not using dependencies (https://github.com/ansible-collections/community.general/pull/6644, https://github.com/ansible-collections/community.general/issues/6639).
|
||||
- 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 ``notes`` (https://github.com/ansible-collections/community.general/pull/7061).
|
||||
- cmd_runner module utils - when a parameter in ``argument_spec`` has no type, meaning it is implicitly a ``str``, ``CmdRunner`` would fail trying to find the ``type`` key in that dictionary (https://github.com/ansible-collections/community.general/pull/6968).
|
||||
- cobbler inventory plugin - fix calculation of cobbler_ipv4/6_address (https://github.com/ansible-collections/community.general/pull/6925).
|
||||
- composer - fix impossible to run ``working_dir`` dependent commands. The module was throwing an error when trying to run a ``working_dir`` dependent command, because it tried to get the command help without passing the ``working_dir`` (https://github.com/ansible-collections/community.general/issues/3787).
|
||||
- csv module utils - detects and remove unicode BOM markers from incoming CSV content (https://github.com/ansible-collections/community.general/pull/6662).
|
||||
- datadog_downtime - presence of ``rrule`` param lead to the Datadog API returning Bad Request due to a missing recurrence type (https://github.com/ansible-collections/community.general/pull/6811).
|
||||
- ejabberd_user - module was failing to detect whether user was already created and/or password was changed (https://github.com/ansible-collections/community.general/pull/7033).
|
||||
- ejabberd_user - provide meaningful error message when the ``ejabberdctl`` command is not found (https://github.com/ansible-collections/community.general/pull/7028, https://github.com/ansible-collections/community.general/issues/6949).
|
||||
- github_deploy_key - fix pagination behaviour causing a crash when only a single page of deploy keys exist (https://github.com/ansible-collections/community.general/pull/7375).
|
||||
- gitlab_group - the module passed parameters to the API call even when not set. The module is now filtering out ``None`` values to remediate this (https://github.com/ansible-collections/community.general/pull/6712).
|
||||
- gitlab_group_variable - deleted all variables when used with ``purge=true`` due to missing ``raw`` property in KNOWN attributes (https://github.com/ansible-collections/community.general/issues/7250).
|
||||
- gitlab_project_variable - deleted all variables when used with ``purge=true`` due to missing ``raw`` property in KNOWN attributes (https://github.com/ansible-collections/community.general/issues/7250).
|
||||
- icinga2_host - fix a key error when updating an existing host (https://github.com/ansible-collections/community.general/pull/6748).
|
||||
- ini_file - add the ``follow`` paramter to follow the symlinks instead of replacing them (https://github.com/ansible-collections/community.general/pull/6546).
|
||||
- ini_file - fix a bug where the inactive options were not used when possible (https://github.com/ansible-collections/community.general/pull/6575).
|
||||
- ipa_dnszone - fix 'idnsallowsyncptr' key error for reverse zone (https://github.com/ansible-collections/community.general/pull/6906, https://github.com/ansible-collections/community.general/issues/6905).
|
||||
- kernel_blacklist - simplified the mechanism to update the file, fixing the error (https://github.com/ansible-collections/community.general/pull/7382, https://github.com/ansible-collections/community.general/issues/7362).
|
||||
- keycloak module util - fix missing ``http_agent``, ``timeout``, and ``validate_certs`` ``open_url()`` parameters (https://github.com/ansible-collections/community.general/pull/7067).
|
||||
- keycloak module utils - fix ``is_struct_included`` handling of lists of lists/dictionaries (https://github.com/ansible-collections/community.general/pull/6688).
|
||||
- keycloak module utils - the function ``get_user_by_username`` now return the user representation or ``None`` as stated in the documentation (https://github.com/ansible-collections/community.general/pull/6758).
|
||||
- keycloak_authentication - fix Keycloak authentication flow (step or sub-flow) indexing during update, if not specified by the user (https://github.com/ansible-collections/community.general/pull/6734).
|
||||
- keycloak_client inventory plugin - fix missing client secret (https://github.com/ansible-collections/community.general/pull/6931).
|
||||
- ldap_search - fix string normalization and the ``base64_attributes`` option on Python 3 (https://github.com/ansible-collections/community.general/issues/5704, https://github.com/ansible-collections/community.general/pull/7264).
|
||||
- locale_gen - now works for locales without the underscore character such as ``C.UTF-8`` (https://github.com/ansible-collections/community.general/pull/6774, https://github.com/ansible-collections/community.general/issues/5142, https://github.com/ansible-collections/community.general/issues/4305).
|
||||
- lvol - add support for percentage of origin size specification when creating snapshot volumes (https://github.com/ansible-collections/community.general/issues/1630, https://github.com/ansible-collections/community.general/pull/7053).
|
||||
- lxc connection plugin - now handles ``remote_addr`` defaulting to ``inventory_hostname`` correctly (https://github.com/ansible-collections/community.general/pull/7104).
|
||||
- lxc connection plugin - properly evaluate options (https://github.com/ansible-collections/community.general/pull/7369).
|
||||
- machinectl become plugin - mark plugin as ``require_tty`` to automatically disable pipelining, with which this plugin is not compatible (https://github.com/ansible-collections/community.general/issues/6932, https://github.com/ansible-collections/community.general/pull/6935).
|
||||
- mail - skip headers containing equals characters due to missing ``maxsplit`` on header key/value parsing (https://github.com/ansible-collections/community.general/pull/7303).
|
||||
- memset module utils - make compatible with ansible-core 2.17 (https://github.com/ansible-collections/community.general/pull/7379).
|
||||
- nmap inventory plugin - fix ``get_option`` calls (https://github.com/ansible-collections/community.general/pull/7323).
|
||||
- nmap inventory plugin - now uses ``get_option`` in all cases to get its configuration information (https://github.com/ansible-collections/community.general/pull/7119).
|
||||
- nmcli - fix bond option ``xmit_hash_policy`` (https://github.com/ansible-collections/community.general/pull/6527).
|
||||
- nmcli - fix support for empty list (in compare and scrape) (https://github.com/ansible-collections/community.general/pull/6769).
|
||||
- nsupdate - fix a possible ``list index out of range`` exception (https://github.com/ansible-collections/community.general/issues/836).
|
||||
- oci_utils module util - fix inappropriate logical comparison expressions and makes them simpler. The previous checks had logical short circuits (https://github.com/ansible-collections/community.general/pull/7125).
|
||||
- oci_utils module utils - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
|
||||
- onepassword - fix KeyError exception when trying to access value of a field that is not filled out in OnePassword item (https://github.com/ansible-collections/community.general/pull/7241).
|
||||
- openbsd_pkg - the pkg_info(1) behavior has changed in OpenBSD >7.3. The error message ``Can't find`` should not lead to an error case (https://github.com/ansible-collections/community.general/pull/6785).
|
||||
- pacman - module recognizes the output of ``yay`` running as ``root`` (https://github.com/ansible-collections/community.general/pull/6713).
|
||||
- portage - fix ``changed_use`` and ``newuse`` not triggering rebuilds (https://github.com/ansible-collections/community.general/issues/6008, https://github.com/ansible-collections/community.general/pull/6548).
|
||||
- pritunl module utils - fix incorrect URL parameter for orgnization add method (https://github.com/ansible-collections/community.general/pull/7161).
|
||||
- proxmox - fix error when a configuration had no ``template`` field (https://github.com/ansible-collections/community.general/pull/6838, https://github.com/ansible-collections/community.general/issues/5372).
|
||||
- proxmox module utils - add logic to detect whether an old Promoxer complains about the ``token_name`` and ``token_value`` parameters and provide a better error message when that happens (https://github.com/ansible-collections/community.general/pull/6839, https://github.com/ansible-collections/community.general/issues/5371).
|
||||
- proxmox module utils - fix proxmoxer library version check (https://github.com/ansible-collections/community.general/issues/6974, https://github.com/ansible-collections/community.general/issues/6975, https://github.com/ansible-collections/community.general/pull/6980).
|
||||
- proxmox_disk - fix unable to create ``cdrom`` media due to ``size`` always being appended (https://github.com/ansible-collections/community.general/pull/6770).
|
||||
- proxmox_kvm - ``absent`` state with ``force`` specified failed to stop the VM due to the ``timeout`` value not being passed to ``stop_vm`` (https://github.com/ansible-collections/community.general/pull/6827).
|
||||
- proxmox_kvm - ``restarted`` state did not actually restart a VM in some VM configurations. The state now uses the Proxmox reboot endpoint instead of calling the ``stop_vm`` and ``start_vm`` functions (https://github.com/ansible-collections/community.general/pull/6773).
|
||||
- proxmox_kvm - allow creation of VM with existing name but new vmid (https://github.com/ansible-collections/community.general/issues/6155, https://github.com/ansible-collections/community.general/pull/6709).
|
||||
- proxmox_kvm - when ``name`` option is provided without ``vmid`` and VM with that name already exists then no new VM will be created (https://github.com/ansible-collections/community.general/issues/6911, https://github.com/ansible-collections/community.general/pull/6981).
|
||||
- proxmox_tasks_info - remove ``api_user`` + ``api_password`` constraint from ``required_together`` as it causes to require ``api_password`` even when API token param is used (https://github.com/ansible-collections/community.general/issues/6201).
|
||||
- proxmox_template - require ``requests_toolbelt`` module to fix issue with uploading large templates (https://github.com/ansible-collections/community.general/issues/5579, https://github.com/ansible-collections/community.general/pull/6757).
|
||||
- proxmox_user_info - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
|
||||
- redfish_info - fix ``ListUsers`` to not show empty account slots (https://github.com/ansible-collections/community.general/issues/6771, https://github.com/ansible-collections/community.general/pull/6772).
|
||||
- redhat_subscription - use the right D-Bus options for the consumer type when
|
||||
registering a RHEL system older than 9 or a RHEL 9 system older than 9.2
|
||||
and using ``consumer_type``
|
||||
(https://github.com/ansible-collections/community.general/pull/7378).
|
||||
- refish_utils module utils - changing variable names to avoid issues occuring when fetching Volumes data (https://github.com/ansible-collections/community.general/pull/6883).
|
||||
- rhsm_repository - when using the ``purge`` option, the ``repositories``
|
||||
dictionary element in the returned JSON is now properly updated according
|
||||
to the pruning operation
|
||||
(https://github.com/ansible-collections/community.general/pull/6676).
|
||||
- rundeck - fix ``TypeError`` on 404 API response (https://github.com/ansible-collections/community.general/pull/6983).
|
||||
- selective callback plugin - fix length of task name lines in output always being 3 characters longer than desired (https://github.com/ansible-collections/community.general/pull/7374).
|
||||
- snap - an exception was being raised when snap list was empty (https://github.com/ansible-collections/community.general/pull/7124, https://github.com/ansible-collections/community.general/issues/7120).
|
||||
- snap - assume default track ``latest`` in parameter ``channel`` when not specified (https://github.com/ansible-collections/community.general/pull/6835, https://github.com/ansible-collections/community.general/issues/6821).
|
||||
- snap - change the change detection mechanism from "parsing installation" to "comparing end state with initial state" (https://github.com/ansible-collections/community.general/pull/7340, https://github.com/ansible-collections/community.general/issues/7265).
|
||||
- snap - fix crash when multiple snaps are specified and one has ``---`` in its description (https://github.com/ansible-collections/community.general/pull/7046).
|
||||
- snap - fix the processing of the commands' output, stripping spaces and newlines from it (https://github.com/ansible-collections/community.general/pull/6826, https://github.com/ansible-collections/community.general/issues/6803).
|
||||
- sorcery - fix interruption of the multi-stage process (https://github.com/ansible-collections/community.general/pull/7012).
|
||||
- sorcery - fix queue generation before the whole system rebuild (https://github.com/ansible-collections/community.general/pull/7012).
|
||||
- sorcery - latest state no longer triggers update_cache (https://github.com/ansible-collections/community.general/pull/7012).
|
||||
- terraform - prevents ``-backend-config`` option double encapsulating with ``shlex_quote`` function. (https://github.com/ansible-collections/community.general/pull/7301).
|
||||
- tss lookup plugin - fix multiple issues when using ``fetch_attachments=true`` (https://github.com/ansible-collections/community.general/pull/6720).
|
||||
- zypper - added handling of zypper exitcode 102. Changed state is set correctly now and rc 102 is still preserved to be evaluated by the playbook (https://github.com/ansible-collections/community.general/pull/6534).
|
||||
|
||||
Known Issues
|
||||
------------
|
||||
|
||||
- Ansible markup will show up in raw form on ansible-doc text output for ansible-core before 2.15. If you have trouble deciphering the documentation markup, please upgrade to ansible-core 2.15 (or newer), or read the HTML documentation on https://docs.ansible.com/ansible/devel/collections/community/general/ (https://github.com/ansible-collections/community.general/pull/6539).
|
||||
|
||||
New Plugins
|
||||
-----------
|
||||
|
||||
Lookup
|
||||
~~~~~~
|
||||
|
||||
- bitwarden_secrets_manager - Retrieve secrets from Bitwarden Secrets Manager
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- consul_policy - Manipulate Consul policies
|
||||
- consul_role - Manipulate Consul roles
|
||||
- facter_facts - Runs the discovery program C(facter) on the remote system and return Ansible facts
|
||||
- gio_mime - Set default handler for MIME type, for applications using Gnome GIO
|
||||
- gitlab_instance_variable - Creates, updates, or deletes GitLab instance variables
|
||||
- gitlab_merge_request - Create, update, or delete GitLab merge requests
|
||||
- jenkins_build_info - Get information about Jenkins builds
|
||||
- keycloak_authentication_required_actions - Allows administration of Keycloak authentication required actions
|
||||
- keycloak_authz_custom_policy - Allows administration of Keycloak client custom Javascript policies via Keycloak API
|
||||
- keycloak_authz_permission - Allows administration of Keycloak client authorization permissions via Keycloak API
|
||||
- keycloak_authz_permission_info - Query Keycloak client authorization permissions information
|
||||
- keycloak_realm_key - Allows administration of Keycloak realm keys via Keycloak API
|
||||
- keycloak_user - Create and configure a user in Keycloak
|
||||
- lvg_rename - Renames LVM volume groups
|
||||
- pnpm - Manage node.js packages with pnpm
|
||||
- proxmox_pool - Pool management for Proxmox VE cluster
|
||||
- proxmox_pool_member - Add or delete members from Proxmox VE cluster pools
|
||||
- proxmox_vm_info - Retrieve information about one or more Proxmox VE virtual machines
|
||||
- simpleinit_msb - Manage services on Source Mage GNU/Linux
|
||||
|
||||
@@ -31,9 +31,7 @@ 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/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 :) )
|
||||
* 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 :) )
|
||||
* 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).
|
||||
|
||||
11
README.md
11
README.md
@@ -6,10 +6,9 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# Community General Collection
|
||||
|
||||
[](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
|
||||
[](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.
|
||||
|
||||
@@ -25,7 +24,7 @@ If you encounter abusive behavior violating the [Ansible Code of Conduct](https:
|
||||
|
||||
## Tested with Ansible
|
||||
|
||||
Tested with the current ansible-core 2.13, ansible-core 2.14, ansible-core 2.15, ansible-core 2.16, ansible-core 2.17 releases and the current development version of ansible-core. Ansible-core versions before 2.13.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases.
|
||||
Tested with the current 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.13.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases.
|
||||
|
||||
## External requirements
|
||||
|
||||
@@ -116,7 +115,7 @@ See the [Releasing guidelines](https://github.com/ansible/community-docs/blob/ma
|
||||
|
||||
## Release notes
|
||||
|
||||
See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-9/CHANGELOG.md).
|
||||
See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-8/CHANGELOG.rst).
|
||||
|
||||
## Roadmap
|
||||
|
||||
@@ -135,8 +134,8 @@ See [this issue](https://github.com/ansible-collections/community.general/issues
|
||||
|
||||
This collection is primarily licensed and distributed as a whole under the GNU General Public License v3.0 or later.
|
||||
|
||||
See [LICENSES/GPL-3.0-or-later.txt](https://github.com/ansible-collections/community.general/blob/stable-9/COPYING) for the full text.
|
||||
See [LICENSES/GPL-3.0-or-later.txt](https://github.com/ansible-collections/community.general/blob/main/COPYING) for the full text.
|
||||
|
||||
Parts of the collection are licensed under the [BSD 2-Clause license](https://github.com/ansible-collections/community.general/blob/stable-9/LICENSES/BSD-2-Clause.txt), the [MIT license](https://github.com/ansible-collections/community.general/blob/stable-9/LICENSES/MIT.txt), and the [PSF 2.0 license](https://github.com/ansible-collections/community.general/blob/stable-9/LICENSES/PSF-2.0.txt).
|
||||
Parts of the collection are licensed under the [BSD 2-Clause license](https://github.com/ansible-collections/community.general/blob/main/LICENSES/BSD-2-Clause.txt), the [MIT license](https://github.com/ansible-collections/community.general/blob/main/LICENSES/MIT.txt), and the [PSF 2.0 license](https://github.com/ansible-collections/community.general/blob/main/LICENSES/PSF-2.0.txt).
|
||||
|
||||
All files have a machine readable `SDPX-License-Identifier:` comment denoting its respective license(s) or an equivalent entry in an accompanying `.license` file. Only changelog fragments (which will not be part of a release) are covered by a blanket statement in `.reuse/dep5`. This conforms to the [REUSE specification](https://reuse.software/spec/).
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,9 +12,6 @@ mention_ancestor: true
|
||||
flatmap: true
|
||||
new_plugins_after_name: removed_features
|
||||
notesdir: fragments
|
||||
output_formats:
|
||||
- md
|
||||
- rst
|
||||
prelude_section_name: release_summary
|
||||
prelude_section_title: Release Summary
|
||||
sections:
|
||||
@@ -35,6 +32,3 @@ sections:
|
||||
- - known_issues
|
||||
- Known Issues
|
||||
title: Community General
|
||||
trivial_section_name: trivial
|
||||
use_fqcn: true
|
||||
add_plugin_period: true
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
changelog:
|
||||
write_changelog: true
|
||||
@@ -12,5 +12,4 @@ Abstract transformations
|
||||
filter_guide_abstract_informations_dictionaries
|
||||
filter_guide_abstract_informations_grouping
|
||||
filter_guide_abstract_informations_merging_lists_of_dictionaries
|
||||
filter_guide_abstract_informations_lists_helper
|
||||
filter_guide_abstract_informations_counting_elements_in_sequence
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
..
|
||||
Copyright (c) Ansible Project
|
||||
GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
Union, intersection and difference of lists
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Starting with Ansible Core 2.16, the builtin filters :ansplugin:`ansible.builtin.union#filter`, :ansplugin:`ansible.builtin.intersect#filter`, :ansplugin:`ansible.builtin.difference#filter` and :ansplugin:`ansible.builtin.symmetric_difference#filter` began to behave differently and do no longer preserve the item order. Items in the resulting lists are returned in arbitrary order and the order can vary between subsequent runs.
|
||||
|
||||
The Ansible community.general collection provides the following additional list filters:
|
||||
|
||||
- :ansplugin:`community.general.lists_union#filter`
|
||||
- :ansplugin:`community.general.lists_intersect#filter`
|
||||
- :ansplugin:`community.general.lists_difference#filter`
|
||||
- :ansplugin:`community.general.lists_symmetric_difference#filter`
|
||||
|
||||
These filters preserve the item order, eliminate duplicates and are an extended version of the builtin ones, because they can operate on more than two lists.
|
||||
|
||||
.. note:: Stick to the builtin filters, when item order is not important or when you do not need the n-ary operating mode. The builtin filters are faster, because they rely mostly on sets as their underlying datastructure.
|
||||
|
||||
Let us use the lists below in the following examples:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
A: [9, 5, 7, 1, 9, 4, 10, 5, 9, 7]
|
||||
B: [4, 1, 2, 8, 3, 1, 7]
|
||||
C: [10, 2, 1, 9, 1]
|
||||
|
||||
The union of ``A`` and ``B`` can be written as:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
result: "{{ A | community.general.lists_union(B) }}"
|
||||
|
||||
This statement produces:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
result: [9, 5, 7, 1, 4, 10, 2, 8, 3]
|
||||
|
||||
If you want to calculate the intersection of ``A``, ``B`` and ``C``, you can use the following statement:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
result: "{{ A | community.general.lists_intersect(B, C) }}"
|
||||
|
||||
Alternatively, you can use a list of lists as an input of the filter
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
result: "{{ [A, B] | community.general.lists_intersect(C) }}"
|
||||
|
||||
or
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
result: "{{ [A, B, C] | community.general.lists_intersect(flatten=true) }}"
|
||||
|
||||
All three statements are equivalent and give:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
result: [1]
|
||||
|
||||
.. note:: Be aware that in most cases, filter calls without any argument require ``flatten=true``, otherwise the input is returned as result. The reason for this is, that the input is considered as a variable argument and is wrapped by an additional outer list. ``flatten=true`` ensures that this list is removed before the input is processed by the filter logic.
|
||||
|
||||
The filters ansplugin:`community.general.lists_difference#filter` or :ansplugin:`community.general.lists_symmetric_difference#filter` can be used in the same way as the filters in the examples above. They calculate the difference or the symmetric difference between two or more lists and preserve the item order.
|
||||
|
||||
For example, the symmetric difference of ``A``, ``B`` and ``C`` may be written as:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
result: "{{ A | community.general.lists_symmetric_difference(B, C) }}"
|
||||
|
||||
This gives:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
result: [5, 8, 3, 1]
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace: community
|
||||
name: general
|
||||
version: 9.0.0
|
||||
version: 8.3.0
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (https://github.com/ansible)
|
||||
|
||||
4143
meta/runtime.yml
4143
meta/runtime.yml
File diff suppressed because it is too large
Load Diff
@@ -78,13 +78,12 @@ DOCUMENTATION = '''
|
||||
EXAMPLES = r'''
|
||||
# A polkit rule needed to use the module with a non-root user.
|
||||
# See the Notes section for details.
|
||||
/etc/polkit-1/rules.d/60-machinectl-fast-user-auth.rules: |
|
||||
polkit.addRule(function(action, subject) {
|
||||
if(action.id == "org.freedesktop.machine1.host-shell" &&
|
||||
subject.isInGroup("wheel")) {
|
||||
return polkit.Result.AUTH_SELF_KEEP;
|
||||
}
|
||||
});
|
||||
60-machinectl-fast-user-auth.rules: |
|
||||
polkit.addRule(function(action, subject) {
|
||||
if(action.id == "org.freedesktop.machine1.host-shell" && subject.isInGroup("wheel")) {
|
||||
return polkit.Result.AUTH_SELF_KEEP;
|
||||
}
|
||||
});
|
||||
'''
|
||||
|
||||
from re import compile as re_compile
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2024, 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
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
name: run0
|
||||
short_description: Systemd's run0
|
||||
description:
|
||||
- This become plugins allows your remote/login user to execute commands as another user via the C(run0) utility.
|
||||
author:
|
||||
- Thomas Sjögren (@konstruktoid)
|
||||
version_added: '9.0.0'
|
||||
options:
|
||||
become_user:
|
||||
description: User you 'become' to execute the task.
|
||||
default: root
|
||||
ini:
|
||||
- section: privilege_escalation
|
||||
key: become_user
|
||||
- section: run0_become_plugin
|
||||
key: user
|
||||
vars:
|
||||
- name: ansible_become_user
|
||||
- name: ansible_run0_user
|
||||
env:
|
||||
- name: ANSIBLE_BECOME_USER
|
||||
- name: ANSIBLE_RUN0_USER
|
||||
type: string
|
||||
become_exe:
|
||||
description: The C(run0) executable.
|
||||
default: run0
|
||||
ini:
|
||||
- section: privilege_escalation
|
||||
key: become_exe
|
||||
- section: run0_become_plugin
|
||||
key: executable
|
||||
vars:
|
||||
- name: ansible_become_exe
|
||||
- name: ansible_run0_exe
|
||||
env:
|
||||
- name: ANSIBLE_BECOME_EXE
|
||||
- name: ANSIBLE_RUN0_EXE
|
||||
type: string
|
||||
become_flags:
|
||||
description: Options to pass to run0.
|
||||
default: ''
|
||||
ini:
|
||||
- section: privilege_escalation
|
||||
key: become_flags
|
||||
- section: run0_become_plugin
|
||||
key: flags
|
||||
vars:
|
||||
- name: ansible_become_flags
|
||||
- name: ansible_run0_flags
|
||||
env:
|
||||
- name: ANSIBLE_BECOME_FLAGS
|
||||
- name: ANSIBLE_RUN0_FLAGS
|
||||
type: string
|
||||
notes:
|
||||
- This plugin will only work when a polkit rule is in place.
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
# An example polkit rule that allows the user 'ansible' in the 'wheel' group
|
||||
# to execute commands using run0 without authentication.
|
||||
/etc/polkit-1/rules.d/60-run0-fast-user-auth.rules: |
|
||||
polkit.addRule(function(action, subject) {
|
||||
if(action.id == "org.freedesktop.systemd1.manage-units" &&
|
||||
subject.isInGroup("wheel") &&
|
||||
subject.user == "ansible") {
|
||||
return polkit.Result.YES;
|
||||
}
|
||||
});
|
||||
"""
|
||||
|
||||
from re import compile as re_compile
|
||||
|
||||
from ansible.plugins.become import BecomeBase
|
||||
from ansible.module_utils._text import to_bytes
|
||||
|
||||
ansi_color_codes = re_compile(to_bytes(r"\x1B\[[0-9;]+m"))
|
||||
|
||||
|
||||
class BecomeModule(BecomeBase):
|
||||
|
||||
name = "community.general.run0"
|
||||
|
||||
prompt = "Password: "
|
||||
fail = ("==== AUTHENTICATION FAILED ====",)
|
||||
success = ("==== AUTHENTICATION COMPLETE ====",)
|
||||
require_tty = (
|
||||
True # see https://github.com/ansible-collections/community.general/issues/6932
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def remove_ansi_codes(line):
|
||||
return ansi_color_codes.sub(b"", line)
|
||||
|
||||
def build_become_command(self, cmd, shell):
|
||||
super().build_become_command(cmd, shell)
|
||||
|
||||
if not cmd:
|
||||
return cmd
|
||||
|
||||
become = self.get_option("become_exe")
|
||||
flags = self.get_option("become_flags")
|
||||
user = self.get_option("become_user")
|
||||
|
||||
return (
|
||||
f"{become} --user={user} {flags} {self._build_success_command(cmd, shell)}"
|
||||
)
|
||||
|
||||
def check_success(self, b_output):
|
||||
b_output = self.remove_ansi_codes(b_output)
|
||||
return super().check_success(b_output)
|
||||
|
||||
def check_incorrect_password(self, b_output):
|
||||
b_output = self.remove_ansi_codes(b_output)
|
||||
return super().check_incorrect_password(b_output)
|
||||
|
||||
def check_missing_password(self, b_output):
|
||||
b_output = self.remove_ansi_codes(b_output)
|
||||
return super().check_missing_password(b_output)
|
||||
@@ -1,46 +0,0 @@
|
||||
# -*- 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
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
name: default_without_diff
|
||||
type: stdout
|
||||
short_description: The default ansible callback without diff output
|
||||
version_added: 8.4.0
|
||||
description:
|
||||
- This is basically the default ansible callback plugin (P(ansible.builtin.default#callback)) without
|
||||
showing diff output. This can be useful when using another callback which sends more detailed information
|
||||
to another service, like the L(ARA, https://ara.recordsansible.org/) callback, and you want diff output
|
||||
sent to that plugin but not shown on the console output.
|
||||
author: Felix Fontein (@felixfontein)
|
||||
extends_documentation_fragment:
|
||||
- ansible.builtin.default_callback
|
||||
- ansible.builtin.result_format_callback
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
# Enable callback in ansible.cfg:
|
||||
ansible_config: |
|
||||
[defaults]
|
||||
stdout_callback = community.general.default_without_diff
|
||||
|
||||
# Enable callback with environment variables:
|
||||
environment_variable: |
|
||||
ANSIBLE_STDOUT_CALLBACK=community.general.default_without_diff
|
||||
'''
|
||||
|
||||
from ansible.plugins.callback.default import CallbackModule as Default
|
||||
|
||||
|
||||
class CallbackModule(Default):
|
||||
CALLBACK_VERSION = 2.0
|
||||
CALLBACK_TYPE = 'stdout'
|
||||
CALLBACK_NAME = 'community.general.default_without_diff'
|
||||
|
||||
def v2_on_file_diff(self, result):
|
||||
pass
|
||||
@@ -18,10 +18,6 @@ DOCUMENTATION = '''
|
||||
description:
|
||||
- This callback plugin sends status updates to a HipChat channel during playbook execution.
|
||||
- Before 2.4 only environment variables were available for configuring this plugin.
|
||||
deprecated:
|
||||
removed_in: 10.0.0
|
||||
why: The hipchat service has been discontinued and the self-hosted variant has been End of Life since 2020.
|
||||
alternative: There is none.
|
||||
options:
|
||||
token:
|
||||
description: HipChat API token for v1 or v2 API.
|
||||
|
||||
@@ -59,16 +59,13 @@ import uuid
|
||||
import socket
|
||||
import getpass
|
||||
|
||||
from datetime import datetime
|
||||
from os.path import basename
|
||||
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.datetime import (
|
||||
now,
|
||||
)
|
||||
|
||||
|
||||
class AzureLogAnalyticsSource(object):
|
||||
def __init__(self):
|
||||
@@ -96,7 +93,7 @@ class AzureLogAnalyticsSource(object):
|
||||
return "https://{0}.ods.opinsights.azure.com/api/logs?api-version=2016-04-01".format(workspace_id)
|
||||
|
||||
def __rfc1123date(self):
|
||||
return now().strftime('%a, %d %b %Y %H:%M:%S GMT')
|
||||
return datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
|
||||
|
||||
def send_event(self, workspace_id, shared_key, state, result, runtime):
|
||||
if result._task_fields['args'].get('_ansible_check_mode') is True:
|
||||
@@ -170,7 +167,7 @@ class CallbackModule(CallbackBase):
|
||||
|
||||
def _seconds_since_start(self, result):
|
||||
return (
|
||||
now() -
|
||||
datetime.utcnow() -
|
||||
self.start_datetimes[result._task._uuid]
|
||||
).total_seconds()
|
||||
|
||||
@@ -188,10 +185,10 @@ class CallbackModule(CallbackBase):
|
||||
self.loganalytics.ansible_playbook = basename(playbook._file_name)
|
||||
|
||||
def v2_playbook_on_task_start(self, task, is_conditional):
|
||||
self.start_datetimes[task._uuid] = now()
|
||||
self.start_datetimes[task._uuid] = datetime.utcnow()
|
||||
|
||||
def v2_playbook_on_handler_task_start(self, task):
|
||||
self.start_datetimes[task._uuid] = now()
|
||||
self.start_datetimes[task._uuid] = datetime.utcnow()
|
||||
|
||||
def v2_runner_on_ok(self, result, **kwargs):
|
||||
self.loganalytics.send_event(
|
||||
|
||||
@@ -99,6 +99,7 @@ from ansible import context
|
||||
import socket
|
||||
import uuid
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
try:
|
||||
import logstash
|
||||
@@ -108,10 +109,6 @@ except ImportError:
|
||||
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.datetime import (
|
||||
now,
|
||||
)
|
||||
|
||||
|
||||
class CallbackModule(CallbackBase):
|
||||
|
||||
@@ -129,7 +126,7 @@ class CallbackModule(CallbackBase):
|
||||
"pip install python-logstash for Python 2"
|
||||
"pip install python3-logstash for Python 3")
|
||||
|
||||
self.start_time = now()
|
||||
self.start_time = datetime.utcnow()
|
||||
|
||||
def _init_plugin(self):
|
||||
if not self.disabled:
|
||||
@@ -188,7 +185,7 @@ class CallbackModule(CallbackBase):
|
||||
self.logger.info("ansible start", extra=data)
|
||||
|
||||
def v2_playbook_on_stats(self, stats):
|
||||
end_time = now()
|
||||
end_time = datetime.utcnow()
|
||||
runtime = end_time - self.start_time
|
||||
summarize_stat = {}
|
||||
for host in stats.processed.keys():
|
||||
|
||||
@@ -84,33 +84,6 @@ DOCUMENTATION = '''
|
||||
- section: callback_opentelemetry
|
||||
key: disable_attributes_in_logs
|
||||
version_added: 7.1.0
|
||||
store_spans_in_file:
|
||||
default: None
|
||||
type: str
|
||||
description:
|
||||
- It stores the exported spans in the given file
|
||||
env:
|
||||
- name: ANSIBLE_OPENTELEMETRY_STORE_SPANS_IN_FILE
|
||||
ini:
|
||||
- section: callback_opentelemetry
|
||||
key: store_spans_in_file
|
||||
version_added: 9.0.0
|
||||
otel_exporter_otlp_traces_protocol:
|
||||
type: str
|
||||
description:
|
||||
- E(OTEL_EXPORTER_OTLP_TRACES_PROTOCOL) represents the the transport protocol for spans.
|
||||
- See
|
||||
U(https://opentelemetry-python.readthedocs.io/en/latest/sdk/environment_variables.html#envvar-OTEL_EXPORTER_OTLP_TRACES_PROTOCOL).
|
||||
default: grpc
|
||||
choices:
|
||||
- grpc
|
||||
- http/protobuf
|
||||
env:
|
||||
- name: OTEL_EXPORTER_OTLP_TRACES_PROTOCOL
|
||||
ini:
|
||||
- section: callback_opentelemetry
|
||||
key: otel_exporter_otlp_traces_protocol
|
||||
version_added: 9.0.0
|
||||
requirements:
|
||||
- opentelemetry-api (Python library)
|
||||
- opentelemetry-exporter-otlp (Python library)
|
||||
@@ -134,7 +107,6 @@ examples: |
|
||||
'''
|
||||
|
||||
import getpass
|
||||
import json
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
@@ -152,19 +124,15 @@ from ansible.plugins.callback import CallbackBase
|
||||
try:
|
||||
from opentelemetry import trace
|
||||
from opentelemetry.trace import SpanKind
|
||||
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter as GRPCOTLPSpanExporter
|
||||
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter as HTTPOTLPSpanExporter
|
||||
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
|
||||
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
|
||||
from opentelemetry.trace.status import Status, StatusCode
|
||||
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
|
||||
from opentelemetry.sdk.trace import TracerProvider
|
||||
from opentelemetry.sdk.trace.export import (
|
||||
BatchSpanProcessor,
|
||||
SimpleSpanProcessor
|
||||
)
|
||||
from opentelemetry.sdk.trace.export.in_memory_span_exporter import (
|
||||
InMemorySpanExporter
|
||||
BatchSpanProcessor
|
||||
)
|
||||
|
||||
# Support for opentelemetry-api <= 1.12
|
||||
try:
|
||||
from opentelemetry.util._time import _time_ns
|
||||
@@ -287,16 +255,7 @@ class OpenTelemetrySource(object):
|
||||
task.dump = dump
|
||||
task.add_host(HostData(host_uuid, host_name, status, result))
|
||||
|
||||
def generate_distributed_traces(self,
|
||||
otel_service_name,
|
||||
ansible_playbook,
|
||||
tasks_data,
|
||||
status,
|
||||
traceparent,
|
||||
disable_logs,
|
||||
disable_attributes_in_logs,
|
||||
otel_exporter_otlp_traces_protocol,
|
||||
store_spans_in_file):
|
||||
def generate_distributed_traces(self, otel_service_name, ansible_playbook, tasks_data, status, traceparent, disable_logs, disable_attributes_in_logs):
|
||||
""" generate distributed traces from the collected TaskData and HostData """
|
||||
|
||||
tasks = []
|
||||
@@ -312,16 +271,7 @@ class OpenTelemetrySource(object):
|
||||
)
|
||||
)
|
||||
|
||||
otel_exporter = None
|
||||
if store_spans_in_file:
|
||||
otel_exporter = InMemorySpanExporter()
|
||||
processor = SimpleSpanProcessor(otel_exporter)
|
||||
else:
|
||||
if otel_exporter_otlp_traces_protocol == 'grpc':
|
||||
otel_exporter = GRPCOTLPSpanExporter()
|
||||
else:
|
||||
otel_exporter = HTTPOTLPSpanExporter()
|
||||
processor = BatchSpanProcessor(otel_exporter)
|
||||
processor = BatchSpanProcessor(OTLPSpanExporter())
|
||||
|
||||
trace.get_tracer_provider().add_span_processor(processor)
|
||||
|
||||
@@ -343,8 +293,6 @@ class OpenTelemetrySource(object):
|
||||
with tracer.start_as_current_span(task.name, start_time=task.start, end_on_exit=False) as span:
|
||||
self.update_span_data(task, host_data, span, disable_logs, disable_attributes_in_logs)
|
||||
|
||||
return otel_exporter
|
||||
|
||||
def update_span_data(self, task_data, host_data, span, disable_logs, disable_attributes_in_logs):
|
||||
""" update the span with the given TaskData and HostData """
|
||||
|
||||
@@ -402,8 +350,7 @@ 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)
|
||||
# Close span always
|
||||
span.end(end_time=host_data.finish)
|
||||
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 """
|
||||
@@ -515,8 +462,6 @@ class CallbackModule(CallbackBase):
|
||||
self.errors = 0
|
||||
self.disabled = False
|
||||
self.traceparent = False
|
||||
self.store_spans_in_file = False
|
||||
self.otel_exporter_otlp_traces_protocol = None
|
||||
|
||||
if OTEL_LIBRARY_IMPORT_ERROR:
|
||||
raise_from(
|
||||
@@ -544,8 +489,6 @@ class CallbackModule(CallbackBase):
|
||||
|
||||
self.disable_logs = self.get_option('disable_logs')
|
||||
|
||||
self.store_spans_in_file = self.get_option('store_spans_in_file')
|
||||
|
||||
self.otel_service_name = self.get_option('otel_service_name')
|
||||
|
||||
if not self.otel_service_name:
|
||||
@@ -554,14 +497,6 @@ class CallbackModule(CallbackBase):
|
||||
# See https://github.com/open-telemetry/opentelemetry-specification/issues/740
|
||||
self.traceparent = self.get_option('traceparent')
|
||||
|
||||
self.otel_exporter_otlp_traces_protocol = self.get_option('otel_exporter_otlp_traces_protocol')
|
||||
|
||||
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)
|
||||
|
||||
@@ -611,7 +546,7 @@ class CallbackModule(CallbackBase):
|
||||
self.tasks_data,
|
||||
status,
|
||||
result,
|
||||
self.dump_results(result)
|
||||
self._dump_results(result._result)
|
||||
)
|
||||
|
||||
def v2_runner_on_ok(self, result):
|
||||
@@ -619,7 +554,7 @@ class CallbackModule(CallbackBase):
|
||||
self.tasks_data,
|
||||
'ok',
|
||||
result,
|
||||
self.dump_results(result)
|
||||
self._dump_results(result._result)
|
||||
)
|
||||
|
||||
def v2_runner_on_skipped(self, result):
|
||||
@@ -627,7 +562,7 @@ class CallbackModule(CallbackBase):
|
||||
self.tasks_data,
|
||||
'skipped',
|
||||
result,
|
||||
self.dump_results(result)
|
||||
self._dump_results(result._result)
|
||||
)
|
||||
|
||||
def v2_playbook_on_include(self, included_file):
|
||||
@@ -643,22 +578,15 @@ class CallbackModule(CallbackBase):
|
||||
status = Status(status_code=StatusCode.OK)
|
||||
else:
|
||||
status = Status(status_code=StatusCode.ERROR)
|
||||
otel_exporter = self.opentelemetry.generate_distributed_traces(
|
||||
self.opentelemetry.generate_distributed_traces(
|
||||
self.otel_service_name,
|
||||
self.ansible_playbook,
|
||||
self.tasks_data,
|
||||
status,
|
||||
self.traceparent,
|
||||
self.disable_logs,
|
||||
self.disable_attributes_in_logs,
|
||||
self.otel_exporter_otlp_traces_protocol,
|
||||
self.store_spans_in_file
|
||||
self.disable_attributes_in_logs
|
||||
)
|
||||
|
||||
if self.store_spans_in_file:
|
||||
spans = [json.loads(span.to_json()) for span in otel_exporter.get_finished_spans()]
|
||||
with open(self.store_spans_in_file, "w", encoding="utf-8") as output:
|
||||
json.dump({"spans": spans}, output, indent=4)
|
||||
|
||||
def v2_runner_on_async_failed(self, result, **kwargs):
|
||||
self.errors += 1
|
||||
|
||||
@@ -88,16 +88,13 @@ import uuid
|
||||
import socket
|
||||
import getpass
|
||||
|
||||
from datetime import datetime
|
||||
from os.path import basename
|
||||
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.datetime import (
|
||||
now,
|
||||
)
|
||||
|
||||
|
||||
class SplunkHTTPCollectorSource(object):
|
||||
def __init__(self):
|
||||
@@ -137,7 +134,7 @@ class SplunkHTTPCollectorSource(object):
|
||||
else:
|
||||
time_format = '%Y-%m-%d %H:%M:%S +0000'
|
||||
|
||||
data['timestamp'] = now().strftime(time_format)
|
||||
data['timestamp'] = datetime.utcnow().strftime(time_format)
|
||||
data['host'] = self.host
|
||||
data['ip_address'] = self.ip_address
|
||||
data['user'] = self.user
|
||||
@@ -184,7 +181,7 @@ class CallbackModule(CallbackBase):
|
||||
|
||||
def _runtime(self, result):
|
||||
return (
|
||||
now() -
|
||||
datetime.utcnow() -
|
||||
self.start_datetimes[result._task._uuid]
|
||||
).total_seconds()
|
||||
|
||||
@@ -223,10 +220,10 @@ class CallbackModule(CallbackBase):
|
||||
self.splunk.ansible_playbook = basename(playbook._file_name)
|
||||
|
||||
def v2_playbook_on_task_start(self, task, is_conditional):
|
||||
self.start_datetimes[task._uuid] = now()
|
||||
self.start_datetimes[task._uuid] = datetime.utcnow()
|
||||
|
||||
def v2_playbook_on_handler_task_start(self, task):
|
||||
self.start_datetimes[task._uuid] = now()
|
||||
self.start_datetimes[task._uuid] = datetime.utcnow()
|
||||
|
||||
def v2_runner_on_ok(self, result, **kwargs):
|
||||
self.splunk.send_event(
|
||||
|
||||
@@ -46,16 +46,13 @@ import uuid
|
||||
import socket
|
||||
import getpass
|
||||
|
||||
from datetime import datetime
|
||||
from os.path import basename
|
||||
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.datetime import (
|
||||
now,
|
||||
)
|
||||
|
||||
|
||||
class SumologicHTTPCollectorSource(object):
|
||||
def __init__(self):
|
||||
@@ -87,7 +84,8 @@ class SumologicHTTPCollectorSource(object):
|
||||
data['uuid'] = result._task._uuid
|
||||
data['session'] = self.session
|
||||
data['status'] = state
|
||||
data['timestamp'] = now().strftime('%Y-%m-%d %H:%M:%S +0000')
|
||||
data['timestamp'] = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S '
|
||||
'+0000')
|
||||
data['host'] = self.host
|
||||
data['ip_address'] = self.ip_address
|
||||
data['user'] = self.user
|
||||
@@ -125,7 +123,7 @@ class CallbackModule(CallbackBase):
|
||||
|
||||
def _runtime(self, result):
|
||||
return (
|
||||
now() -
|
||||
datetime.utcnow() -
|
||||
self.start_datetimes[result._task._uuid]
|
||||
).total_seconds()
|
||||
|
||||
@@ -146,10 +144,10 @@ class CallbackModule(CallbackBase):
|
||||
self.sumologic.ansible_playbook = basename(playbook._file_name)
|
||||
|
||||
def v2_playbook_on_task_start(self, task, is_conditional):
|
||||
self.start_datetimes[task._uuid] = now()
|
||||
self.start_datetimes[task._uuid] = datetime.utcnow()
|
||||
|
||||
def v2_playbook_on_handler_task_start(self, task):
|
||||
self.start_datetimes[task._uuid] = now()
|
||||
self.start_datetimes[task._uuid] = datetime.utcnow()
|
||||
|
||||
def v2_runner_on_ok(self, result, **kwargs):
|
||||
self.sumologic.send_event(
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2024, kurokobo <kurokobo@protonmail.com>
|
||||
# Copyright (c) 2014, Michael DeHaan <michael.dehaan@gmail.com>
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
name: timestamp
|
||||
type: stdout
|
||||
short_description: Adds simple timestamp for each header
|
||||
version_added: 9.0.0
|
||||
description:
|
||||
- This callback adds simple timestamp for each header.
|
||||
author: kurokobo (@kurokobo)
|
||||
options:
|
||||
timezone:
|
||||
description:
|
||||
- Timezone to use for the timestamp in IANA time zone format.
|
||||
- For example C(America/New_York), C(Asia/Tokyo)). Ignored on Python < 3.9.
|
||||
ini:
|
||||
- section: callback_timestamp
|
||||
key: timezone
|
||||
env:
|
||||
- name: ANSIBLE_CALLBACK_TIMESTAMP_TIMEZONE
|
||||
type: string
|
||||
format_string:
|
||||
description:
|
||||
- Format of the timestamp shown to user in 1989 C standard format.
|
||||
- >
|
||||
Refer to L(the Python documentation,https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes)
|
||||
for the available format codes.
|
||||
ini:
|
||||
- section: callback_timestamp
|
||||
key: format_string
|
||||
env:
|
||||
- name: ANSIBLE_CALLBACK_TIMESTAMP_FORMAT_STRING
|
||||
default: "%H:%M:%S"
|
||||
type: string
|
||||
seealso:
|
||||
- plugin: ansible.posix.profile_tasks
|
||||
plugin_type: callback
|
||||
description: >
|
||||
You can use P(ansible.posix.profile_tasks#callback) callback plugin to time individual tasks and overall execution time
|
||||
with detailed timestamps.
|
||||
extends_documentation_fragment:
|
||||
- ansible.builtin.default_callback
|
||||
- ansible.builtin.result_format_callback
|
||||
"""
|
||||
|
||||
|
||||
from ansible.plugins.callback.default import CallbackModule as Default
|
||||
from ansible.utils.display import get_text_width
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from datetime import datetime
|
||||
import types
|
||||
import sys
|
||||
|
||||
# Store whether the zoneinfo module is available
|
||||
_ZONEINFO_AVAILABLE = sys.version_info >= (3, 9)
|
||||
|
||||
|
||||
def get_datetime_now(tz):
|
||||
"""
|
||||
Returns the current timestamp with the specified timezone
|
||||
"""
|
||||
return datetime.now(tz=tz)
|
||||
|
||||
|
||||
def banner(self, msg, color=None, cows=True):
|
||||
"""
|
||||
Prints a header-looking line with cowsay or stars with length depending on terminal width (3 minimum) with trailing timestamp
|
||||
|
||||
Based on the banner method of Display class from ansible.utils.display
|
||||
|
||||
https://github.com/ansible/ansible/blob/4403519afe89138042108e237aef317fd5f09c33/lib/ansible/utils/display.py#L511
|
||||
"""
|
||||
timestamp = get_datetime_now(self.timestamp_tzinfo).strftime(self.timestamp_format_string)
|
||||
timestamp_len = get_text_width(timestamp) + 1 # +1 for leading space
|
||||
|
||||
msg = to_text(msg)
|
||||
if self.b_cowsay and cows:
|
||||
try:
|
||||
self.banner_cowsay("%s @ %s" % (msg, timestamp))
|
||||
return
|
||||
except OSError:
|
||||
self.warning("somebody cleverly deleted cowsay or something during the PB run. heh.")
|
||||
|
||||
msg = msg.strip()
|
||||
try:
|
||||
star_len = self.columns - get_text_width(msg) - timestamp_len
|
||||
except EnvironmentError:
|
||||
star_len = self.columns - len(msg) - timestamp_len
|
||||
if star_len <= 3:
|
||||
star_len = 3
|
||||
stars = "*" * star_len
|
||||
self.display("\n%s %s %s" % (msg, stars, timestamp), color=color)
|
||||
|
||||
|
||||
class CallbackModule(Default):
|
||||
CALLBACK_VERSION = 2.0
|
||||
CALLBACK_TYPE = "stdout"
|
||||
CALLBACK_NAME = "community.general.timestamp"
|
||||
|
||||
def __init__(self):
|
||||
super(CallbackModule, self).__init__()
|
||||
|
||||
# Replace the banner method of the display object with the custom one
|
||||
self._display.banner = types.MethodType(banner, self._display)
|
||||
|
||||
def set_options(self, task_keys=None, var_options=None, direct=None):
|
||||
super(CallbackModule, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct)
|
||||
|
||||
# Store zoneinfo for specified timezone if available
|
||||
tzinfo = None
|
||||
if _ZONEINFO_AVAILABLE and self.get_option("timezone"):
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
tzinfo = ZoneInfo(self.get_option("timezone"))
|
||||
|
||||
# Inject options into the display object
|
||||
setattr(self._display, "timestamp_tzinfo", tzinfo)
|
||||
setattr(self._display, "timestamp_format_string", self.get_option("format_string"))
|
||||
@@ -56,4 +56,5 @@ attributes:
|
||||
support: full
|
||||
membership:
|
||||
- community.general.consul
|
||||
version_added: 8.3.0
|
||||
"""
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2024, Alexei Znamensky <russoz@gmail.com>
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
class ModuleDocFragment(object):
|
||||
DOCUMENTATION = r'''
|
||||
options:
|
||||
venv:
|
||||
description:
|
||||
- Use the the Python interpreter from this virtual environment.
|
||||
- Pass the path to the root of the virtualenv, not the C(bin/) directory nor the C(python) executable.
|
||||
type: path
|
||||
settings:
|
||||
description:
|
||||
- Specifies the settings module to use.
|
||||
- The value will be passed as is to the C(--settings) argument in C(django-admin).
|
||||
type: str
|
||||
required: true
|
||||
pythonpath:
|
||||
description:
|
||||
- Adds the given filesystem path to the Python import search path.
|
||||
- The value will be passed as is to the C(--pythonpath) argument in C(django-admin).
|
||||
type: path
|
||||
traceback:
|
||||
description:
|
||||
- Provides a full stack trace in the output when a C(CommandError) is raised.
|
||||
type: bool
|
||||
verbosity:
|
||||
description:
|
||||
- Specifies the amount of notification and debug information in the output of C(django-admin).
|
||||
type: int
|
||||
choices: [0, 1, 2, 3]
|
||||
skip_checks:
|
||||
description:
|
||||
- Skips running system checks prior to running the command.
|
||||
type: bool
|
||||
|
||||
|
||||
notes:
|
||||
- The C(django-admin) command is always executed using the C(C) locale, and the option C(--no-color) is always passed.
|
||||
|
||||
seealso:
|
||||
- name: django-admin and manage.py in official Django documentation
|
||||
description: >-
|
||||
Refer to this documentation for the builtin commands and options of C(django-admin).
|
||||
Please make sure that you select the right version of Django in the version selector on that page.
|
||||
link: https://docs.djangoproject.com/en/5.0/ref/django-admin/
|
||||
'''
|
||||
@@ -65,13 +65,3 @@ options:
|
||||
- Add the new VM to the specified pool.
|
||||
type: str
|
||||
'''
|
||||
|
||||
ACTIONGROUP_PROXMOX = r"""
|
||||
options: {}
|
||||
attributes:
|
||||
action_group:
|
||||
description: Use C(group/community.general.proxmox) in C(module_defaults) to set defaults for this module.
|
||||
support: full
|
||||
membership:
|
||||
- community.general.proxmox
|
||||
"""
|
||||
|
||||
120
plugins/doc_fragments/rackspace.py
Normal file
120
plugins/doc_fragments/rackspace.py
Normal file
@@ -0,0 +1,120 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2014, Matt Martz <matt@sivel.net>
|
||||
# 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
|
||||
|
||||
|
||||
class ModuleDocFragment(object):
|
||||
|
||||
# Standard Rackspace only documentation fragment
|
||||
DOCUMENTATION = r'''
|
||||
options:
|
||||
api_key:
|
||||
description:
|
||||
- Rackspace API key, overrides O(credentials).
|
||||
type: str
|
||||
aliases: [ password ]
|
||||
credentials:
|
||||
description:
|
||||
- File to find the Rackspace credentials in. Ignored if O(api_key) and
|
||||
O(username) are provided.
|
||||
type: path
|
||||
aliases: [ creds_file ]
|
||||
env:
|
||||
description:
|
||||
- Environment as configured in C(~/.pyrax.cfg),
|
||||
see U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#pyrax-configuration).
|
||||
type: str
|
||||
region:
|
||||
description:
|
||||
- Region to create an instance in.
|
||||
type: str
|
||||
username:
|
||||
description:
|
||||
- Rackspace username, overrides O(credentials).
|
||||
type: str
|
||||
validate_certs:
|
||||
description:
|
||||
- Whether or not to require SSL validation of API endpoints.
|
||||
type: bool
|
||||
aliases: [ verify_ssl ]
|
||||
requirements:
|
||||
- pyrax
|
||||
notes:
|
||||
- The following environment variables can be used, E(RAX_USERNAME),
|
||||
E(RAX_API_KEY), E(RAX_CREDS_FILE), E(RAX_CREDENTIALS), E(RAX_REGION).
|
||||
- E(RAX_CREDENTIALS) and E(RAX_CREDS_FILE) point to a credentials file
|
||||
appropriate for pyrax. See U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating).
|
||||
- E(RAX_USERNAME) and E(RAX_API_KEY) obviate the use of a credentials file.
|
||||
- E(RAX_REGION) defines a Rackspace Public Cloud region (DFW, ORD, LON, ...).
|
||||
'''
|
||||
|
||||
# Documentation fragment including attributes to enable communication
|
||||
# of other OpenStack clouds. Not all rax modules support this.
|
||||
OPENSTACK = r'''
|
||||
options:
|
||||
api_key:
|
||||
type: str
|
||||
description:
|
||||
- Rackspace API key, overrides O(credentials).
|
||||
aliases: [ password ]
|
||||
auth_endpoint:
|
||||
type: str
|
||||
description:
|
||||
- The URI of the authentication service.
|
||||
- If not specified will be set to U(https://identity.api.rackspacecloud.com/v2.0/).
|
||||
credentials:
|
||||
type: path
|
||||
description:
|
||||
- File to find the Rackspace credentials in. Ignored if O(api_key) and
|
||||
O(username) are provided.
|
||||
aliases: [ creds_file ]
|
||||
env:
|
||||
type: str
|
||||
description:
|
||||
- Environment as configured in C(~/.pyrax.cfg),
|
||||
see U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#pyrax-configuration).
|
||||
identity_type:
|
||||
type: str
|
||||
description:
|
||||
- Authentication mechanism to use, such as rackspace or keystone.
|
||||
default: rackspace
|
||||
region:
|
||||
type: str
|
||||
description:
|
||||
- Region to create an instance in.
|
||||
tenant_id:
|
||||
type: str
|
||||
description:
|
||||
- The tenant ID used for authentication.
|
||||
tenant_name:
|
||||
type: str
|
||||
description:
|
||||
- The tenant name used for authentication.
|
||||
username:
|
||||
type: str
|
||||
description:
|
||||
- Rackspace username, overrides O(credentials).
|
||||
validate_certs:
|
||||
description:
|
||||
- Whether or not to require SSL validation of API endpoints.
|
||||
type: bool
|
||||
aliases: [ verify_ssl ]
|
||||
deprecated:
|
||||
removed_in: 9.0.0
|
||||
why: This module relies on the deprecated package pyrax.
|
||||
alternative: Use the Openstack modules instead.
|
||||
requirements:
|
||||
- pyrax
|
||||
notes:
|
||||
- The following environment variables can be used, E(RAX_USERNAME),
|
||||
E(RAX_API_KEY), E(RAX_CREDS_FILE), E(RAX_CREDENTIALS), E(RAX_REGION).
|
||||
- E(RAX_CREDENTIALS) and E(RAX_CREDS_FILE) points to a credentials file
|
||||
appropriate for pyrax. See U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating).
|
||||
- E(RAX_USERNAME) and E(RAX_API_KEY) obviate the use of a credentials file.
|
||||
- E(RAX_REGION) defines a Rackspace Public Cloud region (DFW, ORD, LON, ...).
|
||||
'''
|
||||
@@ -57,7 +57,7 @@ class IniParser(ConfigParser):
|
||||
''' Implements a configparser which is able to return a dict '''
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(interpolation=None)
|
||||
super().__init__()
|
||||
self.optionxform = str
|
||||
|
||||
def as_dict(self):
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# 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
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible.module_utils.common.collections import is_sequence
|
||||
|
||||
|
||||
def remove_duplicates(lst):
|
||||
seen = set()
|
||||
seen_add = seen.add
|
||||
result = []
|
||||
for item in lst:
|
||||
try:
|
||||
if item not in seen:
|
||||
seen_add(item)
|
||||
result.append(item)
|
||||
except TypeError:
|
||||
# This happens for unhashable values `item`. If this happens,
|
||||
# convert `seen` to a list and continue.
|
||||
seen = list(seen)
|
||||
seen_add = seen.append
|
||||
if item not in seen:
|
||||
seen_add(item)
|
||||
result.append(item)
|
||||
return result
|
||||
|
||||
|
||||
def flatten_list(lst):
|
||||
result = []
|
||||
for sublist in lst:
|
||||
if not is_sequence(sublist):
|
||||
msg = ("All arguments must be lists. %s is %s")
|
||||
raise AnsibleFilterError(msg % (sublist, type(sublist)))
|
||||
if len(sublist) > 0:
|
||||
if all(is_sequence(sub) for sub in sublist):
|
||||
for item in sublist:
|
||||
result.append(item)
|
||||
else:
|
||||
result.append(sublist)
|
||||
return result
|
||||
|
||||
|
||||
def lists_union(*args, **kwargs):
|
||||
lists = args
|
||||
flatten = kwargs.pop('flatten', False)
|
||||
|
||||
if kwargs:
|
||||
# Some unused kwargs remain
|
||||
raise AnsibleFilterError(
|
||||
"lists_union() got unexpected keywords arguments: {0}".format(
|
||||
", ".join(kwargs.keys())
|
||||
)
|
||||
)
|
||||
|
||||
if flatten:
|
||||
lists = flatten_list(args)
|
||||
|
||||
if not lists:
|
||||
return []
|
||||
|
||||
if len(lists) == 1:
|
||||
return lists[0]
|
||||
|
||||
a = lists[0]
|
||||
for b in lists[1:]:
|
||||
a = do_union(a, b)
|
||||
return remove_duplicates(a)
|
||||
|
||||
|
||||
def do_union(a, b):
|
||||
return a + b
|
||||
|
||||
|
||||
def lists_intersect(*args, **kwargs):
|
||||
lists = args
|
||||
flatten = kwargs.pop('flatten', False)
|
||||
|
||||
if kwargs:
|
||||
# Some unused kwargs remain
|
||||
raise AnsibleFilterError(
|
||||
"lists_intersect() got unexpected keywords arguments: {0}".format(
|
||||
", ".join(kwargs.keys())
|
||||
)
|
||||
)
|
||||
|
||||
if flatten:
|
||||
lists = flatten_list(args)
|
||||
|
||||
if not lists:
|
||||
return []
|
||||
|
||||
if len(lists) == 1:
|
||||
return lists[0]
|
||||
|
||||
a = remove_duplicates(lists[0])
|
||||
for b in lists[1:]:
|
||||
a = do_intersect(a, b)
|
||||
return a
|
||||
|
||||
|
||||
def do_intersect(a, b):
|
||||
isect = []
|
||||
try:
|
||||
other = set(b)
|
||||
isect = [item for item in a if item in other]
|
||||
except TypeError:
|
||||
# This happens for unhashable values,
|
||||
# use a list instead and redo.
|
||||
other = list(b)
|
||||
isect = [item for item in a if item in other]
|
||||
return isect
|
||||
|
||||
|
||||
def lists_difference(*args, **kwargs):
|
||||
lists = args
|
||||
flatten = kwargs.pop('flatten', False)
|
||||
|
||||
if kwargs:
|
||||
# Some unused kwargs remain
|
||||
raise AnsibleFilterError(
|
||||
"lists_difference() got unexpected keywords arguments: {0}".format(
|
||||
", ".join(kwargs.keys())
|
||||
)
|
||||
)
|
||||
|
||||
if flatten:
|
||||
lists = flatten_list(args)
|
||||
|
||||
if not lists:
|
||||
return []
|
||||
|
||||
if len(lists) == 1:
|
||||
return lists[0]
|
||||
|
||||
a = remove_duplicates(lists[0])
|
||||
for b in lists[1:]:
|
||||
a = do_difference(a, b)
|
||||
return a
|
||||
|
||||
|
||||
def do_difference(a, b):
|
||||
diff = []
|
||||
try:
|
||||
other = set(b)
|
||||
diff = [item for item in a if item not in other]
|
||||
except TypeError:
|
||||
# This happens for unhashable values,
|
||||
# use a list instead and redo.
|
||||
other = list(b)
|
||||
diff = [item for item in a if item not in other]
|
||||
return diff
|
||||
|
||||
|
||||
def lists_symmetric_difference(*args, **kwargs):
|
||||
lists = args
|
||||
flatten = kwargs.pop('flatten', False)
|
||||
|
||||
if kwargs:
|
||||
# Some unused kwargs remain
|
||||
raise AnsibleFilterError(
|
||||
"lists_difference() got unexpected keywords arguments: {0}".format(
|
||||
", ".join(kwargs.keys())
|
||||
)
|
||||
)
|
||||
|
||||
if flatten:
|
||||
lists = flatten_list(args)
|
||||
|
||||
if not lists:
|
||||
return []
|
||||
|
||||
if len(lists) == 1:
|
||||
return lists[0]
|
||||
|
||||
a = lists[0]
|
||||
for b in lists[1:]:
|
||||
a = do_symmetric_difference(a, b)
|
||||
return a
|
||||
|
||||
|
||||
def do_symmetric_difference(a, b):
|
||||
sym_diff = []
|
||||
union = lists_union(a, b)
|
||||
try:
|
||||
isect = set(a) & set(b)
|
||||
sym_diff = [item for item in union if item not in isect]
|
||||
except TypeError:
|
||||
# This happens for unhashable values,
|
||||
# build the intersection of `a` and `b` backed
|
||||
# by a list instead of a set and redo.
|
||||
isect = lists_intersect(a, b)
|
||||
sym_diff = [item for item in union if item not in isect]
|
||||
return sym_diff
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
''' Ansible lists jinja2 filters '''
|
||||
|
||||
def filters(self):
|
||||
return {
|
||||
'lists_union': lists_union,
|
||||
'lists_intersect': lists_intersect,
|
||||
'lists_difference': lists_difference,
|
||||
'lists_symmetric_difference': lists_symmetric_difference,
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
DOCUMENTATION:
|
||||
name: lists_difference
|
||||
short_description: Difference of lists with a predictive order
|
||||
version_added: 8.4.0
|
||||
description:
|
||||
- Provide a unique list of all the elements from the first which do not appear in the other lists.
|
||||
- The order of the items in the resulting list is preserved.
|
||||
options:
|
||||
_input:
|
||||
description: A list.
|
||||
type: list
|
||||
elements: any
|
||||
required: true
|
||||
flatten:
|
||||
description: Whether to remove one hierarchy level from the input list.
|
||||
type: boolean
|
||||
default: false
|
||||
author:
|
||||
- Christoph Fiehe (@cfiehe)
|
||||
|
||||
EXAMPLES: |
|
||||
- name: Return the difference of list1 and list2.
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ list1 | community.general.lists_difference(list2) }}"
|
||||
vars:
|
||||
list1: [1, 2, 5, 3, 4, 10]
|
||||
list2: [1, 2, 3, 4, 5, 11, 99]
|
||||
# => [10]
|
||||
|
||||
- name: Return the difference of list1, list2 and list3.
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ [list1, list2, list3] | community.general.lists_difference(flatten=true) }}"
|
||||
vars:
|
||||
list1: [1, 2, 5, 3, 4, 10]
|
||||
list2: [1, 2, 3, 4, 5, 11, 99]
|
||||
list3: [1, 2, 3, 4, 5, 10, 99, 101]
|
||||
# => []
|
||||
|
||||
RETURN:
|
||||
_value:
|
||||
description: A unique list of all the elements from the first list that do not appear on the other lists.
|
||||
type: list
|
||||
elements: any
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
DOCUMENTATION:
|
||||
name: lists_intersect
|
||||
short_description: Intersection of lists with a predictive order
|
||||
version_added: 8.4.0
|
||||
description:
|
||||
- Provide a unique list of all the common elements of two or more lists.
|
||||
- The order of the items in the resulting list is preserved.
|
||||
options:
|
||||
_input:
|
||||
description: A list.
|
||||
type: list
|
||||
elements: any
|
||||
required: true
|
||||
flatten:
|
||||
description: Whether to remove one hierarchy level from the input list.
|
||||
type: boolean
|
||||
default: false
|
||||
author:
|
||||
- Christoph Fiehe (@cfiehe)
|
||||
|
||||
EXAMPLES: |
|
||||
- name: Return the intersection of list1 and list2.
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ list1 | community.general.lists_intersect(list2) }}"
|
||||
vars:
|
||||
list1: [1, 2, 5, 3, 4, 10]
|
||||
list2: [1, 2, 3, 4, 5, 11, 99]
|
||||
# => [1, 2, 5, 3, 4]
|
||||
|
||||
- name: Return the intersection of list1, list2 and list3.
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ [list1, list2, list3] | community.general.lists_intersect(flatten=true) }}"
|
||||
vars:
|
||||
list1: [1, 2, 5, 3, 4, 10]
|
||||
list2: [1, 2, 3, 4, 5, 11, 99]
|
||||
list3: [1, 2, 3, 4, 5, 10, 99, 101]
|
||||
# => [1, 2, 5, 3, 4]
|
||||
|
||||
RETURN:
|
||||
_value:
|
||||
description: A unique list of all the common elements from the provided lists.
|
||||
type: list
|
||||
elements: any
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
DOCUMENTATION:
|
||||
name: lists_symmetric_difference
|
||||
short_description: Symmetric Difference of lists with a predictive order
|
||||
version_added: 8.4.0
|
||||
description:
|
||||
- Provide a unique list containing the symmetric difference of two or more lists.
|
||||
- The order of the items in the resulting list is preserved.
|
||||
options:
|
||||
_input:
|
||||
description: A list.
|
||||
type: list
|
||||
elements: any
|
||||
required: true
|
||||
flatten:
|
||||
description: Whether to remove one hierarchy level from the input list.
|
||||
type: boolean
|
||||
default: false
|
||||
author:
|
||||
- Christoph Fiehe (@cfiehe)
|
||||
|
||||
EXAMPLES: |
|
||||
- name: Return the symmetric difference of list1 and list2.
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ list1 | community.general.lists_symmetric_difference(list2) }}"
|
||||
vars:
|
||||
list1: [1, 2, 5, 3, 4, 10]
|
||||
list2: [1, 2, 3, 4, 5, 11, 99]
|
||||
# => [10, 11, 99]
|
||||
|
||||
- name: Return the symmetric difference of list1, list2 and list3.
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ [list1, list2, list3] | community.general.lists_symmetric_difference(flatten=true) }}"
|
||||
vars:
|
||||
list1: [1, 2, 5, 3, 4, 10]
|
||||
list2: [1, 2, 3, 4, 5, 11, 99]
|
||||
list3: [1, 2, 3, 4, 5, 10, 99, 101]
|
||||
# => [11, 1, 2, 3, 4, 5, 101]
|
||||
|
||||
RETURN:
|
||||
_value:
|
||||
description: A unique list containing the symmetric difference of two or more lists.
|
||||
type: list
|
||||
elements: any
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
DOCUMENTATION:
|
||||
name: lists_union
|
||||
short_description: Union of lists with a predictive order
|
||||
version_added: 8.4.0
|
||||
description:
|
||||
- Provide a unique list of all the elements of two or more lists.
|
||||
- The order of the items in the resulting list is preserved.
|
||||
options:
|
||||
_input:
|
||||
description: A list.
|
||||
type: list
|
||||
elements: any
|
||||
required: true
|
||||
flatten:
|
||||
description: Whether to remove one hierarchy level from the input list.
|
||||
type: boolean
|
||||
default: false
|
||||
author:
|
||||
- Christoph Fiehe (@cfiehe)
|
||||
|
||||
EXAMPLES: |
|
||||
- name: Return the union of list1, list2 and list3.
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ list1 | community.general.lists_union(list2, list3) }}"
|
||||
vars:
|
||||
list1: [1, 2, 5, 3, 4, 10]
|
||||
list2: [1, 2, 3, 4, 5, 11, 99]
|
||||
list3: [1, 2, 3, 4, 5, 10, 99, 101]
|
||||
# => [1, 2, 5, 3, 4, 10, 11, 99, 101]
|
||||
|
||||
- name: Return the union of list1 and list2.
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ [list1, list2] | community.general.lists_union(flatten=true) }}"
|
||||
vars:
|
||||
list1: [1, 2, 5, 3, 4, 10]
|
||||
list2: [1, 2, 3, 4, 5, 11, 99]
|
||||
# => [1, 2, 5, 3, 4, 10, 11, 99]
|
||||
|
||||
RETURN:
|
||||
_value:
|
||||
description: A unique list of all the elements from the provided lists.
|
||||
type: list
|
||||
elements: any
|
||||
@@ -63,7 +63,7 @@ class IniParser(ConfigParser):
|
||||
''' Implements a configparser which sets the correct optionxform '''
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(interpolation=None)
|
||||
super().__init__()
|
||||
self.optionxform = str
|
||||
|
||||
|
||||
|
||||
@@ -118,8 +118,6 @@ 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
|
||||
@@ -276,9 +274,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 = make_unsafe(host['name']) # None
|
||||
hostname = host['name'] # None
|
||||
else:
|
||||
hostname = make_unsafe(host['hostname']) # None
|
||||
hostname = host['hostname'] # None
|
||||
interfaces = host['interfaces']
|
||||
|
||||
if set(host['mgmt_classes']) & set(self.include_mgmt_classes):
|
||||
@@ -298,7 +296,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 = make_unsafe(this_dns_name)
|
||||
hostname = this_dns_name
|
||||
self.display.vvvv('Set hostname to %s from %s\n' % (hostname, iname))
|
||||
|
||||
if hostname == '':
|
||||
@@ -363,18 +361,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', make_unsafe(ip_address))
|
||||
self.inventory.set_variable(hostname, 'cobbler_ipv4_address', ip_address)
|
||||
if ipv6_address is None and ipv6_address_first is not None:
|
||||
ipv6_address = ipv6_address_first
|
||||
if ipv6_address is not None:
|
||||
self.inventory.set_variable(hostname, 'cobbler_ipv6_address', make_unsafe(ipv6_address))
|
||||
self.inventory.set_variable(hostname, 'cobbler_ipv6_address', ipv6_address)
|
||||
|
||||
if self.get_option('want_facts'):
|
||||
try:
|
||||
self.inventory.set_variable(hostname, 'cobbler', make_unsafe(host))
|
||||
self.inventory.set_variable(hostname, 'cobbler', host)
|
||||
except ValueError as e:
|
||||
self.display.warning("Could not set host info for %s: %s" % (hostname, to_text(e)))
|
||||
|
||||
if self.get_option('want_ip_addresses'):
|
||||
self.inventory.set_variable(self.group, 'cobbler_ipv4_addresses', make_unsafe(ip_addresses))
|
||||
self.inventory.set_variable(self.group, 'cobbler_ipv6_addresses', make_unsafe(ipv6_addresses))
|
||||
self.inventory.set_variable(self.group, 'cobbler_ipv4_addresses', ip_addresses)
|
||||
self.inventory.set_variable(self.group, 'cobbler_ipv6_addresses', ipv6_addresses)
|
||||
|
||||
@@ -84,8 +84,6 @@ 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
|
||||
@@ -107,11 +105,11 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
else:
|
||||
runners = gl.runners.all()
|
||||
for runner in runners:
|
||||
host = make_unsafe(str(runner['id']))
|
||||
host = str(runner['id'])
|
||||
ip_address = runner['ip_address']
|
||||
host_attrs = make_unsafe(vars(gl.runners.get(runner['id']))['_attrs'])
|
||||
host_attrs = vars(gl.runners.get(runner['id']))['_attrs']
|
||||
self.inventory.add_host(host, group='gitlab_runners')
|
||||
self.inventory.set_variable(host, 'ansible_host', make_unsafe(ip_address))
|
||||
self.inventory.set_variable(host, 'ansible_host', ip_address)
|
||||
if self.get_option('verbose_output', True):
|
||||
self.inventory.set_variable(host, 'gitlab_runner_attributes', host_attrs)
|
||||
|
||||
|
||||
@@ -63,12 +63,6 @@ DOCUMENTATION = '''
|
||||
default: address
|
||||
choices: ['name', 'display_name', 'address']
|
||||
version_added: 4.2.0
|
||||
group_by_hostgroups:
|
||||
description:
|
||||
- Uses Icinga2 hostgroups as groups.
|
||||
type: boolean
|
||||
default: true
|
||||
version_added: 8.4.0
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
@@ -103,8 +97,6 @@ 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. '''
|
||||
@@ -122,7 +114,6 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
self.ssl_verify = None
|
||||
self.host_filter = None
|
||||
self.inventory_attr = None
|
||||
self.group_by_hostgroups = None
|
||||
|
||||
self.cache_key = None
|
||||
self.use_cache = None
|
||||
@@ -242,32 +233,31 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
"""Convert Icinga2 API data to JSON format for Ansible"""
|
||||
groups_dict = {"_meta": {"hostvars": {}}}
|
||||
for entry in json_data:
|
||||
host_attrs = make_unsafe(entry['attrs'])
|
||||
host_attrs = entry['attrs']
|
||||
if self.inventory_attr == "name":
|
||||
host_name = make_unsafe(entry.get('name'))
|
||||
host_name = 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 = make_unsafe(host_attrs.get('address'))
|
||||
host_name = host_attrs.get('address')
|
||||
else:
|
||||
host_name = make_unsafe(entry.get('name'))
|
||||
host_name = entry.get('name')
|
||||
if self.inventory_attr == "display_name":
|
||||
host_name = host_attrs.get('display_name')
|
||||
if host_attrs['state'] == 0:
|
||||
host_attrs['state'] = 'on'
|
||||
else:
|
||||
host_attrs['state'] = 'off'
|
||||
host_groups = host_attrs.get('groups')
|
||||
self.inventory.add_host(host_name)
|
||||
if self.group_by_hostgroups:
|
||||
host_groups = host_attrs.get('groups')
|
||||
for group in host_groups:
|
||||
if group not in self.inventory.groups.keys():
|
||||
self.inventory.add_group(group)
|
||||
self.inventory.add_child(group, host_name)
|
||||
for group in host_groups:
|
||||
if group not in self.inventory.groups.keys():
|
||||
self.inventory.add_group(group)
|
||||
self.inventory.add_child(group, host_name)
|
||||
# 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', make_unsafe(entry.get('name')))
|
||||
self.inventory.set_variable(host_name, 'hostname', 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'])
|
||||
@@ -287,23 +277,12 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
self._read_config_data(path)
|
||||
|
||||
# Store the options from the YAML file
|
||||
self.icinga2_url = self.get_option('url')
|
||||
self.icinga2_url = self.get_option('url').rstrip('/') + '/v1'
|
||||
self.icinga2_user = self.get_option('user')
|
||||
self.icinga2_password = self.get_option('password')
|
||||
self.ssl_verify = self.get_option('validate_certs')
|
||||
self.host_filter = self.get_option('host_filter')
|
||||
self.inventory_attr = self.get_option('inventory_attr')
|
||||
self.group_by_hostgroups = self.get_option('group_by_hostgroups')
|
||||
|
||||
if self.templar.is_template(self.icinga2_url):
|
||||
self.icinga2_url = self.templar.template(variable=self.icinga2_url, disable_lookups=False)
|
||||
if self.templar.is_template(self.icinga2_user):
|
||||
self.icinga2_user = self.templar.template(variable=self.icinga2_user, disable_lookups=False)
|
||||
if self.templar.is_template(self.icinga2_password):
|
||||
self.icinga2_password = self.templar.template(variable=self.icinga2_password, disable_lookups=False)
|
||||
|
||||
self.icinga2_url = self.icinga2_url.rstrip('/') + '/v1'
|
||||
|
||||
# Not currently enabled
|
||||
# self.cache_key = self.get_cache_key(path)
|
||||
# self.use_cache = cache and self.get_option('cache')
|
||||
|
||||
@@ -123,8 +123,6 @@ 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
|
||||
@@ -200,21 +198,20 @@ 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(make_unsafe(instance.label), group=instance.group)
|
||||
self.inventory.add_host(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(
|
||||
hostname,
|
||||
instance.label,
|
||||
hostvar_key,
|
||||
make_unsafe(hostvars[hostvar_key])
|
||||
hostvars[hostvar_key]
|
||||
)
|
||||
if ip_style == 'api':
|
||||
ips = instance.ips.ipv4.public + instance.ips.ipv4.private
|
||||
@@ -223,9 +220,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
|
||||
for ip_type in set(ip.type for ip in ips):
|
||||
self.inventory.set_variable(
|
||||
hostname,
|
||||
instance.label,
|
||||
ip_type,
|
||||
make_unsafe(self._ip_data([ip for ip in ips if ip.type == ip_type]))
|
||||
self._ip_data([ip for ip in ips if ip.type == ip_type])
|
||||
)
|
||||
|
||||
def _ip_data(self, ip_list):
|
||||
@@ -256,44 +253,30 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
self._add_instances_to_groups()
|
||||
self._add_hostvars_for_instances()
|
||||
for instance in self.instances:
|
||||
hostname = make_unsafe(instance.label)
|
||||
variables = self.inventory.get_host(hostname).get_vars()
|
||||
variables = self.inventory.get_host(instance.label).get_vars()
|
||||
self._add_host_to_composed_groups(
|
||||
self.get_option('groups'),
|
||||
variables,
|
||||
hostname,
|
||||
instance.label,
|
||||
strict=strict)
|
||||
self._add_host_to_keyed_groups(
|
||||
self.get_option('keyed_groups'),
|
||||
variables,
|
||||
hostname,
|
||||
instance.label,
|
||||
strict=strict)
|
||||
self._set_composite_vars(
|
||||
self.get_option('compose'),
|
||||
variables,
|
||||
hostname,
|
||||
instance.label,
|
||||
strict=strict)
|
||||
|
||||
def verify_file(self, path):
|
||||
"""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
|
||||
"""Verify the Linode configuration file."""
|
||||
if super(InventoryModule, self).verify_file(path):
|
||||
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
|
||||
endings = ('linode.yaml', 'linode.yml')
|
||||
if any((path.endswith(ending) for ending in endings)):
|
||||
return True
|
||||
return False
|
||||
|
||||
def parse(self, inventory, loader, path, cache=True):
|
||||
"""Dynamically parse Linode the cloud inventory."""
|
||||
|
||||
@@ -175,7 +175,6 @@ 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
|
||||
@@ -671,7 +670,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', make_unsafe(interface_selection(instance_name)))
|
||||
self.inventory.set_variable(instance_name, 'ansible_host', interface_selection(instance_name))
|
||||
else:
|
||||
self.inventory.set_variable(instance_name, 'ansible_connection', 'local')
|
||||
|
||||
@@ -697,39 +696,31 @@ 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', make_unsafe(v.lower()))
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_os', 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', make_unsafe(v.lower()))
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_release', v.lower())
|
||||
# add profile
|
||||
self.inventory.set_variable(
|
||||
instance_name, 'ansible_lxd_profile', make_unsafe(self._get_data_entry('inventory/{0}/profile'.format(instance_name))))
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_profile', self._get_data_entry('inventory/{0}/profile'.format(instance_name)))
|
||||
# add state
|
||||
self.inventory.set_variable(
|
||||
instance_name, 'ansible_lxd_state', make_unsafe(instance_state))
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_state', instance_state)
|
||||
# add type
|
||||
self.inventory.set_variable(
|
||||
instance_name, 'ansible_lxd_type', make_unsafe(self._get_data_entry('inventory/{0}/type'.format(instance_name))))
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_type', 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', make_unsafe(self._get_data_entry('inventory/{0}/location'.format(instance_name))))
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_location', 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', make_unsafe(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)))
|
||||
# add project
|
||||
self.inventory.set_variable(
|
||||
instance_name, 'ansible_lxd_project', make_unsafe(self._get_data_entry('inventory/{0}/project'.format(instance_name))))
|
||||
self.inventory.set_variable(instance_name, 'ansible_lxd_project', self._get_data_entry('inventory/{0}/project'.format(instance_name)))
|
||||
|
||||
def build_inventory_groups_location(self, group_name):
|
||||
"""create group by attribute: location
|
||||
@@ -1002,7 +993,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(make_unsafe(group_name))
|
||||
group_type(group_name)
|
||||
|
||||
def build_inventory(self):
|
||||
"""Build dynamic inventory
|
||||
|
||||
@@ -127,8 +127,6 @@ 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):
|
||||
|
||||
@@ -145,7 +143,6 @@ 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,8 +69,6 @@ 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'
|
||||
@@ -171,20 +169,20 @@ class InventoryModule(BaseInventoryPlugin):
|
||||
"support"
|
||||
)
|
||||
for attribute in targeted_attributes:
|
||||
self.inventory.set_variable(hostname, attribute, make_unsafe(host_infos[attribute]))
|
||||
self.inventory.set_variable(hostname, attribute, host_infos[attribute])
|
||||
|
||||
if 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)))
|
||||
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))
|
||||
|
||||
if 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)))
|
||||
self.inventory.set_variable(hostname, "public_ipv4", self.extract_private_ipv4(host_infos=host_infos))
|
||||
|
||||
if 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)))
|
||||
self.inventory.set_variable(hostname, "os_name", self.extract_os_name(host_infos=host_infos))
|
||||
|
||||
if self.extract_os_version(host_infos=host_infos):
|
||||
self.inventory.set_variable(hostname, "os_version", make_unsafe(self.extract_os_name(host_infos=host_infos)))
|
||||
self.inventory.set_variable(hostname, "os_version", self.extract_os_name(host_infos=host_infos))
|
||||
|
||||
def _filter_host(self, host_infos, hostname_preferences):
|
||||
|
||||
@@ -203,8 +201,6 @@ 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)
|
||||
|
||||
@@ -214,8 +210,6 @@ 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,8 +98,6 @@ 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
|
||||
|
||||
@@ -217,7 +215,6 @@ 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']:
|
||||
|
||||
@@ -228,7 +228,6 @@ 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:
|
||||
@@ -335,7 +334,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
|
||||
self._cache[self.cache_key][url] = data
|
||||
|
||||
return make_unsafe(self._cache[self.cache_key][url])
|
||||
return self._cache[self.cache_key][url]
|
||||
|
||||
def _get_nodes(self):
|
||||
return self._get_json("%s/api2/json/nodes" % self.proxmox_url)
|
||||
|
||||
@@ -121,7 +121,6 @@ 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
|
||||
@@ -280,7 +279,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
zone_info = SCALEWAY_LOCATION[zone]
|
||||
|
||||
url = _build_server_url(zone_info["api_endpoint"])
|
||||
raw_zone_hosts_infos = make_unsafe(_fetch_information(url=url, token=token))
|
||||
raw_zone_hosts_infos = _fetch_information(url=url, token=token)
|
||||
|
||||
for host_infos in raw_zone_hosts_infos:
|
||||
|
||||
@@ -342,4 +341,4 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
hostname_preference = self.get_option("hostnames")
|
||||
|
||||
for zone in self._get_zones(config_zones):
|
||||
self.do_zone_inventory(zone=make_unsafe(zone), token=token, tags=tags, hostname_preferences=hostname_preference)
|
||||
self.do_zone_inventory(zone=zone, token=token, tags=tags, hostname_preferences=hostname_preference)
|
||||
|
||||
@@ -73,8 +73,6 @@ 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()
|
||||
|
||||
@@ -273,7 +271,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
if not cache or cache_needs_update:
|
||||
results = self._query()
|
||||
|
||||
self._populate(make_unsafe(results))
|
||||
self._populate(results)
|
||||
|
||||
# If the cache has expired/doesn't exist or
|
||||
# if refresh_inventory/flush cache is used
|
||||
|
||||
@@ -63,8 +63,6 @@ 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. '''
|
||||
@@ -118,7 +116,6 @@ 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':
|
||||
@@ -165,7 +162,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 = make_unsafe(v)
|
||||
current_host = v
|
||||
if current_host not in hostvars:
|
||||
hostvars[current_host] = {}
|
||||
self.inventory.add_host(current_host)
|
||||
@@ -173,13 +170,12 @@ 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', make_unsafe(netdata))
|
||||
self.inventory.set_variable(current_host, 'ansible_host', 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:
|
||||
@@ -189,17 +185,17 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
|
||||
else:
|
||||
# found vars, accumulate in hostvars for clean inventory set
|
||||
pref_k = make_unsafe('vbox_' + k.strip().replace(' ', '_'))
|
||||
pref_k = '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] = make_unsafe(v)
|
||||
hostvars[current_host][prevkey][pref_k] = v
|
||||
elif leading_spaces > 2:
|
||||
continue
|
||||
else:
|
||||
if v != '':
|
||||
hostvars[current_host][pref_k] = make_unsafe(v)
|
||||
hostvars[current_host][pref_k] = v
|
||||
if self._ungrouped_host(current_host, cacheable_results):
|
||||
if 'ungrouped' not in cacheable_results:
|
||||
cacheable_results['ungrouped'] = {'hosts': []}
|
||||
|
||||
@@ -84,7 +84,6 @@ 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:
|
||||
@@ -348,4 +347,4 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
self.protocol = 'ws'
|
||||
|
||||
objects = self._get_objects()
|
||||
self._populate(make_unsafe(objects))
|
||||
self._populate(objects)
|
||||
|
||||
@@ -29,7 +29,6 @@ DOCUMENTATION = """
|
||||
- Field to retrieve, for example V(name) or V(id).
|
||||
- If set to V(id), only zero or one element can be returned.
|
||||
Use the Jinja C(first) filter to get the only list element.
|
||||
- If set to V(None) or V(''), or if O(_terms) is empty, records are not filtered by fields.
|
||||
type: str
|
||||
default: name
|
||||
version_added: 5.7.0
|
||||
@@ -40,14 +39,6 @@ DOCUMENTATION = """
|
||||
description: Collection ID to filter results by collection. Leave unset to skip filtering.
|
||||
type: str
|
||||
version_added: 6.3.0
|
||||
organization_id:
|
||||
description: Organization ID to filter results by organization. Leave unset to skip filtering.
|
||||
type: str
|
||||
version_added: 8.5.0
|
||||
bw_session:
|
||||
description: Pass session key instead of reading from env.
|
||||
type: str
|
||||
version_added: 8.4.0
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -75,16 +66,6 @@ EXAMPLES = """
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
{{ lookup('community.general.bitwarden', 'a_test', field='api_key') }}
|
||||
|
||||
- name: "Get 'password' from all Bitwarden records named 'a_test', using given session key"
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
{{ lookup('community.general.bitwarden', 'a_test', field='password', bw_session='bXZ9B5TXi6...') }}
|
||||
|
||||
- name: "Get all Bitwarden records from collection"
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
{{ lookup('community.general.bitwarden', None, collection_id='bafba515-af11-47e6-abe3-af1200cd18b2') }}
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
@@ -113,20 +94,11 @@ class Bitwarden(object):
|
||||
|
||||
def __init__(self, path='bw'):
|
||||
self._cli_path = path
|
||||
self._session = None
|
||||
|
||||
@property
|
||||
def cli_path(self):
|
||||
return self._cli_path
|
||||
|
||||
@property
|
||||
def session(self):
|
||||
return self._session
|
||||
|
||||
@session.setter
|
||||
def session(self, value):
|
||||
self._session = value
|
||||
|
||||
@property
|
||||
def unlocked(self):
|
||||
out, err = self._run(['status'], stdin="")
|
||||
@@ -134,9 +106,6 @@ class Bitwarden(object):
|
||||
return decoded['status'] == 'unlocked'
|
||||
|
||||
def _run(self, args, stdin=None, expected_rc=0):
|
||||
if self.session:
|
||||
args += ['--session', self.session]
|
||||
|
||||
p = Popen([self.cli_path] + args, stdout=PIPE, stderr=PIPE, stdin=PIPE)
|
||||
out, err = p.communicate(to_bytes(stdin))
|
||||
rc = p.wait()
|
||||
@@ -146,7 +115,7 @@ class Bitwarden(object):
|
||||
raise BitwardenException(err)
|
||||
return to_text(out, errors='surrogate_or_strict'), to_text(err, errors='surrogate_or_strict')
|
||||
|
||||
def _get_matches(self, search_value, search_field, collection_id=None, organization_id=None):
|
||||
def _get_matches(self, search_value, search_field, collection_id):
|
||||
"""Return matching records whose search_field is equal to key.
|
||||
"""
|
||||
|
||||
@@ -154,36 +123,30 @@ class Bitwarden(object):
|
||||
if search_field == 'id':
|
||||
params = ['get', 'item', search_value]
|
||||
else:
|
||||
params = ['list', 'items']
|
||||
if search_value:
|
||||
params.extend(['--search', search_value])
|
||||
params = ['list', 'items', '--search', search_value]
|
||||
|
||||
if collection_id:
|
||||
params.extend(['--collectionid', collection_id])
|
||||
if organization_id:
|
||||
params.extend(['--organizationid', organization_id])
|
||||
|
||||
out, err = self._run(params)
|
||||
|
||||
# This includes things that matched in different fields.
|
||||
initial_matches = AnsibleJSONDecoder().raw_decode(out)[0]
|
||||
|
||||
if search_field == 'id':
|
||||
if initial_matches is None:
|
||||
initial_matches = []
|
||||
else:
|
||||
initial_matches = [initial_matches]
|
||||
|
||||
# Filter to only include results from the right field.
|
||||
return [item for item in initial_matches if not search_value or item[search_field] == search_value]
|
||||
return [item for item in initial_matches if item[search_field] == search_value]
|
||||
|
||||
def get_field(self, field, search_value, search_field="name", collection_id=None, organization_id=None):
|
||||
def get_field(self, field, search_value, search_field="name", collection_id=None):
|
||||
"""Return a list of the specified field for records whose search_field match search_value
|
||||
and filtered by collection if collection has been provided.
|
||||
|
||||
If field is None, return the whole record for each match.
|
||||
"""
|
||||
matches = self._get_matches(search_value, search_field, collection_id, organization_id)
|
||||
matches = self._get_matches(search_value, search_field, collection_id)
|
||||
if not field:
|
||||
return matches
|
||||
field_matches = []
|
||||
@@ -204,30 +167,22 @@ class Bitwarden(object):
|
||||
if field in match:
|
||||
field_matches.append(match[field])
|
||||
continue
|
||||
|
||||
if matches and not field_matches:
|
||||
raise AnsibleError("field {field} does not exist in {search_value}".format(field=field, search_value=search_value))
|
||||
|
||||
return field_matches
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
|
||||
def run(self, terms=None, variables=None, **kwargs):
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
field = self.get_option('field')
|
||||
search_field = self.get_option('search')
|
||||
collection_id = self.get_option('collection_id')
|
||||
organization_id = self.get_option('organization_id')
|
||||
_bitwarden.session = self.get_option('bw_session')
|
||||
|
||||
if not _bitwarden.unlocked:
|
||||
raise AnsibleError("Bitwarden Vault locked. Run 'bw unlock'.")
|
||||
|
||||
if not terms:
|
||||
terms = [None]
|
||||
|
||||
return [_bitwarden.get_field(field, term, search_field, collection_id, organization_id) for term in terms]
|
||||
return [_bitwarden.get_field(field, term, search_field, collection_id) for term in terms]
|
||||
|
||||
|
||||
_bitwarden = Bitwarden()
|
||||
|
||||
@@ -70,7 +70,6 @@ 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
|
||||
@@ -85,29 +84,11 @@ 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(f"Command failed with return code {rc}: {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)
|
||||
@@ -126,7 +107,7 @@ class BitwardenSecretsManager(object):
|
||||
'get', 'secret', secret_id
|
||||
]
|
||||
|
||||
out, err, rc = self._run_with_retry(params)
|
||||
out, err, rc = self._run(params)
|
||||
if rc != 0:
|
||||
raise BitwardenSecretsManagerException(to_text(err))
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ EXAMPLES = '''
|
||||
dest: /srv/checkout
|
||||
vars:
|
||||
github_token: >-
|
||||
lookup('community.general.github_app_access_token', key_path='/home/to_your/key',
|
||||
lookup('github_app_token', key_path='/home/to_your/key',
|
||||
app_id='123456', installation_id='64209')
|
||||
'''
|
||||
|
||||
|
||||
@@ -10,12 +10,11 @@ DOCUMENTATION = """
|
||||
author:
|
||||
- Roy Lenferink (@rlenferink)
|
||||
- Mark Ettema (@m-a-r-k-e)
|
||||
- Alexander Petrenz (@alpex8)
|
||||
name: merge_variables
|
||||
short_description: merge variables with a certain suffix
|
||||
description:
|
||||
- This lookup returns the merged result of all variables in scope that match the given prefixes, suffixes, or
|
||||
regular expressions, optionally.
|
||||
regular expressions, optionally.
|
||||
version_added: 6.5.0
|
||||
options:
|
||||
_terms:
|
||||
@@ -62,13 +61,6 @@ DOCUMENTATION = """
|
||||
ini:
|
||||
- section: merge_variables_lookup
|
||||
key: override
|
||||
groups:
|
||||
description:
|
||||
- Search for variables accross hosts that belong to the given groups. This allows to collect configuration pieces
|
||||
accross different hosts (for example a service on a host with its database on another host).
|
||||
type: list
|
||||
elements: str
|
||||
version_added: 8.5.0
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -139,41 +131,22 @@ def _verify_and_get_type(variable):
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
self.set_options(direct=kwargs)
|
||||
initial_value = self.get_option("initial_value", None)
|
||||
self._override = self.get_option('override', 'error')
|
||||
self._pattern_type = self.get_option('pattern_type', 'regex')
|
||||
self._groups = self.get_option('groups', None)
|
||||
|
||||
ret = []
|
||||
for term in terms:
|
||||
if not isinstance(term, str):
|
||||
raise AnsibleError("Non-string type '{0}' passed, only 'str' types are allowed!".format(type(term)))
|
||||
|
||||
if not self._groups: # consider only own variables
|
||||
ret.append(self._merge_vars(term, initial_value, variables))
|
||||
else: # consider variables of hosts in given groups
|
||||
cross_host_merge_result = initial_value
|
||||
for host in variables["hostvars"]:
|
||||
if self._is_host_in_allowed_groups(variables["hostvars"][host]["group_names"]):
|
||||
host_variables = dict(variables["hostvars"].raw_get(host))
|
||||
host_variables["hostvars"] = variables["hostvars"] # re-add hostvars
|
||||
cross_host_merge_result = self._merge_vars(term, cross_host_merge_result, host_variables)
|
||||
ret.append(cross_host_merge_result)
|
||||
ret.append(self._merge_vars(term, initial_value, variables))
|
||||
|
||||
return ret
|
||||
|
||||
def _is_host_in_allowed_groups(self, host_groups):
|
||||
if 'all' in self._groups:
|
||||
return True
|
||||
|
||||
group_intersection = [host_group_name for host_group_name in host_groups if host_group_name in self._groups]
|
||||
if group_intersection:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _var_matches(self, key, search_pattern):
|
||||
if self._pattern_type == "prefix":
|
||||
return key.startswith(search_pattern)
|
||||
@@ -189,6 +162,7 @@ class LookupModule(LookupBase):
|
||||
display.vvv("Merge variables with {0}: {1}".format(self._pattern_type, search_pattern))
|
||||
var_merge_names = sorted([key for key in variables.keys() if self._var_matches(key, search_pattern)])
|
||||
display.vvv("The following variables will be merged: {0}".format(var_merge_names))
|
||||
|
||||
prev_var_type = None
|
||||
result = None
|
||||
|
||||
@@ -197,8 +171,7 @@ class LookupModule(LookupBase):
|
||||
result = initial_value
|
||||
|
||||
for var_name in var_merge_names:
|
||||
with self._templar.set_temporary_context(available_variables=variables): # tmp. switch renderer to context of current variables
|
||||
var_value = self._templar.template(variables[var_name]) # Render jinja2 templates
|
||||
var_value = self._templar.template(variables[var_name]) # Render jinja2 templates
|
||||
var_type = _verify_and_get_type(var_value)
|
||||
|
||||
if prev_var_type is None:
|
||||
|
||||
@@ -489,10 +489,10 @@ class OnePassCLIv2(OnePassCLIBase):
|
||||
current_section_title = section.get("label", section.get("id", "")).lower()
|
||||
if section_title == current_section_title:
|
||||
# In the correct section. Check "label" then "id" for the desired field_name
|
||||
if field.get("label", "").lower() == field_name:
|
||||
if field.get("label") == field_name:
|
||||
return field.get("value", "")
|
||||
|
||||
if field.get("id", "").lower() == field_name:
|
||||
if field.get("id") == field_name:
|
||||
return field.get("value", "")
|
||||
|
||||
return ""
|
||||
|
||||
@@ -139,21 +139,6 @@ DOCUMENTATION = '''
|
||||
type: bool
|
||||
default: true
|
||||
version_added: 8.1.0
|
||||
missing_subkey:
|
||||
description:
|
||||
- Preference about what to do if the password subkey is missing.
|
||||
- If set to V(error), the lookup will error out if the subkey does not exist.
|
||||
- If set to V(empty) or V(warn), will return a V(none) in case the subkey does not exist.
|
||||
version_added: 8.6.0
|
||||
type: str
|
||||
default: empty
|
||||
choices:
|
||||
- error
|
||||
- warn
|
||||
- empty
|
||||
ini:
|
||||
- section: passwordstore_lookup
|
||||
key: missing_subkey
|
||||
notes:
|
||||
- The lookup supports passing all options as lookup parameters since community.general 6.0.0.
|
||||
'''
|
||||
@@ -162,7 +147,6 @@ ansible.cfg: |
|
||||
[passwordstore_lookup]
|
||||
lock=readwrite
|
||||
locktimeout=45s
|
||||
missing_subkey=warn
|
||||
|
||||
tasks.yml: |
|
||||
---
|
||||
@@ -448,20 +432,6 @@ class LookupModule(LookupBase):
|
||||
if self.paramvals['subkey'] in self.passdict:
|
||||
return self.passdict[self.paramvals['subkey']]
|
||||
else:
|
||||
if self.paramvals["missing_subkey"] == "error":
|
||||
raise AnsibleError(
|
||||
"passwordstore: subkey {0} for passname {1} not found and missing_subkey=error is set".format(
|
||||
self.paramvals["subkey"], self.passname
|
||||
)
|
||||
)
|
||||
|
||||
if self.paramvals["missing_subkey"] == "warn":
|
||||
display.warning(
|
||||
"passwordstore: subkey {0} for passname {1} not found".format(
|
||||
self.paramvals["subkey"], self.passname
|
||||
)
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
@contextmanager
|
||||
@@ -511,7 +481,6 @@ class LookupModule(LookupBase):
|
||||
'umask': self.get_option('umask'),
|
||||
'timestamp': self.get_option('timestamp'),
|
||||
'preserve': self.get_option('preserve'),
|
||||
"missing_subkey": self.get_option("missing_subkey"),
|
||||
}
|
||||
|
||||
def run(self, terms, variables, **kwargs):
|
||||
|
||||
@@ -100,7 +100,7 @@ class LookupModule(LookupBase):
|
||||
result = []
|
||||
for term in terms:
|
||||
try:
|
||||
display.vvv("Secret Server lookup of Secret with ID %s" % term)
|
||||
display.vvv(u"Secret Server lookup of Secret with ID %s" % term)
|
||||
result.append({term: secret_server.get_pam_secret(term)})
|
||||
except Exception as error:
|
||||
raise AnsibleError("Secret Server lookup failure: %s" % error.message)
|
||||
|
||||
@@ -129,15 +129,8 @@ class _Format(object):
|
||||
return _ArgFormat(lambda value: ["{0}={1}".format(arg, value)], ignore_none=ignore_none)
|
||||
|
||||
@staticmethod
|
||||
def as_list(ignore_none=None, min_len=0, max_len=None):
|
||||
def func(value):
|
||||
value = _ensure_list(value)
|
||||
if len(value) < min_len:
|
||||
raise ValueError("Parameter must have at least {0} element(s)".format(min_len))
|
||||
if max_len is not None and len(value) > max_len:
|
||||
raise ValueError("Parameter must have at most {0} element(s)".format(max_len))
|
||||
return value
|
||||
return _ArgFormat(func, ignore_none=ignore_none)
|
||||
def as_list(ignore_none=None):
|
||||
return _ArgFormat(_ensure_list, ignore_none=ignore_none)
|
||||
|
||||
@staticmethod
|
||||
def as_fixed(args):
|
||||
|
||||
@@ -277,7 +277,7 @@ class _ConsulModule:
|
||||
headers["X-Consul-Token"] = token
|
||||
|
||||
try:
|
||||
if data is not None:
|
||||
if data:
|
||||
data = json.dumps(data)
|
||||
headers["Content-Type"] = "application/json"
|
||||
if params:
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2023 Felix Fontein <felix@fontein.de>
|
||||
# Simplified BSD License (see LICENSES/BSD-2-Clause.txt or https://opensource.org/licenses/BSD-2-Clause)
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
import datetime as _datetime
|
||||
import sys
|
||||
|
||||
|
||||
_USE_TIMEZONE = sys.version_info >= (3, 6)
|
||||
|
||||
|
||||
def ensure_timezone_info(value):
|
||||
if not _USE_TIMEZONE or value.tzinfo is not None:
|
||||
return value
|
||||
return value.astimezone(_datetime.timezone.utc)
|
||||
|
||||
|
||||
def fromtimestamp(value):
|
||||
if _USE_TIMEZONE:
|
||||
return _datetime.fromtimestamp(value, tz=_datetime.timezone.utc)
|
||||
return _datetime.utcfromtimestamp(value)
|
||||
|
||||
|
||||
def now():
|
||||
if _USE_TIMEZONE:
|
||||
return _datetime.datetime.now(tz=_datetime.timezone.utc)
|
||||
return _datetime.datetime.utcnow()
|
||||
@@ -1,84 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2024, Alexei Znamensky <russoz@gmail.com>
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.cmd_runner import cmd_runner_fmt
|
||||
from ansible_collections.community.general.plugins.module_utils.python_runner import PythonRunner
|
||||
from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper
|
||||
|
||||
|
||||
django_std_args = dict(
|
||||
# environmental options
|
||||
venv=dict(type="path"),
|
||||
# default options of django-admin
|
||||
settings=dict(type="str", required=True),
|
||||
pythonpath=dict(type="path"),
|
||||
traceback=dict(type="bool"),
|
||||
verbosity=dict(type="int", choices=[0, 1, 2, 3]),
|
||||
skip_checks=dict(type="bool"),
|
||||
)
|
||||
|
||||
_django_std_arg_fmts = dict(
|
||||
command=cmd_runner_fmt.as_list(),
|
||||
settings=cmd_runner_fmt.as_opt_eq_val("--settings"),
|
||||
pythonpath=cmd_runner_fmt.as_opt_eq_val("--pythonpath"),
|
||||
traceback=cmd_runner_fmt.as_bool("--traceback"),
|
||||
verbosity=cmd_runner_fmt.as_opt_val("--verbosity"),
|
||||
no_color=cmd_runner_fmt.as_fixed("--no-color"),
|
||||
skip_checks=cmd_runner_fmt.as_bool("--skip-checks"),
|
||||
)
|
||||
|
||||
|
||||
class _DjangoRunner(PythonRunner):
|
||||
def __init__(self, module, arg_formats=None, **kwargs):
|
||||
arg_fmts = dict(arg_formats) if arg_formats else {}
|
||||
arg_fmts.update(_django_std_arg_fmts)
|
||||
|
||||
super(_DjangoRunner, self).__init__(module, ["-m", "django"], arg_formats=arg_fmts, **kwargs)
|
||||
|
||||
def __call__(self, output_process=None, ignore_value_none=True, check_mode_skip=False, check_mode_return=None, **kwargs):
|
||||
args_order = (
|
||||
("command", "no_color", "settings", "pythonpath", "traceback", "verbosity", "skip_checks") + self._prepare_args_order(self.default_args_order)
|
||||
)
|
||||
return super(_DjangoRunner, self).__call__(args_order, output_process, ignore_value_none, check_mode_skip, check_mode_return, **kwargs)
|
||||
|
||||
|
||||
class DjangoModuleHelper(ModuleHelper):
|
||||
module = {}
|
||||
use_old_vardict = False
|
||||
django_admin_cmd = None
|
||||
arg_formats = {}
|
||||
django_admin_arg_order = ()
|
||||
|
||||
def __init__(self):
|
||||
argument_spec = dict(django_std_args)
|
||||
argument_spec.update(self.module.get("argument_spec", {}))
|
||||
self.module["argument_spec"] = argument_spec
|
||||
super(DjangoModuleHelper, self).__init__(self.module)
|
||||
if self.django_admin_cmd is not None:
|
||||
self.vars.command = self.django_admin_cmd
|
||||
|
||||
def __run__(self):
|
||||
runner = _DjangoRunner(self.module,
|
||||
default_args_order=self.django_admin_arg_order,
|
||||
arg_formats=self.arg_formats,
|
||||
venv=self.vars.venv,
|
||||
check_rc=True)
|
||||
with runner() as ctx:
|
||||
results = ctx.run()
|
||||
self.vars.stdout = ctx.results_out
|
||||
self.vars.stderr = ctx.results_err
|
||||
self.vars.cmd = ctx.cmd
|
||||
if self.verbosity >= 3:
|
||||
self.vars.run_info = ctx.run_info
|
||||
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def execute(cls):
|
||||
cls().run()
|
||||
@@ -33,7 +33,6 @@ class GandiLiveDNSAPI(object):
|
||||
def __init__(self, module):
|
||||
self.module = module
|
||||
self.api_key = module.params['api_key']
|
||||
self.personal_access_token = module.params['personal_access_token']
|
||||
|
||||
def _build_error_message(self, module, info):
|
||||
s = ''
|
||||
@@ -51,12 +50,7 @@ class GandiLiveDNSAPI(object):
|
||||
return s
|
||||
|
||||
def _gandi_api_call(self, api_call, method='GET', payload=None, error_on_404=True):
|
||||
authorization_header = (
|
||||
'Bearer {0}'.format(self.personal_access_token)
|
||||
if self.personal_access_token
|
||||
else 'Apikey {0}'.format(self.api_key)
|
||||
)
|
||||
headers = {'Authorization': authorization_header,
|
||||
headers = {'Authorization': 'Apikey {0}'.format(self.api_key),
|
||||
'Content-Type': 'application/json'}
|
||||
data = None
|
||||
if payload:
|
||||
|
||||
@@ -21,30 +21,15 @@ 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):
|
||||
@@ -81,23 +66,16 @@ def find_group(gitlab_instance, identifier):
|
||||
return group
|
||||
|
||||
|
||||
def ensure_gitlab_package(module, min_version=None):
|
||||
def ensure_gitlab_package(module):
|
||||
if not HAS_GITLAB_PACKAGE:
|
||||
module.fail_json(
|
||||
msg=missing_required_lib("python-gitlab", url='https://python-gitlab.readthedocs.io/en/stable/'),
|
||||
exception=GITLAB_IMP_ERR
|
||||
)
|
||||
gitlab_version = gitlab.__version__
|
||||
if min_version is not None and LooseVersion(gitlab_version) < LooseVersion(min_version):
|
||||
module.fail_json(
|
||||
msg="This module requires python-gitlab Python module >= %s "
|
||||
"(installed version: %s). Please upgrade python-gitlab to version %s or above."
|
||||
% (min_version, gitlab_version, min_version)
|
||||
)
|
||||
|
||||
|
||||
def gitlab_authentication(module, min_version=None):
|
||||
ensure_gitlab_package(module, min_version=min_version)
|
||||
def gitlab_authentication(module):
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
gitlab_url = module.params['api_url']
|
||||
validate_certs = module.params['validate_certs']
|
||||
@@ -115,11 +93,6 @@ def gitlab_authentication(module, min_version=None):
|
||||
# Changelog : https://github.com/python-gitlab/python-gitlab/releases/tag/v1.13.0
|
||||
# This condition allow to still support older version of the python-gitlab library
|
||||
if LooseVersion(gitlab.__version__) < LooseVersion("1.13.0"):
|
||||
module.deprecate(
|
||||
"GitLab basic auth is deprecated and will be removed in next major version, "
|
||||
"using another auth method (API token or OAuth) is strongly recommended.",
|
||||
version='10.0.0',
|
||||
collection_name='community.general')
|
||||
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=verify, email=gitlab_user, password=gitlab_password,
|
||||
private_token=gitlab_token, api_version=4)
|
||||
else:
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) Ansible project
|
||||
# Simplified BSD License (see LICENSES/BSD-2-Clause.txt or https://opensource.org/licenses/BSD-2-Clause)
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
import os
|
||||
import re
|
||||
from ansible.module_utils.six import string_types
|
||||
|
||||
|
||||
def _create_regex_group_complement(s):
|
||||
lines = (line.strip() for line in s.split("\n") if line.strip())
|
||||
chars = filter(None, (line.split("#")[0].strip() for line in lines))
|
||||
group = r"[^" + r"".join(chars) + r"]"
|
||||
return re.compile(group)
|
||||
|
||||
|
||||
class HomebrewValidate(object):
|
||||
# class regexes ------------------------------------------------ {{{
|
||||
VALID_PATH_CHARS = r"""
|
||||
\w # alphanumeric characters (i.e., [a-zA-Z0-9_])
|
||||
\s # spaces
|
||||
: # colons
|
||||
{sep} # the OS-specific path separator
|
||||
. # dots
|
||||
\- # dashes
|
||||
""".format(
|
||||
sep=os.path.sep
|
||||
)
|
||||
|
||||
VALID_BREW_PATH_CHARS = r"""
|
||||
\w # alphanumeric characters (i.e., [a-zA-Z0-9_])
|
||||
\s # spaces
|
||||
{sep} # the OS-specific path separator
|
||||
. # dots
|
||||
\- # dashes
|
||||
""".format(
|
||||
sep=os.path.sep
|
||||
)
|
||||
|
||||
VALID_PACKAGE_CHARS = r"""
|
||||
\w # alphanumeric characters (i.e., [a-zA-Z0-9_])
|
||||
. # dots
|
||||
/ # slash (for taps)
|
||||
\+ # plusses
|
||||
\- # dashes
|
||||
: # colons (for URLs)
|
||||
@ # at-sign
|
||||
"""
|
||||
|
||||
INVALID_PATH_REGEX = _create_regex_group_complement(VALID_PATH_CHARS)
|
||||
INVALID_BREW_PATH_REGEX = _create_regex_group_complement(VALID_BREW_PATH_CHARS)
|
||||
INVALID_PACKAGE_REGEX = _create_regex_group_complement(VALID_PACKAGE_CHARS)
|
||||
# /class regexes ----------------------------------------------- }}}
|
||||
|
||||
# class validations -------------------------------------------- {{{
|
||||
@classmethod
|
||||
def valid_path(cls, path):
|
||||
"""
|
||||
`path` must be one of:
|
||||
- list of paths
|
||||
- a string containing only:
|
||||
- alphanumeric characters
|
||||
- dashes
|
||||
- dots
|
||||
- spaces
|
||||
- colons
|
||||
- os.path.sep
|
||||
"""
|
||||
|
||||
if isinstance(path, string_types):
|
||||
return not cls.INVALID_PATH_REGEX.search(path)
|
||||
|
||||
try:
|
||||
iter(path)
|
||||
except TypeError:
|
||||
return False
|
||||
else:
|
||||
paths = path
|
||||
return all(cls.valid_brew_path(path_) for path_ in paths)
|
||||
|
||||
@classmethod
|
||||
def valid_brew_path(cls, brew_path):
|
||||
"""
|
||||
`brew_path` must be one of:
|
||||
- None
|
||||
- a string containing only:
|
||||
- alphanumeric characters
|
||||
- dashes
|
||||
- dots
|
||||
- spaces
|
||||
- os.path.sep
|
||||
"""
|
||||
|
||||
if brew_path is None:
|
||||
return True
|
||||
|
||||
return isinstance(
|
||||
brew_path, string_types
|
||||
) and not cls.INVALID_BREW_PATH_REGEX.search(brew_path)
|
||||
|
||||
@classmethod
|
||||
def valid_package(cls, package):
|
||||
"""A valid package is either None or alphanumeric."""
|
||||
|
||||
if package is None:
|
||||
return True
|
||||
|
||||
return isinstance(
|
||||
package, string_types
|
||||
) and not cls.INVALID_PACKAGE_REGEX.search(package)
|
||||
@@ -28,9 +28,6 @@ URL_CLIENT_ROLES = "{url}/admin/realms/{realm}/clients/{id}/roles"
|
||||
URL_CLIENT_ROLE = "{url}/admin/realms/{realm}/clients/{id}/roles/{name}"
|
||||
URL_CLIENT_ROLE_COMPOSITES = "{url}/admin/realms/{realm}/clients/{id}/roles/{name}/composites"
|
||||
|
||||
URL_CLIENT_ROLE_SCOPE_CLIENTS = "{url}/admin/realms/{realm}/clients/{id}/scope-mappings/clients/{scopeid}"
|
||||
URL_CLIENT_ROLE_SCOPE_REALM = "{url}/admin/realms/{realm}/clients/{id}/scope-mappings/realm"
|
||||
|
||||
URL_REALM_ROLES = "{url}/admin/realms/{realm}/roles"
|
||||
URL_REALM_ROLE = "{url}/admin/realms/{realm}/roles/{name}"
|
||||
URL_REALM_ROLEMAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappings/realm"
|
||||
@@ -3052,105 +3049,6 @@ class KeycloakAPI(object):
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def get_client_role_scope_from_client(self, clientid, clientscopeid, realm="master"):
|
||||
""" Fetch the roles associated with the client's scope for a specific client on the Keycloak server.
|
||||
:param clientid: ID of the client from which to obtain the associated roles.
|
||||
:param clientscopeid: ID of the client who owns the roles.
|
||||
:param realm: Realm from which to obtain the scope.
|
||||
:return: The client scope of roles from specified client.
|
||||
"""
|
||||
client_role_scope_url = URL_CLIENT_ROLE_SCOPE_CLIENTS.format(url=self.baseurl, realm=realm, id=clientid, scopeid=clientscopeid)
|
||||
try:
|
||||
return json.loads(to_native(open_url(client_role_scope_url, method='GET', http_agent=self.http_agent, headers=self.restheaders,
|
||||
timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
except Exception as e:
|
||||
self.fail_open_url(e, msg='Could not fetch roles scope for client %s in realm %s: %s' % (clientid, realm, str(e)))
|
||||
|
||||
def update_client_role_scope_from_client(self, payload, clientid, clientscopeid, realm="master"):
|
||||
""" Update and fetch the roles associated with the client's scope on the Keycloak server.
|
||||
:param payload: List of roles to be added to the scope.
|
||||
:param clientid: ID of the client to update scope.
|
||||
:param clientscopeid: ID of the client who owns the roles.
|
||||
:param realm: Realm from which to obtain the clients.
|
||||
:return: The client scope of roles from specified client.
|
||||
"""
|
||||
client_role_scope_url = URL_CLIENT_ROLE_SCOPE_CLIENTS.format(url=self.baseurl, realm=realm, id=clientid, scopeid=clientscopeid)
|
||||
try:
|
||||
open_url(client_role_scope_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(payload), validate_certs=self.validate_certs)
|
||||
|
||||
except Exception as e:
|
||||
self.fail_open_url(e, msg='Could not update roles scope for client %s in realm %s: %s' % (clientid, realm, str(e)))
|
||||
|
||||
return self.get_client_role_scope_from_client(clientid, clientscopeid, realm)
|
||||
|
||||
def delete_client_role_scope_from_client(self, payload, clientid, clientscopeid, realm="master"):
|
||||
""" Delete the roles contains in the payload from the client's scope on the Keycloak server.
|
||||
:param payload: List of roles to be deleted.
|
||||
:param clientid: ID of the client to delete roles from scope.
|
||||
:param clientscopeid: ID of the client who owns the roles.
|
||||
:param realm: Realm from which to obtain the clients.
|
||||
:return: The client scope of roles from specified client.
|
||||
"""
|
||||
client_role_scope_url = URL_CLIENT_ROLE_SCOPE_CLIENTS.format(url=self.baseurl, realm=realm, id=clientid, scopeid=clientscopeid)
|
||||
try:
|
||||
open_url(client_role_scope_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(payload), validate_certs=self.validate_certs)
|
||||
|
||||
except Exception as e:
|
||||
self.fail_open_url(e, msg='Could not delete roles scope for client %s in realm %s: %s' % (clientid, realm, str(e)))
|
||||
|
||||
return self.get_client_role_scope_from_client(clientid, clientscopeid, realm)
|
||||
|
||||
def get_client_role_scope_from_realm(self, clientid, realm="master"):
|
||||
""" Fetch the realm roles from the client's scope on the Keycloak server.
|
||||
:param clientid: ID of the client from which to obtain the associated realm roles.
|
||||
:param realm: Realm from which to obtain the clients.
|
||||
:return: The client realm roles scope.
|
||||
"""
|
||||
client_role_scope_url = URL_CLIENT_ROLE_SCOPE_REALM.format(url=self.baseurl, realm=realm, id=clientid)
|
||||
try:
|
||||
return json.loads(to_native(open_url(client_role_scope_url, method='GET', http_agent=self.http_agent, headers=self.restheaders,
|
||||
timeout=self.connection_timeout,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
except Exception as e:
|
||||
self.fail_open_url(e, msg='Could not fetch roles scope for client %s in realm %s: %s' % (clientid, realm, str(e)))
|
||||
|
||||
def update_client_role_scope_from_realm(self, payload, clientid, realm="master"):
|
||||
""" Update and fetch the realm roles from the client's scope on the Keycloak server.
|
||||
:param payload: List of realm roles to add.
|
||||
:param clientid: ID of the client to update scope.
|
||||
:param realm: Realm from which to obtain the clients.
|
||||
:return: The client realm roles scope.
|
||||
"""
|
||||
client_role_scope_url = URL_CLIENT_ROLE_SCOPE_REALM.format(url=self.baseurl, realm=realm, id=clientid)
|
||||
try:
|
||||
open_url(client_role_scope_url, method='POST', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(payload), validate_certs=self.validate_certs)
|
||||
|
||||
except Exception as e:
|
||||
self.fail_open_url(e, msg='Could not update roles scope for client %s in realm %s: %s' % (clientid, realm, str(e)))
|
||||
|
||||
return self.get_client_role_scope_from_realm(clientid, realm)
|
||||
|
||||
def delete_client_role_scope_from_realm(self, payload, clientid, realm="master"):
|
||||
""" Delete the realm roles contains in the payload from the client's scope on the Keycloak server.
|
||||
:param payload: List of realm roles to delete.
|
||||
:param clientid: ID of the client to delete roles from scope.
|
||||
:param realm: Realm from which to obtain the clients.
|
||||
:return: The client realm roles scope.
|
||||
"""
|
||||
client_role_scope_url = URL_CLIENT_ROLE_SCOPE_REALM.format(url=self.baseurl, realm=realm, id=clientid)
|
||||
try:
|
||||
open_url(client_role_scope_url, method='DELETE', http_agent=self.http_agent, headers=self.restheaders, timeout=self.connection_timeout,
|
||||
data=json.dumps(payload), validate_certs=self.validate_certs)
|
||||
|
||||
except Exception as e:
|
||||
self.fail_open_url(e, msg='Could not delete roles scope for client %s in realm %s: %s' % (clientid, realm, str(e)))
|
||||
|
||||
return self.get_client_role_scope_from_realm(clientid, realm)
|
||||
|
||||
def fail_open_url(self, e, msg, **kwargs):
|
||||
try:
|
||||
if isinstance(e, HTTPError):
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
import traceback
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.base import ModuleHelperBase
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.deco import module_fails_on_exception
|
||||
|
||||
|
||||
class DependencyCtxMgr(object):
|
||||
"""
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 11.0.0
|
||||
Modules should use plugins/module_utils/deps.py instead.
|
||||
"""
|
||||
def __init__(self, name, msg=None):
|
||||
self.name = name
|
||||
self.msg = msg
|
||||
@@ -36,3 +35,39 @@ class DependencyCtxMgr(object):
|
||||
@property
|
||||
def text(self):
|
||||
return self.msg or str(self.exc_val)
|
||||
|
||||
|
||||
class DependencyMixin(ModuleHelperBase):
|
||||
"""
|
||||
THIS CLASS IS BEING DEPRECATED.
|
||||
See the deprecation notice in ``DependencyMixin.fail_on_missing_deps()`` below.
|
||||
|
||||
Mixin for mapping module options to running a CLI command with its arguments.
|
||||
"""
|
||||
_dependencies = []
|
||||
|
||||
@classmethod
|
||||
def dependency(cls, name, msg):
|
||||
cls._dependencies.append(DependencyCtxMgr(name, msg))
|
||||
return cls._dependencies[-1]
|
||||
|
||||
def fail_on_missing_deps(self):
|
||||
if not self._dependencies:
|
||||
return
|
||||
self.module.deprecate(
|
||||
'The DependencyMixin is being deprecated. '
|
||||
'Modules should use community.general.plugins.module_utils.deps instead.',
|
||||
version='9.0.0',
|
||||
collection_name='community.general',
|
||||
)
|
||||
for d in self._dependencies:
|
||||
if not d.has_it:
|
||||
self.module.fail_json(changed=False,
|
||||
exception="\n".join(traceback.format_exception(d.exc_type, d.exc_val, d.exc_tb)),
|
||||
msg=d.text,
|
||||
**self.output)
|
||||
|
||||
@module_fails_on_exception
|
||||
def run(self):
|
||||
self.fail_on_missing_deps()
|
||||
super(DependencyMixin, self).run()
|
||||
|
||||
@@ -14,7 +14,7 @@ class VarMeta(object):
|
||||
"""
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 11.0.0
|
||||
This class is deprecated and will be removed in community.general 10.0.0
|
||||
Modules should use the VarDict from plugins/module_utils/vardict.py instead.
|
||||
"""
|
||||
|
||||
@@ -70,7 +70,7 @@ class VarDict(object):
|
||||
"""
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 11.0.0
|
||||
This class is deprecated and will be removed in community.general 10.0.0
|
||||
Modules should use the VarDict from plugins/module_utils/vardict.py instead.
|
||||
"""
|
||||
def __init__(self):
|
||||
@@ -139,7 +139,7 @@ class VarsMixin(object):
|
||||
"""
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 11.0.0
|
||||
This class is deprecated and will be removed in community.general 10.0.0
|
||||
Modules should use the VarDict from plugins/module_utils/vardict.py instead.
|
||||
"""
|
||||
def __init__(self, module=None):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) 2020-2024, Alexei Znamensky <russoz@gmail.com>
|
||||
# Copyright (c) 2020-2024, Ansible Project
|
||||
# (c) 2020, Alexei Znamensky <russoz@gmail.com>
|
||||
# Copyright (c) 2020, Ansible Project
|
||||
# Simplified BSD License (see LICENSES/BSD-2-Clause.txt or https://opensource.org/licenses/BSD-2-Clause)
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
@@ -10,40 +10,23 @@ __metaclass__ = type
|
||||
|
||||
from ansible.module_utils.common.dict_transformations import dict_merge
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.vardict import VarDict as _NewVarDict # remove "as NewVarDict" in 11.0.0
|
||||
# (TODO: remove AnsibleModule!) pylint: disable-next=unused-import
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.base import AnsibleModule # noqa: F401 DEPRECATED, remove in 11.0.0
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.base import ModuleHelperBase
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.base import ModuleHelperBase, AnsibleModule # noqa: F401
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.mixins.state import StateMixin
|
||||
# (TODO: remove mh.mixins.vars!) pylint: disable-next=unused-import
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarsMixin, VarDict as _OldVarDict # noqa: F401 remove in 11.0.0
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.mixins.deps import DependencyMixin
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarsMixin
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.mixins.deprecate_attrs import DeprecateAttrsMixin
|
||||
|
||||
|
||||
class ModuleHelper(DeprecateAttrsMixin, ModuleHelperBase):
|
||||
class ModuleHelper(DeprecateAttrsMixin, VarsMixin, DependencyMixin, ModuleHelperBase):
|
||||
facts_name = None
|
||||
output_params = ()
|
||||
diff_params = ()
|
||||
change_params = ()
|
||||
facts_params = ()
|
||||
use_old_vardict = True # remove in 11.0.0
|
||||
mute_vardict_deprecation = False
|
||||
|
||||
def __init__(self, module=None):
|
||||
if self.use_old_vardict: # remove first half of the if in 11.0.0
|
||||
self.vars = _OldVarDict()
|
||||
super(ModuleHelper, self).__init__(module)
|
||||
if not self.mute_vardict_deprecation:
|
||||
self.module.deprecate(
|
||||
"This class is using the old VarDict from ModuleHelper, which is deprecated. "
|
||||
"Set the class variable use_old_vardict to False and make the necessary adjustments."
|
||||
"The old VarDict class will be removed in community.general 11.0.0",
|
||||
version="11.0.0", collection_name="community.general"
|
||||
)
|
||||
else:
|
||||
self.vars = _NewVarDict()
|
||||
super(ModuleHelper, self).__init__(module)
|
||||
|
||||
super(ModuleHelper, self).__init__(module)
|
||||
for name, value in self.module.params.items():
|
||||
self.vars.set(
|
||||
name, value,
|
||||
@@ -53,12 +36,6 @@ class ModuleHelper(DeprecateAttrsMixin, ModuleHelperBase):
|
||||
fact=name in self.facts_params,
|
||||
)
|
||||
|
||||
def update_vars(self, meta=None, **kwargs):
|
||||
if meta is None:
|
||||
meta = {}
|
||||
for k, v in kwargs.items():
|
||||
self.vars.set(k, v, **meta)
|
||||
|
||||
def update_output(self, **kwargs):
|
||||
self.update_vars(meta={"output": True}, **kwargs)
|
||||
|
||||
@@ -66,10 +43,7 @@ class ModuleHelper(DeprecateAttrsMixin, ModuleHelperBase):
|
||||
self.update_vars(meta={"fact": True}, **kwargs)
|
||||
|
||||
def _vars_changed(self):
|
||||
if self.use_old_vardict:
|
||||
return any(self.vars.has_changed(v) for v in self.vars.change_vars())
|
||||
|
||||
return self.vars.has_changed
|
||||
return any(self.vars.has_changed(v) for v in self.vars.change_vars())
|
||||
|
||||
def has_changed(self):
|
||||
return self.changed or self._vars_changed()
|
||||
|
||||
@@ -9,14 +9,14 @@ __metaclass__ = type
|
||||
|
||||
# pylint: disable=unused-import
|
||||
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.module_helper import (
|
||||
ModuleHelper, StateModuleHelper,
|
||||
AnsibleModule # remove in 11.0.0
|
||||
ModuleHelper, StateModuleHelper, AnsibleModule
|
||||
)
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.mixins.state import StateMixin # noqa: F401 remove in 11.0.0
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.mixins.deps import DependencyCtxMgr # noqa: F401 remove in 11.0.0
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.mixins.state import StateMixin # noqa: F401
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.mixins.deps import DependencyCtxMgr, DependencyMixin # noqa: F401
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.exceptions import ModuleHelperException # noqa: F401
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.deco import (
|
||||
cause_changes, module_fails_on_exception, check_mode_skip, check_mode_skip_returns,
|
||||
)
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarMeta, VarDict, VarsMixin # noqa: F401 remove in 11.0.0
|
||||
from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarMeta, VarDict, VarsMixin # noqa: F401
|
||||
|
||||
@@ -103,11 +103,9 @@ def puppet_runner(module):
|
||||
modulepath=cmd_runner_fmt.as_opt_eq_val("--modulepath"),
|
||||
_execute=cmd_runner_fmt.as_func(execute_func),
|
||||
summarize=cmd_runner_fmt.as_bool("--summarize"),
|
||||
waitforlock=cmd_runner_fmt.as_opt_val("--waitforlock"),
|
||||
debug=cmd_runner_fmt.as_bool("--debug"),
|
||||
verbose=cmd_runner_fmt.as_bool("--verbose"),
|
||||
),
|
||||
check_rc=False,
|
||||
force_lang=module.params["environment_lang"],
|
||||
)
|
||||
return runner
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2024, Alexei Znamensky <russoz@gmail.com>
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
import os
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, _ensure_list
|
||||
|
||||
|
||||
class PythonRunner(CmdRunner):
|
||||
def __init__(self, module, command, arg_formats=None, default_args_order=(),
|
||||
check_rc=False, force_lang="C", path_prefix=None, environ_update=None,
|
||||
python="python", venv=None):
|
||||
self.python = python
|
||||
self.venv = venv
|
||||
self.has_venv = venv is not None
|
||||
|
||||
if (os.path.isabs(python) or '/' in python):
|
||||
self.python = python
|
||||
elif self.has_venv:
|
||||
path_prefix = os.path.join(venv, "bin")
|
||||
if environ_update is None:
|
||||
environ_update = {}
|
||||
environ_update["PATH"] = "%s:%s" % (path_prefix, os.environ["PATH"])
|
||||
environ_update["VIRTUAL_ENV"] = venv
|
||||
|
||||
python_cmd = [self.python] + _ensure_list(command)
|
||||
|
||||
super(PythonRunner, self).__init__(module, python_cmd, arg_formats, default_args_order,
|
||||
check_rc, force_lang, path_prefix, environ_update)
|
||||
334
plugins/module_utils/rax.py
Normal file
334
plugins/module_utils/rax.py
Normal file
@@ -0,0 +1,334 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# This code is part of Ansible, but is an independent component.
|
||||
# This particular file snippet, and this file snippet only, is BSD licensed.
|
||||
# Modules you write using this snippet, which is embedded dynamically by
|
||||
# Ansible still belong to the author of the module, and may assign their own
|
||||
# license to the complete work.
|
||||
#
|
||||
# Copyright (c), Michael DeHaan <michael.dehaan@gmail.com>, 2012-2013
|
||||
#
|
||||
# Simplified BSD License (see LICENSES/BSD-2-Clause.txt or https://opensource.org/licenses/BSD-2-Clause)
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
import os
|
||||
import re
|
||||
from uuid import UUID
|
||||
|
||||
from ansible.module_utils.six import text_type, binary_type
|
||||
|
||||
FINAL_STATUSES = ('ACTIVE', 'ERROR')
|
||||
VOLUME_STATUS = ('available', 'attaching', 'creating', 'deleting', 'in-use',
|
||||
'error', 'error_deleting')
|
||||
|
||||
CLB_ALGORITHMS = ['RANDOM', 'LEAST_CONNECTIONS', 'ROUND_ROBIN',
|
||||
'WEIGHTED_LEAST_CONNECTIONS', 'WEIGHTED_ROUND_ROBIN']
|
||||
CLB_PROTOCOLS = ['DNS_TCP', 'DNS_UDP', 'FTP', 'HTTP', 'HTTPS', 'IMAPS',
|
||||
'IMAPv4', 'LDAP', 'LDAPS', 'MYSQL', 'POP3', 'POP3S', 'SMTP',
|
||||
'TCP', 'TCP_CLIENT_FIRST', 'UDP', 'UDP_STREAM', 'SFTP']
|
||||
|
||||
NON_CALLABLES = (text_type, binary_type, bool, dict, int, list, type(None))
|
||||
PUBLIC_NET_ID = "00000000-0000-0000-0000-000000000000"
|
||||
SERVICE_NET_ID = "11111111-1111-1111-1111-111111111111"
|
||||
|
||||
|
||||
def rax_slugify(value):
|
||||
"""Prepend a key with rax_ and normalize the key name"""
|
||||
return 'rax_%s' % (re.sub(r'[^\w-]', '_', value).lower().lstrip('_'))
|
||||
|
||||
|
||||
def rax_clb_node_to_dict(obj):
|
||||
"""Function to convert a CLB Node object to a dict"""
|
||||
if not obj:
|
||||
return {}
|
||||
node = obj.to_dict()
|
||||
node['id'] = obj.id
|
||||
node['weight'] = obj.weight
|
||||
return node
|
||||
|
||||
|
||||
def rax_to_dict(obj, obj_type='standard'):
|
||||
"""Generic function to convert a pyrax object to a dict
|
||||
|
||||
obj_type values:
|
||||
standard
|
||||
clb
|
||||
server
|
||||
|
||||
"""
|
||||
instance = {}
|
||||
for key in dir(obj):
|
||||
value = getattr(obj, key)
|
||||
if obj_type == 'clb' and key == 'nodes':
|
||||
instance[key] = []
|
||||
for node in value:
|
||||
instance[key].append(rax_clb_node_to_dict(node))
|
||||
elif (isinstance(value, list) and len(value) > 0 and
|
||||
not isinstance(value[0], NON_CALLABLES)):
|
||||
instance[key] = []
|
||||
for item in value:
|
||||
instance[key].append(rax_to_dict(item))
|
||||
elif (isinstance(value, NON_CALLABLES) and not key.startswith('_')):
|
||||
if obj_type == 'server':
|
||||
if key == 'image':
|
||||
if not value:
|
||||
instance['rax_boot_source'] = 'volume'
|
||||
else:
|
||||
instance['rax_boot_source'] = 'local'
|
||||
key = rax_slugify(key)
|
||||
instance[key] = value
|
||||
|
||||
if obj_type == 'server':
|
||||
for attr in ['id', 'accessIPv4', 'name', 'status']:
|
||||
instance[attr] = instance.get(rax_slugify(attr))
|
||||
|
||||
return instance
|
||||
|
||||
|
||||
def rax_find_bootable_volume(module, rax_module, server, exit=True):
|
||||
"""Find a servers bootable volume"""
|
||||
cs = rax_module.cloudservers
|
||||
cbs = rax_module.cloud_blockstorage
|
||||
server_id = rax_module.utils.get_id(server)
|
||||
volumes = cs.volumes.get_server_volumes(server_id)
|
||||
bootable_volumes = []
|
||||
for volume in volumes:
|
||||
vol = cbs.get(volume)
|
||||
if module.boolean(vol.bootable):
|
||||
bootable_volumes.append(vol)
|
||||
if not bootable_volumes:
|
||||
if exit:
|
||||
module.fail_json(msg='No bootable volumes could be found for '
|
||||
'server %s' % server_id)
|
||||
else:
|
||||
return False
|
||||
elif len(bootable_volumes) > 1:
|
||||
if exit:
|
||||
module.fail_json(msg='Multiple bootable volumes found for server '
|
||||
'%s' % server_id)
|
||||
else:
|
||||
return False
|
||||
|
||||
return bootable_volumes[0]
|
||||
|
||||
|
||||
def rax_find_image(module, rax_module, image, exit=True):
|
||||
"""Find a server image by ID or Name"""
|
||||
cs = rax_module.cloudservers
|
||||
try:
|
||||
UUID(image)
|
||||
except ValueError:
|
||||
try:
|
||||
image = cs.images.find(human_id=image)
|
||||
except (cs.exceptions.NotFound, cs.exceptions.NoUniqueMatch):
|
||||
try:
|
||||
image = cs.images.find(name=image)
|
||||
except (cs.exceptions.NotFound,
|
||||
cs.exceptions.NoUniqueMatch):
|
||||
if exit:
|
||||
module.fail_json(msg='No matching image found (%s)' %
|
||||
image)
|
||||
else:
|
||||
return False
|
||||
|
||||
return rax_module.utils.get_id(image)
|
||||
|
||||
|
||||
def rax_find_volume(module, rax_module, name):
|
||||
"""Find a Block storage volume by ID or name"""
|
||||
cbs = rax_module.cloud_blockstorage
|
||||
try:
|
||||
UUID(name)
|
||||
volume = cbs.get(name)
|
||||
except ValueError:
|
||||
try:
|
||||
volume = cbs.find(name=name)
|
||||
except rax_module.exc.NotFound:
|
||||
volume = None
|
||||
except Exception as e:
|
||||
module.fail_json(msg='%s' % e)
|
||||
return volume
|
||||
|
||||
|
||||
def rax_find_network(module, rax_module, network):
|
||||
"""Find a cloud network by ID or name"""
|
||||
cnw = rax_module.cloud_networks
|
||||
try:
|
||||
UUID(network)
|
||||
except ValueError:
|
||||
if network.lower() == 'public':
|
||||
return cnw.get_server_networks(PUBLIC_NET_ID)
|
||||
elif network.lower() == 'private':
|
||||
return cnw.get_server_networks(SERVICE_NET_ID)
|
||||
else:
|
||||
try:
|
||||
network_obj = cnw.find_network_by_label(network)
|
||||
except (rax_module.exceptions.NetworkNotFound,
|
||||
rax_module.exceptions.NetworkLabelNotUnique):
|
||||
module.fail_json(msg='No matching network found (%s)' %
|
||||
network)
|
||||
else:
|
||||
return cnw.get_server_networks(network_obj)
|
||||
else:
|
||||
return cnw.get_server_networks(network)
|
||||
|
||||
|
||||
def rax_find_server(module, rax_module, server):
|
||||
"""Find a Cloud Server by ID or name"""
|
||||
cs = rax_module.cloudservers
|
||||
try:
|
||||
UUID(server)
|
||||
server = cs.servers.get(server)
|
||||
except ValueError:
|
||||
servers = cs.servers.list(search_opts=dict(name='^%s$' % server))
|
||||
if not servers:
|
||||
module.fail_json(msg='No Server was matched by name, '
|
||||
'try using the Server ID instead')
|
||||
if len(servers) > 1:
|
||||
module.fail_json(msg='Multiple servers matched by name, '
|
||||
'try using the Server ID instead')
|
||||
|
||||
# We made it this far, grab the first and hopefully only server
|
||||
# in the list
|
||||
server = servers[0]
|
||||
return server
|
||||
|
||||
|
||||
def rax_find_loadbalancer(module, rax_module, loadbalancer):
|
||||
"""Find a Cloud Load Balancer by ID or name"""
|
||||
clb = rax_module.cloud_loadbalancers
|
||||
try:
|
||||
found = clb.get(loadbalancer)
|
||||
except Exception:
|
||||
found = []
|
||||
for lb in clb.list():
|
||||
if loadbalancer == lb.name:
|
||||
found.append(lb)
|
||||
|
||||
if not found:
|
||||
module.fail_json(msg='No loadbalancer was matched')
|
||||
|
||||
if len(found) > 1:
|
||||
module.fail_json(msg='Multiple loadbalancers matched')
|
||||
|
||||
# We made it this far, grab the first and hopefully only item
|
||||
# in the list
|
||||
found = found[0]
|
||||
|
||||
return found
|
||||
|
||||
|
||||
def rax_argument_spec():
|
||||
"""Return standard base dictionary used for the argument_spec
|
||||
argument in AnsibleModule
|
||||
|
||||
"""
|
||||
return dict(
|
||||
api_key=dict(type='str', aliases=['password'], no_log=True),
|
||||
auth_endpoint=dict(type='str'),
|
||||
credentials=dict(type='path', aliases=['creds_file']),
|
||||
env=dict(type='str'),
|
||||
identity_type=dict(type='str', default='rackspace'),
|
||||
region=dict(type='str'),
|
||||
tenant_id=dict(type='str'),
|
||||
tenant_name=dict(type='str'),
|
||||
username=dict(type='str'),
|
||||
validate_certs=dict(type='bool', aliases=['verify_ssl']),
|
||||
)
|
||||
|
||||
|
||||
def rax_required_together():
|
||||
"""Return the default list used for the required_together argument to
|
||||
AnsibleModule"""
|
||||
return [['api_key', 'username']]
|
||||
|
||||
|
||||
def setup_rax_module(module, rax_module, region_required=True):
|
||||
"""Set up pyrax in a standard way for all modules"""
|
||||
rax_module.USER_AGENT = 'ansible/%s %s' % (module.ansible_version,
|
||||
rax_module.USER_AGENT)
|
||||
|
||||
api_key = module.params.get('api_key')
|
||||
auth_endpoint = module.params.get('auth_endpoint')
|
||||
credentials = module.params.get('credentials')
|
||||
env = module.params.get('env')
|
||||
identity_type = module.params.get('identity_type')
|
||||
region = module.params.get('region')
|
||||
tenant_id = module.params.get('tenant_id')
|
||||
tenant_name = module.params.get('tenant_name')
|
||||
username = module.params.get('username')
|
||||
verify_ssl = module.params.get('validate_certs')
|
||||
|
||||
if env is not None:
|
||||
rax_module.set_environment(env)
|
||||
|
||||
rax_module.set_setting('identity_type', identity_type)
|
||||
if verify_ssl is not None:
|
||||
rax_module.set_setting('verify_ssl', verify_ssl)
|
||||
if auth_endpoint is not None:
|
||||
rax_module.set_setting('auth_endpoint', auth_endpoint)
|
||||
if tenant_id is not None:
|
||||
rax_module.set_setting('tenant_id', tenant_id)
|
||||
if tenant_name is not None:
|
||||
rax_module.set_setting('tenant_name', tenant_name)
|
||||
|
||||
try:
|
||||
username = username or os.environ.get('RAX_USERNAME')
|
||||
if not username:
|
||||
username = rax_module.get_setting('keyring_username')
|
||||
if username:
|
||||
api_key = 'USE_KEYRING'
|
||||
if not api_key:
|
||||
api_key = os.environ.get('RAX_API_KEY')
|
||||
credentials = (credentials or os.environ.get('RAX_CREDENTIALS') or
|
||||
os.environ.get('RAX_CREDS_FILE'))
|
||||
region = (region or os.environ.get('RAX_REGION') or
|
||||
rax_module.get_setting('region'))
|
||||
except KeyError as e:
|
||||
module.fail_json(msg='Unable to load %s' % e.message)
|
||||
|
||||
try:
|
||||
if api_key and username:
|
||||
if api_key == 'USE_KEYRING':
|
||||
rax_module.keyring_auth(username, region=region)
|
||||
else:
|
||||
rax_module.set_credentials(username, api_key=api_key,
|
||||
region=region)
|
||||
elif credentials:
|
||||
credentials = os.path.expanduser(credentials)
|
||||
rax_module.set_credential_file(credentials, region=region)
|
||||
else:
|
||||
raise Exception('No credentials supplied!')
|
||||
except Exception as e:
|
||||
if e.message:
|
||||
msg = str(e.message)
|
||||
else:
|
||||
msg = repr(e)
|
||||
module.fail_json(msg=msg)
|
||||
|
||||
if region_required and region not in rax_module.regions:
|
||||
module.fail_json(msg='%s is not a valid region, must be one of: %s' %
|
||||
(region, ','.join(rax_module.regions)))
|
||||
|
||||
return rax_module
|
||||
|
||||
|
||||
def rax_scaling_group_personality_file(module, files):
|
||||
if not files:
|
||||
return []
|
||||
|
||||
results = []
|
||||
for rpath, lpath in files.items():
|
||||
lpath = os.path.expanduser(lpath)
|
||||
try:
|
||||
with open(lpath, 'r') as f:
|
||||
results.append({
|
||||
'path': rpath,
|
||||
'contents': f.read(),
|
||||
})
|
||||
except Exception as e:
|
||||
module.fail_json(msg='Failed to load %s: %s' % (lpath, str(e)))
|
||||
return results
|
||||
@@ -20,8 +20,6 @@ from ansible.module_utils.six import text_type
|
||||
from ansible.module_utils.six.moves import http_client
|
||||
from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlparse
|
||||
from ansible.module_utils.ansible_release import __version__ as ansible_version
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
GET_HEADERS = {'accept': 'application/json', 'OData-Version': '4.0'}
|
||||
POST_HEADERS = {'content-type': 'application/json', 'accept': 'application/json',
|
||||
@@ -132,7 +130,7 @@ class RedfishUtils(object):
|
||||
return resp
|
||||
|
||||
# The following functions are to send GET/POST/PATCH/DELETE requests
|
||||
def get_request(self, uri, override_headers=None, allow_no_resp=False):
|
||||
def get_request(self, uri, override_headers=None):
|
||||
req_headers = dict(GET_HEADERS)
|
||||
if override_headers:
|
||||
req_headers.update(override_headers)
|
||||
@@ -147,19 +145,13 @@ class RedfishUtils(object):
|
||||
force_basic_auth=basic_auth, validate_certs=False,
|
||||
follow_redirects='all',
|
||||
use_proxy=True, timeout=self.timeout)
|
||||
headers = dict((k.lower(), v) for (k, v) in resp.info().items())
|
||||
try:
|
||||
if headers.get('content-encoding') == 'gzip' and LooseVersion(ansible_version) < LooseVersion('2.14'):
|
||||
# Older versions of Ansible do not automatically decompress the data
|
||||
# Starting in 2.14, open_url will decompress the response data by default
|
||||
data = json.loads(to_native(gzip.open(BytesIO(resp.read()), 'rt', encoding='utf-8').read()))
|
||||
else:
|
||||
data = json.loads(to_native(resp.read()))
|
||||
except Exception as e:
|
||||
# No response data; this is okay in certain cases
|
||||
data = None
|
||||
if not allow_no_resp:
|
||||
raise
|
||||
if override_headers:
|
||||
resp = gzip.open(BytesIO(resp.read()), 'rt', encoding='utf-8')
|
||||
data = json.loads(to_native(resp.read()))
|
||||
headers = req_headers
|
||||
else:
|
||||
data = json.loads(to_native(resp.read()))
|
||||
headers = dict((k.lower(), v) for (k, v) in resp.info().items())
|
||||
except HTTPError as e:
|
||||
msg = self._get_extended_message(e)
|
||||
return {'ret': False,
|
||||
@@ -1149,54 +1141,6 @@ class RedfishUtils(object):
|
||||
return response
|
||||
return {'ret': True, 'changed': True}
|
||||
|
||||
def manager_reset_to_defaults(self, command):
|
||||
return self.reset_to_defaults(command, self.manager_uri,
|
||||
'#Manager.ResetToDefaults')
|
||||
|
||||
def reset_to_defaults(self, command, resource_uri, action_name):
|
||||
key = "Actions"
|
||||
reset_type_values = ['ResetAll',
|
||||
'PreserveNetworkAndUsers',
|
||||
'PreserveNetwork']
|
||||
|
||||
if command not in reset_type_values:
|
||||
return {'ret': False, 'msg': 'Invalid Command (%s)' % command}
|
||||
|
||||
# read the resource and get the current power state
|
||||
response = self.get_request(self.root_uri + resource_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
data = response['data']
|
||||
|
||||
# get the reset Action and target URI
|
||||
if key not in data or action_name not in data[key]:
|
||||
return {'ret': False, 'msg': 'Action %s not found' % action_name}
|
||||
reset_action = data[key][action_name]
|
||||
if 'target' not in reset_action:
|
||||
return {'ret': False,
|
||||
'msg': 'target URI missing from Action %s' % action_name}
|
||||
action_uri = reset_action['target']
|
||||
|
||||
# get AllowableValues
|
||||
ai = self._get_all_action_info_values(reset_action)
|
||||
allowable_values = ai.get('ResetType', {}).get('AllowableValues', [])
|
||||
|
||||
# map ResetType to an allowable value if needed
|
||||
if allowable_values and command not in allowable_values:
|
||||
return {'ret': False,
|
||||
'msg': 'Specified reset type (%s) not supported '
|
||||
'by service. Supported types: %s' %
|
||||
(command, allowable_values)}
|
||||
|
||||
# define payload
|
||||
payload = {'ResetType': command}
|
||||
|
||||
# POST to Action URI
|
||||
response = self.post_request(self.root_uri + action_uri, payload)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
return {'ret': True, 'changed': True}
|
||||
|
||||
def _find_account_uri(self, username=None, acct_id=None):
|
||||
if not any((username, acct_id)):
|
||||
return {'ret': False, 'msg':
|
||||
@@ -1597,8 +1541,6 @@ class RedfishUtils(object):
|
||||
|
||||
data = response['data']
|
||||
|
||||
result['multipart_supported'] = 'MultipartHttpPushUri' in data
|
||||
|
||||
if "Actions" in data:
|
||||
actions = data['Actions']
|
||||
if len(actions) > 0:
|
||||
@@ -1871,7 +1813,7 @@ class RedfishUtils(object):
|
||||
return {'ret': False, 'msg': 'Must provide a handle tracking the update.'}
|
||||
|
||||
# Get the task or job tracking the update
|
||||
response = self.get_request(self.root_uri + update_handle, allow_no_resp=True)
|
||||
response = self.get_request(self.root_uri + update_handle)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
|
||||
@@ -2965,7 +2907,8 @@ class RedfishUtils(object):
|
||||
|
||||
# Get a list of all Chassis and build URIs, then get all PowerSupplies
|
||||
# from each Power entry in the Chassis
|
||||
for chassis_uri in self.chassis_uris:
|
||||
chassis_uri_list = self.chassis_uris
|
||||
for chassis_uri in chassis_uri_list:
|
||||
response = self.get_request(self.root_uri + chassis_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
@@ -3465,11 +3408,6 @@ class RedfishUtils(object):
|
||||
result['ret'] = True
|
||||
return result
|
||||
|
||||
def set_service_identification(self, service_id):
|
||||
data = {"ServiceIdentification": service_id}
|
||||
resp = self.patch_request(self.root_uri + '/redfish/v1/Managers/' + self.resource_id, data, check_pyld=True)
|
||||
return resp
|
||||
|
||||
def set_session_service(self, sessions_config):
|
||||
if sessions_config is None:
|
||||
return {'ret': False, 'msg':
|
||||
@@ -3557,30 +3495,33 @@ class RedfishUtils(object):
|
||||
result = {}
|
||||
key = "Thermal"
|
||||
# Go through list
|
||||
for chassis_uri in self.chassis_uris:
|
||||
for chassis_uri in self.chassis_uri_list:
|
||||
response = self.get_request(self.root_uri + chassis_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
result['ret'] = True
|
||||
data = response['data']
|
||||
val = data.get('Oem', {}).get('Hpe', {}).get('ThermalConfiguration')
|
||||
if val is not None:
|
||||
return {"ret": True, "current_thermal_config": val}
|
||||
return {"ret": False}
|
||||
oem = data.get['Oem']
|
||||
hpe = oem.get['Hpe']
|
||||
thermal_config = hpe.get('ThermalConfiguration')
|
||||
result["current_thermal_config"] = thermal_config
|
||||
return result
|
||||
|
||||
def get_hpe_fan_percent_min(self):
|
||||
result = {}
|
||||
key = "Thermal"
|
||||
# Go through list
|
||||
for chassis_uri in self.chassis_uris:
|
||||
for chassis_uri in self.chassis_uri_list:
|
||||
response = self.get_request(self.root_uri + chassis_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
result['ret'] = True
|
||||
data = response['data']
|
||||
val = data.get('Oem', {}).get('Hpe', {}).get('FanPercentMinimum')
|
||||
if val is not None:
|
||||
return {"ret": True, "fan_percent_min": val}
|
||||
return {"ret": False}
|
||||
oem = data.get['Oem']
|
||||
hpe = oem.get['Hpe']
|
||||
fan_percent_min_config = hpe.get('FanPercentMinimum')
|
||||
result["fan_percent_min"] = fan_percent_min_config
|
||||
return result
|
||||
|
||||
def delete_volumes(self, storage_subsystem_id, volume_ids):
|
||||
# Find the Storage resource from the requested ComputerSystem resource
|
||||
|
||||
@@ -15,8 +15,10 @@ __metaclass__ = type
|
||||
|
||||
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import tempfile
|
||||
import types
|
||||
|
||||
from ansible.module_utils.six.moves import configparser
|
||||
|
||||
@@ -74,3 +76,241 @@ class RegistrationBase(object):
|
||||
|
||||
def subscribe(self, **kwargs):
|
||||
raise NotImplementedError("Must be implemented by a sub-class")
|
||||
|
||||
|
||||
class Rhsm(RegistrationBase):
|
||||
"""
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 9.0.0.
|
||||
There is no replacement for it; please contact the community.general
|
||||
maintainers in case you are using it.
|
||||
"""
|
||||
|
||||
def __init__(self, module, username=None, password=None):
|
||||
RegistrationBase.__init__(self, module, username, password)
|
||||
self.config = self._read_config()
|
||||
self.module = module
|
||||
self.module.deprecate(
|
||||
'The Rhsm class is deprecated with no replacement.',
|
||||
version='9.0.0',
|
||||
collection_name='community.general',
|
||||
)
|
||||
|
||||
def _read_config(self, rhsm_conf='/etc/rhsm/rhsm.conf'):
|
||||
'''
|
||||
Load RHSM configuration from /etc/rhsm/rhsm.conf.
|
||||
Returns:
|
||||
* ConfigParser object
|
||||
'''
|
||||
|
||||
# Read RHSM defaults ...
|
||||
cp = configparser.ConfigParser()
|
||||
cp.read(rhsm_conf)
|
||||
|
||||
# Add support for specifying a default value w/o having to standup some configuration
|
||||
# Yeah, I know this should be subclassed ... but, oh well
|
||||
def get_option_default(self, key, default=''):
|
||||
sect, opt = key.split('.', 1)
|
||||
if self.has_section(sect) and self.has_option(sect, opt):
|
||||
return self.get(sect, opt)
|
||||
else:
|
||||
return default
|
||||
|
||||
cp.get_option = types.MethodType(get_option_default, cp, configparser.ConfigParser)
|
||||
|
||||
return cp
|
||||
|
||||
def enable(self):
|
||||
'''
|
||||
Enable the system to receive updates from subscription-manager.
|
||||
This involves updating affected yum plugins and removing any
|
||||
conflicting yum repositories.
|
||||
'''
|
||||
RegistrationBase.enable(self)
|
||||
self.update_plugin_conf('rhnplugin', False)
|
||||
self.update_plugin_conf('subscription-manager', True)
|
||||
|
||||
def configure(self, **kwargs):
|
||||
'''
|
||||
Configure the system as directed for registration with RHN
|
||||
Raises:
|
||||
* Exception - if error occurs while running command
|
||||
'''
|
||||
args = ['subscription-manager', 'config']
|
||||
|
||||
# Pass supplied **kwargs as parameters to subscription-manager. Ignore
|
||||
# non-configuration parameters and replace '_' with '.'. For example,
|
||||
# 'server_hostname' becomes '--system.hostname'.
|
||||
for k, v in kwargs.items():
|
||||
if re.search(r'^(system|rhsm)_', k):
|
||||
args.append('--%s=%s' % (k.replace('_', '.'), v))
|
||||
|
||||
self.module.run_command(args, check_rc=True)
|
||||
|
||||
@property
|
||||
def is_registered(self):
|
||||
'''
|
||||
Determine whether the current system
|
||||
Returns:
|
||||
* Boolean - whether the current system is currently registered to
|
||||
RHN.
|
||||
'''
|
||||
args = ['subscription-manager', 'identity']
|
||||
rc, stdout, stderr = self.module.run_command(args, check_rc=False)
|
||||
if rc == 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def register(self, username, password, autosubscribe, activationkey):
|
||||
'''
|
||||
Register the current system to the provided RHN server
|
||||
Raises:
|
||||
* Exception - if error occurs while running command
|
||||
'''
|
||||
args = ['subscription-manager', 'register']
|
||||
|
||||
# Generate command arguments
|
||||
if activationkey:
|
||||
args.append('--activationkey "%s"' % activationkey)
|
||||
else:
|
||||
if autosubscribe:
|
||||
args.append('--autosubscribe')
|
||||
if username:
|
||||
args.extend(['--username', username])
|
||||
if password:
|
||||
args.extend(['--password', password])
|
||||
|
||||
# Do the needful...
|
||||
rc, stderr, stdout = self.module.run_command(args, check_rc=True)
|
||||
|
||||
def unsubscribe(self):
|
||||
'''
|
||||
Unsubscribe a system from all subscribed channels
|
||||
Raises:
|
||||
* Exception - if error occurs while running command
|
||||
'''
|
||||
args = ['subscription-manager', 'unsubscribe', '--all']
|
||||
rc, stderr, stdout = self.module.run_command(args, check_rc=True)
|
||||
|
||||
def unregister(self):
|
||||
'''
|
||||
Unregister a currently registered system
|
||||
Raises:
|
||||
* Exception - if error occurs while running command
|
||||
'''
|
||||
args = ['subscription-manager', 'unregister']
|
||||
rc, stderr, stdout = self.module.run_command(args, check_rc=True)
|
||||
self.update_plugin_conf('rhnplugin', False)
|
||||
self.update_plugin_conf('subscription-manager', False)
|
||||
|
||||
def subscribe(self, regexp):
|
||||
'''
|
||||
Subscribe current system to available pools matching the specified
|
||||
regular expression
|
||||
Raises:
|
||||
* Exception - if error occurs while running command
|
||||
'''
|
||||
|
||||
# Available pools ready for subscription
|
||||
available_pools = RhsmPools(self.module)
|
||||
|
||||
for pool in available_pools.filter(regexp):
|
||||
pool.subscribe()
|
||||
|
||||
|
||||
class RhsmPool(object):
|
||||
"""
|
||||
Convenience class for housing subscription information
|
||||
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 9.0.0.
|
||||
There is no replacement for it; please contact the community.general
|
||||
maintainers in case you are using it.
|
||||
"""
|
||||
|
||||
def __init__(self, module, **kwargs):
|
||||
self.module = module
|
||||
for k, v in kwargs.items():
|
||||
setattr(self, k, v)
|
||||
self.module.deprecate(
|
||||
'The RhsmPool class is deprecated with no replacement.',
|
||||
version='9.0.0',
|
||||
collection_name='community.general',
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.__getattribute__('_name'))
|
||||
|
||||
def subscribe(self):
|
||||
args = "subscription-manager subscribe --pool %s" % self.PoolId
|
||||
rc, stdout, stderr = self.module.run_command(args, check_rc=True)
|
||||
if rc == 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class RhsmPools(object):
|
||||
"""
|
||||
This class is used for manipulating pools subscriptions with RHSM
|
||||
|
||||
DEPRECATION WARNING
|
||||
|
||||
This class is deprecated and will be removed in community.general 9.0.0.
|
||||
There is no replacement for it; please contact the community.general
|
||||
maintainers in case you are using it.
|
||||
"""
|
||||
|
||||
def __init__(self, module):
|
||||
self.module = module
|
||||
self.products = self._load_product_list()
|
||||
self.module.deprecate(
|
||||
'The RhsmPools class is deprecated with no replacement.',
|
||||
version='9.0.0',
|
||||
collection_name='community.general',
|
||||
)
|
||||
|
||||
def __iter__(self):
|
||||
return self.products.__iter__()
|
||||
|
||||
def _load_product_list(self):
|
||||
"""
|
||||
Loads list of all available pools for system in data structure
|
||||
"""
|
||||
args = "subscription-manager list --available"
|
||||
rc, stdout, stderr = self.module.run_command(args, check_rc=True)
|
||||
|
||||
products = []
|
||||
for line in stdout.split('\n'):
|
||||
# Remove leading+trailing whitespace
|
||||
line = line.strip()
|
||||
# An empty line implies the end of an output group
|
||||
if len(line) == 0:
|
||||
continue
|
||||
# If a colon ':' is found, parse
|
||||
elif ':' in line:
|
||||
(key, value) = line.split(':', 1)
|
||||
key = key.strip().replace(" ", "") # To unify
|
||||
value = value.strip()
|
||||
if key in ['ProductName', 'SubscriptionName']:
|
||||
# Remember the name for later processing
|
||||
products.append(RhsmPool(self.module, _name=value, key=value))
|
||||
elif products:
|
||||
# Associate value with most recently recorded product
|
||||
products[-1].__setattr__(key, value)
|
||||
# FIXME - log some warning?
|
||||
# else:
|
||||
# warnings.warn("Unhandled subscription key/value: %s/%s" % (key,value))
|
||||
return products
|
||||
|
||||
def filter(self, regexp='^$'):
|
||||
'''
|
||||
Return a list of RhsmPools whose name matches the provided regular expression
|
||||
'''
|
||||
r = re.compile(regexp)
|
||||
for product in self.products:
|
||||
if r.search(product._name):
|
||||
yield product
|
||||
|
||||
@@ -28,7 +28,7 @@ def api_argument_spec():
|
||||
return api_argument_spec
|
||||
|
||||
|
||||
def api_request(module, endpoint, data=None, method="GET", content_type="application/json"):
|
||||
def api_request(module, endpoint, data=None, method="GET"):
|
||||
"""Manages Rundeck API requests via HTTP(S)
|
||||
|
||||
:arg module: The AnsibleModule (used to get url, api_version, api_token, etc).
|
||||
@@ -63,7 +63,7 @@ def api_request(module, endpoint, data=None, method="GET", content_type="applica
|
||||
data=json.dumps(data),
|
||||
method=method,
|
||||
headers={
|
||||
"Content-Type": content_type,
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
"X-Rundeck-Auth-Token": module.params["api_token"]
|
||||
}
|
||||
|
||||
@@ -17,10 +17,6 @@ from ansible.module_utils.basic import env_fallback, missing_required_lib
|
||||
from ansible.module_utils.urls import fetch_url
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlencode
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.datetime import (
|
||||
now,
|
||||
)
|
||||
|
||||
SCALEWAY_SECRET_IMP_ERR = None
|
||||
try:
|
||||
from passlib.hash import argon2
|
||||
@@ -310,10 +306,10 @@ class Scaleway(object):
|
||||
# Prevent requesting the resource status too soon
|
||||
time.sleep(wait_sleep_time)
|
||||
|
||||
start = now()
|
||||
start = datetime.datetime.utcnow()
|
||||
end = start + datetime.timedelta(seconds=wait_timeout)
|
||||
|
||||
while now() < end:
|
||||
while datetime.datetime.utcnow() < end:
|
||||
self.module.debug("We are going to wait for the resource to finish its transition")
|
||||
|
||||
state = self.fetch_state(resource)
|
||||
|
||||
@@ -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])
|
||||
rc, current_all_vgs, err = module.run_command([lsvg_cmd, "%s"])
|
||||
if rc != 0:
|
||||
module.fail_json(msg="Failed executing %s command." % lsvg_cmd)
|
||||
|
||||
@@ -365,53 +365,7 @@ def create_fs(
|
||||
# Creates a LVM file system.
|
||||
crfs_cmd = module.get_bin_path('crfs', True)
|
||||
if not module.check_mode:
|
||||
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)
|
||||
|
||||
cmd = [crfs_cmd, "-v", fs_type, "-m", filesystem, vg, device, mount_group, auto_mount, account_subsystem, "-p", permissions, size, "-a", attributes]
|
||||
rc, crfs_out, err = module.run_command(cmd)
|
||||
|
||||
if rc == 10:
|
||||
@@ -507,7 +461,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),
|
||||
|
||||
@@ -240,6 +240,8 @@ def main():
|
||||
state = module.params['state']
|
||||
pvs = module.params['pvs']
|
||||
|
||||
pv_list = ' '.join(pvs)
|
||||
|
||||
if policy == 'maximum':
|
||||
lv_policy = 'x'
|
||||
else:
|
||||
@@ -247,16 +249,16 @@ def main():
|
||||
|
||||
# Add echo command when running in check-mode
|
||||
if module.check_mode:
|
||||
test_opt = [module.get_bin_path("echo", required=True)]
|
||||
test_opt = 'echo '
|
||||
else:
|
||||
test_opt = []
|
||||
test_opt = ''
|
||||
|
||||
# check if system commands are available
|
||||
lsvg_cmd = module.get_bin_path("lsvg", required=True)
|
||||
lslv_cmd = module.get_bin_path("lslv", required=True)
|
||||
|
||||
# Get information on volume group requested
|
||||
rc, vg_info, err = module.run_command([lsvg_cmd, vg])
|
||||
rc, vg_info, err = module.run_command("%s %s" % (lsvg_cmd, vg))
|
||||
|
||||
if rc != 0:
|
||||
if state == 'absent':
|
||||
@@ -271,7 +273,8 @@ def main():
|
||||
lv_size = round_ppsize(convert_size(module, size), base=this_vg['pp_size'])
|
||||
|
||||
# Get information on logical volume requested
|
||||
rc, lv_info, err = module.run_command([lslv_cmd, lv])
|
||||
rc, lv_info, err = module.run_command(
|
||||
"%s %s" % (lslv_cmd, lv))
|
||||
|
||||
if rc != 0:
|
||||
if state == 'absent':
|
||||
@@ -293,7 +296,7 @@ def main():
|
||||
# create LV
|
||||
mklv_cmd = module.get_bin_path("mklv", required=True)
|
||||
|
||||
cmd = test_opt + [mklv_cmd, "-t", lv_type, "-y", lv, "-c", copies, "-e", lv_policy, opts, vg, "%sM" % (lv_size, )] + pvs
|
||||
cmd = "%s %s -t %s -y %s -c %s -e %s %s %s %sM %s" % (test_opt, mklv_cmd, lv_type, lv, copies, lv_policy, opts, vg, lv_size, pv_list)
|
||||
rc, out, err = module.run_command(cmd)
|
||||
if rc == 0:
|
||||
module.exit_json(changed=True, msg="Logical volume %s created." % lv)
|
||||
@@ -303,7 +306,7 @@ def main():
|
||||
if state == 'absent':
|
||||
# remove LV
|
||||
rmlv_cmd = module.get_bin_path("rmlv", required=True)
|
||||
rc, out, err = module.run_command(test_opt + [rmlv_cmd, "-f", this_lv['name']])
|
||||
rc, out, err = module.run_command("%s %s -f %s" % (test_opt, rmlv_cmd, this_lv['name']))
|
||||
if rc == 0:
|
||||
module.exit_json(changed=True, msg="Logical volume %s deleted." % lv)
|
||||
else:
|
||||
@@ -312,7 +315,7 @@ def main():
|
||||
if this_lv['policy'] != policy:
|
||||
# change lv allocation policy
|
||||
chlv_cmd = module.get_bin_path("chlv", required=True)
|
||||
rc, out, err = module.run_command(test_opt + [chlv_cmd, "-e", lv_policy, this_lv['name']])
|
||||
rc, out, err = module.run_command("%s %s -e %s %s" % (test_opt, chlv_cmd, lv_policy, this_lv['name']))
|
||||
if rc == 0:
|
||||
module.exit_json(changed=True, msg="Logical volume %s policy changed: %s." % (lv, policy))
|
||||
else:
|
||||
@@ -328,7 +331,7 @@ def main():
|
||||
# resize LV based on absolute values
|
||||
if int(lv_size) > this_lv['size']:
|
||||
extendlv_cmd = module.get_bin_path("extendlv", required=True)
|
||||
cmd = test_opt + [extendlv_cmd, lv, "%sM" % (lv_size - this_lv['size'], )]
|
||||
cmd = "%s %s %s %sM" % (test_opt, extendlv_cmd, lv, lv_size - this_lv['size'])
|
||||
rc, out, err = module.run_command(cmd)
|
||||
if rc == 0:
|
||||
module.exit_json(changed=True, msg="Logical volume %s size extended to %sMB." % (lv, lv_size))
|
||||
|
||||
@@ -73,6 +73,16 @@ options:
|
||||
- Using O(force=true) is mandatory when downgrading.
|
||||
type: bool
|
||||
default: false
|
||||
ack_ansible29:
|
||||
description:
|
||||
- This option has no longer any effect and will be removed in community.general 9.0.0.
|
||||
type: bool
|
||||
default: false
|
||||
ack_min_ansiblecore211:
|
||||
description:
|
||||
- This option has no longer any effect and will be removed in community.general 9.0.0.
|
||||
type: bool
|
||||
default: false
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -192,6 +202,18 @@ class AnsibleGalaxyInstall(ModuleHelper):
|
||||
dest=dict(type='path'),
|
||||
force=dict(type='bool', default=False),
|
||||
no_deps=dict(type='bool', default=False),
|
||||
ack_ansible29=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
removed_in_version='9.0.0',
|
||||
removed_from_collection='community.general',
|
||||
),
|
||||
ack_min_ansiblecore211=dict(
|
||||
type='bool',
|
||||
default=False,
|
||||
removed_in_version='9.0.0',
|
||||
removed_from_collection='community.general',
|
||||
),
|
||||
),
|
||||
mutually_exclusive=[('name', 'requirements_file')],
|
||||
required_one_of=[('name', 'requirements_file')],
|
||||
|
||||
@@ -35,9 +35,7 @@ options:
|
||||
default: false
|
||||
name:
|
||||
description:
|
||||
- A package name, like V(foo), or multiple packages, like V(foo,bar).
|
||||
- Do not include additional whitespace when specifying multiple packages as a string.
|
||||
Prefer YAML lists over comma-separating multiple package names.
|
||||
- A package name, like V(foo), or multiple packages, like V(foo, bar).
|
||||
type: list
|
||||
elements: str
|
||||
no_cache:
|
||||
@@ -63,7 +61,7 @@ options:
|
||||
type: str
|
||||
update_cache:
|
||||
description:
|
||||
- Update repository indexes. Can be run with other steps or on its own.
|
||||
- Update repository indexes. Can be run with other steps or on it's own.
|
||||
type: bool
|
||||
default: false
|
||||
upgrade:
|
||||
|
||||
@@ -37,17 +37,7 @@ options:
|
||||
state:
|
||||
description:
|
||||
- Indicates the desired package state.
|
||||
- Please note that V(present) and V(installed) are equivalent to V(latest) right now.
|
||||
This will change in the future. To simply ensure that a package is installed, without upgrading
|
||||
it, use the V(present_not_latest) state.
|
||||
- The states V(latest) and V(present_not_latest) have been added in community.general 8.6.0.
|
||||
choices:
|
||||
- absent
|
||||
- present
|
||||
- present_not_latest
|
||||
- installed
|
||||
- removed
|
||||
- latest
|
||||
choices: [ absent, present, installed, removed ]
|
||||
default: present
|
||||
type: str
|
||||
update_cache:
|
||||
@@ -170,7 +160,7 @@ def local_rpm_package_name(path):
|
||||
def query_package(module, name):
|
||||
# rpm -q returns 0 if the package is installed,
|
||||
# 1 if it is not installed
|
||||
rc, out, err = module.run_command([RPM_PATH, "-q", name])
|
||||
rc, out, err = module.run_command("%s -q %s" % (RPM_PATH, name))
|
||||
if rc == 0:
|
||||
return True
|
||||
else:
|
||||
@@ -190,7 +180,7 @@ def check_package_version(module, name):
|
||||
return False
|
||||
|
||||
|
||||
def query_package_provides(module, name, allow_upgrade=False):
|
||||
def query_package_provides(module, name):
|
||||
# rpm -q returns 0 if the package is installed,
|
||||
# 1 if it is not installed
|
||||
if name.endswith('.rpm'):
|
||||
@@ -203,13 +193,12 @@ def query_package_provides(module, name, allow_upgrade=False):
|
||||
|
||||
name = local_rpm_package_name(name)
|
||||
|
||||
rc, out, err = module.run_command([RPM_PATH, "-q", "--provides", name])
|
||||
rc, out, err = module.run_command("%s -q --provides %s" % (RPM_PATH, name))
|
||||
if rc == 0:
|
||||
if not allow_upgrade:
|
||||
return True
|
||||
if check_package_version(module, name):
|
||||
return True
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def update_package_db(module):
|
||||
@@ -253,7 +242,7 @@ def remove_packages(module, packages):
|
||||
if not query_package(module, package):
|
||||
continue
|
||||
|
||||
rc, out, err = module.run_command([APT_PATH, "-y", "remove", package], environ_update={"LANG": "C"})
|
||||
rc, out, err = module.run_command("%s -y remove %s" % (APT_PATH, package), environ_update={"LANG": "C"})
|
||||
|
||||
if rc != 0:
|
||||
module.fail_json(msg="failed to remove %s: %s" % (package, err))
|
||||
@@ -266,28 +255,28 @@ def remove_packages(module, packages):
|
||||
return (False, "package(s) already absent")
|
||||
|
||||
|
||||
def install_packages(module, pkgspec, allow_upgrade=False):
|
||||
def install_packages(module, pkgspec):
|
||||
|
||||
if pkgspec is None:
|
||||
return (False, "Empty package list")
|
||||
|
||||
packages = []
|
||||
packages = ""
|
||||
for package in pkgspec:
|
||||
if not query_package_provides(module, package, allow_upgrade=allow_upgrade):
|
||||
packages.append(package)
|
||||
if not query_package_provides(module, package):
|
||||
packages += "'%s' " % package
|
||||
|
||||
if packages:
|
||||
command = [APT_PATH, "-y", "install"] + packages
|
||||
rc, out, err = module.run_command(command, environ_update={"LANG": "C"})
|
||||
if len(packages) != 0:
|
||||
|
||||
rc, out, err = module.run_command("%s -y install %s" % (APT_PATH, packages), environ_update={"LANG": "C"})
|
||||
|
||||
installed = True
|
||||
for package in pkgspec:
|
||||
if not query_package_provides(module, package, allow_upgrade=False):
|
||||
for packages in pkgspec:
|
||||
if not query_package_provides(module, package):
|
||||
installed = False
|
||||
|
||||
# apt-rpm always have 0 for exit code if --force is used
|
||||
if rc or not installed:
|
||||
module.fail_json(msg="'%s' failed: %s" % (" ".join(command), err))
|
||||
module.fail_json(msg="'apt-get -y install %s' failed: %s" % (packages, err))
|
||||
else:
|
||||
return (True, "%s present(s)" % packages)
|
||||
else:
|
||||
@@ -297,7 +286,7 @@ def install_packages(module, pkgspec, allow_upgrade=False):
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
state=dict(type='str', default='present', choices=['absent', 'installed', 'present', 'removed', 'present_not_latest', 'latest']),
|
||||
state=dict(type='str', default='present', choices=['absent', 'installed', 'present', 'removed']),
|
||||
update_cache=dict(type='bool', default=False),
|
||||
clean=dict(type='bool', default=False),
|
||||
dist_upgrade=dict(type='bool', default=False),
|
||||
@@ -310,18 +299,6 @@ def main():
|
||||
module.fail_json(msg="cannot find /usr/bin/apt-get and/or /usr/bin/rpm")
|
||||
|
||||
p = module.params
|
||||
if p['state'] in ['installed', 'present']:
|
||||
module.deprecate(
|
||||
'state=%s currently behaves unexpectedly by always upgrading to the latest version if'
|
||||
' the package is already installed. This behavior is deprecated and will change in'
|
||||
' community.general 11.0.0. You can use state=latest to explicitly request this behavior'
|
||||
' or state=present_not_latest to explicitly request the behavior that state=%s will have'
|
||||
' in community.general 11.0.0, namely that the package will not be upgraded if it is'
|
||||
' already installed.' % (p['state'], p['state']),
|
||||
version='11.0.0',
|
||||
collection_name='community.general',
|
||||
)
|
||||
|
||||
modified = False
|
||||
output = ""
|
||||
|
||||
@@ -343,8 +320,8 @@ def main():
|
||||
output += out
|
||||
|
||||
packages = p['package']
|
||||
if p['state'] in ['installed', 'present', 'present_not_latest', 'latest']:
|
||||
(m, out) = install_packages(module, packages, allow_upgrade=p['state'] != 'present_not_latest')
|
||||
if p['state'] in ['installed', 'present']:
|
||||
(m, out) = install_packages(module, packages)
|
||||
modified = modified or m
|
||||
output += out
|
||||
|
||||
|
||||
@@ -572,7 +572,10 @@ class BtrfsSubvolumeModule(object):
|
||||
self.__temporary_mounts[cache_key] = mountpoint
|
||||
|
||||
mount = self.module.get_bin_path("mount", required=True)
|
||||
command = [mount, "-o", "noatime,subvolid=%d" % subvolid, device, mountpoint]
|
||||
command = "%s -o noatime,subvolid=%d %s %s " % (mount,
|
||||
subvolid,
|
||||
device,
|
||||
mountpoint)
|
||||
result = self.module.run_command(command, check_rc=True)
|
||||
|
||||
return mountpoint
|
||||
@@ -583,10 +586,10 @@ class BtrfsSubvolumeModule(object):
|
||||
|
||||
def __cleanup_mount(self, mountpoint):
|
||||
umount = self.module.get_bin_path("umount", required=True)
|
||||
result = self.module.run_command([umount, mountpoint])
|
||||
result = self.module.run_command("%s %s" % (umount, mountpoint))
|
||||
if result[0] == 0:
|
||||
rmdir = self.module.get_bin_path("rmdir", required=True)
|
||||
self.module.run_command([rmdir, mountpoint])
|
||||
self.module.run_command("%s %s" % (rmdir, mountpoint))
|
||||
|
||||
# Format and return results
|
||||
def get_results(self):
|
||||
|
||||
@@ -137,10 +137,6 @@ class Cargo(object):
|
||||
|
||||
def get_installed(self):
|
||||
cmd = ["install", "--list"]
|
||||
if self.path:
|
||||
cmd.append("--root")
|
||||
cmd.append(self.path)
|
||||
|
||||
data, dummy = self._exec(cmd, True, False, False)
|
||||
|
||||
package_regex = re.compile(r"^([\w\-]+) v(.+):$")
|
||||
|
||||
@@ -148,9 +148,9 @@ options:
|
||||
type:
|
||||
description:
|
||||
- The type of DNS record to create. Required if O(state=present).
|
||||
- Support for V(SPF) has been removed from community.general 9.0.0 since that record type is no longer supported by CloudFlare.
|
||||
- Note that V(SPF) is no longer supported by CloudFlare. Support for it will be removed from community.general 9.0.0.
|
||||
type: str
|
||||
choices: [ A, AAAA, CNAME, DS, MX, NS, SRV, SSHFP, TLSA, CAA, TXT ]
|
||||
choices: [ A, AAAA, CNAME, DS, MX, NS, SPF, SRV, SSHFP, TLSA, CAA, TXT ]
|
||||
value:
|
||||
description:
|
||||
- The record value.
|
||||
@@ -674,7 +674,7 @@ class CloudflareAPI(object):
|
||||
if (params['type'] is None) or (params['record'] is None):
|
||||
self.module.fail_json(msg="You must provide a type and a record to create a new record")
|
||||
|
||||
if (params['type'] in ['A', 'AAAA', 'CNAME', 'TXT', 'MX', 'NS']):
|
||||
if (params['type'] in ['A', 'AAAA', 'CNAME', 'TXT', 'MX', 'NS', 'SPF']):
|
||||
if not params['value']:
|
||||
self.module.fail_json(msg="You must provide a non-empty value to create this record type")
|
||||
|
||||
@@ -869,7 +869,7 @@ def main():
|
||||
state=dict(type='str', default='present', choices=['absent', 'present']),
|
||||
timeout=dict(type='int', default=30),
|
||||
ttl=dict(type='int', default=1),
|
||||
type=dict(type='str', choices=['A', 'AAAA', 'CNAME', 'DS', 'MX', 'NS', 'SRV', 'SSHFP', 'TLSA', 'CAA', 'TXT']),
|
||||
type=dict(type='str', choices=['A', 'AAAA', 'CNAME', 'DS', 'MX', 'NS', 'SPF', 'SRV', 'SSHFP', 'TLSA', 'CAA', 'TXT']),
|
||||
value=dict(type='str', aliases=['content']),
|
||||
weight=dict(type='int', default=1),
|
||||
zone=dict(type='str', required=True, aliases=['domain']),
|
||||
|
||||
@@ -75,16 +75,13 @@ RETURN = r'''
|
||||
# Default return values
|
||||
'''
|
||||
|
||||
import datetime
|
||||
import ssl
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.six.moves import xmlrpc_client
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.datetime import (
|
||||
now,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
@@ -113,7 +110,7 @@ def main():
|
||||
changed=True,
|
||||
)
|
||||
|
||||
start = now()
|
||||
start = datetime.datetime.utcnow()
|
||||
|
||||
ssl_context = None
|
||||
if not validate_certs:
|
||||
@@ -145,7 +142,7 @@ def main():
|
||||
except Exception as e:
|
||||
module.fail_json(msg="Failed to sync Cobbler. {error}".format(error=to_text(e)))
|
||||
|
||||
elapsed = now() - start
|
||||
elapsed = datetime.datetime.utcnow() - start
|
||||
module.exit_json(elapsed=elapsed.seconds, **result)
|
||||
|
||||
|
||||
|
||||
@@ -152,6 +152,7 @@ system:
|
||||
type: dict
|
||||
'''
|
||||
|
||||
import datetime
|
||||
import ssl
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
@@ -159,10 +160,6 @@ from ansible.module_utils.six import iteritems
|
||||
from ansible.module_utils.six.moves import xmlrpc_client
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.datetime import (
|
||||
now,
|
||||
)
|
||||
|
||||
IFPROPS_MAPPING = dict(
|
||||
bondingopts='bonding_opts',
|
||||
bridgeopts='bridge_opts',
|
||||
@@ -235,7 +232,7 @@ def main():
|
||||
changed=False,
|
||||
)
|
||||
|
||||
start = now()
|
||||
start = datetime.datetime.utcnow()
|
||||
|
||||
ssl_context = None
|
||||
if not validate_certs:
|
||||
@@ -343,7 +340,7 @@ def main():
|
||||
if module._diff:
|
||||
result['diff'] = dict(before=system, after=result['system'])
|
||||
|
||||
elapsed = now() - start
|
||||
elapsed = datetime.datetime.utcnow() - start
|
||||
module.exit_json(elapsed=elapsed.seconds, **result)
|
||||
|
||||
|
||||
|
||||
@@ -33,8 +33,6 @@ attributes:
|
||||
version_added: 8.3.0
|
||||
details:
|
||||
- In check mode the diff will miss operational attributes.
|
||||
action_group:
|
||||
version_added: 8.3.0
|
||||
options:
|
||||
state:
|
||||
description:
|
||||
|
||||
@@ -32,8 +32,6 @@ attributes:
|
||||
details:
|
||||
- In check mode the diff will miss operational attributes.
|
||||
version_added: 8.3.0
|
||||
action_group:
|
||||
version_added: 8.3.0
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
|
||||
@@ -29,8 +29,6 @@ attributes:
|
||||
support: none
|
||||
diff_mode:
|
||||
support: none
|
||||
action_group:
|
||||
version_added: 8.3.0
|
||||
options:
|
||||
id:
|
||||
description:
|
||||
|
||||
@@ -31,8 +31,6 @@ attributes:
|
||||
support: partial
|
||||
details:
|
||||
- In check mode the diff will miss operational attributes.
|
||||
action_group:
|
||||
version_added: 8.3.0
|
||||
options:
|
||||
state:
|
||||
description:
|
||||
@@ -239,12 +237,6 @@ class ConsulTokenModule(_ConsulModule):
|
||||
|
||||
create_only_fields = {"expiration_ttl"}
|
||||
|
||||
def read_object(self):
|
||||
# if `accessor_id` is not supplied we can only create objects and are not idempotent
|
||||
if not self.params.get(self.unique_identifier):
|
||||
return None
|
||||
return super(ConsulTokenModule, self).read_object()
|
||||
|
||||
def needs_update(self, api_obj, module_obj):
|
||||
# SecretID is usually not supplied
|
||||
if "SecretID" not in module_obj and "SecretID" in api_obj:
|
||||
|
||||
@@ -68,10 +68,9 @@ options:
|
||||
mode:
|
||||
description:
|
||||
- Controls the module behavior. See notes below for more details.
|
||||
- The default changed from V(compatibility) to V(new) in community.general 9.0.0.
|
||||
- Default is V(compatibility) but that behavior is deprecated and will be changed to V(new) in community.general 9.0.0.
|
||||
type: str
|
||||
choices: [compatibility, new]
|
||||
default: new
|
||||
version_added: 3.0.0
|
||||
name_check:
|
||||
description:
|
||||
@@ -81,16 +80,12 @@ options:
|
||||
notes:
|
||||
- Please note that U(http://search.cpan.org/dist/App-cpanminus/bin/cpanm, cpanm) must be installed on the remote host.
|
||||
- "This module now comes with a choice of execution O(mode): V(compatibility) or V(new)."
|
||||
- >
|
||||
O(mode=compatibility): When using V(compatibility) mode, the module will keep backward compatibility.
|
||||
This was the default mode before community.general 9.0.0.
|
||||
- "O(mode=compatibility): When using V(compatibility) mode, the module will keep backward compatibility. This is the default mode.
|
||||
O(name) must be either a module name or a distribution file. If the perl module given by O(name) is installed (at the exact O(version)
|
||||
when specified), then nothing happens. Otherwise, it will be installed using the C(cpanm) executable. O(name) cannot be an URL, or a git URL.
|
||||
C(cpanm) version specifiers do not work in this mode.
|
||||
- >
|
||||
O(mode=new): When using V(new) mode, the module will behave differently. The O(name) parameter may refer to a module name, a distribution file,
|
||||
a HTTP URL or a git repository URL as described in C(cpanminus) documentation. C(cpanm) version specifiers are recognized.
|
||||
This is the default mode from community.general 9.0.0 onwards.
|
||||
C(cpanm) version specifiers do not work in this mode."
|
||||
- "O(mode=new): When using V(new) mode, the module will behave differently. The O(name) parameter may refer to a module name, a distribution file,
|
||||
a HTTP URL or a git repository URL as described in C(cpanminus) documentation. C(cpanm) version specifiers are recognized."
|
||||
author:
|
||||
- "Franck Cuny (@fcuny)"
|
||||
- "Alexei Znamensky (@russoz)"
|
||||
@@ -155,7 +150,7 @@ class CPANMinus(ModuleHelper):
|
||||
mirror_only=dict(type='bool', default=False),
|
||||
installdeps=dict(type='bool', default=False),
|
||||
executable=dict(type='path'),
|
||||
mode=dict(type='str', default='new', choices=['compatibility', 'new']),
|
||||
mode=dict(type='str', choices=['compatibility', 'new']),
|
||||
name_check=dict(type='str')
|
||||
),
|
||||
required_one_of=[('name', 'from_path')],
|
||||
@@ -173,6 +168,14 @@ class CPANMinus(ModuleHelper):
|
||||
|
||||
def __init_module__(self):
|
||||
v = self.vars
|
||||
if v.mode is None:
|
||||
self.deprecate(
|
||||
"The default value 'compatibility' for parameter 'mode' is being deprecated "
|
||||
"and it will be replaced by 'new'",
|
||||
version="9.0.0",
|
||||
collection_name="community.general"
|
||||
)
|
||||
v.mode = "compatibility"
|
||||
if v.mode == "compatibility":
|
||||
if v.name_check:
|
||||
self.do_raise("Parameter name_check can only be used with mode=new")
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2024, Alexei Znamensky <russoz@gmail.com>
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
module: django_command
|
||||
author:
|
||||
- Alexei Znamensky (@russoz)
|
||||
short_description: Run Django admin commands
|
||||
version_added: 9.0.0
|
||||
description:
|
||||
- This module allows the execution of arbitrary Django admin commands.
|
||||
extends_documentation_fragment:
|
||||
- community.general.attributes
|
||||
- community.general.django
|
||||
attributes:
|
||||
check_mode:
|
||||
support: none
|
||||
diff_mode:
|
||||
support: none
|
||||
options:
|
||||
command:
|
||||
description:
|
||||
- Django admin command. It must be a valid command accepted by C(python -m django) at the target system.
|
||||
type: str
|
||||
required: true
|
||||
extra_args:
|
||||
type: list
|
||||
elements: str
|
||||
description:
|
||||
- List of extra arguments passed to the django admin command.
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
- name: Check the project
|
||||
community.general.django_command:
|
||||
command: check
|
||||
settings: myproject.settings
|
||||
|
||||
- name: Check the project in specified python path, using virtual environment
|
||||
community.general.django_command:
|
||||
command: check
|
||||
settings: fancysite.settings
|
||||
pythonpath: /home/joedoe/project/fancysite
|
||||
venv: /home/joedoe/project/fancysite/venv
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
run_info:
|
||||
description: Command-line execution information.
|
||||
type: dict
|
||||
returned: success and O(verbosity) >= 3
|
||||
"""
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.django import DjangoModuleHelper
|
||||
from ansible_collections.community.general.plugins.module_utils.cmd_runner import cmd_runner_fmt
|
||||
|
||||
|
||||
class DjangoCommand(DjangoModuleHelper):
|
||||
module = dict(
|
||||
argument_spec=dict(
|
||||
command=dict(type="str", required=True),
|
||||
extra_args=dict(type="list", elements="str"),
|
||||
),
|
||||
supports_check_mode=False,
|
||||
)
|
||||
arg_formats = dict(
|
||||
extra_args=cmd_runner_fmt.as_list(),
|
||||
)
|
||||
django_admin_arg_order = "extra_args"
|
||||
|
||||
|
||||
def main():
|
||||
DjangoCommand.execute()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -28,16 +28,23 @@ options:
|
||||
command:
|
||||
description:
|
||||
- The name of the Django management command to run. The commands listed below are built in this module and have some basic parameter validation.
|
||||
- >
|
||||
V(cleanup) - clean up old data from the database (deprecated in Django 1.5). This parameter will be
|
||||
removed in community.general 9.0.0. Use V(clearsessions) instead.
|
||||
- V(collectstatic) - Collects the static files into C(STATIC_ROOT).
|
||||
- V(createcachetable) - Creates the cache tables for use with the database cache backend.
|
||||
- V(flush) - Removes all data from the database.
|
||||
- V(loaddata) - Searches for and loads the contents of the named O(fixtures) into the database.
|
||||
- V(migrate) - Synchronizes the database state with models and migrations.
|
||||
- >
|
||||
V(syncdb) - Synchronizes the database state with models and migrations (deprecated in Django 1.7).
|
||||
This parameter will be removed in community.general 9.0.0. Use V(migrate) instead.
|
||||
- V(test) - Runs tests for all installed apps.
|
||||
- Other commands can be entered, but will fail if they are unknown to Django. Other commands that may
|
||||
- >
|
||||
V(validate) - Validates all installed models (deprecated in Django 1.7). This parameter will be
|
||||
removed in community.general 9.0.0. Use V(check) instead.
|
||||
- Other commands can be entered, but will fail if they are unknown to Django. Other commands that may
|
||||
prompt for user input should be run with the C(--noinput) flag.
|
||||
- Support for the values V(cleanup), V(syncdb), V(validate) was removed in community.general 9.0.0.
|
||||
See note about supported versions of Django.
|
||||
type: str
|
||||
required: true
|
||||
project_path:
|
||||
@@ -62,7 +69,6 @@ options:
|
||||
virtualenv:
|
||||
description:
|
||||
- An optional path to a C(virtualenv) installation to use while running the manage application.
|
||||
- The virtual environment must exist, otherwise the module will fail.
|
||||
type: path
|
||||
aliases: [virtual_env]
|
||||
apps:
|
||||
@@ -126,24 +132,31 @@ options:
|
||||
aliases: [test_runner]
|
||||
ack_venv_creation_deprecation:
|
||||
description:
|
||||
- This option no longer has any effect since community.general 9.0.0.
|
||||
- It will be removed from community.general 11.0.0.
|
||||
- >-
|
||||
When a O(virtualenv) is set but the virtual environment does not exist, the current behavior is
|
||||
to create a new virtual environment. That behavior is deprecated and if that case happens it will
|
||||
generate a deprecation warning. Set this flag to V(true) to suppress the deprecation warning.
|
||||
- Please note that you will receive no further warning about this being removed until the module
|
||||
will start failing in such cases from community.general 9.0.0 on.
|
||||
type: bool
|
||||
version_added: 5.8.0
|
||||
|
||||
notes:
|
||||
- >
|
||||
B(ATTENTION): Support for Django releases older than 4.1 has been removed in
|
||||
community.general version 9.0.0. While the module allows for free-form commands
|
||||
does not verify the version of Django being used, it is B(strongly recommended)
|
||||
to use a more recent version of Django.
|
||||
- Please notice that Django 4.1 requires Python 3.8 or greater.
|
||||
- This module will not create a virtualenv if the O(virtualenv) parameter is specified and a virtual environment
|
||||
does not already exist at the given location. This behavior changed in community.general version 9.0.0.
|
||||
- The recommended way to create a virtual environment in Ansible is by using M(ansible.builtin.pip).
|
||||
B(ATTENTION - DEPRECATION): Support for Django releases older than 4.1 will be removed in
|
||||
community.general version 9.0.0 (estimated to be released in May 2024).
|
||||
Please notice that Django 4.1 requires Python 3.8 or greater.
|
||||
- C(virtualenv) (U(http://www.virtualenv.org)) must be installed on the remote host if the O(virtualenv) parameter
|
||||
is specified. This requirement is deprecated and will be removed in community.general version 9.0.0.
|
||||
- This module will create a virtualenv if the O(virtualenv) parameter is specified and a virtual environment does not already
|
||||
exist at the given location. This behavior is deprecated and will be removed in community.general version 9.0.0.
|
||||
- The parameter O(virtualenv) will remain in use, but it will require the specified virtualenv to exist.
|
||||
The recommended way to create one in Ansible is by using M(ansible.builtin.pip).
|
||||
- This module assumes English error messages for the V(createcachetable) command to detect table existence,
|
||||
unfortunately.
|
||||
- To be able to use the V(collectstatic) command, you must have enabled C(staticfiles) in your settings.
|
||||
- To be able to use the V(migrate) command with django versions < 1.7, you must have C(south) installed and added
|
||||
as an app in your settings.
|
||||
- To be able to use the V(collectstatic) command, you must have enabled staticfiles in your settings.
|
||||
- Your C(manage.py) application must be executable (C(rwxr-xr-x)), and must have a valid shebang,
|
||||
for example C(#!/usr/bin/env python), for invoking the appropriate Python interpreter.
|
||||
seealso:
|
||||
@@ -156,7 +169,7 @@ seealso:
|
||||
- name: What Python version can I use with Django?
|
||||
description: From the Django FAQ, the response to Python requirements for the framework.
|
||||
link: https://docs.djangoproject.com/en/dev/faq/install/#what-python-version-can-i-use-with-django
|
||||
requirements: [ "django >= 4.1" ]
|
||||
requirements: [ "virtualenv", "django" ]
|
||||
author:
|
||||
- Alexei Znamensky (@russoz)
|
||||
- Scott Anderson (@tastychutney)
|
||||
@@ -165,7 +178,7 @@ author:
|
||||
EXAMPLES = """
|
||||
- name: Run cleanup on the application installed in django_dir
|
||||
community.general.django_manage:
|
||||
command: clearsessions
|
||||
command: cleanup
|
||||
project_path: "{{ django_dir }}"
|
||||
|
||||
- name: Load the initial_data fixture into the application
|
||||
@@ -176,7 +189,7 @@ EXAMPLES = """
|
||||
|
||||
- name: Run syncdb on the application
|
||||
community.general.django_manage:
|
||||
command: migrate
|
||||
command: syncdb
|
||||
project_path: "{{ django_dir }}"
|
||||
settings: "{{ settings_app_name }}"
|
||||
pythonpath: "{{ settings_dir }}"
|
||||
@@ -220,7 +233,22 @@ def _ensure_virtualenv(module):
|
||||
activate = os.path.join(vbin, 'activate')
|
||||
|
||||
if not os.path.exists(activate):
|
||||
module.fail_json(msg='%s does not point to a valid virtual environment' % venv_param)
|
||||
# In version 9.0.0, if the venv is not found, it should fail_json() here.
|
||||
if not module.params['ack_venv_creation_deprecation']:
|
||||
module.deprecate(
|
||||
'The behavior of "creating the virtual environment when missing" is being '
|
||||
'deprecated and will be removed in community.general version 9.0.0. '
|
||||
'Set the module parameter `ack_venv_creation_deprecation: true` to '
|
||||
'prevent this message from showing up when creating a virtualenv.',
|
||||
version='9.0.0',
|
||||
collection_name='community.general',
|
||||
)
|
||||
|
||||
virtualenv = module.get_bin_path('virtualenv', True)
|
||||
vcmd = [virtualenv, venv_param]
|
||||
rc, out_venv, err_venv = module.run_command(vcmd)
|
||||
if rc != 0:
|
||||
_fail(module, vcmd, out_venv, err_venv)
|
||||
|
||||
os.environ["PATH"] = "%s:%s" % (vbin, os.environ["PATH"])
|
||||
os.environ["VIRTUAL_ENV"] = venv_param
|
||||
@@ -238,6 +266,11 @@ def loaddata_filter_output(line):
|
||||
return "Installed" in line and "Installed 0 object" not in line
|
||||
|
||||
|
||||
def syncdb_filter_output(line):
|
||||
return ("Creating table " in line) \
|
||||
or ("Installed" in line and "Installed 0 object" not in line)
|
||||
|
||||
|
||||
def migrate_filter_output(line):
|
||||
return ("Migrating forwards " in line) \
|
||||
or ("Installed" in line and "Installed 0 object" not in line) \
|
||||
@@ -250,10 +283,13 @@ def collectstatic_filter_output(line):
|
||||
|
||||
def main():
|
||||
command_allowed_param_map = dict(
|
||||
cleanup=(),
|
||||
createcachetable=('cache_table', 'database', ),
|
||||
flush=('database', ),
|
||||
loaddata=('database', 'fixtures', ),
|
||||
syncdb=('database', ),
|
||||
test=('failfast', 'testrunner', 'apps', ),
|
||||
validate=(),
|
||||
migrate=('apps', 'skip', 'merge', 'database',),
|
||||
collectstatic=('clear', 'link', ),
|
||||
)
|
||||
@@ -265,6 +301,7 @@ def main():
|
||||
# forces --noinput on every command that needs it
|
||||
noinput_commands = (
|
||||
'flush',
|
||||
'syncdb',
|
||||
'migrate',
|
||||
'test',
|
||||
'collectstatic',
|
||||
@@ -296,7 +333,7 @@ def main():
|
||||
skip=dict(type='bool'),
|
||||
merge=dict(type='bool'),
|
||||
link=dict(type='bool'),
|
||||
ack_venv_creation_deprecation=dict(type='bool', removed_in_version='11.0.0', removed_from_collection='community.general'),
|
||||
ack_venv_creation_deprecation=dict(type='bool'),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -305,6 +342,21 @@ def main():
|
||||
project_path = module.params['project_path']
|
||||
virtualenv = module.params['virtualenv']
|
||||
|
||||
try:
|
||||
_deprecation = dict(
|
||||
cleanup="clearsessions",
|
||||
syncdb="migrate",
|
||||
validate="check",
|
||||
)
|
||||
module.deprecate(
|
||||
'The command {0} has been deprecated as it is no longer supported in recent Django versions.'
|
||||
'Please use the command {1} instead that provide similar capability.'.format(command_bin, _deprecation[command_bin]),
|
||||
version='9.0.0',
|
||||
collection_name='community.general'
|
||||
)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
for param in specific_params:
|
||||
value = module.params[param]
|
||||
if value and param not in command_allowed_param_map[command_bin]:
|
||||
|
||||
@@ -86,7 +86,7 @@ class EjabberdUser(object):
|
||||
object manages user creation and deletion using ejabberdctl. The following
|
||||
commands are currently supported:
|
||||
* ejabberdctl register
|
||||
* ejabberdctl unregister
|
||||
* ejabberdctl deregister
|
||||
"""
|
||||
|
||||
def __init__(self, module):
|
||||
|
||||
@@ -40,12 +40,11 @@ options:
|
||||
default: present
|
||||
version_added: 1.3.0
|
||||
fstype:
|
||||
choices: [ bcachefs, btrfs, ext2, ext3, ext4, ext4dev, f2fs, lvm, ocfs2, reiserfs, xfs, vfat, swap, ufs ]
|
||||
choices: [ btrfs, ext2, ext3, ext4, ext4dev, f2fs, lvm, ocfs2, reiserfs, xfs, vfat, swap, ufs ]
|
||||
description:
|
||||
- Filesystem type to be created. This option is required with
|
||||
O(state=present) (or if O(state) is omitted).
|
||||
- ufs support has been added in community.general 3.4.0.
|
||||
- bcachefs support has been added in community.general 8.6.0.
|
||||
type: str
|
||||
aliases: [type]
|
||||
dev:
|
||||
@@ -68,7 +67,7 @@ options:
|
||||
resizefs:
|
||||
description:
|
||||
- If V(true), if the block device and filesystem size differ, grow the filesystem into the space.
|
||||
- Supported for C(bcachefs), C(btrfs), C(ext2), C(ext3), C(ext4), C(ext4dev), C(f2fs), C(lvm), C(xfs), C(ufs) and C(vfat) filesystems.
|
||||
- Supported for C(btrfs), C(ext2), C(ext3), C(ext4), C(ext4dev), C(f2fs), C(lvm), C(xfs), C(ufs) and C(vfat) filesystems.
|
||||
Attempts to resize other filesystem types will fail.
|
||||
- XFS Will only grow if mounted. Currently, the module is based on commands
|
||||
from C(util-linux) package to perform operations, so resizing of XFS is
|
||||
@@ -87,7 +86,7 @@ options:
|
||||
- The UUID options specified in O(opts) take precedence over this value.
|
||||
- See xfs_admin(8) (C(xfs)), tune2fs(8) (C(ext2), C(ext3), C(ext4), C(ext4dev)) for possible values.
|
||||
- For O(fstype=lvm) the value is ignored, it resets the PV UUID if set.
|
||||
- Supported for O(fstype) being one of C(bcachefs), C(ext2), C(ext3), C(ext4), C(ext4dev), C(lvm), or C(xfs).
|
||||
- Supported for O(fstype) being one of C(ext2), C(ext3), C(ext4), C(ext4dev), C(lvm), or C(xfs).
|
||||
- This is B(not idempotent). Specifying this option will always result in a change.
|
||||
- Mutually exclusive with O(resizefs).
|
||||
type: str
|
||||
@@ -406,48 +405,6 @@ class Reiserfs(Filesystem):
|
||||
MKFS_FORCE_FLAGS = ['-q']
|
||||
|
||||
|
||||
class Bcachefs(Filesystem):
|
||||
MKFS = 'mkfs.bcachefs'
|
||||
MKFS_FORCE_FLAGS = ['--force']
|
||||
MKFS_SET_UUID_OPTIONS = ['-U', '--uuid']
|
||||
INFO = 'bcachefs'
|
||||
GROW = 'bcachefs'
|
||||
GROW_MAX_SPACE_FLAGS = ['device', 'resize']
|
||||
|
||||
def get_fs_size(self, dev):
|
||||
"""Return size in bytes of filesystem on device (integer)."""
|
||||
dummy, stdout, dummy = self.module.run_command([self.module.get_bin_path(self.INFO),
|
||||
'show-super', str(dev)], check_rc=True)
|
||||
|
||||
for line in stdout.splitlines():
|
||||
if "Size: " in line:
|
||||
parts = line.split()
|
||||
unit = parts[2]
|
||||
|
||||
base = None
|
||||
exp = None
|
||||
|
||||
units_2 = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]
|
||||
units_10 = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
|
||||
|
||||
try:
|
||||
exp = units_2.index(unit)
|
||||
base = 1024
|
||||
except ValueError:
|
||||
exp = units_10.index(unit)
|
||||
base = 1000
|
||||
|
||||
if exp == 0:
|
||||
value = int(parts[1])
|
||||
else:
|
||||
value = float(parts[1])
|
||||
|
||||
if base is not None and exp is not None:
|
||||
return int(value * pow(base, exp))
|
||||
|
||||
raise ValueError(repr(stdout))
|
||||
|
||||
|
||||
class Btrfs(Filesystem):
|
||||
MKFS = 'mkfs.btrfs'
|
||||
INFO = 'btrfs'
|
||||
@@ -610,7 +567,6 @@ class UFS(Filesystem):
|
||||
|
||||
|
||||
FILESYSTEMS = {
|
||||
'bcachefs': Bcachefs,
|
||||
'ext2': Ext2,
|
||||
'ext3': Ext3,
|
||||
'ext4': Ext4,
|
||||
|
||||
@@ -26,9 +26,7 @@ extends_documentation_fragment:
|
||||
- community.general.attributes
|
||||
attributes:
|
||||
check_mode:
|
||||
support: partial
|
||||
details:
|
||||
- If O(state=latest), the module will always return C(changed=true).
|
||||
support: full
|
||||
diff_mode:
|
||||
support: none
|
||||
options:
|
||||
@@ -55,12 +53,12 @@ options:
|
||||
- Both C(https://) and C(http://) URLs are supported.
|
||||
- When supplying a reverse DNS name, you can use the O(remote) option to specify on what remote
|
||||
to look for the flatpak. An example for a reverse DNS name is C(org.gnome.gedit).
|
||||
- When used with O(state=absent) or O(state=latest), it is recommended to specify the name in
|
||||
the reverse DNS format.
|
||||
- When supplying a URL with O(state=absent) or O(state=latest), the module will try to match the
|
||||
installed flatpak based on the name of the flatpakref to remove or update it. However, there
|
||||
is no guarantee that the names of the flatpakref file and the reverse DNS name of the
|
||||
installed flatpak do match.
|
||||
- When used with O(state=absent), it is recommended to specify the name in the reverse DNS
|
||||
format.
|
||||
- When supplying a URL with O(state=absent), the module will try to match the
|
||||
installed flatpak based on the name of the flatpakref to remove it. However, there is no
|
||||
guarantee that the names of the flatpakref file and the reverse DNS name of the installed
|
||||
flatpak do match.
|
||||
type: list
|
||||
elements: str
|
||||
required: true
|
||||
@@ -84,8 +82,7 @@ options:
|
||||
state:
|
||||
description:
|
||||
- Indicates the desired package state.
|
||||
- The value V(latest) is supported since community.general 8.6.0.
|
||||
choices: [ absent, present, latest ]
|
||||
choices: [ absent, present ]
|
||||
type: str
|
||||
default: present
|
||||
'''
|
||||
@@ -121,37 +118,6 @@ EXAMPLES = r'''
|
||||
- org.inkscape.Inkscape
|
||||
- org.mozilla.firefox
|
||||
|
||||
- name: Update the spotify flatpak
|
||||
community.general.flatpak:
|
||||
name: https://s3.amazonaws.com/alexlarsson/spotify-repo/spotify.flatpakref
|
||||
state: latest
|
||||
|
||||
- name: Update the gedit flatpak package without dependencies (not recommended)
|
||||
community.general.flatpak:
|
||||
name: https://git.gnome.org/browse/gnome-apps-nightly/plain/gedit.flatpakref
|
||||
state: latest
|
||||
no_dependencies: true
|
||||
|
||||
- name: Update the gedit package from flathub for current user
|
||||
community.general.flatpak:
|
||||
name: org.gnome.gedit
|
||||
state: latest
|
||||
method: user
|
||||
|
||||
- name: Update the Gnome Calendar flatpak from the gnome remote system-wide
|
||||
community.general.flatpak:
|
||||
name: org.gnome.Calendar
|
||||
state: latest
|
||||
remote: gnome
|
||||
|
||||
- name: Update multiple packages
|
||||
community.general.flatpak:
|
||||
name:
|
||||
- org.gimp.GIMP
|
||||
- org.inkscape.Inkscape
|
||||
- org.mozilla.firefox
|
||||
state: latest
|
||||
|
||||
- name: Remove the gedit flatpak
|
||||
community.general.flatpak:
|
||||
name: org.gnome.gedit
|
||||
@@ -229,28 +195,6 @@ def install_flat(module, binary, remote, names, method, no_dependencies):
|
||||
result['changed'] = True
|
||||
|
||||
|
||||
def update_flat(module, binary, names, method, no_dependencies):
|
||||
"""Update existing flatpaks."""
|
||||
global result # pylint: disable=global-variable-not-assigned
|
||||
installed_flat_names = [
|
||||
_match_installed_flat_name(module, binary, name, method)
|
||||
for name in names
|
||||
]
|
||||
command = [binary, "update", "--{0}".format(method)]
|
||||
flatpak_version = _flatpak_version(module, binary)
|
||||
if LooseVersion(flatpak_version) < LooseVersion('1.1.3'):
|
||||
command += ["-y"]
|
||||
else:
|
||||
command += ["--noninteractive"]
|
||||
if no_dependencies:
|
||||
command += ["--no-deps"]
|
||||
command += installed_flat_names
|
||||
stdout = _flatpak_command(module, module.check_mode, command)
|
||||
result["changed"] = (
|
||||
True if module.check_mode else stdout.find("Nothing to do.") == -1
|
||||
)
|
||||
|
||||
|
||||
def uninstall_flat(module, binary, names, method):
|
||||
"""Remove existing flatpaks."""
|
||||
global result # pylint: disable=global-variable-not-assigned
|
||||
@@ -369,7 +313,7 @@ def main():
|
||||
method=dict(type='str', default='system',
|
||||
choices=['user', 'system']),
|
||||
state=dict(type='str', default='present',
|
||||
choices=['absent', 'present', 'latest']),
|
||||
choices=['absent', 'present']),
|
||||
no_dependencies=dict(type='bool', default=False),
|
||||
executable=dict(type='path', default='flatpak')
|
||||
),
|
||||
@@ -394,13 +338,10 @@ def main():
|
||||
module.fail_json(msg="Executable '%s' was not found on the system." % executable, **result)
|
||||
|
||||
installed, not_installed = flatpak_exists(module, binary, name, method)
|
||||
if state == 'absent' and installed:
|
||||
if state == 'present' and not_installed:
|
||||
install_flat(module, binary, remote, not_installed, method, no_dependencies)
|
||||
elif state == 'absent' and installed:
|
||||
uninstall_flat(module, binary, installed, method)
|
||||
else:
|
||||
if state == 'latest' and installed:
|
||||
update_flat(module, binary, installed, method, no_dependencies)
|
||||
if state in ('present', 'latest') and not_installed:
|
||||
install_flat(module, binary, remote, not_installed, method, no_dependencies)
|
||||
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
211
plugins/modules/flowdock.py
Normal file
211
plugins/modules/flowdock.py
Normal file
@@ -0,0 +1,211 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2013 Matt Coddington <coddington@gmail.com>
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
|
||||
deprecated:
|
||||
removed_in: 9.0.0
|
||||
why: the endpoints this module relies on do not exist any more and do not resolve to IPs in DNS.
|
||||
alternative: no known alternative at this point
|
||||
|
||||
module: flowdock
|
||||
author: "Matt Coddington (@mcodd)"
|
||||
short_description: Send a message to a flowdock
|
||||
description:
|
||||
- Send a message to a flowdock team inbox or chat using the push API (see https://www.flowdock.com/api/team-inbox and https://www.flowdock.com/api/chat)
|
||||
extends_documentation_fragment:
|
||||
- community.general.attributes
|
||||
attributes:
|
||||
check_mode:
|
||||
support: full
|
||||
diff_mode:
|
||||
support: none
|
||||
options:
|
||||
token:
|
||||
type: str
|
||||
description:
|
||||
- API token.
|
||||
required: true
|
||||
type:
|
||||
type: str
|
||||
description:
|
||||
- Whether to post to 'inbox' or 'chat'
|
||||
required: true
|
||||
choices: [ "inbox", "chat" ]
|
||||
msg:
|
||||
type: str
|
||||
description:
|
||||
- Content of the message
|
||||
required: true
|
||||
tags:
|
||||
type: str
|
||||
description:
|
||||
- tags of the message, separated by commas
|
||||
required: false
|
||||
external_user_name:
|
||||
type: str
|
||||
description:
|
||||
- (chat only - required) Name of the "user" sending the message
|
||||
required: false
|
||||
from_address:
|
||||
type: str
|
||||
description:
|
||||
- (inbox only - required) Email address of the message sender
|
||||
required: false
|
||||
source:
|
||||
type: str
|
||||
description:
|
||||
- (inbox only - required) Human readable identifier of the application that uses the Flowdock API
|
||||
required: false
|
||||
subject:
|
||||
type: str
|
||||
description:
|
||||
- (inbox only - required) Subject line of the message
|
||||
required: false
|
||||
from_name:
|
||||
type: str
|
||||
description:
|
||||
- (inbox only) Name of the message sender
|
||||
required: false
|
||||
reply_to:
|
||||
type: str
|
||||
description:
|
||||
- (inbox only) Email address for replies
|
||||
required: false
|
||||
project:
|
||||
type: str
|
||||
description:
|
||||
- (inbox only) Human readable identifier for more detailed message categorization
|
||||
required: false
|
||||
link:
|
||||
type: str
|
||||
description:
|
||||
- (inbox only) Link associated with the message. This will be used to link the message subject in Team Inbox.
|
||||
required: false
|
||||
validate_certs:
|
||||
description:
|
||||
- If V(false), SSL certificates will not be validated. This should only be used
|
||||
on personally controlled sites using self-signed certificates.
|
||||
required: false
|
||||
default: true
|
||||
type: bool
|
||||
|
||||
requirements: [ ]
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Send a message to a flowdock
|
||||
community.general.flowdock:
|
||||
type: inbox
|
||||
token: AAAAAA
|
||||
from_address: user@example.com
|
||||
source: my cool app
|
||||
msg: test from ansible
|
||||
subject: test subject
|
||||
|
||||
- name: Send a message to a flowdock
|
||||
community.general.flowdock:
|
||||
type: chat
|
||||
token: AAAAAA
|
||||
external_user_name: testuser
|
||||
msg: test from ansible
|
||||
tags: tag1,tag2,tag3
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlencode
|
||||
from ansible.module_utils.urls import fetch_url
|
||||
|
||||
|
||||
# ===========================================
|
||||
# Module execution.
|
||||
#
|
||||
|
||||
def main():
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
token=dict(required=True, no_log=True),
|
||||
msg=dict(required=True),
|
||||
type=dict(required=True, choices=["inbox", "chat"]),
|
||||
external_user_name=dict(required=False),
|
||||
from_address=dict(required=False),
|
||||
source=dict(required=False),
|
||||
subject=dict(required=False),
|
||||
from_name=dict(required=False),
|
||||
reply_to=dict(required=False),
|
||||
project=dict(required=False),
|
||||
tags=dict(required=False),
|
||||
link=dict(required=False),
|
||||
validate_certs=dict(default=True, type='bool'),
|
||||
),
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
type = module.params["type"]
|
||||
token = module.params["token"]
|
||||
if type == 'inbox':
|
||||
url = "https://api.flowdock.com/v1/messages/team_inbox/%s" % (token)
|
||||
else:
|
||||
url = "https://api.flowdock.com/v1/messages/chat/%s" % (token)
|
||||
|
||||
params = {}
|
||||
|
||||
# required params
|
||||
params['content'] = module.params["msg"]
|
||||
|
||||
# required params for the 'chat' type
|
||||
if module.params['external_user_name']:
|
||||
if type == 'inbox':
|
||||
module.fail_json(msg="external_user_name is not valid for the 'inbox' type")
|
||||
else:
|
||||
params['external_user_name'] = module.params["external_user_name"]
|
||||
elif type == 'chat':
|
||||
module.fail_json(msg="external_user_name is required for the 'chat' type")
|
||||
|
||||
# required params for the 'inbox' type
|
||||
for item in ['from_address', 'source', 'subject']:
|
||||
if module.params[item]:
|
||||
if type == 'chat':
|
||||
module.fail_json(msg="%s is not valid for the 'chat' type" % item)
|
||||
else:
|
||||
params[item] = module.params[item]
|
||||
elif type == 'inbox':
|
||||
module.fail_json(msg="%s is required for the 'inbox' type" % item)
|
||||
|
||||
# optional params
|
||||
if module.params["tags"]:
|
||||
params['tags'] = module.params["tags"]
|
||||
|
||||
# optional params for the 'inbox' type
|
||||
for item in ['from_name', 'reply_to', 'project', 'link']:
|
||||
if module.params[item]:
|
||||
if type == 'chat':
|
||||
module.fail_json(msg="%s is not valid for the 'chat' type" % item)
|
||||
else:
|
||||
params[item] = module.params[item]
|
||||
|
||||
# If we're in check mode, just exit pretending like we succeeded
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=False)
|
||||
|
||||
# Send the data to Flowdock
|
||||
data = urlencode(params)
|
||||
response, info = fetch_url(module, url, data=data)
|
||||
if info['status'] != 200:
|
||||
module.fail_json(msg="unable to send msg: %s" % info['msg'])
|
||||
|
||||
module.exit_json(changed=True, msg=module.params["msg"])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -25,19 +25,11 @@ attributes:
|
||||
diff_mode:
|
||||
support: none
|
||||
options:
|
||||
personal_access_token:
|
||||
description:
|
||||
- Scoped API token.
|
||||
- One of O(personal_access_token) and O(api_key) must be specified.
|
||||
type: str
|
||||
version_added: 9.0.0
|
||||
api_key:
|
||||
description:
|
||||
- Account API token.
|
||||
- Note that these type of keys are deprecated and might stop working at some point.
|
||||
Use personal access tokens instead.
|
||||
- One of O(personal_access_token) and O(api_key) must be specified.
|
||||
type: str
|
||||
required: true
|
||||
record:
|
||||
description:
|
||||
- Record to add.
|
||||
@@ -81,7 +73,7 @@ EXAMPLES = r'''
|
||||
values:
|
||||
- 127.0.0.1
|
||||
ttl: 7200
|
||||
personal_access_token: dummytoken
|
||||
api_key: dummyapitoken
|
||||
register: record
|
||||
|
||||
- name: Create a mail CNAME record to www.my.com domain
|
||||
@@ -92,7 +84,7 @@ EXAMPLES = r'''
|
||||
values:
|
||||
- www
|
||||
ttl: 7200
|
||||
personal_access_token: dummytoken
|
||||
api_key: dummyapitoken
|
||||
state: present
|
||||
|
||||
- name: Change its TTL
|
||||
@@ -103,7 +95,7 @@ EXAMPLES = r'''
|
||||
values:
|
||||
- www
|
||||
ttl: 10800
|
||||
personal_access_token: dummytoken
|
||||
api_key: dummyapitoken
|
||||
state: present
|
||||
|
||||
- name: Delete the record
|
||||
@@ -111,18 +103,8 @@ EXAMPLES = r'''
|
||||
domain: my.com
|
||||
type: CNAME
|
||||
record: mail
|
||||
personal_access_token: dummytoken
|
||||
api_key: dummyapitoken
|
||||
state: absent
|
||||
|
||||
- name: Use a (deprecated) API Key
|
||||
community.general.gandi_livedns:
|
||||
domain: my.com
|
||||
record: test
|
||||
type: A
|
||||
values:
|
||||
- 127.0.0.1
|
||||
ttl: 7200
|
||||
api_key: dummyapikey
|
||||
'''
|
||||
|
||||
RETURN = r'''
|
||||
@@ -169,8 +151,7 @@ from ansible_collections.community.general.plugins.module_utils.gandi_livedns_ap
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
api_key=dict(type='str', no_log=True),
|
||||
personal_access_token=dict(type='str', no_log=True),
|
||||
api_key=dict(type='str', required=True, no_log=True),
|
||||
record=dict(type='str', required=True),
|
||||
state=dict(type='str', default='present', choices=['absent', 'present']),
|
||||
ttl=dict(type='int'),
|
||||
@@ -182,12 +163,6 @@ def main():
|
||||
required_if=[
|
||||
('state', 'present', ['values', 'ttl']),
|
||||
],
|
||||
mutually_exclusive=[
|
||||
('api_key', 'personal_access_token'),
|
||||
],
|
||||
required_one_of=[
|
||||
('api_key', 'personal_access_token'),
|
||||
],
|
||||
)
|
||||
|
||||
gandi_api = GandiLiveDNSAPI(module)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user