Compare commits

...

28 Commits
4.6.0 ... 4.7.0

Author SHA1 Message Date
Felix Fontein
22b72e6684 Release 4.7.0. 2022-04-05 14:02:29 +02:00
patchback[bot]
8e7bee4217 Fix small typo (#4452) (#4454)
(cherry picked from commit 380de2d0c1)

Co-authored-by: Wouter Schoot <wouter@schoot.org>
2022-04-05 14:00:35 +02:00
patchback[bot]
cef6b81e5b Bug fix: Warns user if incorrect SDK version is installed (#4422) (#4450)
* Add error handling to check correct SDK version installed

* Fix CI errors

* Added changelog fragment

* Changed exeption type

* Update changelogs fragment

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit e7ffa76db6)

Co-authored-by: Ricky White <rickywhite@outlook.com>
2022-04-05 07:49:30 +02:00
patchback[bot]
182c365d87 nmcli: suggest new routes4 and routes6 format (#4328) (#4447)
* suggest new routes4 and routes6 format

* make new options instead of modifying exiting one

* fix docs and some small errors

* fixing docs

(cherry picked from commit feb0fffd58)

Co-authored-by: Alex Groshev <38885591+haddystuff@users.noreply.github.com>
2022-04-05 07:12:38 +02:00
patchback[bot]
587cdc82e7 Keycloak client, Add always_display_in_console option (#4429) (#4448)
* Keycloak client, Add always_display_in_console option

* Add 4429-keycloak-client-add-always-display-in-console.yml fragment.

* Update changelogs/fragments/4429-keycloak-client-add-always-display-in-console.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/identity/keycloak/keycloak_client.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/identity/keycloak/keycloak_client.py

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Michal Vasko <mvasko@cloudwerkstatt.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 79256b2bd2)

Co-authored-by: whoamiUNIX <40315055+whoamiUNIX@users.noreply.github.com>
2022-04-05 07:09:20 +02:00
Felix Fontein
cb1a50a273 Prepare 4.7.0 release. 2022-04-05 07:05:07 +02:00
patchback[bot]
f0df50e665 Bugfix: zypper issue with specified package versions (#4421) (#4446)
* fixed issue with specified package versions

zypper.py was doing nothing on state=present, when ALL requestet/checked packages had a specific version stated. This was caused by get_installed_state() being called with an empty package list, which in this case returns information about all ALL installed packages. This lead to an exessive filter list prerun_state, essentially removing all packages that are installed in ANY version on the target system from the request list.

* Create 4421-zypper_package_version_handling_fix

added changelog fragment for https://github.com/ansible-collections/community.general/pull/4421

* Delete 4421-zypper_package_version_handling_fix

* Create 4421-zypper_package_version_handling_fix.yml

(cherry picked from commit bbe231e261)

Co-authored-by: tover99 <101673769+tover99@users.noreply.github.com>
2022-04-05 06:28:15 +02:00
patchback[bot]
47aa93d970 cronvar: ensure creation of /etc/cron.d in test (#4440) (#4444)
* ensure creation of /etc/cron.d in test

* fixed typo

(cherry picked from commit 9e0ff8ba4b)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2022-04-03 10:54:44 +02:00
patchback[bot]
e89648a114 Remove OpenSuSE Python 2 from devel CI. (#4442) (#4443)
(cherry picked from commit bd83490b45)

Co-authored-by: Felix Fontein <felix@fontein.de>
2022-04-02 18:31:40 +02:00
patchback[bot]
6f1bdb3e49 pids: re-enabled tests on Alpine Linux (#4405) (#4439)
* [WIP] pids: re-enabled tests on Alpine Linux

* trying to compile a simple-faked sleep command

* make FreeBSD happy

* remove the block testing for Alpine Linux

* simpler version of sleeper.c

* simpler version of sleeper.c, part II

* Update tests/integration/targets/pids/tasks/main.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update tests/integration/targets/pids/tasks/main.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* added license to sleeper.c file

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 21ee4c84b7)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2022-04-02 08:45:53 +02:00
patchback[bot]
fbf11668f4 CI: Remove 'warn:' that's removed in ansible-core 2.14 (#4434) (#4437)
* Remove 'warn:' that's removed in ansible-core 2.14.

* Install virtualenv when needed.

(cherry picked from commit 24ca69aa05)

Co-authored-by: Felix Fontein <felix@fontein.de>
2022-04-01 23:11:39 +02:00
patchback[bot]
3376442aa2 Proxmox Inventory: Add support for templating in inventory file (#4418) (#4435)
* added templating to the url, user, and password

* added changelog fragment

* typo in description for url, and password

* clarify in the changelog what can you change

* update documentation and added an example

* missing quote from examples

* Apply suggestions from code review

Changed to I for option names

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/inventory/proxmox.py

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 13d18c9aa8)

Co-authored-by: Ilija Matoski <ilijamt@gmail.com>
2022-04-01 23:07:42 +02:00
patchback[bot]
868edfa664 ipa_service: Add skip_host_check option (#4417) (#4436)
* ipa_service: Add `skip_host_check` option

* Update plugins/modules/identity/ipa/ipa_service.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/identity/ipa/ipa_service.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/identity/ipa/ipa_service.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* changelogs/fragments: Add 4417-ipa_service-add-skip_host_check.yml

Co-authored-by: sodd <4178855+sodd@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 1b357bade7)

Co-authored-by: sodd <sodd@users.noreply.github.com>
2022-04-01 23:07:23 +02:00
patchback[bot]
2fcb77f7fb Replace antsibull-lint collection-docs with antsibull-docs lint-collection-docs. (#4423) (#4426)
(cherry picked from commit 668bbed602)

Co-authored-by: Felix Fontein <felix@fontein.de>
2022-03-30 08:17:38 +02:00
patchback[bot]
17135dd082 Add stable-2.13 to CI, thin out older version matrix (#4413) (#4414)
* Add stable-2.13 to CI, thin out older version matrix.

* Thin out matrix more.

* And a bit more.

(cherry picked from commit caedcc3075)

Co-authored-by: Felix Fontein <felix@fontein.de>
2022-03-29 07:52:32 +02:00
patchback[bot]
7516018cfb keycloak: add missing validate_certs parameters for open_url calls (#4382) (#4410)
* fix: missing `validate_certs` parameters for `open_url` calls

As stated in the documentation, the `validate_certs` parameter can be
used to verify (or not) the TLS certificates. But, for some modules (at
least for the `keycloak_authentication` module), this parameter is not
used with the `open_url` function.

* add changelog fragment

* Update changelogs/fragments/4382-keycloak-add-missing-validate_certs-parameters.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Laurent Meunier <lme@atolcd.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 34420e143e)

Co-authored-by: Laurent Meunier <laurent@deltalima.net>
2022-03-28 22:25:14 +02:00
patchback[bot]
58df1df107 keycloak_client: add default_client_scopes and optional_client_scopes (#4385) (#4409)
* keycloak_client: add default_client_scopes and optional_client_scopes

* Changelog fragment for #4385

* Update changelogs/fragments/4385-keycloak-client-default-optional-scopes.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/identity/keycloak/keycloak_client.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/identity/keycloak/keycloak_client.py

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 30c65cd84c)

Co-authored-by: Alex Lubbock <alex@lubbock.uk>
2022-03-28 22:25:00 +02:00
patchback[bot]
e9b3705809 feat: sudoers module supports runas parameter with default of root (#4380) (#4399)
* feat: sudoers module supports runas parameter with default of root

* fix: sudoers tests now pass

* chore: add changelog fragment for 4380

* fix: runas feature now a non-breaking change wh no def with no default

* fix: no trailing space in sudoers.py

* Update plugins/modules/system/sudoers.py

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 17fe813c18)

Co-authored-by: doubletwist13 <doubletwist@fearthepenguin.net>
2022-03-24 06:44:48 +00:00
patchback[bot]
743e9c851f ldap: added documentation as requested (#4389) (#4398)
* added documentation as requested

* Update plugins/doc_fragments/ldap.py

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 8515c03dc7)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2022-03-24 06:44:30 +00:00
patchback[bot]
a7883ee489 Fixed typo in keycloak_client_rolemapping examples (#4393) (#4401)
* Fixed typo in keycloak_client_rolemapping examples

* Add a changelog fragment.

* Removed changelogs fragment for docs-only change.

Co-authored-by: shnee <shnee@shnee.net>
(cherry picked from commit cb30eb2d30)

Co-authored-by: shnee <CurtyD13@gmail.com>
2022-03-24 06:44:18 +00:00
patchback[bot]
518af70b77 Proxmox inventory plugin - Fix tags parsing (#4378) (#4402)
* Proxmox inventory plugin - Fix tags parsing

  * In some cases the Proxmox API returns a tags string that consists in
    a single space. The Proxmox inventory plugin parsed that into a
    single, empty tag. Stripping the initial string then checking
    whether it actually contains something fixes that.
  * Do not call `_to_safe` on the concatenation of a known safe string
    and a string that was already made safe.

* Changelog fragment for Proxmox inventory plugin tags fix

* Proxmox inventory plugin - Include link to PR in fragment

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 622895fb55)

Co-authored-by: Emmanuel Benoît <tseeker@nocternity.net>
2022-03-24 06:44:02 +00:00
patchback[bot]
ce7d98aa6f Add collection links file. (#4384) (#4386)
(cherry picked from commit eb4495b716)

Co-authored-by: Felix Fontein <felix@fontein.de>
2022-03-22 07:21:28 +01:00
Felix Fontein
9f91f4b5cd Next expected release is 4.7.0. 2022-03-16 19:12:20 +01:00
Felix Fontein
c45c38f04b Release 4.6.1. 2022-03-16 18:20:34 +01:00
patchback[bot]
f7efb2e394 plugins/inventory/lxd.py: fix listing of containers without os / release (#4351) (#4372)
* plugins/inventory/lxd.py: fix listing of containers without os / release

In some cases, a container might be present, that was initialized empty, therefore lacking meta information about the os or the release.
Test if the data entry is None to avoid calling lower on it.

* Update plugins/inventory/lxd.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/inventory/lxd.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Create 4351-inventory-lxd-handling_metadata_wo_os_and_release.yml

* fix yaml readability of changelog fragment

* Update changelogs/fragments/4351-inventory-lxd-handling_metadata_wo_os_and_release.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Malte Kuhn <mkuhn@maxcluster.de>
(cherry picked from commit 421ccd5dc9)

Co-authored-by: monkz <git@monkz.de>
2022-03-16 18:19:44 +01:00
Felix Fontein
093b83c34f [stable-4] Revert "Allow complex values in variables parameter of terraform module (#4281)" (#4370)
* Revert "Allow complex values in variables parameter of terraform module (#4281)" (#4368)

This reverts commit 4cc7f41395.

(cherry picked from commit 9618fb9786)

* Add changelog fragment.
2022-03-16 07:24:38 +01:00
Felix Fontein
579fdbbc1c Prepare 4.6.1 release. 2022-03-16 07:24:24 +01:00
Felix Fontein
c970c14c71 The next expected release is 4.7.0. 2022-03-15 13:36:57 +01:00
33 changed files with 830 additions and 268 deletions

View File

@@ -69,6 +69,19 @@ stages:
- test: 3
- test: 4
- test: extra
- stage: Sanity_2_13
displayName: Sanity 2.13
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: 2.13/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
- stage: Sanity_2_12
displayName: Sanity 2.12
dependsOn: []
@@ -138,6 +151,19 @@ stages:
- test: 3.8
- test: 3.9
- test: '3.10'
- stage: Units_2_13
displayName: Units 2.13
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.13/units/{0}/1
targets:
- test: 2.7
- test: 3.6
- test: 3.8
- test: 3.9
- stage: Units_2_12
displayName: Units 2.12
dependsOn: []
@@ -148,12 +174,8 @@ stages:
testFormat: 2.12/units/{0}/1
targets:
- test: 2.6
- test: 2.7
- test: 3.5
- test: 3.6
- test: 3.7
- test: 3.8
- test: '3.10'
- stage: Units_2_11
displayName: Units 2.11
dependsOn: []
@@ -166,9 +188,6 @@ stages:
- test: 2.6
- test: 2.7
- test: 3.5
- test: 3.6
- test: 3.7
- test: 3.8
- test: 3.9
- stage: Units_2_10
displayName: Units 2.10
@@ -191,11 +210,7 @@ stages:
testFormat: 2.9/units/{0}/1
targets:
- test: 2.6
- test: 2.7
- test: 3.5
- test: 3.6
- test: 3.7
- test: 3.8
## Remote
- stage: Remote_devel
@@ -220,6 +235,22 @@ stages:
- 1
- 2
- 3
- stage: Remote_2_13
displayName: Remote 2.13
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.13/{0}
targets:
- name: macOS 12.0
test: macos/12.0
- name: RHEL 8.5
test: rhel/8.5
groups:
- 1
- 2
- 3
- stage: Remote_2_12
displayName: Remote 2.12
dependsOn: []
@@ -302,9 +333,7 @@ stages:
test: fedora34
- name: Fedora 35
test: fedora35
- name: openSUSE 15 py2
test: opensuse15py2
- name: openSUSE 15 py3
- name: openSUSE 15
test: opensuse15
- name: Ubuntu 18.04
test: ubuntu1804
@@ -316,6 +345,24 @@ stages:
- 1
- 2
- 3
- stage: Docker_2_13
displayName: Docker 2.13
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.13/linux/{0}
targets:
- name: Fedora 35
test: fedora35
- name: openSUSE 15 py2
test: opensuse15py2
- name: Alpine 3
test: alpine3
groups:
- 1
- 2
- 3
- stage: Docker_2_12
displayName: Docker 2.12
dependsOn: []
@@ -328,8 +375,6 @@ stages:
test: centos6
- name: Fedora 34
test: fedora34
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 20.04
test: ubuntu2004
groups:
@@ -344,12 +389,8 @@ stages:
parameters:
testFormat: 2.11/linux/{0}
targets:
- name: CentOS 7
test: centos7
- name: Fedora 33
test: fedora33
- name: openSUSE 15 py2
test: opensuse15py2
- name: Alpine 3
test: alpine3
groups:
@@ -380,8 +421,6 @@ stages:
targets:
- name: Fedora 31
test: fedora31
- name: openSUSE 15 py3
test: opensuse15
groups:
- 2
- 3
@@ -417,6 +456,16 @@ stages:
testFormat: devel/cloud/{0}/1
targets:
- test: 2.7
- test: '3.10'
- stage: Cloud_2_13
displayName: Cloud 2.13
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.13/cloud/{0}/1
targets:
- test: 3.9
- stage: Cloud_2_12
displayName: Cloud 2.12
@@ -466,26 +515,31 @@ stages:
- Sanity_2_10
- Sanity_2_11
- Sanity_2_12
- Sanity_2_13
- Units_devel
- Units_2_9
- Units_2_10
- Units_2_11
- Units_2_12
- Units_2_13
- Remote_devel
- Remote_2_9
- Remote_2_10
- Remote_2_11
- Remote_2_12
- Remote_2_13
- Docker_devel
- Docker_2_9
- Docker_2_10
- Docker_2_11
- Docker_2_12
- Docker_2_13
- Docker_community_devel
- Cloud_devel
- Cloud_2_9
- Cloud_2_10
- Cloud_2_11
- Cloud_2_12
- Cloud_2_13
jobs:
- template: templates/coverage.yml

View File

@@ -6,6 +6,47 @@ Community General Release Notes
This changelog describes changes after version 3.0.0.
v4.7.0
======
Release Summary
---------------
Regular bugfix and feature release.
Minor Changes
-------------
- ipa_service - add ``skip_host_check`` parameter. (https://github.com/ansible-collections/community.general/pull/4417).
- keycloak_client - add ``always_display_in_console`` parameter (https://github.com/ansible-collections/community.general/issues/4390).
- keycloak_client - add ``default_client_scopes`` and ``optional_client_scopes`` parameters. (https://github.com/ansible-collections/community.general/pull/4385).
- proxmox inventory plugin - add support for templating the ``url``, ``user``, and ``password`` options (https://github.com/ansible-collections/community.general/pull/4418).
- sudoers - add support for ``runas`` parameter (https://github.com/ansible-collections/community.general/issues/4379).
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).
- keycloak_* - the documented ``validate_certs`` parameter was not taken into account when calling the ``open_url`` function in some cases, thus enforcing certificate validation even when ``validate_certs`` was set to ``false``. (https://github.com/ansible-collections/community.general/pull/4382)
- nmcli - fix returning "changed" when routes parameters set, also suggest new routes4 and routes6 format (https://github.com/ansible-collections/community.general/issues/4131).
- proxmox inventory plugin - fixed the ``tags_parsed`` field when Proxmox returns a single space for the ``tags`` entry (https://github.com/ansible-collections/community.general/pull/4378).
- 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).
v4.6.1
======
Release Summary
---------------
Extraordinary bugfix release to fix a breaking change in ``terraform``.
Bugfixes
--------
- lxd inventory plugin - do not crash if OS and release metadata are not present
(https://github.com/ansible-collections/community.general/pull/4351).
- terraform - revert bugfix https://github.com/ansible-collections/community.general/pull/4281 that tried to fix ``variable`` handling to allow complex values. It turned out that this was breaking several valid use-cases (https://github.com/ansible-collections/community.general/issues/4367, https://github.com/ansible-collections/community.general/pull/4370).
v4.6.0
======

View File

@@ -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, ansible-core 2.13 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported.
## External requirements

View File

@@ -1585,3 +1585,59 @@ releases:
- 4352-proxmox-inventory-filters.yml
- 4355-ldap-recursive-delete.yml
release_date: '2022-03-15'
4.6.1:
changes:
bugfixes:
- 'lxd inventory plugin - do not crash if OS and release metadata are not present
(https://github.com/ansible-collections/community.general/pull/4351).
'
- terraform - revert bugfix https://github.com/ansible-collections/community.general/pull/4281
that tried to fix ``variable`` handling to allow complex values. It turned
out that this was breaking several valid use-cases (https://github.com/ansible-collections/community.general/issues/4367,
https://github.com/ansible-collections/community.general/pull/4370).
release_summary: Extraordinary bugfix release to fix a breaking change in ``terraform``.
fragments:
- 4.6.1.yml
- 4351-inventory-lxd-handling_metadata_wo_os_and_release.yml
- 4368-reverts-4281.yml
release_date: '2022-03-16'
4.7.0:
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).
- keycloak_* - the documented ``validate_certs`` parameter was not taken into
account when calling the ``open_url`` function in some cases, thus enforcing
certificate validation even when ``validate_certs`` was set to ``false``.
(https://github.com/ansible-collections/community.general/pull/4382)
- nmcli - fix returning "changed" when routes parameters set, also suggest new
routes4 and routes6 format (https://github.com/ansible-collections/community.general/issues/4131).
- proxmox inventory plugin - fixed the ``tags_parsed`` field when Proxmox returns
a single space for the ``tags`` entry (https://github.com/ansible-collections/community.general/pull/4378).
- 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).
minor_changes:
- ipa_service - add ``skip_host_check`` parameter. (https://github.com/ansible-collections/community.general/pull/4417).
- keycloak_client - add ``always_display_in_console`` parameter (https://github.com/ansible-collections/community.general/issues/4390).
- keycloak_client - add ``default_client_scopes`` and ``optional_client_scopes``
parameters. (https://github.com/ansible-collections/community.general/pull/4385).
- proxmox inventory plugin - add support for templating the ``url``, ``user``,
and ``password`` options (https://github.com/ansible-collections/community.general/pull/4418).
- sudoers - add support for ``runas`` parameter (https://github.com/ansible-collections/community.general/issues/4379).
release_summary: Regular bugfix and feature release.
fragments:
- 4.7.0.yml
- 4131-nmcli_fix_reports_changed_for_routes4_parameter.yml
- 4378-proxmox-inventory-tags.yml
- 4380-sudoers-runas-parameter.yml
- 4382-keycloak-add-missing-validate_certs-parameters.yml
- 4385-keycloak-client-default-optional-scopes.yml
- 4386-proxmox-support-templating-in-inventory-file.yml
- 4417-ipa_service-add-skip_host_check.yml
- 4421-zypper_package_version_handling_fix.yml
- 4422-warn-user-if-incorrect-SDK-version-is-installed.yaml
- 4429-keycloak-client-add-always-display-in-console.yml
release_date: '2022-04-05'

23
docs/docsite/links.yml Normal file
View File

@@ -0,0 +1,23 @@
---
edit_on_github:
repository: ansible-collections/community.general
branch: main
path_prefix: ''
extra_links:
- description: Submit a bug report
url: https://github.com/ansible-collections/community.general/issues/new?assignees=&labels=&template=bug_report.yml
- description: Request a feature
url: https://github.com/ansible-collections/community.general/issues/new?assignees=&labels=&template=feature_request.yml
communication:
matrix_rooms:
- topic: General usage and support questions
room: '#users:ansible.im'
irc_channels:
- topic: General usage and support questions
network: Libera
channel: '#ansible'
mailing_lists:
- topic: Ansible Project List
url: https://groups.google.com/g/ansible-project

View File

@@ -1,6 +1,6 @@
namespace: community
name: general
version: 4.6.0
version: 4.7.0
readme: README.md
authors:
- Ansible (https://github.com/ansible)

View File

@@ -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:

View File

@@ -666,9 +666,13 @@ class InventoryModule(BaseInventoryPlugin):
# add network informations
self.build_inventory_network(instance_name)
# add os
self.inventory.set_variable(instance_name, 'ansible_lxd_os', self._get_data_entry('inventory/{0}/os'.format(instance_name)).lower())
v = self._get_data_entry('inventory/{0}/os'.format(instance_name))
if v:
self.inventory.set_variable(instance_name, 'ansible_lxd_os', v.lower())
# add release
self.inventory.set_variable(instance_name, 'ansible_lxd_release', self._get_data_entry('inventory/{0}/release'.format(instance_name)).lower())
v = self._get_data_entry('inventory/{0}/release'.format(instance_name))
if v:
self.inventory.set_variable(instance_name, 'ansible_lxd_release', v.lower())
# add profile
self.inventory.set_variable(instance_name, 'ansible_lxd_profile', self._get_data_entry('inventory/{0}/profile'.format(instance_name)))
# add state

View File

@@ -31,6 +31,7 @@ DOCUMENTATION = '''
description:
- URL to Proxmox cluster.
- If the value is not specified in the inventory configuration, the value of environment variable C(PROXMOX_URL) will be used instead.
- Since community.general 4.7.0 you can also use templating to specify the value of the I(url).
default: 'http://localhost:8006'
type: str
env:
@@ -40,6 +41,7 @@ DOCUMENTATION = '''
description:
- Proxmox authentication user.
- If the value is not specified in the inventory configuration, the value of environment variable C(PROXMOX_USER) will be used instead.
- Since community.general 4.7.0 you can also use templating to specify the value of the I(user).
required: yes
type: str
env:
@@ -49,6 +51,7 @@ DOCUMENTATION = '''
description:
- Proxmox authentication password.
- If the value is not specified in the inventory configuration, the value of environment variable C(PROXMOX_PASSWORD) will be used instead.
- Since community.general 4.7.0 you can also use templating to specify the value of the I(password).
required: yes
type: str
env:
@@ -136,6 +139,14 @@ compose:
my_inv_var_1: "'my_var1_value'"
my_inv_var_2: >
"my_var_2_value"
# Specify the url, user and password using templating
# my.proxmox.yml
plugin: community.general.proxmox
url: "{{ lookup('ansible.builtin.ini', 'url', section='proxmox', file='file.ini') }}"
user: "{{ lookup('ansible.builtin.env','PM_USER') | default('ansible@pve') }}"
password: "{{ lookup('community.general.random_string', base64=True) }}"
'''
import itertools
@@ -148,6 +159,7 @@ from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cachea
from ansible.module_utils.common.text.converters import to_native
from ansible.module_utils.six.moves.urllib.parse import urlencode
from ansible.utils.display import Display
from ansible.template import Templar
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
@@ -323,8 +335,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
# Additional field containing parsed tags as list
if config == 'tags':
parsed_key = self.to_safe('%s%s' % (key, "_parsed"))
properties[parsed_key] = [tag.strip() for tag in value.split(",")]
stripped_value = value.strip()
if stripped_value:
parsed_key = key + "_parsed"
properties[parsed_key] = [tag.strip() for tag in stripped_value.split(",")]
# The first field in the agent string tells you whether the agent is enabled
# the rest of the comma separated string is extra config for the agent
@@ -498,10 +512,24 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
# read config from file, this sets 'options'
self._read_config_data(path)
t = Templar(loader=loader)
# read options
self.proxmox_url = self.get_option('url').rstrip('/')
self.proxmox_user = self.get_option('user')
self.proxmox_password = self.get_option('password')
proxmox_url = self.get_option('url')
if t.is_template(proxmox_url):
proxmox_url = t.template(variable=proxmox_url, disable_lookups=False)
self.proxmox_url = proxmox_url.rstrip('/')
proxmox_user = self.get_option('user')
if t.is_template(proxmox_user):
proxmox_user = t.template(variable=proxmox_user, disable_lookups=False)
self.proxmox_user = proxmox_user
proxmox_password = self.get_option('password')
if t.is_template(proxmox_password):
proxmox_password = t.template(variable=proxmox_password, disable_lookups=False)
self.proxmox_password = proxmox_password
self.cache_key = self.get_cache_key(path)
self.use_cache = cache and self.get_option('cache')
self.host_filters = self.get_option('filters')

View File

@@ -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)

View File

@@ -1237,7 +1237,7 @@ class KeycloakAPI(object):
authentication_flow = {}
# Check if the authentication flow exists on the Keycloak serveraders
authentications = json.load(open_url(URL_AUTHENTICATION_FLOWS.format(url=self.baseurl, realm=realm), method='GET',
headers=self.restheaders, timeout=self.connection_timeout))
headers=self.restheaders, timeout=self.connection_timeout, validate_certs=self.validate_certs))
for authentication in authentications:
if authentication["alias"] == alias:
authentication_flow = authentication
@@ -1281,14 +1281,16 @@ class KeycloakAPI(object):
method='POST',
headers=self.restheaders,
data=json.dumps(new_name),
timeout=self.connection_timeout)
timeout=self.connection_timeout,
validate_certs=self.validate_certs)
flow_list = json.load(
open_url(
URL_AUTHENTICATION_FLOWS.format(url=self.baseurl,
realm=realm),
method='GET',
headers=self.restheaders,
timeout=self.connection_timeout))
timeout=self.connection_timeout,
validate_certs=self.validate_certs))
for flow in flow_list:
if flow["alias"] == config["alias"]:
return flow
@@ -1318,7 +1320,8 @@ class KeycloakAPI(object):
method='POST',
headers=self.restheaders,
data=json.dumps(new_flow),
timeout=self.connection_timeout)
timeout=self.connection_timeout,
validate_certs=self.validate_certs)
flow_list = json.load(
open_url(
URL_AUTHENTICATION_FLOWS.format(
@@ -1326,7 +1329,8 @@ class KeycloakAPI(object):
realm=realm),
method='GET',
headers=self.restheaders,
timeout=self.connection_timeout))
timeout=self.connection_timeout,
validate_certs=self.validate_certs))
for flow in flow_list:
if flow["alias"] == config["alias"]:
return flow
@@ -1351,7 +1355,8 @@ class KeycloakAPI(object):
method='PUT',
headers=self.restheaders,
data=json.dumps(updatedExec),
timeout=self.connection_timeout)
timeout=self.connection_timeout,
validate_certs=self.validate_certs)
except Exception as e:
self.module.fail_json(msg="Unable to update executions %s: %s" % (updatedExec, str(e)))
@@ -1371,7 +1376,8 @@ class KeycloakAPI(object):
method='POST',
headers=self.restheaders,
data=json.dumps(authenticationConfig),
timeout=self.connection_timeout)
timeout=self.connection_timeout,
validate_certs=self.validate_certs)
except Exception as e:
self.module.fail_json(msg="Unable to add authenticationConfig %s: %s" % (executionId, str(e)))
@@ -1395,7 +1401,8 @@ class KeycloakAPI(object):
method='POST',
headers=self.restheaders,
data=json.dumps(newSubFlow),
timeout=self.connection_timeout)
timeout=self.connection_timeout,
validate_certs=self.validate_certs)
except Exception as e:
self.module.fail_json(msg="Unable to create new subflow %s: %s" % (subflowName, str(e)))
@@ -1418,7 +1425,8 @@ class KeycloakAPI(object):
method='POST',
headers=self.restheaders,
data=json.dumps(newExec),
timeout=self.connection_timeout)
timeout=self.connection_timeout,
validate_certs=self.validate_certs)
except Exception as e:
self.module.fail_json(msg="Unable to create new execution %s: %s" % (execution["provider"], str(e)))
@@ -1440,7 +1448,8 @@ class KeycloakAPI(object):
id=executionId),
method='POST',
headers=self.restheaders,
timeout=self.connection_timeout)
timeout=self.connection_timeout,
validate_certs=self.validate_certs)
elif diff < 0:
for i in range(-diff):
open_url(
@@ -1450,7 +1459,8 @@ class KeycloakAPI(object):
id=executionId),
method='POST',
headers=self.restheaders,
timeout=self.connection_timeout)
timeout=self.connection_timeout,
validate_certs=self.validate_certs)
except Exception as e:
self.module.fail_json(msg="Unable to change execution priority %s: %s" % (executionId, str(e)))
@@ -1471,7 +1481,8 @@ class KeycloakAPI(object):
flowalias=quote(config["alias"])),
method='GET',
headers=self.restheaders,
timeout=self.connection_timeout))
timeout=self.connection_timeout,
validate_certs=self.validate_certs))
for execution in executions:
if "authenticationConfig" in execution:
execConfigId = execution["authenticationConfig"]
@@ -1483,7 +1494,8 @@ class KeycloakAPI(object):
id=execConfigId),
method='GET',
headers=self.restheaders,
timeout=self.connection_timeout))
timeout=self.connection_timeout,
validate_certs=self.validate_certs))
execution["authenticationConfig"] = execConfig
return executions
except Exception as e:

