mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-29 09:56:53 +00:00
Compare commits
84 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92203378fd | ||
|
|
bf1a0450fe | ||
|
|
1d2e10b812 | ||
|
|
77c42e7e18 | ||
|
|
a339f97d89 | ||
|
|
75dce4b1de | ||
|
|
ec2fa9fa52 | ||
|
|
e40cb558c6 | ||
|
|
9552140d23 | ||
|
|
83d1c6ea8f | ||
|
|
c572ff2501 | ||
|
|
e8d276e689 | ||
|
|
78113c061b | ||
|
|
2ffcda21dd | ||
|
|
515e6832e6 | ||
|
|
a71a35a19e | ||
|
|
96d191d549 | ||
|
|
e294cc2aa4 | ||
|
|
f7baaafae2 | ||
|
|
32dad20033 | ||
|
|
231fae71cc | ||
|
|
f7c8a89328 | ||
|
|
b0e518967d | ||
|
|
55a3ca024d | ||
|
|
323c95437b | ||
|
|
2473c08ed2 | ||
|
|
e879afd802 | ||
|
|
56c5a8b9b2 | ||
|
|
78de6f2494 | ||
|
|
316b36862f | ||
|
|
a110f6eb4b | ||
|
|
512a46a18c | ||
|
|
d97c7aa777 | ||
|
|
4a32f7bc56 | ||
|
|
49ae02d445 | ||
|
|
1b609a34ae | ||
|
|
e6c90cc52c | ||
|
|
15a80aa004 | ||
|
|
b9ea3ce19b | ||
|
|
f314ab6679 | ||
|
|
25778a8da4 | ||
|
|
c40a1e561a | ||
|
|
aaee4a5a59 | ||
|
|
e600fe573f | ||
|
|
3f79a173a8 | ||
|
|
08eac051f4 | ||
|
|
5f20d7f109 | ||
|
|
96f8d1b8a1 | ||
|
|
f7276b152b | ||
|
|
5e503bfcc7 | ||
|
|
d2b4151b7a | ||
|
|
57b73e0d5e | ||
|
|
5f47d47f27 | ||
|
|
7e2f20f482 | ||
|
|
3023312334 | ||
|
|
fe3de232f0 | ||
|
|
2024dc37af | ||
|
|
b8469a5c28 | ||
|
|
2a0ec9c572 | ||
|
|
fa92f8efb0 | ||
|
|
03e068e298 | ||
|
|
8f084ac065 | ||
|
|
e02568d28a | ||
|
|
73580d09e0 | ||
|
|
093036a2ae | ||
|
|
7f1de4869e | ||
|
|
8df1b93531 | ||
|
|
c055ea2bcc | ||
|
|
27c094a095 | ||
|
|
86a5b4f28c | ||
|
|
4e14c429c7 | ||
|
|
c34fb01462 | ||
|
|
2086977af6 | ||
|
|
587d221376 | ||
|
|
5ed6b38477 | ||
|
|
2c0cfe4d16 | ||
|
|
c344d20a9a | ||
|
|
53480b25c8 | ||
|
|
cfffaa5b6f | ||
|
|
726918930b | ||
|
|
614a84d0f2 | ||
|
|
a11022e896 | ||
|
|
491196937d | ||
|
|
af7a6dc29f |
@@ -24,14 +24,15 @@ schedules:
|
||||
always: true
|
||||
branches:
|
||||
include:
|
||||
- stable-2
|
||||
- stable-3
|
||||
- stable-4
|
||||
- cron: 0 11 * * 0
|
||||
displayName: Weekly (old stable branches)
|
||||
always: true
|
||||
branches:
|
||||
include:
|
||||
- stable-1
|
||||
- stable-2
|
||||
|
||||
variables:
|
||||
- name: checkoutPath
|
||||
@@ -54,14 +55,14 @@ pool: Standard
|
||||
|
||||
stages:
|
||||
### Sanity
|
||||
- stage: Sanity_devel
|
||||
displayName: Sanity devel
|
||||
- stage: Sanity_2_13
|
||||
displayName: Sanity 2.13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Test {0}
|
||||
testFormat: devel/sanity/{0}
|
||||
testFormat: 2.13/sanity/{0}
|
||||
targets:
|
||||
- test: 1
|
||||
- test: 2
|
||||
@@ -121,14 +122,14 @@ stages:
|
||||
- test: 3
|
||||
- test: 4
|
||||
### Units
|
||||
- stage: Units_devel
|
||||
displayName: Units devel
|
||||
- stage: Units_2_13
|
||||
displayName: Units 2.13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: devel/units/{0}/1
|
||||
testFormat: 2.13/units/{0}/1
|
||||
targets:
|
||||
- test: 2.7
|
||||
- test: 3.5
|
||||
@@ -197,22 +198,22 @@ stages:
|
||||
- test: 3.8
|
||||
|
||||
## Remote
|
||||
- stage: Remote_devel
|
||||
displayName: Remote devel
|
||||
- stage: Remote_2_13
|
||||
displayName: Remote 2.13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: devel/{0}
|
||||
testFormat: 2.13/{0}
|
||||
targets:
|
||||
- name: macOS 11.1
|
||||
test: macos/11.1
|
||||
- name: macOS 12.0
|
||||
test: macos/12.0
|
||||
- name: RHEL 7.9
|
||||
test: rhel/7.9
|
||||
- name: RHEL 8.5
|
||||
test: rhel/8.5
|
||||
- name: FreeBSD 12.2
|
||||
test: freebsd/12.2
|
||||
- name: FreeBSD 12.3
|
||||
test: freebsd/12.3
|
||||
- name: FreeBSD 13.0
|
||||
test: freebsd/13.0
|
||||
groups:
|
||||
@@ -287,13 +288,13 @@ stages:
|
||||
- 2
|
||||
|
||||
### Docker
|
||||
- stage: Docker_devel
|
||||
displayName: Docker devel
|
||||
- stage: Docker_2_13
|
||||
displayName: Docker 2.13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: devel/linux/{0}
|
||||
testFormat: 2.13/linux/{0}
|
||||
targets:
|
||||
- name: CentOS 7
|
||||
test: centos7
|
||||
@@ -323,8 +324,6 @@ stages:
|
||||
targets:
|
||||
- name: CentOS 6
|
||||
test: centos6
|
||||
- name: CentOS 8
|
||||
test: centos8
|
||||
- name: Fedora 34
|
||||
test: fedora34
|
||||
- name: openSUSE 15 py3
|
||||
@@ -384,14 +383,14 @@ stages:
|
||||
- 3
|
||||
|
||||
### Cloud
|
||||
- stage: Cloud_devel
|
||||
displayName: Cloud devel
|
||||
- stage: Cloud_2_13
|
||||
displayName: Cloud 2.13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
nameFormat: Python {0}
|
||||
testFormat: devel/cloud/{0}/1
|
||||
testFormat: 2.13/cloud/{0}/1
|
||||
targets:
|
||||
- test: 2.7
|
||||
- test: 3.9
|
||||
@@ -438,27 +437,27 @@ stages:
|
||||
- stage: Summary
|
||||
condition: succeededOrFailed()
|
||||
dependsOn:
|
||||
- Sanity_devel
|
||||
- Sanity_2_13
|
||||
- Sanity_2_9
|
||||
- Sanity_2_10
|
||||
- Sanity_2_11
|
||||
- Sanity_2_12
|
||||
- Units_devel
|
||||
- Units_2_13
|
||||
- Units_2_9
|
||||
- Units_2_10
|
||||
- Units_2_11
|
||||
- Units_2_12
|
||||
- Remote_devel
|
||||
- Remote_2_13
|
||||
- Remote_2_9
|
||||
- Remote_2_10
|
||||
- Remote_2_11
|
||||
- Remote_2_12
|
||||
- Docker_devel
|
||||
- Docker_2_13
|
||||
- Docker_2_9
|
||||
- Docker_2_10
|
||||
- Docker_2_11
|
||||
- Docker_2_12
|
||||
- Cloud_devel
|
||||
- Cloud_2_13
|
||||
- Cloud_2_9
|
||||
- Cloud_2_10
|
||||
- Cloud_2_11
|
||||
|
||||
25
.github/BOTMETA.yml
vendored
25
.github/BOTMETA.yml
vendored
@@ -156,7 +156,7 @@ files:
|
||||
maintainers: conloos
|
||||
$inventories/nmap.py: {}
|
||||
$inventories/online.py:
|
||||
maintainers: sieben
|
||||
maintainers: remyleone
|
||||
$inventories/opennebula.py:
|
||||
maintainers: feldsam
|
||||
labels: cloud opennebula
|
||||
@@ -164,7 +164,7 @@ files:
|
||||
$inventories/proxmox.py:
|
||||
maintainers: $team_virt ilijamt
|
||||
$inventories/icinga2.py:
|
||||
maintainers: bongoeadgc6
|
||||
maintainers: BongoEADGC6
|
||||
$inventories/scaleway.py:
|
||||
maintainers: $team_scaleway
|
||||
labels: cloud scaleway
|
||||
@@ -320,6 +320,10 @@ files:
|
||||
$modules/cloud/misc/proxmox_kvm.py:
|
||||
maintainers: helldorado
|
||||
ignore: skvidal
|
||||
$modules/cloud/misc/proxmox_nic.py:
|
||||
maintainers: Kogelvis
|
||||
$modules/cloud/misc/proxmox_tasks_info:
|
||||
maintainers: paginabianca
|
||||
$modules/cloud/misc/proxmox_template.py:
|
||||
maintainers: UnderGreen
|
||||
ignore: skvidal
|
||||
@@ -339,7 +343,7 @@ files:
|
||||
$modules/cloud/oneandone/:
|
||||
maintainers: aajdinov edevenport
|
||||
$modules/cloud/online/:
|
||||
maintainers: sieben
|
||||
maintainers: remyleone
|
||||
$modules/cloud/opennebula/:
|
||||
maintainers: $team_opennebula
|
||||
$modules/cloud/opennebula/one_host.py:
|
||||
@@ -409,11 +413,11 @@ files:
|
||||
$modules/cloud/scaleway/scaleway_ip_info.py:
|
||||
maintainers: Spredzy
|
||||
$modules/cloud/scaleway/scaleway_organization_info.py:
|
||||
maintainers: sieben Spredzy
|
||||
maintainers: Spredzy
|
||||
$modules/cloud/scaleway/scaleway_security_group.py:
|
||||
maintainers: DenBeke
|
||||
$modules/cloud/scaleway/scaleway_security_group_info.py:
|
||||
maintainers: sieben Spredzy
|
||||
maintainers: Spredzy
|
||||
$modules/cloud/scaleway/scaleway_security_group_rule.py:
|
||||
maintainers: DenBeke
|
||||
$modules/cloud/scaleway/scaleway_server_info.py:
|
||||
@@ -914,6 +918,10 @@ files:
|
||||
$modules/remote_management/manageiq/:
|
||||
labels: manageiq
|
||||
maintainers: $team_manageiq
|
||||
$modules/remote_management/manageiq/manageiq_alert_profiles.py:
|
||||
maintainers: elad661
|
||||
$modules/remote_management/manageiq/manageiq_alerts.py:
|
||||
maintainers: elad661
|
||||
$modules/remote_management/manageiq/manageiq_group.py:
|
||||
maintainers: evertmulder
|
||||
$modules/remote_management/manageiq/manageiq_tenant.py:
|
||||
@@ -1155,7 +1163,8 @@ files:
|
||||
$modules/web_infrastructure/jenkins_script.py:
|
||||
maintainers: hogarthj
|
||||
$modules/web_infrastructure/jira.py:
|
||||
maintainers: Slezhuk tarka pertoft DWSR
|
||||
maintainers: Slezhuk tarka pertoft
|
||||
ignore: DWSR
|
||||
labels: jira
|
||||
$modules/web_infrastructure/nginx_status_info.py:
|
||||
maintainers: resmo
|
||||
@@ -1221,7 +1230,7 @@ macros:
|
||||
team_cyberark_conjur: jvanderhoof ryanprior
|
||||
team_e_spirit: MatrixCrawler getjack
|
||||
team_flatpak: JayKayy oolongbrothers
|
||||
team_gitlab: Lunik Shaps dj-wasabi marwatk waheedi zanssa scodeman metanovii sh0shin
|
||||
team_gitlab: Lunik Shaps dj-wasabi marwatk waheedi zanssa scodeman metanovii sh0shin nejch lgatellier suukit
|
||||
team_hpux: bcoca davx8342
|
||||
team_huawei: QijunPan TommyLike edisonxiang freesky-edward hwDCN niuzhenguo xuxiaowei0512 yanzhangi zengchen1024 zhongjun2
|
||||
team_ipa: Akasurde Nosmoht fxfitz justchris1
|
||||
@@ -1236,7 +1245,7 @@ macros:
|
||||
team_purestorage: bannaych dnix101 genegr lionmax opslounge raekins sdodsley sile16
|
||||
team_redfish: mraineri tomasg2012 xmadsen renxulei
|
||||
team_rhn: FlossWare alikins barnabycourt vritant
|
||||
team_scaleway: QuentinBrosse abarbare jerome-quere kindermoumoute remyleone sieben
|
||||
team_scaleway: remyleone abarbare
|
||||
team_solaris: bcoca fishman jasperla jpdasma mator scathatheworm troy2914 xen0l
|
||||
team_suse: commel dcermak evrardjp lrupp toabctl AnderEnder alxgu andytom sealor
|
||||
team_virt: joshainglis karmab tleguern Thulium-Drake Ajpantuso
|
||||
|
||||
@@ -6,6 +6,97 @@ Community General Release Notes
|
||||
|
||||
This changelog describes changes after version 2.0.0.
|
||||
|
||||
v3.8.6
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix release.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- dsv lookup plugin - raise an Ansible error if the wrong ``python-dsv-sdk`` version is installed (https://github.com/ansible-collections/community.general/pull/4422).
|
||||
- filesize - add support for busybox dd implementation, that is used by default on Alpine linux (https://github.com/ansible-collections/community.general/pull/4288, https://github.com/ansible-collections/community.general/issues/4259).
|
||||
- proxmox inventory plugin - always convert strings that follow the ``key=value[,key=value[...]]`` form into dictionaries (https://github.com/ansible-collections/community.general/pull/4349).
|
||||
- proxmox inventory plugin - fixed the ``description`` field being ignored if it contained a comma (https://github.com/ansible-collections/community.general/issues/4348).
|
||||
- zypper - fixed bug that caused zypper to always report [ok] and do nothing on ``state=present`` when all packages in ``name`` had a version specification (https://github.com/ansible-collections/community.general/issues/4371, https://github.com/ansible-collections/community.general/pull/4421).
|
||||
|
||||
v3.8.5
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix release.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- dconf - skip processes that disappeared while we inspected them (https://github.com/ansible-collections/community.general/issues/4151).
|
||||
- gitlab_runner - use correct API endpoint to create and retrieve project level runners when using ``project`` (https://github.com/ansible-collections/community.general/pull/3965).
|
||||
- homebrew_cask - fix force install operation (https://github.com/ansible-collections/community.general/issues/3703).
|
||||
- imc_rest - fixes the module failure due to the usage of ``itertools.izip_longest`` which is not available in Python 3 (https://github.com/ansible-collections/community.general/issues/4206).
|
||||
- ini_file - when removing nothing do not report changed (https://github.com/ansible-collections/community.general/issues/4154).
|
||||
- keycloak_user_federation - creating a user federation while specifying an ID (that does not exist yet) no longer fail with a 404 Not Found (https://github.com/ansible-collections/community.general/pull/4212).
|
||||
- keycloak_user_federation - mappers auto-created by keycloak are matched and merged by their name and no longer create duplicated entries (https://github.com/ansible-collections/community.general/pull/4212).
|
||||
- mail callback plugin - fix crash on Python 3 (https://github.com/ansible-collections/community.general/issues/4025, https://github.com/ansible-collections/community.general/pull/4026).
|
||||
- passwordstore lookup plugin - fix error detection for non-English locales (https://github.com/ansible-collections/community.general/pull/4219).
|
||||
- passwordstore lookup plugin - prevent returning path names as passwords by accident (https://github.com/ansible-collections/community.general/issues/4185, https://github.com/ansible-collections/community.general/pull/4192).
|
||||
- python_requirements_info - store ``mismatched`` return values per package as documented in the module (https://github.com/ansible-collections/community.general/pull/4078).
|
||||
- vdo - fix options error (https://github.com/ansible-collections/community.general/pull/4163).
|
||||
- yarn - fix incorrect handling of ``yarn list`` and ``yarn global list`` output that could result in fatal error (https://github.com/ansible-collections/community.general/pull/4050).
|
||||
- yarn - fix incorrectly reported status when installing a package globally (https://github.com/ansible-collections/community.general/issues/4045, https://github.com/ansible-collections/community.general/pull/4050).
|
||||
- yarn - fix missing ``~`` expansion in yarn global install folder which resulted in incorrect task status (https://github.com/ansible-collections/community.general/issues/4045, https://github.com/ansible-collections/community.general/pull/4048).
|
||||
- yum_versionlock - fix matching of existing entries with names passed to the module. Match yum and dnf lock format (https://github.com/ansible-collections/community.general/pull/4183).
|
||||
|
||||
v3.8.4
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix release.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Various modules and plugins - use vendored version of ``distutils.version`` instead of the deprecated Python standard library ``distutils`` (https://github.com/ansible-collections/community.general/pull/3936).
|
||||
- alternatives - fix output parsing for alternatives groups (https://github.com/ansible-collections/community.general/pull/3976).
|
||||
- jail connection plugin - replace deprecated ``distutils.spawn.find_executable`` with Ansible's ``get_bin_path`` to find the executable (https://github.com/ansible-collections/community.general/pull/3934).
|
||||
- jira - fixed bug where module returns error related to dictionary key ``body`` (https://github.com/ansible-collections/community.general/issues/3419).
|
||||
- lxd connection plugin - replace deprecated ``distutils.spawn.find_executable`` with Ansible's ``get_bin_path`` to find the ``lxc`` executable (https://github.com/ansible-collections/community.general/pull/3934).
|
||||
- nrdp callback plugin - fix error ``string arguments without an encoding`` (https://github.com/ansible-collections/community.general/issues/3903).
|
||||
- passwordstore lookup plugin - replace deprecated ``distutils.util.strtobool`` with Ansible's ``convert_bool.boolean`` to interpret values for the ``create``, ``returnall``, ``overwrite``, 'backup``, and ``nosymbols`` options (https://github.com/ansible-collections/community.general/pull/3934).
|
||||
- say callback plugin - replace deprecated ``distutils.spawn.find_executable`` with Ansible's ``get_bin_path`` to find the ``say`` resp. ``espeak`` executables (https://github.com/ansible-collections/community.general/pull/3934).
|
||||
- scaleway_user_data - fix double-quote added where no double-quote is needed to user data in scaleway's server (``Content-type`` -> ``Content-Type``) (https://github.com/ansible-collections/community.general/pull/3940).
|
||||
- slack - add ``charset`` to HTTP headers to avoid Slack API warning (https://github.com/ansible-collections/community.general/issues/3932).
|
||||
- zone connection plugin - replace deprecated ``distutils.spawn.find_executable`` with Ansible's ``get_bin_path`` to find the executable (https://github.com/ansible-collections/community.general/pull/3934).
|
||||
|
||||
v3.8.3
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- lxd connection plugin - make sure that ``ansible_lxd_host``, ``ansible_executable``, and ``ansible_lxd_executable`` work (https://github.com/ansible-collections/community.general/pull/3798).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- interfaces_file - fixed the check for existing option in interface (https://github.com/ansible-collections/community.general/issues/3841).
|
||||
- nmcli - fix returning "changed" when no mask set for IPv4 or IPv6 addresses on task rerun (https://github.com/ansible-collections/community.general/issues/3768).
|
||||
- nmcli - pass ``flags``, ``ingress``, ``egress`` params to ``nmcli`` (https://github.com/ansible-collections/community.general/issues/1086).
|
||||
- opentelemetry_plugin - honour ``ignore_errors`` when a task has failed instead of reporting an error (https://github.com/ansible-collections/community.general/pull/3837).
|
||||
- pipx - passes the correct command line option ``--include-apps`` (https://github.com/ansible-collections/community.general/issues/3791).
|
||||
- proxmox - fixed ``onboot`` parameter causing module failures when undefined (https://github.com/ansible-collections/community.general/issues/3844).
|
||||
|
||||
v3.8.2
|
||||
======
|
||||
|
||||
|
||||
@@ -24,7 +24,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 respository checkout.
|
||||
* Do not add merge commits to your PR. The bot will complain and you will have to rebase ([instructions for rebasing](https://docs.ansible.com/ansible/latest/dev_guide/developing_rebasing.html)) to remove them before your PR can be merged. To avoid that git automatically does merges during pulls, you can configure it to do rebases instead by running `git config pull.rebase true` inside the repository checkout.
|
||||
* Make sure your PR includes a [changelog fragment](https://docs.ansible.com/ansible/devel/community/development_process.html#changelogs-how-to). (You must not include a fragment for new modules or new plugins, except for test and filter 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.
|
||||
|
||||
@@ -36,6 +36,54 @@ If you want to test a PR locally, refer to [our testing guide](https://github.co
|
||||
|
||||
If you find any inconsistencies or places in this document which can be improved, feel free to raise an issue or pull request to fix it.
|
||||
|
||||
## Run sanity, unit or integration tests locally
|
||||
|
||||
You have to check out the repository into a specific path structure to be able to run `ansible-test`. The path to the git checkout must end with `.../ansible_collections/community/general`. Please see [our testing guide](https://github.com/ansible/community-docs/blob/main/test_pr_locally_guide.rst) for instructions on how to check out the repository into a correct path structure. The short version of these instructions is:
|
||||
|
||||
```.bash
|
||||
mkdir -p ~/dev/ansible_collections/community
|
||||
git clone https://github.com/ansible-collections/community.general.git ~/dev/ansible_collections/community/general
|
||||
cd ~/dev/ansible_collections/community/general
|
||||
```
|
||||
|
||||
Then you can run `ansible-test` (which is a part of [ansible-core](https://pypi.org/project/ansible-core/)) inside the checkout. The following example commands expect that you have installed Docker or Podman. Note that Podman has only been supported by more recent ansible-core releases. If you are using Docker, the following will work with Ansible 2.9+.
|
||||
|
||||
The following commands show how to run sanity tests:
|
||||
|
||||
```.bash
|
||||
# Run sanity tests for all files in the collection:
|
||||
ansible-test sanity --docker -v
|
||||
|
||||
# Run sanity tests for the given files and directories:
|
||||
ansible-test sanity --docker -v plugins/modules/system/pids.py tests/integration/targets/pids/
|
||||
```
|
||||
|
||||
The following commands show how to run unit tests:
|
||||
|
||||
```.bash
|
||||
# Run all unit tests:
|
||||
ansible-test units --docker -v
|
||||
|
||||
# Run all unit tests for one Python version (a lot faster):
|
||||
ansible-test units --docker -v --python 3.8
|
||||
|
||||
# Run a specific unit test (for the nmcli module) for one Python version:
|
||||
ansible-test units --docker -v --python 3.8 tests/unit/plugins/modules/net_tools/test_nmcli.py
|
||||
```
|
||||
|
||||
The following commands show how to run integration tests:
|
||||
|
||||
```.bash
|
||||
# Run integration tests for the interfaces_files module in a Docker container using the
|
||||
# fedora35 operating system image (the supported images depend on your ansible-core version):
|
||||
ansible-test integration --docker fedora35 -v interfaces_file
|
||||
|
||||
# Run integration tests for the flattened lookup **without any isolation**:
|
||||
ansible-test integration -v lookup_flattened
|
||||
```
|
||||
|
||||
If you are unsure about the integration test target name for a module or plugin, you can take a look in `tests/integration/targets/`. Tests for plugins have the plugin type prepended.
|
||||
|
||||
## Creating new modules or plugins
|
||||
|
||||
Creating new modules and plugins requires a bit more work than other Pull Requests.
|
||||
|
||||
@@ -17,7 +17,7 @@ If you encounter abusive behavior violating the [Ansible Code of Conduct](https:
|
||||
|
||||
## Tested with Ansible
|
||||
|
||||
Tested with the current Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported.
|
||||
Tested with the current Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12 and ansible-core 2.13 releases. Ansible versions before 2.9.10 are not supported.
|
||||
|
||||
## External requirements
|
||||
|
||||
|
||||
@@ -2004,3 +2004,139 @@ releases:
|
||||
- 3709-support-batch-mode.yml
|
||||
- 3726-terraform-missing-parameters-planned-fix.yml
|
||||
release_date: '2021-11-23'
|
||||
3.8.3:
|
||||
changes:
|
||||
bugfixes:
|
||||
- interfaces_file - fixed the check for existing option in interface (https://github.com/ansible-collections/community.general/issues/3841).
|
||||
- nmcli - fix returning "changed" when no mask set for IPv4 or IPv6 addresses
|
||||
on task rerun (https://github.com/ansible-collections/community.general/issues/3768).
|
||||
- nmcli - pass ``flags``, ``ingress``, ``egress`` params to ``nmcli`` (https://github.com/ansible-collections/community.general/issues/1086).
|
||||
- opentelemetry_plugin - honour ``ignore_errors`` when a task has failed instead
|
||||
of reporting an error (https://github.com/ansible-collections/community.general/pull/3837).
|
||||
- pipx - passes the correct command line option ``--include-apps`` (https://github.com/ansible-collections/community.general/issues/3791).
|
||||
- proxmox - fixed ``onboot`` parameter causing module failures when undefined
|
||||
(https://github.com/ansible-collections/community.general/issues/3844).
|
||||
minor_changes:
|
||||
- lxd connection plugin - make sure that ``ansible_lxd_host``, ``ansible_executable``,
|
||||
and ``ansible_lxd_executable`` work (https://github.com/ansible-collections/community.general/pull/3798).
|
||||
release_summary: Regular bugfix release.
|
||||
fragments:
|
||||
- 3.8.3.yml
|
||||
- 3768-nmcli_fix_changed_when_no_mask_set.yml
|
||||
- 3798-fix-lxd-connection-option-vars-support.yml
|
||||
- 3800-pipx-include-apps.yaml
|
||||
- 3837-opentelemetry_plugin-honour_ignore_errors.yaml
|
||||
- 3862-interfaces-file-fix-dup-option.yaml
|
||||
- 3874-proxmox-fix-onboot-param.yml
|
||||
- 3896-nmcli_vlan_missing_options.yaml
|
||||
release_date: '2021-12-14'
|
||||
3.8.4:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Various modules and plugins - use vendored version of ``distutils.version``
|
||||
instead of the deprecated Python standard library ``distutils`` (https://github.com/ansible-collections/community.general/pull/3936).
|
||||
- alternatives - fix output parsing for alternatives groups (https://github.com/ansible-collections/community.general/pull/3976).
|
||||
- jail connection plugin - replace deprecated ``distutils.spawn.find_executable``
|
||||
with Ansible's ``get_bin_path`` to find the executable (https://github.com/ansible-collections/community.general/pull/3934).
|
||||
- jira - fixed bug where module returns error related to dictionary key ``body``
|
||||
(https://github.com/ansible-collections/community.general/issues/3419).
|
||||
- lxd connection plugin - replace deprecated ``distutils.spawn.find_executable``
|
||||
with Ansible's ``get_bin_path`` to find the ``lxc`` executable (https://github.com/ansible-collections/community.general/pull/3934).
|
||||
- nrdp callback plugin - fix error ``string arguments without an encoding``
|
||||
(https://github.com/ansible-collections/community.general/issues/3903).
|
||||
- passwordstore lookup plugin - replace deprecated ``distutils.util.strtobool``
|
||||
with Ansible's ``convert_bool.boolean`` to interpret values for the ``create``,
|
||||
``returnall``, ``overwrite``, 'backup``, and ``nosymbols`` options (https://github.com/ansible-collections/community.general/pull/3934).
|
||||
- say callback plugin - replace deprecated ``distutils.spawn.find_executable``
|
||||
with Ansible's ``get_bin_path`` to find the ``say`` resp. ``espeak`` executables
|
||||
(https://github.com/ansible-collections/community.general/pull/3934).
|
||||
- scaleway_user_data - fix double-quote added where no double-quote is needed
|
||||
to user data in scaleway's server (``Content-type`` -> ``Content-Type``) (https://github.com/ansible-collections/community.general/pull/3940).
|
||||
- slack - add ``charset`` to HTTP headers to avoid Slack API warning (https://github.com/ansible-collections/community.general/issues/3932).
|
||||
- zone connection plugin - replace deprecated ``distutils.spawn.find_executable``
|
||||
with Ansible's ``get_bin_path`` to find the executable (https://github.com/ansible-collections/community.general/pull/3934).
|
||||
release_summary: Regular bugfix release.
|
||||
fragments:
|
||||
- 3.8.4.yml
|
||||
- 3867-jira-fix-body.yaml
|
||||
- 3909-nrdp_fix_string_args_without_encoding.yaml
|
||||
- 3933-slack-charset-header.yaml
|
||||
- 3934-distutils.yml
|
||||
- 3936-distutils.version.yml
|
||||
- 3940_fix_contenttype_scaleway_user_data.yml
|
||||
- 3976-fix-alternatives-parsing.yml
|
||||
release_date: '2022-01-11'
|
||||
3.8.5:
|
||||
changes:
|
||||
bugfixes:
|
||||
- dconf - skip processes that disappeared while we inspected them (https://github.com/ansible-collections/community.general/issues/4151).
|
||||
- gitlab_runner - use correct API endpoint to create and retrieve project level
|
||||
runners when using ``project`` (https://github.com/ansible-collections/community.general/pull/3965).
|
||||
- homebrew_cask - fix force install operation (https://github.com/ansible-collections/community.general/issues/3703).
|
||||
- imc_rest - fixes the module failure due to the usage of ``itertools.izip_longest``
|
||||
which is not available in Python 3 (https://github.com/ansible-collections/community.general/issues/4206).
|
||||
- ini_file - when removing nothing do not report changed (https://github.com/ansible-collections/community.general/issues/4154).
|
||||
- keycloak_user_federation - creating a user federation while specifying an
|
||||
ID (that does not exist yet) no longer fail with a 404 Not Found (https://github.com/ansible-collections/community.general/pull/4212).
|
||||
- keycloak_user_federation - mappers auto-created by keycloak are matched and
|
||||
merged by their name and no longer create duplicated entries (https://github.com/ansible-collections/community.general/pull/4212).
|
||||
- mail callback plugin - fix crash on Python 3 (https://github.com/ansible-collections/community.general/issues/4025,
|
||||
https://github.com/ansible-collections/community.general/pull/4026).
|
||||
- passwordstore lookup plugin - fix error detection for non-English locales
|
||||
(https://github.com/ansible-collections/community.general/pull/4219).
|
||||
- passwordstore lookup plugin - prevent returning path names as passwords by
|
||||
accident (https://github.com/ansible-collections/community.general/issues/4185,
|
||||
https://github.com/ansible-collections/community.general/pull/4192).
|
||||
- python_requirements_info - store ``mismatched`` return values per package
|
||||
as documented in the module (https://github.com/ansible-collections/community.general/pull/4078).
|
||||
- vdo - fix options error (https://github.com/ansible-collections/community.general/pull/4163).
|
||||
- yarn - fix incorrect handling of ``yarn list`` and ``yarn global list`` output
|
||||
that could result in fatal error (https://github.com/ansible-collections/community.general/pull/4050).
|
||||
- yarn - fix incorrectly reported status when installing a package globally
|
||||
(https://github.com/ansible-collections/community.general/issues/4045, https://github.com/ansible-collections/community.general/pull/4050).
|
||||
- yarn - fix missing ``~`` expansion in yarn global install folder which resulted
|
||||
in incorrect task status (https://github.com/ansible-collections/community.general/issues/4045,
|
||||
https://github.com/ansible-collections/community.general/pull/4048).
|
||||
- yum_versionlock - fix matching of existing entries with names passed to the
|
||||
module. Match yum and dnf lock format (https://github.com/ansible-collections/community.general/pull/4183).
|
||||
release_summary: Regular bugfix release.
|
||||
fragments:
|
||||
- 3.8.5.yml
|
||||
- 3703-force-install-homebrew-cask.yml
|
||||
- 3916-fix-vdo-options-type.yml
|
||||
- 3935-use-gitlab-instance-runner-to-create-runner.yml
|
||||
- 4026-fix-mail-callback.yml
|
||||
- 4048-expand-tilde-in-yarn-global-install-folder.yaml
|
||||
- 4050-properly-parse-json-lines-output-from-yarn.yaml
|
||||
- 4078-python_requirements_info.yaml
|
||||
- 4151-dconf-catch-psutil-nosuchprocess.yaml
|
||||
- 4154-ini_file_changed.yml
|
||||
- 4183-fix-yum_versionlock.yaml
|
||||
- 4192-improve-passwordstore-consistency.yml
|
||||
- 4206-imc-rest-module.yaml
|
||||
- 4212-fixes-for-keycloak-user-federation.yml
|
||||
- 4219-passwordstore-locale-fix.yml
|
||||
release_date: '2022-02-22'
|
||||
3.8.6:
|
||||
changes:
|
||||
bugfixes:
|
||||
- dsv lookup plugin - raise an Ansible error if the wrong ``python-dsv-sdk``
|
||||
version is installed (https://github.com/ansible-collections/community.general/pull/4422).
|
||||
- filesize - add support for busybox dd implementation, that is used by default
|
||||
on Alpine linux (https://github.com/ansible-collections/community.general/pull/4288,
|
||||
https://github.com/ansible-collections/community.general/issues/4259).
|
||||
- proxmox inventory plugin - always convert strings that follow the ``key=value[,key=value[...]]``
|
||||
form into dictionaries (https://github.com/ansible-collections/community.general/pull/4349).
|
||||
- proxmox inventory plugin - fixed the ``description`` field being ignored if
|
||||
it contained a comma (https://github.com/ansible-collections/community.general/issues/4348).
|
||||
- zypper - fixed bug that caused zypper to always report [ok] and do nothing
|
||||
on ``state=present`` when all packages in ``name`` had a version specification
|
||||
(https://github.com/ansible-collections/community.general/issues/4371, https://github.com/ansible-collections/community.general/pull/4421).
|
||||
release_summary: Regular bugfix release.
|
||||
fragments:
|
||||
- 3.8.6.yml
|
||||
- 4288-fix-4259-support-busybox-dd.yml
|
||||
- 4349-proxmox-inventory-dict-facts.yml
|
||||
- 4421-zypper_package_version_handling_fix.yml
|
||||
- 4422-warn-user-if-incorrect-SDK-version-is-installed.yaml
|
||||
release_date: '2022-04-05'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace: community
|
||||
name: general
|
||||
version: 3.8.2
|
||||
version: 3.8.6
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (https://github.com/ansible)
|
||||
|
||||
1
plugins/cache/memcached.py
vendored
1
plugins/cache/memcached.py
vendored
@@ -20,6 +20,7 @@ DOCUMENTATION = '''
|
||||
- List of connection information for the memcached DBs
|
||||
default: ['127.0.0.1:11211']
|
||||
type: list
|
||||
elements: string
|
||||
env:
|
||||
- name: ANSIBLE_CACHE_PLUGIN_CONNECTION
|
||||
ini:
|
||||
|
||||
@@ -100,28 +100,21 @@ class CallbackModule(CallbackBase):
|
||||
|
||||
smtp = smtplib.SMTP(self.smtphost, port=self.smtpport)
|
||||
|
||||
b_sender = to_bytes(self.sender)
|
||||
b_to = to_bytes(self.to)
|
||||
b_cc = to_bytes(self.cc)
|
||||
b_bcc = to_bytes(self.bcc)
|
||||
b_subject = to_bytes(subject)
|
||||
b_body = to_bytes(body)
|
||||
|
||||
b_content = b'From: %s\n' % b_sender
|
||||
b_content += b'To: %s\n' % b_to
|
||||
content = 'From: %s\n' % self.sender
|
||||
content += 'To: %s\n' % self.to
|
||||
if self.cc:
|
||||
b_content += b'Cc: %s\n' % b_cc
|
||||
b_content += b'Subject: %s\n\n' % b_subject
|
||||
b_content += b_body
|
||||
content += 'Cc: %s\n' % self.cc
|
||||
content += 'Subject: %s\n\n' % subject.strip()
|
||||
content += body
|
||||
|
||||
b_addresses = b_to.split(b',')
|
||||
addresses = self.to.split(',')
|
||||
if self.cc:
|
||||
b_addresses += b_cc.split(b',')
|
||||
addresses += self.cc.split(',')
|
||||
if self.bcc:
|
||||
b_addresses += b_bcc.split(b',')
|
||||
addresses += self.bcc.split(',')
|
||||
|
||||
for b_address in b_addresses:
|
||||
smtp.sendmail(b_sender, b_address, b_content)
|
||||
for address in addresses:
|
||||
smtp.sendmail(self.sender, address, to_bytes(content))
|
||||
|
||||
smtp.quit()
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ import os
|
||||
import json
|
||||
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlencode
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
@@ -143,7 +144,7 @@ class CallbackModule(CallbackBase):
|
||||
body = {
|
||||
'cmd': 'submitcheck',
|
||||
'token': self.token,
|
||||
'XMLDATA': bytes(xmldata)
|
||||
'XMLDATA': to_bytes(xmldata)
|
||||
}
|
||||
|
||||
try:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# (C) 2021, Victor Martinez <VictorMartinezRubio@gmail.com>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
@@ -263,6 +264,8 @@ class OpenTelemetrySource(object):
|
||||
else:
|
||||
message = 'skipped'
|
||||
status = Status(status_code=StatusCode.UNSET)
|
||||
elif host_data.status == 'ignored':
|
||||
status = Status(status_code=StatusCode.UNSET)
|
||||
|
||||
span.set_status(status)
|
||||
self.set_span_attribute(span, "ansible.task.args", task_data.args)
|
||||
@@ -392,10 +395,15 @@ class CallbackModule(CallbackBase):
|
||||
)
|
||||
|
||||
def v2_runner_on_failed(self, result, ignore_errors=False):
|
||||
self.errors += 1
|
||||
if ignore_errors:
|
||||
status = 'ignored'
|
||||
else:
|
||||
status = 'failed'
|
||||
self.errors += 1
|
||||
|
||||
self.opentelemetry.finish_task(
|
||||
self.tasks_data,
|
||||
'failed',
|
||||
status,
|
||||
result
|
||||
)
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@ DOCUMENTATION = '''
|
||||
- In 2.8, this callback has been renamed from C(osx_say) into M(community.general.say).
|
||||
'''
|
||||
|
||||
import distutils.spawn
|
||||
import platform
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
|
||||
@@ -47,21 +47,24 @@ class CallbackModule(CallbackBase):
|
||||
self.HAPPY_VOICE = None
|
||||
self.LASER_VOICE = None
|
||||
|
||||
self.synthesizer = distutils.spawn.find_executable('say')
|
||||
if not self.synthesizer:
|
||||
self.synthesizer = distutils.spawn.find_executable('espeak')
|
||||
if self.synthesizer:
|
||||
try:
|
||||
self.synthesizer = get_bin_path('say')
|
||||
if platform.system() != 'Darwin':
|
||||
# 'say' binary available, it might be GNUstep tool which doesn't support 'voice' parameter
|
||||
self._display.warning("'say' executable found but system is '%s': ignoring voice parameter" % platform.system())
|
||||
else:
|
||||
self.FAILED_VOICE = 'Zarvox'
|
||||
self.REGULAR_VOICE = 'Trinoids'
|
||||
self.HAPPY_VOICE = 'Cellos'
|
||||
self.LASER_VOICE = 'Princess'
|
||||
except ValueError:
|
||||
try:
|
||||
self.synthesizer = get_bin_path('espeak')
|
||||
self.FAILED_VOICE = 'klatt'
|
||||
self.HAPPY_VOICE = 'f5'
|
||||
self.LASER_VOICE = 'whisper'
|
||||
elif platform.system() != 'Darwin':
|
||||
# 'say' binary available, it might be GNUstep tool which doesn't support 'voice' parameter
|
||||
self._display.warning("'say' executable found but system is '%s': ignoring voice parameter" % platform.system())
|
||||
else:
|
||||
self.FAILED_VOICE = 'Zarvox'
|
||||
self.REGULAR_VOICE = 'Trinoids'
|
||||
self.HAPPY_VOICE = 'Cellos'
|
||||
self.LASER_VOICE = 'Princess'
|
||||
except ValueError:
|
||||
self.synthesizer = None
|
||||
|
||||
# plugin disable itself if say is not present
|
||||
# ansible will not call any callback if disabled is set to True
|
||||
|
||||
@@ -31,7 +31,6 @@ DOCUMENTATION = '''
|
||||
- name: ansible_jail_user
|
||||
'''
|
||||
|
||||
import distutils.spawn
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
@@ -39,6 +38,7 @@ import traceback
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.six.moves import shlex_quote
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||
from ansible.plugins.connection import ConnectionBase, BUFSIZE
|
||||
from ansible.utils.display import Display
|
||||
@@ -75,10 +75,10 @@ class Connection(ConnectionBase):
|
||||
|
||||
@staticmethod
|
||||
def _search_executable(executable):
|
||||
cmd = distutils.spawn.find_executable(executable)
|
||||
if not cmd:
|
||||
try:
|
||||
return get_bin_path(executable)
|
||||
except ValueError:
|
||||
raise AnsibleError("%s command not found in PATH" % executable)
|
||||
return cmd
|
||||
|
||||
def list_jails(self):
|
||||
p = subprocess.Popen([self.jls_cmd, '-q', 'name'],
|
||||
|
||||
@@ -43,10 +43,10 @@ DOCUMENTATION = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
from distutils.spawn import find_executable
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
from ansible.plugins.connection import ConnectionBase
|
||||
|
||||
@@ -62,9 +62,9 @@ class Connection(ConnectionBase):
|
||||
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
|
||||
|
||||
self._host = self._play_context.remote_addr
|
||||
self._lxc_cmd = find_executable("lxc")
|
||||
|
||||
if not self._lxc_cmd:
|
||||
try:
|
||||
self._lxc_cmd = get_bin_path("lxc")
|
||||
except ValueError:
|
||||
raise AnsibleError("lxc command not found in PATH")
|
||||
|
||||
if self._play_context.remote_user is not None and self._play_context.remote_user != 'root':
|
||||
@@ -89,9 +89,9 @@ class Connection(ConnectionBase):
|
||||
local_cmd.extend(["--project", self.get_option("project")])
|
||||
local_cmd.extend([
|
||||
"exec",
|
||||
"%s:%s" % (self.get_option("remote"), self._host),
|
||||
"%s:%s" % (self.get_option("remote"), self.get_option("remote_addr")),
|
||||
"--",
|
||||
self._play_context.executable, "-c", cmd
|
||||
self.get_option("executable"), "-c", cmd
|
||||
])
|
||||
|
||||
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
|
||||
@@ -126,7 +126,7 @@ class Connection(ConnectionBase):
|
||||
local_cmd.extend([
|
||||
"file", "push",
|
||||
in_path,
|
||||
"%s:%s/%s" % (self.get_option("remote"), self._host, out_path)
|
||||
"%s:%s/%s" % (self.get_option("remote"), self.get_option("remote_addr"), out_path)
|
||||
])
|
||||
|
||||
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
|
||||
@@ -145,7 +145,7 @@ class Connection(ConnectionBase):
|
||||
local_cmd.extend(["--project", self.get_option("project")])
|
||||
local_cmd.extend([
|
||||
"file", "pull",
|
||||
"%s:%s/%s" % (self.get_option("remote"), self._host, in_path),
|
||||
"%s:%s/%s" % (self.get_option("remote"), self.get_option("remote_addr"), in_path),
|
||||
out_path
|
||||
])
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ DOCUMENTATION = '''
|
||||
- name: ansible_zone_host
|
||||
'''
|
||||
|
||||
import distutils.spawn
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
@@ -34,6 +33,7 @@ import traceback
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.six.moves import shlex_quote
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.plugins.connection import ConnectionBase, BUFSIZE
|
||||
from ansible.utils.display import Display
|
||||
@@ -64,10 +64,10 @@ class Connection(ConnectionBase):
|
||||
|
||||
@staticmethod
|
||||
def _search_executable(executable):
|
||||
cmd = distutils.spawn.find_executable(executable)
|
||||
if not cmd:
|
||||
try:
|
||||
return get_bin_path(executable)
|
||||
except ValueError:
|
||||
raise AnsibleError("%s command not found in PATH" % executable)
|
||||
return cmd
|
||||
|
||||
def list_zones(self):
|
||||
process = subprocess.Popen([self.zoneadm_cmd, 'list', '-ip'],
|
||||
|
||||
@@ -38,8 +38,10 @@ options:
|
||||
version_added: 2.0.0
|
||||
server_uri:
|
||||
description:
|
||||
- A URI to the LDAP server.
|
||||
- The I(server_uri) parameter may be a comma- or whitespace-separated list of URIs containing only the schema, the host, and the port fields.
|
||||
- The default value lets the underlying LDAP client library look for a UNIX domain socket in its default location.
|
||||
- Note that when using multiple URIs you cannot determine to which URI your client gets connected.
|
||||
- For URIs containing additional fields, particularly when using commas, behavior is undefined.
|
||||
type: str
|
||||
default: ldapi:///
|
||||
start_tls:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
|
||||
def version_sort(value, reverse=False):
|
||||
|
||||
@@ -47,6 +47,7 @@ DOCUMENTATION = '''
|
||||
group_by:
|
||||
description: Keys to group hosts by
|
||||
type: list
|
||||
elements: string
|
||||
default: [ 'mgmt_classes', 'owners', 'status' ]
|
||||
group:
|
||||
description: Group to place all hosts into
|
||||
@@ -68,7 +69,6 @@ user: ansible-tester
|
||||
password: secure
|
||||
'''
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
import socket
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
|
||||
@@ -35,7 +35,6 @@ DOCUMENTATION = '''
|
||||
version_added: 1.0.0
|
||||
type: str
|
||||
required: true
|
||||
default: https://gitlab.com
|
||||
api_token:
|
||||
description: GitLab token for logging in.
|
||||
env:
|
||||
|
||||
@@ -43,15 +43,18 @@ DOCUMENTATION = r'''
|
||||
description: Populate inventory with instances in this region.
|
||||
default: []
|
||||
type: list
|
||||
elements: string
|
||||
tags:
|
||||
description: Populate inventory only with instances which have at least one of the tags listed here.
|
||||
default: []
|
||||
type: list
|
||||
elements: string
|
||||
version_added: 2.0.0
|
||||
types:
|
||||
description: Populate inventory with instances with this type.
|
||||
default: []
|
||||
type: list
|
||||
elements: string
|
||||
strict:
|
||||
version_added: 2.0.0
|
||||
compose:
|
||||
|
||||
@@ -27,6 +27,7 @@ DOCUMENTATION = '''
|
||||
exclude:
|
||||
description: list of addresses to exclude
|
||||
type: list
|
||||
elements: string
|
||||
ports:
|
||||
description: Enable/disable scanning for open ports
|
||||
type: boolean
|
||||
|
||||
@@ -8,7 +8,7 @@ __metaclass__ = type
|
||||
DOCUMENTATION = r'''
|
||||
name: online
|
||||
author:
|
||||
- Remy Leone (@sieben)
|
||||
- Remy Leone (@remyleone)
|
||||
short_description: Scaleway (previously Online SAS or Online.net) inventory source
|
||||
description:
|
||||
- Get inventory hosts from Scaleway (previously Online SAS or Online.net).
|
||||
@@ -28,6 +28,7 @@ DOCUMENTATION = r'''
|
||||
hostnames:
|
||||
description: List of preference about what to use as an hostname.
|
||||
type: list
|
||||
elements: string
|
||||
default:
|
||||
- public_ipv4
|
||||
choices:
|
||||
@@ -37,6 +38,7 @@ DOCUMENTATION = r'''
|
||||
groups:
|
||||
description: List of groups.
|
||||
type: list
|
||||
elements: string
|
||||
choices:
|
||||
- location
|
||||
- offer
|
||||
|
||||
@@ -114,17 +114,34 @@ groups:
|
||||
mailservers: "'mail' in (proxmox_tags_parsed|list)"
|
||||
compose:
|
||||
ansible_port: 2222
|
||||
|
||||
# Using the inventory to allow ansible to connect via the first IP address of the VM / Container
|
||||
# (Default is connection by name of QEMU/LXC guests)
|
||||
# Note: my_inv_var demonstrates how to add a string variable to every host used by the inventory.
|
||||
# my.proxmox.yml
|
||||
plugin: community.general.proxmox
|
||||
url: http://pve.domain.com:8006
|
||||
user: ansible@pve
|
||||
password: secure
|
||||
validate_certs: false
|
||||
want_facts: true
|
||||
compose:
|
||||
ansible_host: proxmox_ipconfig0.ip | default(proxmox_net0.ip) | ipaddr('address')
|
||||
my_inv_var_1: "'my_var1_value'"
|
||||
my_inv_var_2: >
|
||||
"my_var_2_value"
|
||||
'''
|
||||
|
||||
import re
|
||||
|
||||
from ansible.module_utils.common._collections_compat import MutableMapping
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlencode
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
# 3rd party imports
|
||||
try:
|
||||
import requests
|
||||
@@ -290,7 +307,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
self.inventory.set_variable(name, vmtype_key, vmtype)
|
||||
|
||||
plaintext_configs = [
|
||||
'tags',
|
||||
'description',
|
||||
]
|
||||
|
||||
for config in ret:
|
||||
@@ -316,11 +333,11 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
if agent_iface_value:
|
||||
self.inventory.set_variable(name, agent_iface_key, agent_iface_value)
|
||||
|
||||
if not (isinstance(value, int) or ',' not in value):
|
||||
if config not in plaintext_configs and not isinstance(value, int) and all("=" in v for v in value.split(",")):
|
||||
# split off strings with commas to a dict
|
||||
# skip over any keys that cannot be processed
|
||||
try:
|
||||
value = dict(key.split("=") for key in value.split(","))
|
||||
value = dict(key.split("=", 1) for key in value.split(","))
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ __metaclass__ = type
|
||||
DOCUMENTATION = r'''
|
||||
name: scaleway
|
||||
author:
|
||||
- Remy Leone (@sieben)
|
||||
- Remy Leone (@remyleone)
|
||||
short_description: Scaleway inventory source
|
||||
description:
|
||||
- Get inventory hosts from Scaleway.
|
||||
@@ -23,6 +23,7 @@ DOCUMENTATION = r'''
|
||||
regions:
|
||||
description: Filter results on a specific Scaleway region.
|
||||
type: list
|
||||
elements: string
|
||||
default:
|
||||
- ams1
|
||||
- par1
|
||||
@@ -31,6 +32,7 @@ DOCUMENTATION = r'''
|
||||
tags:
|
||||
description: Filter results on a specific tag.
|
||||
type: list
|
||||
elements: string
|
||||
oauth_token:
|
||||
description:
|
||||
- Scaleway OAuth token.
|
||||
@@ -45,6 +47,7 @@ DOCUMENTATION = r'''
|
||||
hostnames:
|
||||
description: List of preference about what to use as an hostname.
|
||||
type: list
|
||||
elements: string
|
||||
default:
|
||||
- public_ipv4
|
||||
choices:
|
||||
|
||||
@@ -20,6 +20,7 @@ DOCUMENTATION = '''
|
||||
_raw:
|
||||
description: List of key(s) to retrieve.
|
||||
type: list
|
||||
elements: string
|
||||
recurse:
|
||||
type: boolean
|
||||
description: If true, will retrieve all the values that have the given key as prefix.
|
||||
|
||||
@@ -17,11 +17,11 @@ DOCUMENTATION = '''
|
||||
_terms:
|
||||
description: term or list of terms to lookup in the credit store
|
||||
type: list
|
||||
required: True
|
||||
elements: string
|
||||
required: true
|
||||
table:
|
||||
description: name of the credstash table to query
|
||||
default: 'credential-store'
|
||||
required: True
|
||||
version:
|
||||
description: Credstash version
|
||||
region:
|
||||
|
||||
@@ -18,6 +18,7 @@ DOCUMENTATION = '''
|
||||
description: domain or list of domains to query TXT records from
|
||||
required: True
|
||||
type: list
|
||||
elements: string
|
||||
'''
|
||||
|
||||
EXAMPLES = """
|
||||
|
||||
@@ -105,11 +105,15 @@ display = Display()
|
||||
class LookupModule(LookupBase):
|
||||
@staticmethod
|
||||
def Client(vault_parameters):
|
||||
return SecretsVault(**vault_parameters)
|
||||
try:
|
||||
vault = SecretsVault(**vault_parameters)
|
||||
return vault
|
||||
except TypeError:
|
||||
raise AnsibleError("python-dsv-sdk==0.0.1 must be installed to use this plugin")
|
||||
|
||||
def run(self, terms, variables, **kwargs):
|
||||
if sdk_is_missing:
|
||||
raise AnsibleError("python-dsv-sdk must be installed to use this plugin")
|
||||
raise AnsibleError("python-dsv-sdk==0.0.1 must be installed to use this plugin")
|
||||
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ DOCUMENTATION = '''
|
||||
environment variable and keep I(endpoints), I(host), and I(port) unused.
|
||||
seealso:
|
||||
- module: community.general.etcd3
|
||||
- ref: etcd_lookup
|
||||
- ref: ansible_collections.community.general.etcd_lookup
|
||||
description: The etcd v2 lookup.
|
||||
|
||||
requirements:
|
||||
|
||||
@@ -23,7 +23,7 @@ DOCUMENTATION = '''
|
||||
EXAMPLES = """
|
||||
- name: "'unnest' all elements into single list"
|
||||
ansible.builtin.debug:
|
||||
msg: "all in one list {{lookup('community.general.flattened', [1,2,3,[5,6]], [a,b,c], [[5,6,1,3], [34,a,b,c]])}}"
|
||||
msg: "all in one list {{lookup('community.general.flattened', [1,2,3,[5,6]], ['a','b','c'], [[5,6,1,3], [34,'a','b','c']])}}"
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
||||
@@ -48,7 +48,6 @@ options:
|
||||
- The CIDR of the network to retrieve the next network from next available network within the
|
||||
specified container. Also, Requested CIDR must be specified and greater than the parent CIDR.
|
||||
required: True
|
||||
default: 24
|
||||
num:
|
||||
description: The number of network addresses to return from network-container
|
||||
required: false
|
||||
|
||||
@@ -141,9 +141,9 @@ import time
|
||||
import yaml
|
||||
|
||||
|
||||
from distutils import util
|
||||
from ansible.errors import AnsibleError, AnsibleAssertionError
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.parsing.convert_bool import boolean
|
||||
from ansible.utils.display import Display
|
||||
from ansible.utils.encrypt import random_password
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
@@ -154,6 +154,7 @@ display = Display()
|
||||
|
||||
# backhacked check_output with input for python 2.7
|
||||
# http://stackoverflow.com/questions/10103551/passing-data-to-subprocess-check-output
|
||||
# note: contains special logic for calling 'pass', so not a drop-in replacement for check_output
|
||||
def check_output2(*popenargs, **kwargs):
|
||||
if 'stdout' in kwargs:
|
||||
raise ValueError('stdout argument not allowed, it will be overridden.')
|
||||
@@ -175,9 +176,10 @@ def check_output2(*popenargs, **kwargs):
|
||||
process.wait()
|
||||
raise
|
||||
retcode = process.poll()
|
||||
if retcode != 0 or \
|
||||
b'encryption failed: Unusable public key' in b_out or \
|
||||
b'encryption failed: Unusable public key' in b_err:
|
||||
if retcode == 0 and (b'encryption failed: Unusable public key' in b_out or
|
||||
b'encryption failed: Unusable public key' in b_err):
|
||||
retcode = 78 # os.EX_CONFIG
|
||||
if retcode != 0:
|
||||
cmd = kwargs.get("args")
|
||||
if cmd is None:
|
||||
cmd = popenargs[0]
|
||||
@@ -211,7 +213,7 @@ class LookupModule(LookupBase):
|
||||
try:
|
||||
for key in ['create', 'returnall', 'overwrite', 'backup', 'nosymbols']:
|
||||
if not isinstance(self.paramvals[key], bool):
|
||||
self.paramvals[key] = util.strtobool(self.paramvals[key])
|
||||
self.paramvals[key] = boolean(self.paramvals[key])
|
||||
except (ValueError, AssertionError) as e:
|
||||
raise AnsibleError(e)
|
||||
if self.paramvals['missing'] not in ['error', 'warn', 'create', 'empty']:
|
||||
@@ -227,13 +229,13 @@ class LookupModule(LookupBase):
|
||||
|
||||
# Collect pass environment variables from the plugin's parameters.
|
||||
self.env = os.environ.copy()
|
||||
self.env['LANGUAGE'] = 'C' # make sure to get errors in English as required by check_output2
|
||||
|
||||
# Set PASSWORD_STORE_DIR if directory is set
|
||||
if self.paramvals['directory']:
|
||||
if os.path.isdir(self.paramvals['directory']):
|
||||
self.env['PASSWORD_STORE_DIR'] = self.paramvals['directory']
|
||||
else:
|
||||
raise AnsibleError('Passwordstore directory \'{0}\' does not exist'.format(self.paramvals['directory']))
|
||||
# Set PASSWORD_STORE_DIR
|
||||
if os.path.isdir(self.paramvals['directory']):
|
||||
self.env['PASSWORD_STORE_DIR'] = self.paramvals['directory']
|
||||
else:
|
||||
raise AnsibleError('Passwordstore directory \'{0}\' does not exist'.format(self.paramvals['directory']))
|
||||
|
||||
# Set PASSWORD_STORE_UMASK if umask is set
|
||||
if 'umask' in self.paramvals:
|
||||
@@ -261,19 +263,20 @@ class LookupModule(LookupBase):
|
||||
if ':' in line:
|
||||
name, value = line.split(':', 1)
|
||||
self.passdict[name.strip()] = value.strip()
|
||||
if os.path.isfile(os.path.join(self.paramvals['directory'], self.passname + ".gpg")):
|
||||
# Only accept password as found, if there a .gpg file for it (might be a tree node otherwise)
|
||||
return True
|
||||
except (subprocess.CalledProcessError) as e:
|
||||
if e.returncode != 0 and 'not in the password store' in e.output:
|
||||
# if pass returns 1 and return string contains 'is not in the password store.'
|
||||
# We need to determine if this is valid or Error.
|
||||
if self.paramvals['missing'] == 'error':
|
||||
raise AnsibleError('passwordstore: passname {0} not found and missing=error is set'.format(self.passname))
|
||||
else:
|
||||
if self.paramvals['missing'] == 'warn':
|
||||
display.warning('passwordstore: passname {0} not found'.format(self.passname))
|
||||
return False
|
||||
else:
|
||||
# 'not in password store' is the expected error if a password wasn't found
|
||||
if 'not in the password store' not in e.output:
|
||||
raise AnsibleError(e)
|
||||
return True
|
||||
|
||||
if self.paramvals['missing'] == 'error':
|
||||
raise AnsibleError('passwordstore: passname {0} not found and missing=error is set'.format(self.passname))
|
||||
elif self.paramvals['missing'] == 'warn':
|
||||
display.warning('passwordstore: passname {0} not found'.format(self.passname))
|
||||
|
||||
return False
|
||||
|
||||
def get_newpass(self):
|
||||
if self.paramvals['nosymbols']:
|
||||
@@ -329,7 +332,9 @@ class LookupModule(LookupBase):
|
||||
result = []
|
||||
self.paramvals = {
|
||||
'subkey': 'password',
|
||||
'directory': variables.get('passwordstore'),
|
||||
'directory': variables.get('passwordstore', os.environ.get(
|
||||
'PASSWORD_STORE_DIR',
|
||||
os.path.expanduser('~/.password-store'))),
|
||||
'create': False,
|
||||
'returnall': False,
|
||||
'overwrite': False,
|
||||
|
||||
@@ -14,6 +14,10 @@ description:
|
||||
- Uses the Thycotic Secret Server Python SDK to get Secrets from Secret
|
||||
Server using token authentication with I(username) and I(password) on
|
||||
the REST API at I(base_url).
|
||||
- When using self-signed certificates the environment variable
|
||||
C(REQUESTS_CA_BUNDLE) can be set to a file containing the trusted certificates
|
||||
(in C(.pem) format).
|
||||
- For example, C(export REQUESTS_CA_BUNDLE='/etc/ssl/certs/ca-bundle.trust.crt').
|
||||
requirements:
|
||||
- python-tss-sdk - https://pypi.org/project/python-tss-sdk/
|
||||
options:
|
||||
|
||||
343
plugins/module_utils/_version.py
Normal file
343
plugins/module_utils/_version.py
Normal file
@@ -0,0 +1,343 @@
|
||||
# Vendored copy of distutils/version.py from CPython 3.9.5
|
||||
#
|
||||
# Implements multiple version numbering conventions for the
|
||||
# Python Module Distribution Utilities.
|
||||
#
|
||||
# PSF License (see licenses/PSF-license.txt or https://opensource.org/licenses/Python-2.0)
|
||||
#
|
||||
|
||||
"""Provides classes to represent module version numbers (one class for
|
||||
each style of version numbering). There are currently two such classes
|
||||
implemented: StrictVersion and LooseVersion.
|
||||
|
||||
Every version number class implements the following interface:
|
||||
* the 'parse' method takes a string and parses it to some internal
|
||||
representation; if the string is an invalid version number,
|
||||
'parse' raises a ValueError exception
|
||||
* the class constructor takes an optional string argument which,
|
||||
if supplied, is passed to 'parse'
|
||||
* __str__ reconstructs the string that was passed to 'parse' (or
|
||||
an equivalent string -- ie. one that will generate an equivalent
|
||||
version number instance)
|
||||
* __repr__ generates Python code to recreate the version number instance
|
||||
* _cmp compares the current instance with either another instance
|
||||
of the same class or a string (which will be parsed to an instance
|
||||
of the same class, thus must follow the same rules)
|
||||
"""
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
import re
|
||||
|
||||
try:
|
||||
RE_FLAGS = re.VERBOSE | re.ASCII
|
||||
except AttributeError:
|
||||
RE_FLAGS = re.VERBOSE
|
||||
|
||||
|
||||
class Version:
|
||||
"""Abstract base class for version numbering classes. Just provides
|
||||
constructor (__init__) and reproducer (__repr__), because those
|
||||
seem to be the same for all version numbering classes; and route
|
||||
rich comparisons to _cmp.
|
||||
"""
|
||||
|
||||
def __init__(self, vstring=None):
|
||||
if vstring:
|
||||
self.parse(vstring)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s ('%s')" % (self.__class__.__name__, str(self))
|
||||
|
||||
def __eq__(self, other):
|
||||
c = self._cmp(other)
|
||||
if c is NotImplemented:
|
||||
return c
|
||||
return c == 0
|
||||
|
||||
def __lt__(self, other):
|
||||
c = self._cmp(other)
|
||||
if c is NotImplemented:
|
||||
return c
|
||||
return c < 0
|
||||
|
||||
def __le__(self, other):
|
||||
c = self._cmp(other)
|
||||
if c is NotImplemented:
|
||||
return c
|
||||
return c <= 0
|
||||
|
||||
def __gt__(self, other):
|
||||
c = self._cmp(other)
|
||||
if c is NotImplemented:
|
||||
return c
|
||||
return c > 0
|
||||
|
||||
def __ge__(self, other):
|
||||
c = self._cmp(other)
|
||||
if c is NotImplemented:
|
||||
return c
|
||||
return c >= 0
|
||||
|
||||
|
||||
# Interface for version-number classes -- must be implemented
|
||||
# by the following classes (the concrete ones -- Version should
|
||||
# be treated as an abstract class).
|
||||
# __init__ (string) - create and take same action as 'parse'
|
||||
# (string parameter is optional)
|
||||
# parse (string) - convert a string representation to whatever
|
||||
# internal representation is appropriate for
|
||||
# this style of version numbering
|
||||
# __str__ (self) - convert back to a string; should be very similar
|
||||
# (if not identical to) the string supplied to parse
|
||||
# __repr__ (self) - generate Python code to recreate
|
||||
# the instance
|
||||
# _cmp (self, other) - compare two version numbers ('other' may
|
||||
# be an unparsed version string, or another
|
||||
# instance of your version class)
|
||||
|
||||
|
||||
class StrictVersion(Version):
|
||||
"""Version numbering for anal retentives and software idealists.
|
||||
Implements the standard interface for version number classes as
|
||||
described above. A version number consists of two or three
|
||||
dot-separated numeric components, with an optional "pre-release" tag
|
||||
on the end. The pre-release tag consists of the letter 'a' or 'b'
|
||||
followed by a number. If the numeric components of two version
|
||||
numbers are equal, then one with a pre-release tag will always
|
||||
be deemed earlier (lesser) than one without.
|
||||
|
||||
The following are valid version numbers (shown in the order that
|
||||
would be obtained by sorting according to the supplied cmp function):
|
||||
|
||||
0.4 0.4.0 (these two are equivalent)
|
||||
0.4.1
|
||||
0.5a1
|
||||
0.5b3
|
||||
0.5
|
||||
0.9.6
|
||||
1.0
|
||||
1.0.4a3
|
||||
1.0.4b1
|
||||
1.0.4
|
||||
|
||||
The following are examples of invalid version numbers:
|
||||
|
||||
1
|
||||
2.7.2.2
|
||||
1.3.a4
|
||||
1.3pl1
|
||||
1.3c4
|
||||
|
||||
The rationale for this version numbering system will be explained
|
||||
in the distutils documentation.
|
||||
"""
|
||||
|
||||
version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$',
|
||||
RE_FLAGS)
|
||||
|
||||
def parse(self, vstring):
|
||||
match = self.version_re.match(vstring)
|
||||
if not match:
|
||||
raise ValueError("invalid version number '%s'" % vstring)
|
||||
|
||||
(major, minor, patch, prerelease, prerelease_num) = \
|
||||
match.group(1, 2, 4, 5, 6)
|
||||
|
||||
if patch:
|
||||
self.version = tuple(map(int, [major, minor, patch]))
|
||||
else:
|
||||
self.version = tuple(map(int, [major, minor])) + (0,)
|
||||
|
||||
if prerelease:
|
||||
self.prerelease = (prerelease[0], int(prerelease_num))
|
||||
else:
|
||||
self.prerelease = None
|
||||
|
||||
def __str__(self):
|
||||
if self.version[2] == 0:
|
||||
vstring = '.'.join(map(str, self.version[0:2]))
|
||||
else:
|
||||
vstring = '.'.join(map(str, self.version))
|
||||
|
||||
if self.prerelease:
|
||||
vstring = vstring + self.prerelease[0] + str(self.prerelease[1])
|
||||
|
||||
return vstring
|
||||
|
||||
def _cmp(self, other):
|
||||
if isinstance(other, str):
|
||||
other = StrictVersion(other)
|
||||
elif not isinstance(other, StrictVersion):
|
||||
return NotImplemented
|
||||
|
||||
if self.version != other.version:
|
||||
# numeric versions don't match
|
||||
# prerelease stuff doesn't matter
|
||||
if self.version < other.version:
|
||||
return -1
|
||||
else:
|
||||
return 1
|
||||
|
||||
# have to compare prerelease
|
||||
# case 1: neither has prerelease; they're equal
|
||||
# case 2: self has prerelease, other doesn't; other is greater
|
||||
# case 3: self doesn't have prerelease, other does: self is greater
|
||||
# case 4: both have prerelease: must compare them!
|
||||
|
||||
if (not self.prerelease and not other.prerelease):
|
||||
return 0
|
||||
elif (self.prerelease and not other.prerelease):
|
||||
return -1
|
||||
elif (not self.prerelease and other.prerelease):
|
||||
return 1
|
||||
elif (self.prerelease and other.prerelease):
|
||||
if self.prerelease == other.prerelease:
|
||||
return 0
|
||||
elif self.prerelease < other.prerelease:
|
||||
return -1
|
||||
else:
|
||||
return 1
|
||||
else:
|
||||
raise AssertionError("never get here")
|
||||
|
||||
# end class StrictVersion
|
||||
|
||||
# The rules according to Greg Stein:
|
||||
# 1) a version number has 1 or more numbers separated by a period or by
|
||||
# sequences of letters. If only periods, then these are compared
|
||||
# left-to-right to determine an ordering.
|
||||
# 2) sequences of letters are part of the tuple for comparison and are
|
||||
# compared lexicographically
|
||||
# 3) recognize the numeric components may have leading zeroes
|
||||
#
|
||||
# The LooseVersion class below implements these rules: a version number
|
||||
# string is split up into a tuple of integer and string components, and
|
||||
# comparison is a simple tuple comparison. This means that version
|
||||
# numbers behave in a predictable and obvious way, but a way that might
|
||||
# not necessarily be how people *want* version numbers to behave. There
|
||||
# wouldn't be a problem if people could stick to purely numeric version
|
||||
# numbers: just split on period and compare the numbers as tuples.
|
||||
# However, people insist on putting letters into their version numbers;
|
||||
# the most common purpose seems to be:
|
||||
# - indicating a "pre-release" version
|
||||
# ('alpha', 'beta', 'a', 'b', 'pre', 'p')
|
||||
# - indicating a post-release patch ('p', 'pl', 'patch')
|
||||
# but of course this can't cover all version number schemes, and there's
|
||||
# no way to know what a programmer means without asking him.
|
||||
#
|
||||
# The problem is what to do with letters (and other non-numeric
|
||||
# characters) in a version number. The current implementation does the
|
||||
# obvious and predictable thing: keep them as strings and compare
|
||||
# lexically within a tuple comparison. This has the desired effect if
|
||||
# an appended letter sequence implies something "post-release":
|
||||
# eg. "0.99" < "0.99pl14" < "1.0", and "5.001" < "5.001m" < "5.002".
|
||||
#
|
||||
# However, if letters in a version number imply a pre-release version,
|
||||
# the "obvious" thing isn't correct. Eg. you would expect that
|
||||
# "1.5.1" < "1.5.2a2" < "1.5.2", but under the tuple/lexical comparison
|
||||
# implemented here, this just isn't so.
|
||||
#
|
||||
# Two possible solutions come to mind. The first is to tie the
|
||||
# comparison algorithm to a particular set of semantic rules, as has
|
||||
# been done in the StrictVersion class above. This works great as long
|
||||
# as everyone can go along with bondage and discipline. Hopefully a
|
||||
# (large) subset of Python module programmers will agree that the
|
||||
# particular flavour of bondage and discipline provided by StrictVersion
|
||||
# provides enough benefit to be worth using, and will submit their
|
||||
# version numbering scheme to its domination. The free-thinking
|
||||
# anarchists in the lot will never give in, though, and something needs
|
||||
# to be done to accommodate them.
|
||||
#
|
||||
# Perhaps a "moderately strict" version class could be implemented that
|
||||
# lets almost anything slide (syntactically), and makes some heuristic
|
||||
# assumptions about non-digits in version number strings. This could
|
||||
# sink into special-case-hell, though; if I was as talented and
|
||||
# idiosyncratic as Larry Wall, I'd go ahead and implement a class that
|
||||
# somehow knows that "1.2.1" < "1.2.2a2" < "1.2.2" < "1.2.2pl3", and is
|
||||
# just as happy dealing with things like "2g6" and "1.13++". I don't
|
||||
# think I'm smart enough to do it right though.
|
||||
#
|
||||
# In any case, I've coded the test suite for this module (see
|
||||
# ../test/test_version.py) specifically to fail on things like comparing
|
||||
# "1.2a2" and "1.2". That's not because the *code* is doing anything
|
||||
# wrong, it's because the simple, obvious design doesn't match my
|
||||
# complicated, hairy expectations for real-world version numbers. It
|
||||
# would be a snap to fix the test suite to say, "Yep, LooseVersion does
|
||||
# the Right Thing" (ie. the code matches the conception). But I'd rather
|
||||
# have a conception that matches common notions about version numbers.
|
||||
|
||||
|
||||
class LooseVersion(Version):
|
||||
"""Version numbering for anarchists and software realists.
|
||||
Implements the standard interface for version number classes as
|
||||
described above. A version number consists of a series of numbers,
|
||||
separated by either periods or strings of letters. When comparing
|
||||
version numbers, the numeric components will be compared
|
||||
numerically, and the alphabetic components lexically. The following
|
||||
are all valid version numbers, in no particular order:
|
||||
|
||||
1.5.1
|
||||
1.5.2b2
|
||||
161
|
||||
3.10a
|
||||
8.02
|
||||
3.4j
|
||||
1996.07.12
|
||||
3.2.pl0
|
||||
3.1.1.6
|
||||
2g6
|
||||
11g
|
||||
0.960923
|
||||
2.2beta29
|
||||
1.13++
|
||||
5.5.kw
|
||||
2.0b1pl0
|
||||
|
||||
In fact, there is no such thing as an invalid version number under
|
||||
this scheme; the rules for comparison are simple and predictable,
|
||||
but may not always give the results you want (for some definition
|
||||
of "want").
|
||||
"""
|
||||
|
||||
component_re = re.compile(r'(\d+ | [a-z]+ | \.)', re.VERBOSE)
|
||||
|
||||
def __init__(self, vstring=None):
|
||||
if vstring:
|
||||
self.parse(vstring)
|
||||
|
||||
def parse(self, vstring):
|
||||
# I've given up on thinking I can reconstruct the version string
|
||||
# from the parsed tuple -- so I just store the string here for
|
||||
# use by __str__
|
||||
self.vstring = vstring
|
||||
components = [x for x in self.component_re.split(vstring) if x and x != '.']
|
||||
for i, obj in enumerate(components):
|
||||
try:
|
||||
components[i] = int(obj)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
self.version = components
|
||||
|
||||
def __str__(self):
|
||||
return self.vstring
|
||||
|
||||
def __repr__(self):
|
||||
return "LooseVersion ('%s')" % str(self)
|
||||
|
||||
def _cmp(self, other):
|
||||
if isinstance(other, str):
|
||||
other = LooseVersion(other)
|
||||
elif not isinstance(other, LooseVersion):
|
||||
return NotImplemented
|
||||
|
||||
if self.version == other.version:
|
||||
return 0
|
||||
if self.version < other.version:
|
||||
return -1
|
||||
if self.version > other.version:
|
||||
return 1
|
||||
|
||||
# end class LooseVersion
|
||||
@@ -8,12 +8,13 @@ from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
import json
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
from ansible.module_utils.basic import missing_required_lib
|
||||
from ansible.module_utils.urls import fetch_url
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
try:
|
||||
from urllib import quote_plus # Python 2.X
|
||||
except ImportError:
|
||||
@@ -90,7 +91,7 @@ def gitlabAuthentication(module):
|
||||
# python-gitlab library remove support for username/password authentication since 1.13.0
|
||||
# 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 StrictVersion(gitlab.__version__) < StrictVersion("1.13.0"):
|
||||
if LooseVersion(gitlab.__version__) < LooseVersion("1.13.0"):
|
||||
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=validate_certs, email=gitlab_user, password=gitlab_password,
|
||||
private_token=gitlab_token, api_version=4)
|
||||
else:
|
||||
|
||||
@@ -9,7 +9,8 @@ __metaclass__ = type
|
||||
import traceback
|
||||
|
||||
from ansible.module_utils.basic import missing_required_lib
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
|
||||
@@ -54,6 +54,17 @@ def proxmox_to_ansible_bool(value):
|
||||
return True if value == 1 else False
|
||||
|
||||
|
||||
def ansible_to_proxmox_bool(value):
|
||||
'''Convert Ansible representation of a boolean to be proxmox-friendly'''
|
||||
if value is None:
|
||||
return None
|
||||
|
||||
if not isinstance(value, bool):
|
||||
raise ValueError("%s must be of type bool not %s" % (value, type(value)))
|
||||
|
||||
return 1 if value else 0
|
||||
|
||||
|
||||
class ProxmoxAnsible(object):
|
||||
"""Base class for Proxmox modules"""
|
||||
def __init__(self, module):
|
||||
|
||||
17
plugins/module_utils/version.py
Normal file
17
plugins/module_utils/version.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2021, Felix Fontein <felix@fontein.de>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
"""Provide version object to compare version numbers."""
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
# Once we drop support for Ansible 2.9, ansible-base 2.10, and ansible-core 2.11, we can
|
||||
# remove the _version.py file, and replace the following import by
|
||||
#
|
||||
# from ansible.module_utils.compat.version import LooseVersion
|
||||
|
||||
from ._version import LooseVersion
|
||||
@@ -120,7 +120,7 @@ __version__ = '${version}'
|
||||
import os
|
||||
import traceback
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
|
||||
@@ -161,7 +161,8 @@ __version__ = '${version}'
|
||||
import json
|
||||
import os
|
||||
import traceback
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
|
||||
@@ -42,7 +42,7 @@ options:
|
||||
description:
|
||||
- Whether to wait for the tasks to finish before returning.
|
||||
type: str
|
||||
default: True
|
||||
default: 'True'
|
||||
required: False
|
||||
requirements:
|
||||
- python = 2.7
|
||||
@@ -89,7 +89,8 @@ __version__ = '${version}'
|
||||
|
||||
import os
|
||||
import traceback
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
@@ -132,8 +133,7 @@ class ClcBlueprintPackage:
|
||||
self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR)
|
||||
if not REQUESTS_FOUND:
|
||||
self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR)
|
||||
if requests.__version__ and LooseVersion(
|
||||
requests.__version__) < LooseVersion('2.5.0'):
|
||||
if requests.__version__ and LooseVersion(requests.__version__) < LooseVersion('2.5.0'):
|
||||
self.module.fail_json(
|
||||
msg='requests library version should be >= 2.5.0')
|
||||
|
||||
|
||||
@@ -66,8 +66,8 @@ options:
|
||||
description:
|
||||
- Whether the firewall policy is enabled or disabled
|
||||
type: str
|
||||
choices: [True, False]
|
||||
default: True
|
||||
choices: ['True', 'False']
|
||||
default: 'True'
|
||||
requirements:
|
||||
- python = 2.7
|
||||
- requests >= 2.5.0
|
||||
@@ -162,7 +162,8 @@ import os
|
||||
import traceback
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlparse
|
||||
from time import sleep
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
@@ -203,8 +204,7 @@ class ClcFirewallPolicy:
|
||||
self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR)
|
||||
if not REQUESTS_FOUND:
|
||||
self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR)
|
||||
if requests.__version__ and LooseVersion(
|
||||
requests.__version__) < LooseVersion('2.5.0'):
|
||||
if requests.__version__ and LooseVersion(requests.__version__) < LooseVersion('2.5.0'):
|
||||
self.module.fail_json(
|
||||
msg='requests library version should be >= 2.5.0')
|
||||
|
||||
|
||||
@@ -207,7 +207,8 @@ __version__ = '${version}'
|
||||
|
||||
import os
|
||||
import traceback
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
|
||||
@@ -48,7 +48,7 @@ options:
|
||||
description:
|
||||
- Port to configure on the public-facing side of the load balancer pool
|
||||
type: str
|
||||
choices: [80, 443]
|
||||
choices: ['80', '443']
|
||||
nodes:
|
||||
description:
|
||||
- A list of nodes that needs to be added to the load balancer pool
|
||||
@@ -210,7 +210,8 @@ import json
|
||||
import os
|
||||
import traceback
|
||||
from time import sleep
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
@@ -255,8 +256,7 @@ class ClcLoadBalancer:
|
||||
self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR)
|
||||
if not REQUESTS_FOUND:
|
||||
self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR)
|
||||
if requests.__version__ and LooseVersion(
|
||||
requests.__version__) < LooseVersion('2.5.0'):
|
||||
if requests.__version__ and LooseVersion(requests.__version__) < LooseVersion('2.5.0'):
|
||||
self.module.fail_json(
|
||||
msg='requests library version should be >= 2.5.0')
|
||||
|
||||
|
||||
@@ -311,7 +311,8 @@ __version__ = '${version}'
|
||||
import json
|
||||
import os
|
||||
import traceback
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
@@ -355,8 +356,7 @@ class ClcModifyServer:
|
||||
self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR)
|
||||
if not REQUESTS_FOUND:
|
||||
self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR)
|
||||
if requests.__version__ and LooseVersion(
|
||||
requests.__version__) < LooseVersion('2.5.0'):
|
||||
if requests.__version__ and LooseVersion(requests.__version__) < LooseVersion('2.5.0'):
|
||||
self.module.fail_json(
|
||||
msg='requests library version should be >= 2.5.0')
|
||||
|
||||
|
||||
@@ -117,7 +117,8 @@ __version__ = '${version}'
|
||||
|
||||
import os
|
||||
import traceback
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
|
||||
@@ -433,7 +433,8 @@ import json
|
||||
import os
|
||||
import time
|
||||
import traceback
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
@@ -478,8 +479,7 @@ class ClcServer:
|
||||
self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR)
|
||||
if not REQUESTS_FOUND:
|
||||
self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR)
|
||||
if requests.__version__ and LooseVersion(
|
||||
requests.__version__) < LooseVersion('2.5.0'):
|
||||
if requests.__version__ and LooseVersion(requests.__version__) < LooseVersion('2.5.0'):
|
||||
self.module.fail_json(
|
||||
msg='requests library version should be >= 2.5.0')
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ options:
|
||||
wait:
|
||||
description:
|
||||
- Whether to wait for the provisioning tasks to finish before returning.
|
||||
default: True
|
||||
default: 'True'
|
||||
required: False
|
||||
type: str
|
||||
requirements:
|
||||
@@ -101,7 +101,8 @@ __version__ = '${version}'
|
||||
|
||||
import os
|
||||
import traceback
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
@@ -145,8 +146,7 @@ class ClcSnapshot:
|
||||
self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR)
|
||||
if not REQUESTS_FOUND:
|
||||
self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR)
|
||||
if requests.__version__ and LooseVersion(
|
||||
requests.__version__) < LooseVersion('2.5.0'):
|
||||
if requests.__version__ and LooseVersion(requests.__version__) < LooseVersion('2.5.0'):
|
||||
self.module.fail_json(
|
||||
msg='requests library version should be >= 2.5.0')
|
||||
|
||||
|
||||
@@ -51,7 +51,6 @@ options:
|
||||
group.s
|
||||
type: str
|
||||
required: false
|
||||
default: 0
|
||||
vpc_id:
|
||||
description:
|
||||
- Specifies the resource ID of the VPC to which the security group
|
||||
|
||||
@@ -363,7 +363,8 @@ EXAMPLES = r'''
|
||||
|
||||
import time
|
||||
import traceback
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
try:
|
||||
from proxmoxer import ProxmoxAPI
|
||||
@@ -374,6 +375,10 @@ except ImportError:
|
||||
from ansible.module_utils.basic import AnsibleModule, env_fallback
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.proxmox import (
|
||||
ansible_to_proxmox_bool
|
||||
)
|
||||
|
||||
|
||||
VZ_TYPE = None
|
||||
|
||||
@@ -627,14 +632,14 @@ def main():
|
||||
netif=module.params['netif'],
|
||||
mounts=module.params['mounts'],
|
||||
ip_address=module.params['ip_address'],
|
||||
onboot=int(module.params['onboot']),
|
||||
onboot=ansible_to_proxmox_bool(module.params['onboot']),
|
||||
cpuunits=module.params['cpuunits'],
|
||||
nameserver=module.params['nameserver'],
|
||||
searchdomain=module.params['searchdomain'],
|
||||
force=int(module.params['force']),
|
||||
force=ansible_to_proxmox_bool(module.params['force']),
|
||||
pubkey=module.params['pubkey'],
|
||||
features=",".join(module.params['features']) if module.params['features'] is not None else None,
|
||||
unprivileged=int(module.params['unprivileged']),
|
||||
unprivileged=ansible_to_proxmox_bool(module.params['unprivileged']),
|
||||
description=module.params['description'],
|
||||
hookscript=module.params['hookscript'])
|
||||
|
||||
|
||||
@@ -761,9 +761,10 @@ msg:
|
||||
import re
|
||||
import time
|
||||
import traceback
|
||||
from distutils.version import LooseVersion
|
||||
from ansible.module_utils.six.moves.urllib.parse import quote
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
try:
|
||||
from proxmoxer import ProxmoxAPI
|
||||
HAS_PROXMOXER = True
|
||||
|
||||
@@ -230,11 +230,12 @@ command:
|
||||
import os
|
||||
import json
|
||||
import tempfile
|
||||
from distutils.version import LooseVersion
|
||||
from ansible.module_utils.six.moves import shlex_quote
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
module = None
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ description:
|
||||
- Gather information about the servers.
|
||||
- U(https://www.online.net/en/dedicated-server)
|
||||
author:
|
||||
- "Remy Leone (@sieben)"
|
||||
- "Remy Leone (@remyleone)"
|
||||
extends_documentation_fragment:
|
||||
- community.general.online
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ short_description: Gather information about Online user.
|
||||
description:
|
||||
- Gather information about the user.
|
||||
author:
|
||||
- "Remy Leone (@sieben)"
|
||||
- "Remy Leone (@remyleone)"
|
||||
extends_documentation_fragment:
|
||||
- community.general.online
|
||||
'''
|
||||
|
||||
@@ -97,7 +97,7 @@ EXAMPLES = '''
|
||||
register: my_volume
|
||||
'''
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
try:
|
||||
import pyrax
|
||||
|
||||
@@ -42,7 +42,7 @@ options:
|
||||
description:
|
||||
- version of database (MySQL supports 5.1 and 5.6, MariaDB supports 10, Percona supports 5.6)
|
||||
- "The available choices are: C(5.1), C(5.6) and C(10)."
|
||||
default: 5.6
|
||||
default: '5.6'
|
||||
aliases: ['version']
|
||||
state:
|
||||
type: str
|
||||
|
||||
@@ -16,7 +16,7 @@ DOCUMENTATION = '''
|
||||
---
|
||||
module: scaleway_compute
|
||||
short_description: Scaleway compute management module
|
||||
author: Remy Leone (@sieben)
|
||||
author: Remy Leone (@remyleone)
|
||||
description:
|
||||
- "This module manages compute instances on Scaleway."
|
||||
extends_documentation_fragment:
|
||||
|
||||
@@ -15,7 +15,7 @@ description:
|
||||
- Gather information about the Scaleway images available.
|
||||
author:
|
||||
- "Yanis Guenane (@Spredzy)"
|
||||
- "Remy Leone (@sieben)"
|
||||
- "Remy Leone (@remyleone)"
|
||||
extends_documentation_fragment:
|
||||
- community.general.scaleway
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ DOCUMENTATION = '''
|
||||
---
|
||||
module: scaleway_ip
|
||||
short_description: Scaleway IP management module
|
||||
author: Remy Leone (@sieben)
|
||||
author: Remy Leone (@remyleone)
|
||||
description:
|
||||
- This module manages IP on Scaleway account
|
||||
U(https://developer.scaleway.com)
|
||||
|
||||
@@ -15,7 +15,7 @@ description:
|
||||
- Gather information about the Scaleway ips available.
|
||||
author:
|
||||
- "Yanis Guenane (@Spredzy)"
|
||||
- "Remy Leone (@sieben)"
|
||||
- "Remy Leone (@remyleone)"
|
||||
extends_documentation_fragment:
|
||||
- community.general.scaleway
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ DOCUMENTATION = '''
|
||||
---
|
||||
module: scaleway_lb
|
||||
short_description: Scaleway load-balancer management module
|
||||
author: Remy Leone (@sieben)
|
||||
author: Remy Leone (@remyleone)
|
||||
description:
|
||||
- "This module manages load-balancers on Scaleway."
|
||||
extends_documentation_fragment:
|
||||
|
||||
@@ -15,7 +15,7 @@ description:
|
||||
- Gather information about the Scaleway organizations available.
|
||||
author:
|
||||
- "Yanis Guenane (@Spredzy)"
|
||||
- "Remy Leone (@sieben)"
|
||||
- "Remy Leone (@remyleone)"
|
||||
options:
|
||||
api_url:
|
||||
description:
|
||||
|
||||
@@ -15,7 +15,7 @@ description:
|
||||
- Gather information about the Scaleway security groups available.
|
||||
author:
|
||||
- "Yanis Guenane (@Spredzy)"
|
||||
- "Remy Leone (@sieben)"
|
||||
- "Remy Leone (@remyleone)"
|
||||
options:
|
||||
region:
|
||||
type: str
|
||||
|
||||
@@ -15,7 +15,7 @@ description:
|
||||
- Gather information about the Scaleway servers available.
|
||||
author:
|
||||
- "Yanis Guenane (@Spredzy)"
|
||||
- "Remy Leone (@sieben)"
|
||||
- "Remy Leone (@remyleone)"
|
||||
extends_documentation_fragment:
|
||||
- community.general.scaleway
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ description:
|
||||
- Gather information about the Scaleway snapshot available.
|
||||
author:
|
||||
- "Yanis Guenane (@Spredzy)"
|
||||
- "Remy Leone (@sieben)"
|
||||
- "Remy Leone (@remyleone)"
|
||||
extends_documentation_fragment:
|
||||
- community.general.scaleway
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ DOCUMENTATION = '''
|
||||
---
|
||||
module: scaleway_sshkey
|
||||
short_description: Scaleway SSH keys management module
|
||||
author: Remy Leone (@sieben)
|
||||
author: Remy Leone (@remyleone)
|
||||
description:
|
||||
- This module manages SSH keys on Scaleway account
|
||||
U(https://developer.scaleway.com)
|
||||
|
||||
@@ -16,7 +16,7 @@ DOCUMENTATION = '''
|
||||
---
|
||||
module: scaleway_user_data
|
||||
short_description: Scaleway user_data management module
|
||||
author: Remy Leone (@sieben)
|
||||
author: Remy Leone (@remyleone)
|
||||
description:
|
||||
- "This module manages user_data on compute instances on Scaleway."
|
||||
- "It can be used to configure cloud-init for instance"
|
||||
@@ -75,7 +75,7 @@ def patch_user_data(compute_api, server_id, key, value):
|
||||
compute_api.module.debug("Starting patching user_data attributes")
|
||||
|
||||
path = "servers/%s/user_data/%s" % (server_id, key)
|
||||
response = compute_api.patch(path=path, data=value, headers={"Content-type": "text/plain"})
|
||||
response = compute_api.patch(path=path, data=value, headers={"Content-Type": "text/plain"})
|
||||
if not response.ok:
|
||||
msg = 'Error during user_data patching: %s %s' % (response.status_code, response.body)
|
||||
compute_api.module.fail_json(msg=msg)
|
||||
|
||||
@@ -15,7 +15,7 @@ description:
|
||||
- Gather information about the Scaleway volumes available.
|
||||
author:
|
||||
- "Yanis Guenane (@Spredzy)"
|
||||
- "Remy Leone (@sieben)"
|
||||
- "Remy Leone (@remyleone)"
|
||||
extends_documentation_fragment:
|
||||
- community.general.scaleway
|
||||
|
||||
|
||||
@@ -117,9 +117,10 @@ state:
|
||||
'''
|
||||
|
||||
import os
|
||||
from distutils.version import LooseVersion
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
|
||||
PACKAGE_STATE_MAP = dict(
|
||||
present="--install",
|
||||
|
||||
@@ -26,6 +26,7 @@ extends_documentation_fragment:
|
||||
- community.general.redis
|
||||
|
||||
seealso:
|
||||
- module: community.general.redis_data
|
||||
- module: community.general.redis_info
|
||||
- module: community.general.redis
|
||||
'''
|
||||
|
||||
@@ -25,7 +25,7 @@ options:
|
||||
port:
|
||||
description:
|
||||
Database port to connect to.
|
||||
default: 5433
|
||||
default: '5433'
|
||||
type: str
|
||||
db:
|
||||
description:
|
||||
|
||||
@@ -44,7 +44,7 @@ options:
|
||||
port:
|
||||
description:
|
||||
- Vertica cluster port to connect to.
|
||||
default: 5433
|
||||
default: '5433'
|
||||
type: str
|
||||
login_user:
|
||||
description:
|
||||
|
||||
@@ -58,7 +58,7 @@ options:
|
||||
port:
|
||||
description:
|
||||
- Vertica cluster port to connect to.
|
||||
default: 5433
|
||||
default: '5433'
|
||||
type: str
|
||||
login_user:
|
||||
description:
|
||||
|
||||
@@ -70,7 +70,7 @@ options:
|
||||
port:
|
||||
description:
|
||||
- Vertica cluster port to connect to.
|
||||
default: 5433
|
||||
default: '5433'
|
||||
type: str
|
||||
login_user:
|
||||
description:
|
||||
|
||||
@@ -83,7 +83,7 @@ options:
|
||||
- Whether or not the file to create should be a sparse file.
|
||||
- This option is effective only on newly created files, or when growing a
|
||||
file, only for the bytes to append.
|
||||
- This option is not supported on OpenBSD, Solaris and AIX.
|
||||
- This option is not supported on OSes or filesystems not supporting sparse files.
|
||||
- I(force=true) and I(sparse=true) are mutually exclusive.
|
||||
type: bool
|
||||
default: false
|
||||
@@ -129,6 +129,10 @@ seealso:
|
||||
- name: dd(1) manpage for NetBSD
|
||||
description: Manual page of the NetBSD's dd implementation.
|
||||
link: https://man.netbsd.org/dd.1
|
||||
|
||||
- name: busybox(1) manpage for Linux
|
||||
description: Manual page of the GNU/Linux's busybox, that provides its own dd implementation.
|
||||
link: https://www.unix.com/man-page/linux/1/busybox
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
@@ -377,12 +381,10 @@ def complete_dd_cmdline(args, dd_cmd):
|
||||
return list()
|
||||
|
||||
bs = args['size_spec']['blocksize']
|
||||
conv = list()
|
||||
|
||||
# For sparse files (create, truncate, grow): write count=0 block.
|
||||
if args['sparse']:
|
||||
seek = args['size_spec']['blocks']
|
||||
conv += ['sparse']
|
||||
elif args['force'] or not os.path.exists(args['path']): # Create file
|
||||
seek = 0
|
||||
elif args['size_diff'] < 0: # Truncate file
|
||||
@@ -394,8 +396,6 @@ def complete_dd_cmdline(args, dd_cmd):
|
||||
|
||||
count = args['size_spec']['blocks'] - seek
|
||||
dd_cmd += ['bs=%s' % str(bs), 'seek=%s' % str(seek), 'count=%s' % str(count)]
|
||||
if conv:
|
||||
dd_cmd += ['conv=%s' % ','.join(conv)]
|
||||
|
||||
return dd_cmd
|
||||
|
||||
|
||||
@@ -367,9 +367,10 @@ def do_ini(module, filename, section=None, option=None, values=None,
|
||||
section_lines = new_section_lines
|
||||
else:
|
||||
# drop the entire section
|
||||
section_lines = []
|
||||
msg = 'section removed'
|
||||
changed = True
|
||||
if section_lines:
|
||||
section_lines = []
|
||||
msg = 'section removed'
|
||||
changed = True
|
||||
|
||||
# reassemble the ini_lines after manipulation
|
||||
ini_lines = before + section_lines + after
|
||||
|
||||
@@ -356,9 +356,10 @@ import os
|
||||
import re
|
||||
import traceback
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
from io import BytesIO
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
LXML_IMP_ERR = None
|
||||
try:
|
||||
from lxml import etree, objectify
|
||||
|
||||
@@ -74,11 +74,12 @@ subca:
|
||||
type: dict
|
||||
'''
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.general.plugins.module_utils.ipa import IPAClient, ipa_argument_spec
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
|
||||
class SubCAIPAClient(IPAClient):
|
||||
def __init__(self, module, host, port, protocol):
|
||||
|
||||
@@ -103,7 +103,7 @@ author:
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Map a client role to a group, authentication with credentials
|
||||
community.general.keycloak_client_rolemappings:
|
||||
community.general.keycloak_client_rolemapping:
|
||||
realm: MyCustomRealm
|
||||
auth_client_id: admin-cli
|
||||
auth_keycloak_url: https://auth.example.com/auth
|
||||
@@ -121,7 +121,7 @@ EXAMPLES = '''
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Map a client role to a group, authentication with token
|
||||
community.general.keycloak_client_rolemappings:
|
||||
community.general.keycloak_client_rolemapping:
|
||||
realm: MyCustomRealm
|
||||
auth_client_id: admin-cli
|
||||
auth_keycloak_url: https://auth.example.com/auth
|
||||
@@ -137,7 +137,7 @@ EXAMPLES = '''
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Unmap client role from a group
|
||||
community.general.keycloak_client_rolemappings:
|
||||
community.general.keycloak_client_rolemapping:
|
||||
realm: MyCustomRealm
|
||||
auth_client_id: admin-cli
|
||||
auth_keycloak_url: https://auth.example.com/auth
|
||||
|
||||
@@ -828,7 +828,7 @@ def main():
|
||||
before_comp = dict()
|
||||
|
||||
# if user federation exists, get associated mappers
|
||||
if cid is not None:
|
||||
if cid is not None and before_comp:
|
||||
before_comp['mappers'] = sorted(kc.get_components(urlencode(dict(parent=cid)), realm), key=lambda x: x.get('name'))
|
||||
|
||||
# build a changeset
|
||||
@@ -904,12 +904,23 @@ def main():
|
||||
after_comp = kc.create_component(updated_comp, realm)
|
||||
|
||||
for mapper in updated_mappers:
|
||||
if mapper.get('id') is not None:
|
||||
kc.update_component(mapper, realm)
|
||||
found = kc.get_components(urlencode(dict(parent=cid, name=mapper['name'])), realm)
|
||||
if len(found) > 1:
|
||||
module.fail_json(msg='Found multiple mappers with name `{name}`. Cannot continue.'.format(name=mapper['name']))
|
||||
if len(found) == 1:
|
||||
old_mapper = found[0]
|
||||
else:
|
||||
if mapper.get('parentId') is None:
|
||||
mapper['parentId'] = after_comp['id']
|
||||
mapper = kc.create_component(mapper, realm)
|
||||
old_mapper = {}
|
||||
|
||||
new_mapper = old_mapper.copy()
|
||||
new_mapper.update(mapper)
|
||||
|
||||
if new_mapper.get('id') is not None:
|
||||
kc.update_component(new_mapper, realm)
|
||||
else:
|
||||
if new_mapper.get('parentId') is None:
|
||||
new_mapper['parentId'] = after_comp['id']
|
||||
mapper = kc.create_component(new_mapper, realm)
|
||||
|
||||
after_comp['mappers'] = updated_mappers
|
||||
result['end_state'] = sanitize(after_comp)
|
||||
|
||||
@@ -294,7 +294,7 @@ class OnePasswordInfo(object):
|
||||
except AnsibleModuleError as e:
|
||||
module.fail_json(msg="Failed to perform initial sign in to 1Password: %s" % to_native(e))
|
||||
else:
|
||||
module.fail_json(msg="Unable to perform an initial sign in to 1Password. Please run '%s sigin' "
|
||||
module.fail_json(msg="Unable to perform an initial sign in to 1Password. Please run '%s signin' "
|
||||
"or define credentials in 'auto_login'. See the module documentation for details." % self.cli_path)
|
||||
|
||||
def get_token(self):
|
||||
|
||||
@@ -143,7 +143,8 @@ annotation:
|
||||
import json
|
||||
import time
|
||||
import traceback
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REQUESTS_IMP_ERR = None
|
||||
try:
|
||||
|
||||
@@ -84,7 +84,6 @@ options:
|
||||
description:
|
||||
- Dictionary of scopes to silence, with timestamps or None.
|
||||
- Each scope will be muted until the given POSIX timestamp or forever if the value is None.
|
||||
default: ""
|
||||
notify_no_data:
|
||||
description:
|
||||
- Whether this monitor will notify when data stops reporting.
|
||||
|
||||
@@ -146,9 +146,10 @@ EXAMPLES = '''
|
||||
RETURN = r"""# """
|
||||
|
||||
import traceback
|
||||
from distutils.version import LooseVersion
|
||||
import re
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
|
||||
class DNSimpleV1():
|
||||
"""class which uses dnsimple-python < 2"""
|
||||
|
||||
@@ -77,8 +77,8 @@ options:
|
||||
description:
|
||||
- Network family defined by Infinity, e.g. IPv4, IPv6 and Dual stack
|
||||
type: str
|
||||
choices: [ 4, 6, dual ]
|
||||
default: 4
|
||||
choices: [ '4', '6', dual ]
|
||||
default: '4'
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
|
||||
@@ -70,7 +70,7 @@ options:
|
||||
ip4:
|
||||
description:
|
||||
- The IPv4 address to this interface.
|
||||
- Use the format C(192.0.2.24/24).
|
||||
- Use the format C(192.0.2.24/24) or C(192.0.2.24).
|
||||
- If defined and I(method4) is not specified, automatically set C(ipv4.method) to C(manual).
|
||||
type: str
|
||||
gw4:
|
||||
@@ -143,7 +143,7 @@ options:
|
||||
ip6:
|
||||
description:
|
||||
- The IPv6 address to this interface.
|
||||
- Use the format C(abbe::cafe).
|
||||
- Use the format C(abbe::cafe/128 or abbe::cafe).
|
||||
- If defined and I(method6) is not specified, automatically set C(ipv6.method) to C(manual).
|
||||
type: str
|
||||
gw6:
|
||||
@@ -1241,7 +1241,7 @@ class Nmcli(object):
|
||||
# IP address options.
|
||||
if self.ip_conn_type and not self.master:
|
||||
options.update({
|
||||
'ipv4.addresses': self.ip4,
|
||||
'ipv4.addresses': self.enforce_ipv4_cidr_notation(self.ip4),
|
||||
'ipv4.dhcp-client-id': self.dhcp_client_id,
|
||||
'ipv4.dns': self.dns4,
|
||||
'ipv4.dns-search': self.dns4_search,
|
||||
@@ -1254,7 +1254,7 @@ class Nmcli(object):
|
||||
'ipv4.never-default': self.never_default4,
|
||||
'ipv4.method': self.ipv4_method,
|
||||
'ipv4.may-fail': self.may_fail4,
|
||||
'ipv6.addresses': self.ip6,
|
||||
'ipv6.addresses': self.enforce_ipv6_cidr_notation(self.ip6),
|
||||
'ipv6.dns': self.dns6,
|
||||
'ipv6.dns-search': self.dns6_search,
|
||||
'ipv6.ignore-auto-dns': self.dns6_ignore_auto,
|
||||
@@ -1332,6 +1332,9 @@ class Nmcli(object):
|
||||
options.update({
|
||||
'vlan.id': self.vlanid,
|
||||
'vlan.parent': self.vlandev,
|
||||
'vlan.flags': self.flags,
|
||||
'vlan.ingress': self.ingress,
|
||||
'vlan.egress': self.egress,
|
||||
})
|
||||
elif self.type == 'vxlan':
|
||||
options.update({
|
||||
@@ -1444,6 +1447,22 @@ class Nmcli(object):
|
||||
'sit',
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def enforce_ipv4_cidr_notation(ip4_address):
|
||||
if ip4_address is None or '/' in ip4_address:
|
||||
return ip4_address
|
||||
|
||||
return ip4_address + '/32'
|
||||
|
||||
@staticmethod
|
||||
def enforce_ipv6_cidr_notation(ip6_address):
|
||||
if ip6_address is None:
|
||||
return None
|
||||
elif '/' in ip6_address:
|
||||
return ip6_address
|
||||
else:
|
||||
return ip6_address + '/128'
|
||||
|
||||
@staticmethod
|
||||
def bool_to_string(boolean):
|
||||
if boolean:
|
||||
|
||||
@@ -127,7 +127,7 @@ ansible_sysname:
|
||||
type: str
|
||||
sample: ubuntu-user
|
||||
ansible_syslocation:
|
||||
description: The physical location of this node (e.g., `telephone closet, 3rd floor').
|
||||
description: The physical location of this node (e.g., C(telephone closet, 3rd floor)).
|
||||
returned: success
|
||||
type: str
|
||||
sample: Sitting on the Dock of the Bay
|
||||
|
||||
@@ -124,7 +124,8 @@ import os
|
||||
import ssl
|
||||
import traceback
|
||||
import platform
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
HAS_PAHOMQTT = True
|
||||
PAHOMQTT_IMP_ERR = None
|
||||
@@ -207,7 +208,7 @@ def main():
|
||||
if tls_version:
|
||||
tls_version = tls_map.get(tls_version, ssl.PROTOCOL_SSLv23)
|
||||
else:
|
||||
if LooseVersion(platform.python_version()) <= "3.5.2":
|
||||
if LooseVersion(platform.python_version()) <= LooseVersion("3.5.2"):
|
||||
# Specifying `None` on later versions of python seems sufficient to
|
||||
# instruct python to autonegotiate the SSL/TLS connection. On versions
|
||||
# 3.5.2 and lower though we need to specify the version.
|
||||
|
||||
@@ -124,7 +124,7 @@ EXAMPLES = r'''
|
||||
import os
|
||||
import traceback
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
SENDGRID_IMP_ERR = None
|
||||
try:
|
||||
|
||||
@@ -346,7 +346,7 @@ def build_payload_for_slack(text, channel, thread_id, username, icon_url, icon_e
|
||||
|
||||
def get_slack_message(module, token, channel, ts):
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Accept': 'application/json',
|
||||
'Authorization': 'Bearer ' + token
|
||||
}
|
||||
@@ -383,7 +383,7 @@ def do_notify_slack(module, domain, token, payload):
|
||||
slack_uri = OLD_SLACK_INCOMING_WEBHOOK % (domain, token)
|
||||
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Accept': 'application/json',
|
||||
}
|
||||
if use_webapi:
|
||||
|
||||
@@ -10,7 +10,7 @@ __metaclass__ = type
|
||||
DOCUMENTATION = """
|
||||
module: ansible_galaxy_install
|
||||
author:
|
||||
- "Alexei Znamensky (@russoz)"
|
||||
- "Alexei Znamensky (@russoz)"
|
||||
short_description: Install Ansible roles or collections using ansible-galaxy
|
||||
version_added: 3.5.0
|
||||
description:
|
||||
@@ -24,44 +24,46 @@ requirements:
|
||||
options:
|
||||
type:
|
||||
description:
|
||||
- The type of installation performed by C(ansible-galaxy).
|
||||
- If I(type) is C(both), then I(requirements_file) must be passed and it may contain both roles and collections.
|
||||
- "Note however that the opposite is not true: if using a I(requirements_file), then I(type) can be any of the three choices."
|
||||
- "B(Ansible 2.9): The option C(both) will have the same effect as C(role)."
|
||||
- The type of installation performed by C(ansible-galaxy).
|
||||
- If I(type) is C(both), then I(requirements_file) must be passed and it may contain both roles and collections.
|
||||
- "Note however that the opposite is not true: if using a I(requirements_file), then I(type) can be any of the three choices."
|
||||
- "B(Ansible 2.9): The option C(both) will have the same effect as C(role)."
|
||||
type: str
|
||||
choices: [collection, role, both]
|
||||
required: true
|
||||
name:
|
||||
description:
|
||||
- Name of the collection or role being installed.
|
||||
- Versions can be specified with C(ansible-galaxy) usual formats. For example, C(community.docker:1.6.1) or C(ansistrano.deploy,3.8.0).
|
||||
- I(name) and I(requirements_file) are mutually exclusive.
|
||||
- Name of the collection or role being installed.
|
||||
- >
|
||||
Versions can be specified with C(ansible-galaxy) usual formats.
|
||||
For example, the collection C(community.docker:1.6.1) or the role C(ansistrano.deploy,3.8.0).
|
||||
- I(name) and I(requirements_file) are mutually exclusive.
|
||||
type: str
|
||||
requirements_file:
|
||||
description:
|
||||
- Path to a file containing a list of requirements to be installed.
|
||||
- It works for I(type) equals to C(collection) and C(role).
|
||||
- I(name) and I(requirements_file) are mutually exclusive.
|
||||
- "B(Ansible 2.9): It can only be used to install either I(type=role) or I(type=collection), but not both at the same run."
|
||||
- Path to a file containing a list of requirements to be installed.
|
||||
- It works for I(type) equals to C(collection) and C(role).
|
||||
- I(name) and I(requirements_file) are mutually exclusive.
|
||||
- "B(Ansible 2.9): It can only be used to install either I(type=role) or I(type=collection), but not both at the same run."
|
||||
type: path
|
||||
dest:
|
||||
description:
|
||||
- The path to the directory containing your collections or roles, according to the value of I(type).
|
||||
- >
|
||||
Please notice that C(ansible-galaxy) will not install collections with I(type=both), when I(requirements_file)
|
||||
contains both roles and collections and I(dest) is specified.
|
||||
- The path to the directory containing your collections or roles, according to the value of I(type).
|
||||
- >
|
||||
Please notice that C(ansible-galaxy) will not install collections with I(type=both), when I(requirements_file)
|
||||
contains both roles and collections and I(dest) is specified.
|
||||
type: path
|
||||
force:
|
||||
description:
|
||||
- Force overwriting an existing role or collection.
|
||||
- Using I(force=true) is mandatory when downgrading.
|
||||
- "B(Ansible 2.9 and 2.10): Must be C(true) to upgrade roles and collections."
|
||||
- Force overwriting an existing role or collection.
|
||||
- Using I(force=true) is mandatory when downgrading.
|
||||
- "B(Ansible 2.9 and 2.10): Must be C(true) to upgrade roles and collections."
|
||||
type: bool
|
||||
default: false
|
||||
ack_ansible29:
|
||||
description:
|
||||
- Acknowledge using Ansible 2.9 with its limitations, and prevents the module from generating warnings about them.
|
||||
- This option is completely ignored if using a version Ansible greater than C(2.9.x).
|
||||
- Acknowledge using Ansible 2.9 with its limitations, and prevents the module from generating warnings about them.
|
||||
- This option is completely ignored if using a version of Ansible greater than C(2.9.x).
|
||||
type: bool
|
||||
default: false
|
||||
"""
|
||||
@@ -114,9 +116,9 @@ RETURN = """
|
||||
returned: always
|
||||
installed_roles:
|
||||
description:
|
||||
- If I(requirements_file) is specified instead, returns dictionary with all the roles installed per path.
|
||||
- If I(name) is specified, returns that role name and the version installed per path.
|
||||
- "B(Ansible 2.9): Returns empty because C(ansible-galaxy) has no C(list) subcommand."
|
||||
- If I(requirements_file) is specified instead, returns dictionary with all the roles installed per path.
|
||||
- If I(name) is specified, returns that role name and the version installed per path.
|
||||
- "B(Ansible 2.9): Returns empty because C(ansible-galaxy) has no C(list) subcommand."
|
||||
type: dict
|
||||
returned: always when installing roles
|
||||
contains:
|
||||
@@ -131,9 +133,9 @@ RETURN = """
|
||||
ansistrano.deploy: 3.8.0
|
||||
installed_collections:
|
||||
description:
|
||||
- If I(requirements_file) is specified instead, returns dictionary with all the collections installed per path.
|
||||
- If I(name) is specified, returns that collection name and the version installed per path.
|
||||
- "B(Ansible 2.9): Returns empty because C(ansible-galaxy) has no C(list) subcommand."
|
||||
- If I(requirements_file) is specified instead, returns dictionary with all the collections installed per path.
|
||||
- If I(name) is specified, returns that collection name and the version installed per path.
|
||||
- "B(Ansible 2.9): Returns empty because C(ansible-galaxy) has no C(list) subcommand."
|
||||
type: dict
|
||||
returned: always when installing collections
|
||||
contains:
|
||||
|
||||
@@ -167,7 +167,7 @@ class PipX(CmdStateModuleHelper):
|
||||
command_args_formats = dict(
|
||||
state=dict(fmt=lambda v: [_state_map.get(v, v)]),
|
||||
name_source=dict(fmt=lambda n, s: [s] if s else [n], stars=1),
|
||||
install_deps=dict(fmt="--install-deps", style=ArgFormat.BOOLEAN),
|
||||
install_deps=dict(fmt="--include-deps", style=ArgFormat.BOOLEAN),
|
||||
inject_packages=dict(fmt=lambda v: v),
|
||||
force=dict(fmt="--force", style=ArgFormat.BOOLEAN),
|
||||
include_injected=dict(fmt="--include-injected", style=ArgFormat.BOOLEAN),
|
||||
|
||||
@@ -163,7 +163,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
class Yarn(object):
|
||||
|
||||
DEFAULT_GLOBAL_INSTALLATION_PATH = '~/.config/yarn/global'
|
||||
DEFAULT_GLOBAL_INSTALLATION_PATH = os.path.expanduser('~/.config/yarn/global')
|
||||
|
||||
def __init__(self, module, **kwargs):
|
||||
self.module = module
|
||||
@@ -241,16 +241,19 @@ class Yarn(object):
|
||||
if error:
|
||||
self.module.fail_json(msg=error)
|
||||
|
||||
data = json.loads(result)
|
||||
try:
|
||||
dependencies = data['data']['trees']
|
||||
except KeyError:
|
||||
missing.append(self.name)
|
||||
return installed, missing
|
||||
for json_line in result.strip().split('\n'):
|
||||
data = json.loads(json_line)
|
||||
if self.globally:
|
||||
if data['type'] == 'list' and data['data']['type'].startswith('bins-'):
|
||||
# This is a string in format: 'bins-<PACKAGE_NAME>'
|
||||
installed.append(data['data']['type'][5:])
|
||||
else:
|
||||
if data['type'] == 'tree':
|
||||
dependencies = data['data']['trees']
|
||||
|
||||
for dep in dependencies:
|
||||
name, version = dep['name'].rsplit('@', 1)
|
||||
installed.append(name)
|
||||
for dep in dependencies:
|
||||
name, version = dep['name'].rsplit('@', 1)
|
||||
installed.append(name)
|
||||
|
||||
if self.name not in installed:
|
||||
missing.append(self.name)
|
||||
|
||||
@@ -152,11 +152,11 @@ stdout:
|
||||
sample: "org.gnome.Calendar/x86_64/stable\tcurrent\norg.gnome.gitg/x86_64/stable\tcurrent\n"
|
||||
'''
|
||||
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlparse
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
OUTDATED_FLATPAK_VERSION_ERROR_MESSAGE = "Unknown option --columns=application"
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ def install_flat(module, binary, remote, names, method, no_dependencies):
|
||||
id_names.append(name)
|
||||
base_command = [binary, "install", "--{0}".format(method)]
|
||||
flatpak_version = _flatpak_version(module, binary)
|
||||
if StrictVersion(flatpak_version) < StrictVersion('1.1.3'):
|
||||
if LooseVersion(flatpak_version) < LooseVersion('1.1.3'):
|
||||
base_command += ["-y"]
|
||||
else:
|
||||
base_command += ["--noninteractive"]
|
||||
@@ -196,7 +196,7 @@ def uninstall_flat(module, binary, names, method):
|
||||
]
|
||||
command = [binary, "uninstall"]
|
||||
flatpak_version = _flatpak_version(module, binary)
|
||||
if StrictVersion(flatpak_version) < StrictVersion('1.1.3'):
|
||||
if LooseVersion(flatpak_version) < LooseVersion('1.1.3'):
|
||||
command += ["-y"]
|
||||
else:
|
||||
command += ["--noninteractive"]
|
||||
|
||||
@@ -102,6 +102,12 @@ EXAMPLES = '''
|
||||
state: present
|
||||
install_options: 'debug,appdir=/Applications'
|
||||
|
||||
- name: Install cask with force option
|
||||
community.general.homebrew_cask:
|
||||
name: alfred
|
||||
state: present
|
||||
install_options: force
|
||||
|
||||
- name: Allow external app
|
||||
community.general.homebrew_cask:
|
||||
name: alfred
|
||||
@@ -140,7 +146,8 @@ EXAMPLES = '''
|
||||
import os
|
||||
import re
|
||||
import tempfile
|
||||
from distutils import version
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
@@ -493,7 +500,7 @@ class HomebrewCask(object):
|
||||
|
||||
def _brew_cask_command_is_deprecated(self):
|
||||
# The `brew cask` replacements were fully available in 2.6.0 (https://brew.sh/2020/12/01/homebrew-2.6.0/)
|
||||
return version.LooseVersion(self._get_brew_version()) >= version.LooseVersion('2.6.0')
|
||||
return LooseVersion(self._get_brew_version()) >= LooseVersion('2.6.0')
|
||||
# /checks ------------------------------------------------------ }}}
|
||||
|
||||
# commands ----------------------------------------------------- {{{
|
||||
@@ -599,7 +606,7 @@ class HomebrewCask(object):
|
||||
self.message = 'Invalid cask: {0}.'.format(self.current_cask)
|
||||
raise HomebrewCaskException(self.message)
|
||||
|
||||
if self._current_cask_is_installed():
|
||||
if '--force' not in self.install_options and self._current_cask_is_installed():
|
||||
self.unchanged_count += 1
|
||||
self.message = 'Cask already installed: {0}'.format(
|
||||
self.current_cask,
|
||||
|
||||
@@ -97,9 +97,10 @@ RETURN = r''' # '''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from distutils.version import StrictVersion
|
||||
import os
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
|
||||
class Mas(object):
|
||||
|
||||
@@ -145,7 +146,7 @@ class Mas(object):
|
||||
|
||||
# Is the version recent enough?
|
||||
rc, out, err = self.run(['version'])
|
||||
if rc != 0 or not out.strip() or StrictVersion(out.strip()) < StrictVersion('1.5.0'):
|
||||
if rc != 0 or not out.strip() or LooseVersion(out.strip()) < LooseVersion('1.5.0'):
|
||||
self.module.fail_json(msg='`mas` tool in version 1.5.0+ needed, got ' + out.strip())
|
||||
|
||||
def check_signin(self):
|
||||
|
||||
@@ -135,10 +135,10 @@ import re
|
||||
import shlex
|
||||
import sqlite3
|
||||
|
||||
from distutils.version import StrictVersion
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
|
||||
# Function used for executing commands.
|
||||
def execute_command(cmd, module):
|
||||
@@ -435,7 +435,7 @@ def parse_package_name(names, pkg_spec, module):
|
||||
if pkg_spec[name]['branch']:
|
||||
branch_release = "6.0"
|
||||
|
||||
if StrictVersion(platform.release()) < StrictVersion(branch_release):
|
||||
if LooseVersion(platform.release()) < LooseVersion(branch_release):
|
||||
module.fail_json(msg="package name using 'branch' syntax requires at least OpenBSD %s: %s" % (branch_release, name))
|
||||
|
||||
# Sanity check that there are no trailing dashes in flavor.
|
||||
|
||||
@@ -17,7 +17,7 @@ description:
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- Package name or a list of packages.
|
||||
- Package name or a list of package names with optional wildcards.
|
||||
type: list
|
||||
required: true
|
||||
elements: str
|
||||
@@ -74,10 +74,17 @@ state:
|
||||
sample: present
|
||||
'''
|
||||
|
||||
import re
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from fnmatch import fnmatch
|
||||
|
||||
# on DNF-based distros, yum is a symlink to dnf, so we try to handle their different entry formats.
|
||||
NEVRA_RE_YUM = re.compile(r'^(?P<exclude>!)?(?P<epoch>\d+):(?P<name>.+)-'
|
||||
r'(?P<version>.+)-(?P<release>.+)\.(?P<arch>.+)$')
|
||||
NEVRA_RE_DNF = re.compile(r"^(?P<exclude>!)?(?P<name>.+)-(?P<epoch>\d+):(?P<version>.+)-"
|
||||
r"(?P<release>.+)\.(?P<arch>.+)$")
|
||||
|
||||
|
||||
class YumVersionLock:
|
||||
def __init__(self, module):
|
||||
@@ -102,6 +109,15 @@ class YumVersionLock:
|
||||
self.module.fail_json(msg="Error: " + to_native(err) + to_native(out))
|
||||
|
||||
|
||||
def match(entry, name):
|
||||
m = NEVRA_RE_YUM.match(entry)
|
||||
if not m:
|
||||
m = NEVRA_RE_DNF.match(entry)
|
||||
if not m:
|
||||
return False
|
||||
return fnmatch(m.group("name"), name)
|
||||
|
||||
|
||||
def main():
|
||||
""" start main program to add/remove a package to yum versionlock"""
|
||||
module = AnsibleModule(
|
||||
@@ -123,20 +139,20 @@ def main():
|
||||
|
||||
# Ensure versionlock state of packages
|
||||
packages_list = []
|
||||
if state in ('present'):
|
||||
if state in ('present', ):
|
||||
command = 'add'
|
||||
for single_pkg in packages:
|
||||
if not any(fnmatch(pkg.split(":", 1)[-1], single_pkg) for pkg in versionlock_packages.split()):
|
||||
if not any(match(pkg, single_pkg) for pkg in versionlock_packages.split()):
|
||||
packages_list.append(single_pkg)
|
||||
if packages_list:
|
||||
if module.check_mode:
|
||||
changed = True
|
||||
else:
|
||||
changed = yum_v.ensure_state(packages_list, command)
|
||||
elif state in ('absent'):
|
||||
elif state in ('absent', ):
|
||||
command = 'delete'
|
||||
for single_pkg in packages:
|
||||
if any(fnmatch(pkg, single_pkg) for pkg in versionlock_packages.split()):
|
||||
if any(match(pkg, single_pkg) for pkg in versionlock_packages.split()):
|
||||
packages_list.append(single_pkg)
|
||||
if packages_list:
|
||||
if module.check_mode:
|
||||
|
||||
@@ -417,7 +417,9 @@ def package_present(m, name, want_latest):
|
||||
# if a version is given leave the package in to let zypper handle the version
|
||||
# resolution
|
||||
packageswithoutversion = [p for p in packages if not p.version]
|
||||
prerun_state = get_installed_state(m, packageswithoutversion)
|
||||
prerun_state = {}
|
||||
if packageswithoutversion:
|
||||
prerun_state = get_installed_state(m, packageswithoutversion)
|
||||
# generate lists of packages to install or remove
|
||||
packages = [p for p in packages if p.shouldinstall != (p.name in prerun_state)]
|
||||
|
||||
|
||||
@@ -133,8 +133,6 @@ except ImportError:
|
||||
XML_IMP_ERR = traceback.format_exc()
|
||||
HAS_XML = False
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
|
||||
from ansible.module_utils.urls import fetch_url
|
||||
@@ -142,6 +140,8 @@ from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils.six.moves import configparser, StringIO
|
||||
from io import open
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
REPO_OPTS = ['alias', 'name', 'priority', 'enabled', 'autorefresh', 'gpgcheck']
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user