View File

@@ -443,7 +443,7 @@ def main():
for k, v in variables.items():
variables_args.extend([
'-var',
'{0}={1}'.format(k, json.dumps(v))
'{0}={1}'.format(k, v)
])
if variables_files:
for f in variables_files:

View File

@@ -32,6 +32,14 @@ options:
- Force principal name even if host is not in DNS.
required: false
type: bool
skip_host_check:
description:
- Force service to be created even when host object does not exist to manage it.
- This is only used on creation, not for updating existing services.
required: false
type: bool
default: false
version_added: 4.7.0
state:
description: State to ensure.
required: false
@@ -111,17 +119,19 @@ class ServiceIPAClient(IPAClient):
return self._post_json(method='service_remove_host', name=name, item={'host': item})
def get_service_dict(force=None, krbcanonicalname=None):
def get_service_dict(force=None, krbcanonicalname=None, skip_host_check=None):
data = {}
if force is not None:
data['force'] = force
if krbcanonicalname is not None:
data['krbcanonicalname'] = krbcanonicalname
if skip_host_check is not None:
data['skip_host_check'] = skip_host_check
return data
def get_service_diff(client, ipa_host, module_service):
non_updateable_keys = ['force', 'krbcanonicalname']
non_updateable_keys = ['force', 'krbcanonicalname', 'skip_host_check']
for key in non_updateable_keys:
if key in module_service:
del module_service[key]
@@ -135,7 +145,7 @@ def ensure(module, client):
hosts = module.params['hosts']
ipa_service = client.service_find(name=name)
module_service = get_service_dict(force=module.params['force'])
module_service = get_service_dict(force=module.params['force'], skip_host_check=module.params['skip_host_check'])
changed = False
if state in ['present', 'enabled', 'disabled']:
if not ipa_service:
@@ -183,6 +193,7 @@ def main():
argument_spec.update(
krbcanonicalname=dict(type='str', required=True, aliases=['name']),
force=dict(type='bool', required=False),
skip_host_check=dict(type='bool', default=False, required=False),
hosts=dict(type='list', required=False, elements='str'),
state=dict(type='str', required=False, default='present',
choices=['present', 'absent']))

View File

@@ -301,6 +301,15 @@ options:
- useTemplateMappers
type: bool
always_display_in_console:
description:
- Whether or not to display this client in account console, even if the
user does not have an active session.
aliases:
- alwaysDisplayInConsole
type: bool
version_added: 4.7.0
surrogate_auth_required:
description:
- Whether or not surrogate auth is required.
@@ -326,6 +335,24 @@ options:
- authenticationFlowBindingOverrides
version_added: 3.4.0
default_client_scopes:
description:
- List of default client scopes.
aliases:
- defaultClientScopes
type: list
elements: str
version_added: 4.7.0
optional_client_scopes:
description:
- List of optional client scopes.
aliases:
- optionalClientScopes
type: list
elements: str
version_added: 4.7.0
protocol_mappers:
description:
- a list of dicts defining protocol mappers for this client.
@@ -593,6 +620,7 @@ EXAMPLES = '''
use_template_config: False
use_template_scope: false
use_template_mappers: no
always_display_in_console: true
registered_nodes:
node01.example.com: 1507828202
registration_access_token: eyJWT_TOKEN
@@ -786,9 +814,12 @@ def main():
use_template_config=dict(type='bool', aliases=['useTemplateConfig']),
use_template_scope=dict(type='bool', aliases=['useTemplateScope']),
use_template_mappers=dict(type='bool', aliases=['useTemplateMappers']),
always_display_in_console=dict(type='bool', aliases=['alwaysDisplayInConsole']),
authentication_flow_binding_overrides=dict(type='dict', aliases=['authenticationFlowBindingOverrides']),
protocol_mappers=dict(type='list', elements='dict', options=protmapper_spec, aliases=['protocolMappers']),
authorization_settings=dict(type='dict', aliases=['authorizationSettings']),
default_client_scopes=dict(type='list', elements='str', aliases=['defaultClientScopes']),
optional_client_scopes=dict(type='list', elements='str', aliases=['optionalClientScopes']),
)
argument_spec.update(meta_args)

View File

@@ -104,7 +104,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
@@ -122,7 +122,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
@@ -138,7 +138,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

View File

@@ -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):

View File

@@ -90,11 +90,53 @@ options:
version_added: 3.2.0
routes4:
description:
- The list of ipv4 routes.
- Use the format '192.0.3.0/24 192.0.2.1'
- The list of IPv4 routes.
- Use the format C(192.0.3.0/24 192.0.2.1).
- To specify more complex routes, use the I(routes4_extended) option.
type: list
elements: str
version_added: 2.0.0
routes4_extended:
description:
- The list of IPv4 routes.
type: list
elements: dict
suboptions:
ip:
description:
- IP or prefix of route.
- Use the format C(192.0.3.0/24).
type: str
required: true
next_hop:
description:
- Use the format C(192.0.2.1).
type: str
metric:
description:
- Route metric.
type: int
table:
description:
- The table to add this route to.
- The default depends on C(ipv4.route-table).
type: int
cwnd:
description:
- The clamp for congestion window.
type: int
mtu:
description:
- If non-zero, only transmit packets of the specified size or smaller.
type: int
onlink:
description:
- Pretend that the nexthop is directly attached to this link, even if it does not match any interface prefix.
type: bool
tos:
description:
- The Type Of Service.
type: int
route_metric4:
description:
- Set metric level of ipv4 routes configured on interface.
@@ -165,9 +207,47 @@ options:
description:
- The list of IPv6 routes.
- Use the format C(fd12:3456:789a:1::/64 2001:dead:beef::1).
- To specify more complex routes, use the I(routes6_extended) option.
type: list
elements: str
version_added: 4.4.0
routes6_extended:
description:
- The list of IPv6 routes but with parameters.
type: list
elements: dict
suboptions:
ip:
description:
- IP or prefix of route.
- Use the format C(fd12:3456:789a:1::/64).
type: str
required: true
next_hop:
description:
- Use the format C(2001:dead:beef::1).
type: str
metric:
description:
- Route metric.
type: int
table:
description:
- The table to add this route to.
- The default depends on C(ipv6.route-table).
type: int
cwnd:
description:
- The clamp for congestion window.
type: int
mtu:
description:
- If non-zero, only transmit packets of the specified size or smaller.
type: int
onlink:
description:
- Pretend that the nexthop is directly attached to this link, even if it does not match any interface prefix.
type: bool
route_metric6:
description:
- Set metric level of IPv6 routes configured on interface.
@@ -1260,6 +1340,7 @@ class Nmcli(object):
self.gw4 = module.params['gw4']
self.gw4_ignore_auto = module.params['gw4_ignore_auto']
self.routes4 = module.params['routes4']
self.routes4_extended = module.params['routes4_extended']
self.route_metric4 = module.params['route_metric4']
self.routing_rules4 = module.params['routing_rules4']
self.never_default4 = module.params['never_default4']
@@ -1272,6 +1353,7 @@ class Nmcli(object):
self.gw6 = module.params['gw6']
self.gw6_ignore_auto = module.params['gw6_ignore_auto']
self.routes6 = module.params['routes6']
self.routes6_extended = module.params['routes6_extended']
self.route_metric6 = module.params['route_metric6']
self.dns6 = module.params['dns6']
self.dns6_search = module.params['dns6_search']
@@ -1371,7 +1453,7 @@ class Nmcli(object):
'ipv4.ignore-auto-dns': self.dns4_ignore_auto,
'ipv4.gateway': self.gw4,
'ipv4.ignore-auto-routes': self.gw4_ignore_auto,
'ipv4.routes': self.routes4,
'ipv4.routes': self.enforce_routes_format(self.routes4, self.routes4_extended),
'ipv4.route-metric': self.route_metric4,
'ipv4.routing-rules': self.routing_rules4,
'ipv4.never-default': self.never_default4,
@@ -1383,7 +1465,7 @@ class Nmcli(object):
'ipv6.ignore-auto-dns': self.dns6_ignore_auto,
'ipv6.gateway': self.gw6,
'ipv6.ignore-auto-routes': self.gw6_ignore_auto,
'ipv6.routes': self.routes6,
'ipv6.routes': self.enforce_routes_format(self.routes6, self.routes6_extended),
'ipv6.route-metric': self.route_metric6,
'ipv6.method': self.ipv6_method,
'ipv6.ip6-privacy': self.ip_privacy6,
@@ -1614,6 +1696,29 @@ class Nmcli(object):
return None
return [address if '/' in address else address + '/128' for address in ip6_addresses]
def enforce_routes_format(self, routes, routes_extended):
if routes is not None:
return routes
elif routes_extended is not None:
return [self.route_to_string(route) for route in routes_extended]
else:
return None
@staticmethod
def route_to_string(route):
result_str = ''
result_str += route['ip']
if route.get('next_hop') is not None:
result_str += ' ' + route['next_hop']
if route.get('metric') is not None:
result_str += ' ' + str(route['metric'])
for attribute, value in sorted(route.items()):
if attribute not in ('ip', 'next_hop', 'metric') and value is not None:
result_str += ' {0}={1}'.format(attribute, str(value).lower())
return result_str
@staticmethod
def bool_to_string(boolean):
if boolean:
@@ -1657,6 +1762,20 @@ class Nmcli(object):
return list
return str
def get_route_params(self, raw_values):
routes_params = []
for raw_value in raw_values:
route_params = {}
for parameter, value in re.findall(r'([\w-]*)\s?=\s?([^\s,}]*)', raw_value):
if parameter == 'nh':
route_params['next_hop'] = value
elif parameter == 'mt':
route_params['metric'] = value
else:
route_params[parameter] = value
routes_params.append(route_params)
return [self.route_to_string(route_params) for route_params in routes_params]
def list_connection_info(self):
cmd = [self.nmcli_bin, '--fields', 'name', '--terse', 'con', 'show']
(rc, out, err) = self.execute_command(cmd)
@@ -1852,13 +1971,7 @@ class Nmcli(object):
if key in conn_info:
current_value = conn_info[key]
if key in ('ipv4.routes', 'ipv6.routes') and current_value is not None:
# ipv4.routes and ipv6.routes do not have same options and show_connection() format
# options: ['10.11.0.0/24 10.10.0.2', '10.12.0.0/24 10.10.0.2 200']
# show_connection(): ['{ ip = 10.11.0.0/24, nh = 10.10.0.2 }', '{ ip = 10.12.0.0/24, nh = 10.10.0.2, mt = 200 }']
# Need to convert in order to compare both
current_value = [re.sub(r'^{\s*ip\s*=\s*([^, ]+),\s*nh\s*=\s*([^} ]+),\s*mt\s*=\s*([^} ]+)\s*}', r'\1 \2 \3',
route) for route in current_value]
current_value = [re.sub(r'^{\s*ip\s*=\s*([^, ]+),\s*nh\s*=\s*([^} ]+)\s*}', r'\1 \2', route) for route in current_value]
current_value = self.get_route_params(current_value)
if key == self.mac_setting:
# MAC addresses are case insensitive, nmcli always reports them in uppercase
value = value.upper()
@@ -1942,6 +2055,18 @@ def main():
gw4=dict(type='str'),
gw4_ignore_auto=dict(type='bool', default=False),
routes4=dict(type='list', elements='str'),
routes4_extended=dict(type='list',
elements='dict',
options=dict(
ip=dict(type='str', required=True),
next_hop=dict(type='str'),
metric=dict(type='int'),
table=dict(type='int'),
tos=dict(type='int'),
cwnd=dict(type='int'),
mtu=dict(type='int'),
onlink=dict(type='bool')
)),
route_metric4=dict(type='int'),
routing_rules4=dict(type='list', elements='str'),
never_default4=dict(type='bool', default=False),
@@ -1958,6 +2083,17 @@ def main():
dns6_search=dict(type='list', elements='str'),
dns6_ignore_auto=dict(type='bool', default=False),
routes6=dict(type='list', elements='str'),
routes6_extended=dict(type='list',
elements='dict',
options=dict(
ip=dict(type='str', required=True),
next_hop=dict(type='str'),
metric=dict(type='int'),
table=dict(type='int'),
cwnd=dict(type='int'),
mtu=dict(type='int'),
onlink=dict(type='bool')
)),
route_metric6=dict(type='int'),
method6=dict(type='str', choices=['ignore', 'auto', 'dhcp', 'link-local', 'manual', 'shared', 'disabled']),
ip_privacy6=dict(type='str', choices=['disabled', 'prefer-public-addr', 'prefer-temp-addr', 'unknown']),
@@ -2014,7 +2150,9 @@ def main():
gsm=dict(type='dict'),
wireguard=dict(type='dict'),
),
mutually_exclusive=[['never_default4', 'gw4']],
mutually_exclusive=[['never_default4', 'gw4'],
['routes4_extended', 'routes4'],
['routes6_extended', 'routes6']],
required_if=[("type", "wifi", [("ssid")])],
supports_check_mode=True,
)

View File

@@ -427,7 +427,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)]

View File

@@ -41,6 +41,11 @@ options:
- Whether a password will be required to run the sudo'd command.
default: true
type: bool
runas:
description:
- Specify the target user the command(s) will run as.
type: str
version_added: 4.7.0
sudoers_path:
description:
- The path which sudoers config files will be managed in.
@@ -69,6 +74,14 @@ EXAMPLES = '''
user: backup
commands: /usr/local/bin/backup
- name: Allow the bob user to run any commands as alice with sudo -u alice
community.general.sudoers:
name: bob-do-as-alice
state: present
user: bob
runas: alice
commands: ANY
- name: >-
Allow the monitoring group to run sudo /usr/local/bin/gather-app-metrics
without requiring a password
@@ -108,6 +121,7 @@ class Sudoers(object):
self.group = module.params['group']
self.state = module.params['state']
self.nopassword = module.params['nopassword']
self.runas = module.params['runas']
self.sudoers_path = module.params['sudoers_path']
self.file = os.path.join(self.sudoers_path, self.name)
self.commands = module.params['commands']
@@ -140,7 +154,8 @@ class Sudoers(object):
commands_str = ', '.join(self.commands)
nopasswd_str = 'NOPASSWD:' if self.nopassword else ''
return "{owner} ALL={nopasswd} {commands}\n".format(owner=owner, nopasswd=nopasswd_str, commands=commands_str)
runas_str = '({runas})'.format(runas=self.runas) if self.runas is not None else ''
return "{owner} ALL={runas}{nopasswd} {commands}\n".format(owner=owner, runas=runas_str, nopasswd=nopasswd_str, commands=commands_str)
def run(self):
if self.state == 'absent' and self.exists():
@@ -168,6 +183,10 @@ def main():
'type': 'bool',
'default': True,
},
'runas': {
'type': 'str',
'default': None,
},
'sudoers_path': {
'type': 'str',
'default': '/etc/sudoers.d',

View File

@@ -3,115 +3,117 @@
# and should not be used as examples of how to write Ansible roles #
####################################################################
- when:
- not (ansible_os_family == 'Alpine' and ansible_distribution_version is version('3.15', '<')) # TODO
block:
- name: Create EMAIL cron var
cronvar:
name: EMAIL
value: doug@ansibmod.con.com
register: create_cronvar1
- name: Ensure /etc/cron.d directory exists
file:
path: /etc/cron.d
state: directory
- name: Create EMAIL cron var again
cronvar:
name: EMAIL
value: doug@ansibmod.con.com
register: create_cronvar2
- name: Create EMAIL cron var
cronvar:
name: EMAIL
value: doug@ansibmod.con.com
register: create_cronvar1
- name: Check cron var value
shell: crontab -l -u root | grep -c EMAIL=doug@ansibmod.con.com
register: varcheck1
- name: Create EMAIL cron var again
cronvar:
name: EMAIL
value: doug@ansibmod.con.com
register: create_cronvar2
- name: Modify EMAIL cron var
cronvar:
name: EMAIL
value: jane@ansibmod.con.com
register: create_cronvar3
- name: Check cron var value
shell: crontab -l -u root | grep -c EMAIL=doug@ansibmod.con.com
register: varcheck1
- name: Check cron var value again
shell: crontab -l -u root | grep -c EMAIL=jane@ansibmod.con.com
register: varcheck2
- name: Modify EMAIL cron var
cronvar:
name: EMAIL
value: jane@ansibmod.con.com
register: create_cronvar3
- name: Remove EMAIL cron var
cronvar:
name: EMAIL
state: absent
register: remove_cronvar1
- name: Check cron var value again
shell: crontab -l -u root | grep -c EMAIL=jane@ansibmod.con.com
register: varcheck2
- name: Remove EMAIL cron var again
cronvar:
name: EMAIL
state: absent
register: remove_cronvar2
- name: Remove EMAIL cron var
cronvar:
name: EMAIL
state: absent
register: remove_cronvar1
- name: Check cron var value again
shell: crontab -l -u root | grep -c EMAIL
register: varcheck3
failed_when: varcheck3.rc == 0
- name: Remove EMAIL cron var again
cronvar:
name: EMAIL
state: absent
register: remove_cronvar2
- name: Add cron var to custom file
cronvar:
name: TESTVAR
value: somevalue
cron_file: cronvar_test
register: custom_cronfile1
- name: Check cron var value again
shell: crontab -l -u root | grep -c EMAIL
register: varcheck3
failed_when: varcheck3.rc == 0
- name: Add cron var to custom file again
cronvar:
name: TESTVAR
value: somevalue
cron_file: cronvar_test
register: custom_cronfile2
- name: Add cron var to custom file
cronvar:
name: TESTVAR
value: somevalue
cron_file: cronvar_test
register: custom_cronfile1
- name: Check cron var value in custom file
command: grep -c TESTVAR=somevalue {{ cron_config_path }}/cronvar_test
register: custom_varcheck1
- name: Add cron var to custom file again
cronvar:
name: TESTVAR
value: somevalue
cron_file: cronvar_test
register: custom_cronfile2
- name: Change cron var in custom file
cronvar:
name: TESTVAR
value: newvalue
cron_file: cronvar_test
register: custom_cronfile3
- name: Check cron var value in custom file
command: grep -c TESTVAR=somevalue {{ cron_config_path }}/cronvar_test
register: custom_varcheck1
- name: Check cron var value in custom file
command: grep -c TESTVAR=newvalue {{ cron_config_path }}/cronvar_test
register: custom_varcheck2
- name: Change cron var in custom file
cronvar:
name: TESTVAR
value: newvalue
cron_file: cronvar_test
register: custom_cronfile3
- name: Remove cron var from custom file
cronvar:
name: TESTVAR
value: newvalue
cron_file: cronvar_test
state: absent
register: custom_remove_cronvar1
- name: Check cron var value in custom file
command: grep -c TESTVAR=newvalue {{ cron_config_path }}/cronvar_test
register: custom_varcheck2
- name: Remove cron var from custom file again
cronvar:
name: TESTVAR
value: newvalue
cron_file: cronvar_test
state: absent
register: custom_remove_cronvar2
- name: Remove cron var from custom file
cronvar:
name: TESTVAR
value: newvalue
cron_file: cronvar_test
state: absent
register: custom_remove_cronvar1
- name: Check cron var value
command: grep -c TESTVAR=newvalue {{ cron_config_path }}/cronvar_test
register: custom_varcheck3
failed_when: custom_varcheck3.rc == 0
- name: Remove cron var from custom file again
cronvar:
name: TESTVAR
value: newvalue
cron_file: cronvar_test
state: absent
register: custom_remove_cronvar2
- name: Esure cronvar tasks did the right thing
assert:
that:
- create_cronvar1 is changed
- create_cronvar2 is not changed
- create_cronvar3 is changed
- remove_cronvar1 is changed
- remove_cronvar2 is not changed
- varcheck1.stdout == '1'
- varcheck2.stdout == '1'
- varcheck3.stdout == '0'
- custom_remove_cronvar1 is changed
- custom_remove_cronvar2 is not changed
- custom_varcheck1.stdout == '1'
- custom_varcheck2.stdout == '1'
- custom_varcheck3.stdout == '0'
- name: Check cron var value
command: grep -c TESTVAR=newvalue {{ cron_config_path }}/cronvar_test
register: custom_varcheck3
failed_when: custom_varcheck3.rc == 0
- name: Ensure cronvar tasks did the right thing
assert:
that:
- create_cronvar1 is changed
- create_cronvar2 is not changed
- create_cronvar3 is changed
- remove_cronvar1 is changed
- remove_cronvar2 is not changed
- varcheck1.stdout == '1'
- varcheck2.stdout == '1'
- varcheck3.stdout == '0'
- custom_remove_cronvar1 is changed
- custom_remove_cronvar2 is not changed
- custom_varcheck1.stdout == '1'
- custom_varcheck2.stdout == '1'
- custom_varcheck3.stdout == '0'

View File

@@ -37,8 +37,6 @@
command: >-
dnf update -y
--setopt=obsoletes=0 {{ _packages | join(' ') }}
args:
warn: false
register: update_locked_packages
changed_when: '"Nothing to do" not in update_locked_packages.stdout'

View File

@@ -1,7 +1,5 @@
- name: "{{ reason }} ('up')"
command: "curl -sf http://localhost:8082/hello"
args:
warn: false
when: service_state == 'up'
register: curl_result
until: not curl_result.failed
@@ -10,8 +8,6 @@
- name: "{{ reason }} ('down')"
command: "curl -sf http://localhost:8082/hello"
args:
warn: false
register: curl_result
failed_when: curl_result == 0
when: service_state == 'down'

View File

@@ -43,6 +43,18 @@
src: httpd_echo.py
dest: "{{ process_file }}"
- name: Install virtualenv
package:
name: virtualenv
state: present
when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '8'
- name: Install virtualenv
package:
name: python-virtualenv
state: present
when: ansible_os_family == 'Archlinux'
- name: install dependencies
pip:
name: "{{ item }}"

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env bash
"$1" 100 &
"$1" 100 &
echo "$!" > "$2"

View File

@@ -0,0 +1,12 @@
/*
* (c) 2022, Alexei Znamensky <russoz@gmail.com>
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
*/
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv) {
int delay = atoi(argv[1]);
sleep(delay);
}

View File

@@ -7,112 +7,105 @@
# Copyright: (c) 2019, Saranya Sridharan
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- when:
- not (ansible_os_family == 'Alpine') # TODO
block:
- name: Attempt installation of latest 'psutil' version
pip:
name: psutil
ignore_errors: true
register: psutil_latest_install
- name: Attempt installation of latest 'psutil' version
pip:
name: psutil
ignore_errors: true
register: psutil_latest_install
- name: Install greatest 'psutil' version which will work with all pip versions
pip:
name: psutil < 5.7.0
when: psutil_latest_install is failed
- name: Install greatest 'psutil' version which will work with all pip versions
pip:
name: psutil < 5.7.0
when: psutil_latest_install is failed
- name: "Checking the empty result"
pids:
name: "blahblah"
register: emptypids
- name: "Checking the empty result"
pids:
name: "blahblah"
register: emptypids
- name: "Verify that the list of Process IDs (PIDs) returned is empty"
assert:
that:
- emptypids is not changed
- emptypids.pids == []
- name: "Verify that the list of Process IDs (PIDs) returned is empty"
assert:
that:
- emptypids is not changed
- emptypids.pids == []
- name: "Picking a random process name"
set_fact:
random_name: some-random-long-name-{{ 99999999 | random }}
- name: "Picking a random process name"
set_fact:
random_name: some-random-long-name-{{ 99999999 | random }}
- name: Copy the fake 'sleep' source code
copy:
src: sleeper.c
dest: "{{ remote_tmp_dir }}/sleeper.c"
mode: 0644
- name: "finding the 'sleep' binary"
command: which sleep
register: find_sleep
- name: Compile fake 'sleep' binary
command: cc {{ remote_tmp_dir }}/sleeper.c -o {{ remote_tmp_dir }}/{{ random_name }}
- name: "Copying 'sleep' binary"
command: cp {{ find_sleep.stdout }} {{ remote_tmp_dir }}/{{ random_name }}
# The following does not work on macOS 11.1 (it uses shutil.copystat, and that will die with a PermissionError):
# copy:
# src: "{{ find_sleep.stdout }}"
# dest: "{{ remote_tmp_dir }}/{{ random_name }}"
# mode: "0777"
# remote_src: true
- name: Copy helper script
copy:
src: obtainpid.sh
dest: "{{ remote_tmp_dir }}/obtainpid.sh"
mode: 0755
- name: Copy helper script
copy:
src: obtainpid.sh
dest: "{{ remote_tmp_dir }}/obtainpid.sh"
- name: "Run the fake 'sleep' binary"
command: "sh {{ remote_tmp_dir }}/obtainpid.sh '{{ remote_tmp_dir }}/{{ random_name }}' '{{ remote_tmp_dir }}/obtainpid.txt'"
- name: "Running the copy of 'sleep' binary"
command: "sh {{ remote_tmp_dir }}/obtainpid.sh '{{ remote_tmp_dir }}/{{ random_name }}' '{{ remote_tmp_dir }}/obtainpid.txt'"
async: 100
poll: 0
async: 100
poll: 0
- name: "Wait for one second to make sure that the fake 'sleep' binary has actually been started"
pause:
seconds: 1
- name: "Wait for one second to make sure that the sleep copy has actually been started"
pause:
seconds: 1
- name: "Checking the process IDs (PIDs) of fake 'sleep' binary"
pids:
name: "{{ random_name }}"
register: pids
- name: "Checking the process IDs (PIDs) of sleep binary"
pids:
name: "{{ random_name }}"
register: pids
- name: "Checking that exact non-substring matches are required"
pids:
name: "{{ random_name[0:5] }}"
register: exactpidmatch
- name: "Checking that exact non-substring matches are required"
pids:
name: "{{ random_name[0:5] }}"
register: exactpidmatch
- name: "Checking that patterns can be used with the pattern option"
pids:
pattern: "{{ random_name[0:5] }}"
register: pattern_pid_match
- name: "Checking that patterns can be used with the pattern option"
pids:
pattern: "{{ random_name[0:5] }}"
register: pattern_pid_match
- name: "Checking that case-insensitive patterns can be used with the pattern option"
pids:
pattern: "{{ random_name[0:5] | upper }}"
ignore_case: true
register: caseinsensitive_pattern_pid_match
- name: "Checking that case-insensitive patterns can be used with the pattern option"
pids:
pattern: "{{ random_name[0:5] | upper }}"
ignore_case: true
register: caseinsensitive_pattern_pid_match
- name: "Checking that .* includes test pid"
pids:
pattern: .*
register: match_all
- name: "Checking that .* includes test pid"
pids:
pattern: .*
register: match_all
- name: "Reading pid from the file"
slurp:
src: "{{ remote_tmp_dir }}/obtainpid.txt"
register: newpid
- name: "Reading pid from the file"
slurp:
src: "{{ remote_tmp_dir }}/obtainpid.txt"
register: newpid
- name: "Verify that the Process IDs (PIDs) returned is not empty and also equal to the PIDs obtained in console"
assert:
that:
- "pids.pids | join(' ') == newpid.content | b64decode | trim"
- "pids.pids | length > 0"
- "exactpidmatch.pids == []"
- "pattern_pid_match.pids | join(' ') == newpid.content | b64decode | trim"
- "caseinsensitive_pattern_pid_match.pids | join(' ') == newpid.content | b64decode | trim"
- newpid.content | b64decode | trim | int in match_all.pids
- name: "Verify that the Process IDs (PIDs) returned is not empty and also equal to the PIDs obtained in console"
assert:
that:
- "pids.pids | join(' ') == newpid.content | b64decode | trim"
- "pids.pids | length > 0"
- "exactpidmatch.pids == []"
- "pattern_pid_match.pids | join(' ') == newpid.content | b64decode | trim"
- "caseinsensitive_pattern_pid_match.pids | join(' ') == newpid.content | b64decode | trim"
- newpid.content | b64decode | trim | int in match_all.pids
- name: "Register output of bad input pattern"
pids:
pattern: (unterminated
register: bad_pattern_result
ignore_errors: true
- name: "Register output of bad input pattern"
pids:
pattern: (unterminated
register: bad_pattern_result
ignore_errors: true
- name: "Verify that bad input pattern result is failed"
assert:
that:
- bad_pattern_result is failed
- name: "Verify that bad input pattern result is failed"
assert:
that:
- bad_pattern_result is failed

View File

@@ -21,7 +21,6 @@
- '{{ pkgng_test_outofdate_pkg_tempdir.path }}'
- '--manifest'
- '{{ pkgng_test_outofdate_pkg_tempdir.path }}/MANIFEST'
warn: no
# pkg switched from .txz to .pkg in version 1.17.0
# Might as well look for all valid pkg extensions.

View File

@@ -32,8 +32,6 @@
until: faketime_package_installed is success
- name: Find libfaketime path
shell: '{{ list_pkg_files }} {{ faketime_pkg }} | grep -F libfaketime.so.1'
args:
warn: false
register: libfaketime_path
- when: ansible_service_mgr == 'systemd'
block:

View File

@@ -165,8 +165,6 @@
- name: Reinstall internationalization files
shell: yum -y reinstall glibc-common || yum -y install glibc-common
args:
warn: false
when: locale_present is failed
- name: Generate locale (RedHat)

View File

@@ -102,6 +102,21 @@
src: "{{ alt_sudoers_path }}/my-sudo-rule-5"
register: rule_5_contents
- name: Create rule to runas another user
community.general.sudoers:
name: my-sudo-rule-6
state: present
user: alice
commands: /usr/local/bin/command
runas: bob
sudoers_path: "{{ sudoers_path }}"
register: rule_6
- name: Grab contents of my-sudo-rule-6 (in alternative directory)
ansible.builtin.slurp:
src: "{{ sudoers_path }}/my-sudo-rule-6"
register: rule_6_contents
- name: Revoke rule 1
community.general.sudoers:
@@ -133,6 +148,7 @@
- "rule_3_contents['content'] | b64decode == 'alice ALL= /usr/local/bin/command\n'"
- "rule_4_contents['content'] | b64decode == '%students ALL=NOPASSWD: /usr/local/bin/command\n'"
- "rule_5_contents['content'] | b64decode == 'alice ALL=NOPASSWD: /usr/local/bin/command\n'"
- "rule_6_contents['content'] | b64decode == 'alice ALL=(bob)NOPASSWD: /usr/local/bin/command\n'"
- name: Check stats
ansible.builtin.assert:

View File

@@ -14,7 +14,7 @@ def main():
"""Main entry point."""
if not os.path.isdir(os.path.join('docs', 'docsite')):
return
p = subprocess.run(['antsibull-lint', 'collection-docs', '.'], check=False)
p = subprocess.run(['antsibull-docs', 'lint-collection-docs', '.'], check=False)
if p.returncode not in (0, 3):
print('{0}:0:0: unexpected return code {1}'.format(sys.argv[0], p.returncode))

View File

@@ -0,0 +1,50 @@
.azure-pipelines/scripts/publish-codecov.py replace-urlopen
plugins/modules/cloud/lxc/lxc_container.py use-argspec-type-path
plugins/modules/cloud/lxc/lxc_container.py validate-modules:use-run-command-not-popen
plugins/modules/cloud/misc/rhevm.py validate-modules:parameter-state-invalid-choice
plugins/modules/cloud/rackspace/rax.py use-argspec-type-path # fix needed
plugins/modules/cloud/rackspace/rax_files.py validate-modules:parameter-state-invalid-choice
plugins/modules/cloud/rackspace/rax_files_objects.py use-argspec-type-path
plugins/modules/cloud/rackspace/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values
plugins/modules/cloud/scaleway/scaleway_organization_info.py validate-modules:return-syntax-error
plugins/modules/cloud/smartos/vmadm.py validate-modules:parameter-type-not-in-doc
plugins/modules/cloud/smartos/vmadm.py validate-modules:undocumented-parameter
plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py validate-modules:parameter-list-no-elements
plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py validate-modules:parameter-type-not-in-doc
plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py validate-modules:undocumented-parameter
plugins/modules/cloud/univention/udm_share.py validate-modules:parameter-list-no-elements
plugins/modules/cloud/univention/udm_user.py validate-modules:parameter-list-no-elements
plugins/modules/clustering/consul/consul.py validate-modules:doc-missing-type
plugins/modules/clustering/consul/consul.py validate-modules:undocumented-parameter
plugins/modules/clustering/consul/consul_session.py validate-modules:parameter-state-invalid-choice
plugins/modules/packaging/language/composer.py validate-modules:parameter-invalid # invalid alias - removed in 5.0.0
plugins/modules/packaging/language/yarn.py use-argspec-type-path
plugins/modules/packaging/os/apt_rpm.py validate-modules:parameter-invalid # invalid alias - removed in 5.0.0
plugins/modules/packaging/os/homebrew.py validate-modules:parameter-invalid # invalid alias - removed in 5.0.0
plugins/modules/packaging/os/homebrew_cask.py validate-modules:parameter-invalid # invalid alias - removed in 5.0.0
plugins/modules/packaging/os/opkg.py validate-modules:parameter-invalid # invalid alias - removed in 5.0.0
plugins/modules/packaging/os/pacman.py validate-modules:parameter-invalid # invalid alias - removed in 5.0.0
plugins/modules/packaging/os/redhat_subscription.py validate-modules:return-syntax-error
plugins/modules/packaging/os/slackpkg.py validate-modules:parameter-invalid # invalid alias - removed in 5.0.0
plugins/modules/packaging/os/urpmi.py validate-modules:parameter-invalid # invalid alias - removed in 5.0.0
plugins/modules/packaging/os/xbps.py validate-modules:parameter-invalid # invalid alias - removed in 5.0.0
plugins/modules/remote_management/hpilo/hpilo_boot.py validate-modules:parameter-type-not-in-doc
plugins/modules/remote_management/hpilo/hpilo_info.py validate-modules:parameter-type-not-in-doc
plugins/modules/remote_management/hpilo/hponcfg.py validate-modules:parameter-type-not-in-doc
plugins/modules/remote_management/manageiq/manageiq_policies.py validate-modules:parameter-state-invalid-choice
plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions
plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:doc-missing-type # missing docs on suboptions
plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions
plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:undocumented-parameter # missing docs on suboptions
plugins/modules/remote_management/manageiq/manageiq_tags.py validate-modules:parameter-state-invalid-choice
plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-invalid
plugins/modules/system/gconftool2.py validate-modules:parameter-state-invalid-choice
plugins/modules/system/iptables_state.py validate-modules:undocumented-parameter
plugins/modules/system/osx_defaults.py validate-modules:parameter-state-invalid-choice
plugins/modules/system/parted.py validate-modules:parameter-state-invalid-choice
plugins/modules/system/puppet.py use-argspec-type-path
plugins/modules/system/puppet.py validate-modules:parameter-invalid # invalid alias - removed in 7.0.0
plugins/modules/system/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path
plugins/modules/system/xfconf.py validate-modules:parameter-state-invalid-choice # state get removed in 5.0.0
plugins/modules/system/xfconf.py validate-modules:return-syntax-error
plugins/modules/web_infrastructure/jenkins_plugin.py use-argspec-type-path

View File

@@ -169,6 +169,17 @@ TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_ROUTE = [
'state': 'present',
'_ansible_check_mode': False,
},
{
'type': 'ethernet',
'conn_name': 'non_existent_nw_device',
'ifname': 'ethernet_non_existant',
'ip6': '2001:beef:cafe:10::1/64',
'routes6_extended': [{'ip': 'fd2e:446f:d85d:5::/64',
'next_hop': '2001:beef:cafe:10::2'}],
'method6': 'manual',
'state': 'present',
'_ansible_check_mode': False,
},
]
TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_ROUTE_SHOW_OUTPUT = """\
@@ -197,6 +208,14 @@ TESTCASE_ETHERNET_MOD_IPV4_INT_WITH_ROUTE_AND_METRIC = [
'state': 'present',
'_ansible_check_mode': False,
},
{
'type': 'ethernet',
'conn_name': 'non_existent_nw_device',
'routes4_extended': [{'ip': '192.168.200.0/24', 'next_hop': '192.168.1.1'}],
'route_metric4': 10,
'state': 'present',
'_ansible_check_mode': False,
},
]
TESTCASE_ETHERNET_MOD_IPV4_INT_WITH_ROUTE_AND_METRIC_SHOW_OUTPUT = """\
@@ -218,6 +237,14 @@ TESTCASE_ETHERNET_MOD_IPV6_INT_WITH_ROUTE_AND_METRIC = [
'state': 'present',
'_ansible_check_mode': False,
},
{
'type': 'ethernet',
'conn_name': 'non_existent_nw_device',
'routes6_extended': [{'ip': 'fd2e:446f:d85d:5::/64', 'next_hop': '2001:beef:cafe:10::2'}],
'route_metric6': 10,
'state': 'present',
'_ansible_check_mode': False,
},
]
TESTCASE_ETHERNET_MOD_IPV6_INT_WITH_ROUTE_AND_METRIC_SHOW_OUTPUT = """\
@@ -241,6 +268,17 @@ TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_MULTIPLE_ROUTES = [
'state': 'present',
'_ansible_check_mode': False,
},
{
'type': 'ethernet',
'conn_name': 'non_existent_nw_device',
'ifname': 'ethernet_non_existant',
'ip6': '2001:beef:cafe:10::1/64',
'routes6_extended': [{'ip': 'fd2e:446f:d85d:5::/64', 'next_hop': '2001:beef:cafe:10::2'},
{'ip': 'fd2e:8890:abcd:25::/64', 'next_hop': '2001:beef:cafe:10::5'}],
'method6': 'manual',
'state': 'present',
'_ansible_check_mode': False,
},
]
TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_MULTIPLE_ROUTES_SHOW_OUTPUT = """\
@@ -273,6 +311,18 @@ TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_ROUTE_AND_METRIC = [
'state': 'present',
'_ansible_check_mode': False,
},
{
'type': 'ethernet',
'conn_name': 'non_existent_nw_device',
'ifname': 'ethernet_non_existant',
'method4': 'disabled',
'ip6': '2001:beef:cafe:10::1/64',
'routes6_extended': [{'ip': 'fd2e:446f:d85d:5::/64', 'next_hop': '2001:beef:cafe:10::2'}],
'route_metric6': 5,
'method6': 'manual',
'state': 'present',
'_ansible_check_mode': False,
},
]
TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_ROUTE_AND_METRIC_SHOW_OUTPUT = """\
@@ -305,6 +355,19 @@ TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_MULTIPLE_ROUTES_AND_METRIC = [
'state': 'present',
'_ansible_check_mode': False,
},
{
'type': 'ethernet',
'conn_name': 'non_existent_nw_device',
'ifname': 'ethernet_non_existant',
'method4': 'disabled',
'ip6': '2001:beef:cafe:10::1/64',
'routes6_extended': [{'ip': 'fd2e:446f:d85d:5::/64', 'next_hop': '2001:beef:cafe:10::2'},
{'ip': 'fd2e:8890:abcd:25::/64', 'next_hop': '2001:beef:cafe:10::5'}],
'route_metric6': 5,
'method6': 'manual',
'state': 'present',
'_ansible_check_mode': False,
},
]
TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_MULTIPLE_ROUTES_AND_METRIC_SHOW_OUTPUT = """\