Compare commits

..

446 Commits
4.0.2 ... 3.8.2

Author SHA1 Message Date
Felix Fontein
16ffb4ba10 Release 3.8.2. 2021-11-23 05:54:00 +01:00
Felix Fontein
31c3865251 Prepare 3.8.2 release. 2021-11-23 05:53:21 +01:00
patchback[bot]
53e0bf8297 terraform: ensuring command options are applied during build_plan (#3726) (#3777)
* Fixes parameters missing in planned state

* Added new line at end of file

* Added changelog fragment for pr 3726

* Added changes mentioned by felixfontein

* Removed blank space for pep8 validation

* Update changelogs/fragments/3726-terraform-missing-parameters-planned-fix.yml

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

* Update plugins/modules/cloud/misc/terraform.py

extend needs to be a list

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

Co-authored-by: Thomas Arringe <thomas.arringe@fouredge.se>
Co-authored-by: Thomas Arringe <Thomas.Arringe@ica.se>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 946430e1fb)

Co-authored-by: egnirra <37709886+egnirra@users.noreply.github.com>
2021-11-23 05:51:17 +01:00
patchback[bot]
9b80b14956 Fix collection dependency installation in CI. (#3753) (#3755)
(cherry picked from commit 17b4c6972f)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-19 06:59:47 +01:00
patchback[bot]
be763e6ed2 CI: Replace RHEL 8.4 by RHEL 8.5 for devel (#3747) (#3748)
* Replace RHEL 8.4 by RHEL 8.5 for devel.

* Install virtualenv.

* Revert "Install virtualenv."

This reverts commit 22ba0d074e.

* Just do another skip...

(cherry picked from commit 26c7995c82)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-17 22:30:00 +01:00
patchback[bot]
4375280497 Restrict redis version. (#3733) (#3735)
(cherry picked from commit bf7a954f00)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-16 07:31:25 +01:00
patchback[bot]
ebda14ba41 Enable counter_enabled.py to support batch mode (#3709) (#3731)
* Enable counter_enabled.py to support serial mode

Enable counter_enabled.py to support batch playbook executions using the serial tag in plays. Currently, the host counter gets reset at the beginning of every task. However, during batch executions we want it to keep track of the previous batch executions and print the host counter based on the previous runs. This proposal keeps track of how many servers have been updated in previous batches and starts the host counter at that tracked value.

```
- hosts: allthethings
  gather_facts: no
  serial:
    - 3
    - 15%
    - 20%
    - 35%
    - 55%
    - 90%
    - 100%
  tasks:
    - name: Ping Hello!
      ping:
        data: "Hello!!!!"
```

* Reset task counter on play start

Reset task counter on play start for batch mode playbook executions.

* Add changelog fragment

* change changelog fragment after feedback

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

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

Co-authored-by: Nabheet Sandhu <nabheet@users.noreply.github.com>
2021-11-15 22:13:12 +01:00
patchback[bot]
c16a5f3780 Allow LDAP search to run in check mode (#3667) (#3724)
* Allow ldap search to run in check mode always

* Fix indentions

* Remove Comments and Chg Fragment

* Update changelogs/fragments/3667-ldap_search.yml

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

Co-authored-by: Sebastian Trupiano <sebastian.trupiano@srpnet.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
(cherry picked from commit 115d435d2d)

Co-authored-by: sabman3 <sabman3@aol.com>
2021-11-13 15:27:43 +01:00
patchback[bot]
f6c1566924 Example command has wrong arg in redfish_command (#3711) (#3721)
Example command arg `boot_next` missing the underscore

(cherry picked from commit 4fe5d54b9e)

Co-authored-by: bluikko <14869000+bluikko@users.noreply.github.com>
2021-11-13 14:58:49 +01:00
patchback[bot]
bffed2fda5 Rework safety check on size arguments for when LV doesn't exist (#3681) (#3719)
* Rework safety check on size arguments for when LV doesn't exist

* Update changelogs/fragments/3681-lvol-fix-create.yml

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

Co-authored-by: Jake Reynolds <jake.reynolds@bidfx.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 352047314b)

Co-authored-by: jake2184 <jake2184@users.noreply.github.com>
2021-11-13 14:34:31 +01:00
Felix Fontein
440804fd62 Replace Bash codecov uploader by new Python codecov uploader. (#3713) (#3715)
ci_coverage

(cherry picked from commit 5948809162)
2021-11-13 13:22:11 +01:00
patchback[bot]
a915a4b7c5 BOTMETA.yml: add new maintainer to gitlab team (#3696) (#3704)
(cherry picked from commit 18a17acaa4)

Co-authored-by: Andrew Klychkov <aklychko@redhat.com>
2021-11-13 10:37:08 +01:00
patchback[bot]
ed69bde7a9 Fix dummy interface returning changed (#3625) (#3687)
* fix dummy interface bug

* fix dummy interface bug

* Update nmcli.py

* Update nmcli.py

* Update nmcli.py

* Update nmcli.py

* adding tests and requested conditional

* Fix pylint problems and remove 2 lines from previous version of bugfix

* Fix pep8 issue

* add changelog

* Update changelogs/fragments/3625-nmcli_false_changed_mtu_fix.yml

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

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

Co-authored-by: Alex Groshev <38885591+haddystuff@users.noreply.github.com>
2021-11-10 08:00:30 +01:00
patchback[bot]
77700e7110 Fix docs issues. (#3682) (#3683)
(cherry picked from commit 146af089e9)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-09 20:27:28 +01:00
patchback[bot]
91d445ab35 Replace Fedora 33 with Fedora 35 for devel tests (#3674) (#3679)
* Replace Fedora 33 with Fedora 35 for devel tests.

* Skip Fedora 35 for reiserfs tests.

(cherry picked from commit fc99893f10)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-09 07:05:06 +01:00
patchback[bot]
19c2af03b7 Better handling of base64-encoded values in xattr module (#3675) (#3677)
* Fix exception in xattr module when existing extended attribute's value contains non-printable characters and the base64-encoded string contains a '=' sign

* Added changelog fragment for #3675

* Apply suggestions from code review

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

Co-authored-by: sc-anssi <sc-anssi@users.noreply.github.com>
2021-11-09 06:29:01 +01:00
David Moreau Simard
58a5463ddb Fix urpmi typo in changelog (#3659)
The module is urpmi, not urmpi.
2021-11-02 19:06:49 +01:00
Felix Fontein
84941d0a7f Next expected release is 3.8.2. 2021-11-02 06:49:01 +01:00
Felix Fontein
87880da6da Release 3.8.1. 2021-11-02 06:14:23 +01:00
patchback[bot]
7acc0b897a Revert "Temporarily disable yaml callback tests. (#3651)" (#3657) (#3658)
This reverts commit 2324f350bc.

(cherry picked from commit 29af59822d)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-11-01 19:19:01 +01:00
patchback[bot]
5174fc98d2 Fixed - TypeError: unexpected keyword argument (#3649) (#3654)
* Fixed - TypeError: unexpected keyword argument

- File proxmox_group_info.py creates the error "TypeError:
  get_group() got an unexpected keyword argument \'group\'\r\n'" if a
  group parameter is used.
  Issue is an argument naming conflict. After changing the argument
  name to 'groupid', as used in method ProxmoxGroupInfoAnsible::get_group,
  testing a Proxmox group name is working now.

* Changelog fragment added for #3649

changelog fragment for TypeError: unexpected keyword argument #3649

* Update changelogs/fragments/3649-proxmox_group_info_TypeError.yml

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

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

Co-authored-by: hklausing <hklausing@users.noreply.github.com>
2021-10-31 20:35:43 +01:00
patchback[bot]
d9ad386a13 Temporarily disable yaml callback tests. (#3651) (#3652)
(cherry picked from commit 2324f350bc)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-31 18:08:17 +00:00
patchback[bot]
739719a3b1 opennebula: fix error message when renaming an image (#3626) (#3650)
While porting this module to make use of `pyone` I have overlooked one
attribute.  Luckily the error only occurs when trying to rename an image
to a name that has already been taken.

Instead of telling the user which image ID already uses that name, the
module failed with the following error (along with a huge backtrace):

    AttributeError: 'IMAGESub' object has no attribute 'id'

With this commit the error message is much more obvous again.

(cherry picked from commit b429c520f5)

Co-authored-by: Georg Gadinger <nilsding@nilsding.org>
2021-10-31 18:50:20 +01:00
patchback[bot]
311b618016 provide more fitting description for runner timeout (#3624) (#3645)
* provide more fitting description for runner timeout

* Update plugins/modules/source_control/gitlab/gitlab_runner.py

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

Co-authored-by: Tim Herren <tim.herren@gmx.ch>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 96de25fc94)

Co-authored-by: nerrehmit <accounts+github@herren.id>
2021-10-30 17:04:18 +02:00
patchback[bot]
70820cab5d Fix CI (#3637) (#3641)
* Replace yaml.load with yaml.safe_load in unit tests.

* Remove no longer needed loader arg in two instances.

(cherry picked from commit 753df78877)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-30 11:22:18 +02:00
patchback[bot]
a75a12227f gitlab_project_members: improve project name matching (#3602) (#3636)
* Update gitlab_project_members.py

The actual search method doesn't accept path with namespace for project_name. If you have many project with same name, this module gitlab_project_members can't work.

* Update gitlab_project_members.py

* Update gitlab_project_members.py

* Update gitlab_project_members.py

* Create 3602-fix-gitlab_project_members-improve-search-method

* Rename 3602-fix-gitlab_project_members-improve-search-method to 3602-fix-gitlab_project_members-improve-search-method.yml

(cherry picked from commit cdfc4dcf49)

Co-authored-by: paytroff <93038288+paytroff@users.noreply.github.com>
2021-10-30 08:32:06 +02:00
patchback[bot]
6959847701 pipx - fixed bug in state=inject (#3611) (#3634)
* pipx - fixed bug in state=inject

* added changelog fragment

* copy/paste error in the integration test

* replaced injected package with simpler one

* testing force_lang = None

* disable UTF-8 emojis in pipx output

* better way to achieve the same outcome

* Adjsuted the changelog fragment

(cherry picked from commit 40ccd1501b)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-10-30 08:30:13 +02:00
patchback[bot]
ad93c40d40 fix gitlab_deploy_key task in check mode (#3622) (#3629)
fixes #3621

* running check mode used to accidentally delete the existing
  ssh key; change it so deletion is skipped in check mode

(cherry picked from commit 8ba7fd5d61)

Co-authored-by: Waldek Maleska <w.maleska@gmail.com>
2021-10-28 20:19:54 +02:00
Felix Fontein
5bfbd65115 Prepare 3.8.1 release. 2021-10-22 08:31:37 +02:00
patchback[bot]
71de1ee1d5 Fix exception in pkgin module when all packages are already installed (#3583) (#3596)
* Fix exception in pkgin module when all packages are already installed.

* Update plugins/modules/packaging/os/pkgin.py

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

* Add changelog fragment for #3583

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

Co-authored-by: Nate Coraor <nate@bx.psu.edu>
2021-10-22 08:07:10 +02:00
patchback[bot]
ad4efaeb31 Redfish: Do not set the boot source override mode if not provided by the user (#3581) (#3595)
* Redfish: Do not set the boot source override mode if not provided by the user

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Corrected changelog file extension

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Update changelogs/fragments/3509-redfish_utils-SetOneTimeBoot-mode-fix.yml

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

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

Co-authored-by: Mike Raineri <michael.raineri@dell.com>
2021-10-22 07:41:09 +02:00
patchback[bot]
786ea68016 nmcli: Fix ipv6.dns not being recongnized as list (#3563) (#3593)
* nmcli: Fix ipv6.dns not being recongnized as list

There was a missing comma on the previous line.

* nmcli: Add changelog fragment for #3563

* nmcli: Update changelogs/fragments/3563-nmcli-ipv6_dns.yaml

Make the fix description more descriptive

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* nmcli: Remove ipv4.route-metric from list-typed properties

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* nmcli: Update fragment 3563 with ipv4.route-metric bug

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit e7e2ab94da)

Co-authored-by: Matyáš Kroupa <kroupa.matyas@gmail.com>
2021-10-21 08:22:55 +02:00
patchback[bot]
dd878f931f Redfish: perform manager network interface configuration even if property is missing (#3582) (#3591)
* Redfish: perform manager network interface configuration even if property is missing

Signed-off-by: Mike Raineri <michael.raineri@dell.com>

* Update changelogs/fragments/3404-redfish_utils-skip-manager-network-check.yml

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

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

Co-authored-by: Mike Raineri <michael.raineri@dell.com>
2021-10-20 17:51:35 +02:00
patchback[bot]
8f03511d9c Remove non-working example. (#3571) (#3587)
(cherry picked from commit e8c37ca605)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-18 23:07:04 +02:00
patchback[bot]
004e6d06c3 Fixed typo in homebrew documentation (#3577) (#3585)
Fixed typo in community.general.homebrew documentation

(cherry picked from commit 02c534bb8e)

Co-authored-by: Premkumar Subramanian <prem_x87@outlook.com>
2021-10-18 23:04:16 +02:00
patchback[bot]
25f46caefb Misc doc issues (#3572) (#3580)
* Add names to tasks in oneview module examples

* Fix task name in github_webhook module example

* Fix trailing whitespace

* Add changelog fragment

* Remove changelog fragment

(cherry picked from commit 3731064368)

Co-authored-by: Vitaly Khabarov <vitkhab@users.noreply.github.com>
2021-10-18 14:09:34 +02:00
patchback[bot]
0a733c60ca Use correct FQCN. (#3573) (#3575)
(cherry picked from commit c3813d4533)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-17 18:25:50 +02:00
patchback[bot]
f006aa4cf6 Fix bug with returning results in IPA role (#3561) (#3568)
* Fix bug with returning results in IPA role

Fix #3560

* Add changelog

* Fix typo in changelog

* Update changelogs/fragments/3561-fix-ipa-host-var-detection.yml

Co-authored-by: Brian Scholer <1260690+briantist@users.noreply.github.com>

* Update changelogs/fragments/3561-fix-ipa-host-var-detection.yml

Co-authored-by: Brian Scholer <1260690+briantist@users.noreply.github.com>

* Update changelogs/fragments/3561-fix-ipa-host-var-detection.yml

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

Co-authored-by: Brian Scholer <1260690+briantist@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 191d2e08bb)

Co-authored-by: Sergey <sshnaidm@users.noreply.github.com>
2021-10-16 21:08:01 +02:00
patchback[bot]
72e0d8c310 Remove centos8 for devel from CI. (#3565) (#3566)
(cherry picked from commit 249d490f10)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-16 09:27:55 +02:00
Felix Fontein
b96aaffeae Next expected release is 3.8.1. 2021-10-12 13:18:09 +02:00
Felix Fontein
5bd5de4281 Release 3.8.0. 2021-10-12 12:34:31 +02:00
patchback[bot]
4aebefcf9e Bugfix issue2692 logstash callbackmodule with no attribute options (#3530) (#3550)
* Update logstash.py

replacing _options with context.cliargs

* Create 2692-logstash-callback-plugin-replacing_options

logstash callback plugin replace _option with context.CLIARGS

* Rename 2692-logstash-callback-plugin-replacing_options to 2692-logstash-callback-plugin-replacing_options.yml

missed out the extenstion

* Update logstash.py

context imported

* Update 2692-logstash-callback-plugin-replacing_options.yml

dict to string

* Update changelogs/fragments/2692-logstash-callback-plugin-replacing_options.yml

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

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

Co-authored-by: Anand Victor <anandvict@gmail.com>
2021-10-12 05:07:26 +00:00
patchback[bot]
62f9a5b0a9 Improve contributing instructions (#3541) (#3548)
* Improve contributing instructions.

* Update CONTRIBUTING.md

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit 316adebd68)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-11 23:21:41 +02:00
patchback[bot]
3d03eda99e keycloak_identity_provider: Fix mappers update (#3538) (#3546)
* set identityprovideralias by default

* refactor mappers change detection

* fix sanity check

* update tests

* add changelog fragment

* Update changelogs/fragments/3538-fix-keycloak-idp-mappers-change-detection.yml

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

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

Co-authored-by: Laurent Paumier <30328363+laurpaum@users.noreply.github.com>
2021-10-11 23:21:25 +02:00
patchback[bot]
c01ce10b4b terraform: add parallelism parameter (#3540) (#3547)
* terraform: add parallelism parameter

* terraform: add parallelism parameter version

(cherry picked from commit ed2c1e4ac9)

Co-authored-by: linxside <39219399+linxside@users.noreply.github.com>
2021-10-11 23:21:16 +02:00
patchback[bot]
16aa776c93 Add elastic callback plugin (#3380) (#3542)
* Add elastic callback plugin

* Capture task failures

* Catch errors and add UTs

* Skip 3.5< python versions and install dependency

* fix lint

* Fix linting

* Fix linting

* Add botmeta

* Apply suggestions from code review

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

* It's not required

* As suggested in the code review OrderedDict has been added to the Python stdlib since version 2.7

* Update plugins/callback/elastic.py

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

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

Co-authored-by: Victor Martinez <victormartinezrubio@gmail.com>
2021-10-11 07:35:09 +02:00
patchback[bot]
d7d1659e34 Add new modules rundeck_job_run and rundeck_job_executions_info (#3521) (#3544)
* Add new module rundeck_job_run

* Add new module rundeck_job_executions_info

* Removed supports_check_mode

* Fix supports_check_mode

* Fix version_added

* Fixes for PR#3521

* Fix default value for loglevel in the doc

* Fix job_status_check loop

* Add proposed changes in PR#3521

* Add proposed changes in PR#3521

* Change executions_info output to executions

* Add rundeck integration tests

* Fix rundeck integration test

* Add more tests to rundeck integration tests

* Update job_options doc

* Add more tests to rundeck integration tests

* Add more examples to rundeck_job_run doc

* Add proposed fixes for PR#3521

* Add proposed fixes for PR#3521

* Fix job_options

* Add proposed changes for PR#3521

(cherry picked from commit 9772485d3c)

Co-authored-by: Phillipe Smith <phsmithcc@gmail.com>
2021-10-11 07:26:27 +02:00
patchback[bot]
5b9b99384f macports: add stdout and stderr to status (#3499) (#3500) (#3543)
* macports: add stdout and stderr to status (#3499)

* Add changelog fragment

* Update changelogs/fragments/3500-macports-add-stdout-and-stderr-to-status.yaml

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

Co-authored-by: Aoife Finch <aoife@finch.ink>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 8ece0d3609)

Co-authored-by: Aoife Finch <aoife.github@finch.ink>
2021-10-11 07:26:17 +02:00
Felix Fontein
f898279c8c Prepare 3.8.0 release. 2021-10-11 07:07:13 +02:00
patchback[bot]
2215c6d360 keycloak_role: quote role name in urls (#3536) (#3539)
* quote role name in urls

* add changelog fragment

* Update changelogs/fragments/3536-quote-role-name-in-url.yml

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* fix linefeeds

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit 9de01e04f2)

Co-authored-by: Laurent Paumier <30328363+laurpaum@users.noreply.github.com>
2021-10-09 12:08:05 +00:00
patchback[bot]
ca3948858a Fix shellcheck error. (#3531) (#3534)
(cherry picked from commit d1f820ed06)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-08 14:41:44 +00:00
patchback[bot]
f14e566cc7 Pkgng many packages one command (#3393) (#3529)
* pkgng: join package list into one command

Change the pkgng module so all packages being
installed (or upgraded) are acted on in one
command (per action). This will make installs
and upgrades a bit faster, because pkg will be
invoked fewer times per module run. More important,
module actions will be more atomic, making it less
likely that some packages are acted on because they
appear earlier in the argument list.

This change also improves the status reporting of
packages acted on, specifying the number of packages
for each action (install or upgrade).

* pkgng: make upgrade check lazily evaluated

Make upgrade_available an inner function so that the
if statement that checks whether installed packages
are up-to-date only runs the upgrade check on packages
that are already installed. This gets lazily evaluated
because of boolean operator short-circuiting:
https://docs.python.org/3.8/library/stdtypes.html#boolean-operations-and-or-not

Previously, the module would always check for upgrades,
even for not-installed packages, when running with
`state=latest`.

* pkgng: add changelog fragment

* pkgng: Apply changelog suggestions from code review

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

* pkgng: resolve pep8 style issue

Remove inline function. It's purpose would be confusing for
future maintainers, and someone refactoring it to a variable,
with good intentions, would introduce a performance regression.

Including the `query_update()` call in the if expression makes
the intent more legible and still ensures lazy evaluation of the
function call if the first `and` is `False`.

* pkgng: Fix changelog fragment syntax issue

Need to escape quotes so YAML doesn't eat them

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

* pkgng: Improve output message English grammar

Make word "package" plural only if reporting on more than one package

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

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

Co-authored-by: Ross Williams <ross@ross-williams.net>
2021-10-08 07:57:27 +02:00
patchback[bot]
a2c93f5e99 zypper_repository: Improve .repo file idempotency (#3474) (#3528)
* If repo option points to .repo file, download for later parsing

* Parse downloaded .repo file content (ini format)

* Validate downloaded file, map values to repodata, workaround to ignore old .repo related code

* Integration Test adjusted to install python package 'requests' first

* Revert "Integration Test adjusted to install python package 'requests' first"

This reverts commit 0d18352c2238d098831ba6d59b66e731fa8f0cd9.
Not allowed to introduce new dependencies at this point, module_utils usage required

* Remove python 'requests' dependency, using 'fetch_url' and 'to_text' from 'ansible.module_utils' instead

* Prefer alias (name) if given instead repo (url)

* If gpgkey was given in .repo file ensure key get automatically imported

* ConfigParser Import made Python2 compatible

* New .repo code moved below existing run-time parameters checks to keep previous logic

* Obsolete workaround removed

* two pylint/pep8 errors fixed

* name added to autorefresh assert

* Missing assert for 'Delete test repo' added

* name added to priority option assert

* name added to check repo is updated by url assert

* name added to check repo is updated by name assert

* name added to check add a repo by releasever assert

* name added to check remove added repo assert

* name added to check add a repo by basearch assert

* name added to check remove added repo #2 assert

* Bugfix to avoid 'KeyError' Exception in if statements

* Refactoring of configparser related code, usage of module_utils, py2 compatibility

* Removal of some leftover from earlier testing

* Integration tests for add/remove repositories by url to .repo file added

* Additional name added to list of test repos that has to be removed

* Test added to verify cleanup of local .repo file after removal via zypper

* Changelog fragment related to PR #3474 added

* yamllint error resolved

* Refactoring to reduce indentation and removal of else statements

* Integration tests added for loading .repo file from local path

* Test .repo file added

* Dependency to setup_remote_tmp_dir added

* New entry added to 'remove repositories added during test'

* Support for .repo file from local path

* Changelog: Ref to https://github.com/ansible-collections/community.general/issues/3466 added

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

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

Co-authored-by: Dominik Wombacher <dominik@wombacher.cc>
2021-10-08 07:56:34 +02:00
patchback[bot]
67a2abcab2 [opentelemetry][callback] add option to support enabling plugin in the CI (#3498) (#3524)
* [opentelemetry][callback] add option to support enabling plugin in the CI only

* [opentelemetry][callback] add changelog fragment

* Apply suggestions from code review

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* [opentelemetry][callback] use enable_from_environment

* Apply suggestions from code review

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

* [opentelemetry] ensure the value is true otherwise the plugin is not enabled

* [opentelemetry][changelog] update entry with the new option

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 3a460751a4)

Co-authored-by: Victor Martinez <victormartinezrubio@gmail.com>
2021-10-07 22:16:28 +02:00
patchback[bot]
2e4864db7f [ufw] Insert or delete biased when deletion enabled - as for append or delete. (#3514) (#3525)
* [ufw] Insert or delete biased when deletion enabled - as for append or delete.

* [ufw] Insert or delete biased when deletion enabled - as for append or delete.

* [ufw] Insert or delete biased when deletion enabled - as for append or delete.

* [ufw] Insert or delete biased when deletion enabled - as for append or delete.

* [ufw] Insert or delete biased when deletion enabled - as for append or delete.

* [ufw] Insert or delete biased when deletion enabled - as for append or delete.

* [ufw] Insert or delete biased when deletion enabled - as for append or delete.

* [ufw] Insert or delete biased when deletion enabled - as for append or delete.

(cherry picked from commit 80bb42325b)

Co-authored-by: Greg <greg-a-atkinson@users.noreply.github.com>
2021-10-07 22:15:40 +02:00
patchback[bot]
1f0b2a5173 [opentelemetry][callback] enrich stacktrace errors (#3496) (#3523)
* [opentelemetry][callback] refactor get_error_message and add UTs

* [opentelemetry][callback] enrich exception with msg, exception and stderr fields

* [opentelemetry] fix linting

* [opentelemetry][callback] add changelog fragment

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* [opentelemetry][callback] chore: remove comment

* [opentelemetry][callback] refactor tests

* [opentelemetry] refactor UTs

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit e22fff2b12)

Co-authored-by: Victor Martinez <victormartinezrubio@gmail.com>
2021-10-07 07:45:15 +02:00
patchback[bot]
25482000f0 lxd_container: improvements to the comments (#3520) (#3522)
* improvements to the comments

* next documentation improvements

Co-authored-by: Frank Dornheim <“dornheim@posteo.de@users.noreply.github.com”>
(cherry picked from commit 57e5f8c7be)

Co-authored-by: Frank Dornheim <524257+conloos@users.noreply.github.com>
2021-10-07 07:14:42 +02:00
patchback[bot]
c0f3aa14cf pipx - new module (#3507) (#3518)
* pipx - new module

* using python instead of python3

* removed ensure_path as it is unused

* ensuring we are running the same python as Ansible

* changed the last solution to adding a pipx_path parameter to the module, with a sensible default

* added docs for the new parameter

* changed param name to executable, and customized it for Darwin

* use executable if passed, otherwise use python -m pipx

* minor update

* added examples

* Update plugins/modules/packaging/language/pipx.py

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

* Update plugins/modules/packaging/language/pipx.py

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

* Update plugins/modules/packaging/language/pipx.py

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

* tests names 324 -> 3.24.0

* ensure tox is uninstalled by the beginning of the test

* Renamed option+suggestions from PR

* improved idempotency

* fixed sanity

* fixed test

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-10-06 07:30:19 +02:00
patchback[bot]
1ef104be61 Fix: gitlab_deploy_key idempotency (#3473) (#3512)
* Fix: gitlab_deploy_key idempotency

The module was not retrieving all the deploy keys leading to non
idempotency on projects with multiple deploy keys.
SEE: https://python-gitlab.readthedocs.io/en/stable/api-usage.html#pagination

* Update changelogs/fragments/3473-gitlab_deploy_key-fix_idempotency.yml

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

Co-authored-by: Jonathan Piron <jonathanpiron@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 0bc4518f3b)

Co-authored-by: Jonathan Piron <jonathan@piron.at>
2021-10-04 21:42:04 +02:00
patchback[bot]
773df88a41 Proxmox tasks module (#3226) (#3508)
* Started creating Unit tests for Proxmox Tasks module

* Tried really hard to get the mock to work

* unit tests  for the module

* Fixed symslink and permissions

* Suggested changes and more unit tests

* Fixed isFalse

* Apply suggestions from code review

* Update plugins/modules/cloud/misc/proxmox_tasks_info.py

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

Co-authored-by: Andreas Botzner <paginabianca66@gmail.com>
2021-10-03 22:37:41 +02:00
patchback[bot]
d77e256088 Fix OSX 10.11 CI runs (#3501) (#3504)
* Restrict to OSX 10.11 tests.

* See whether updating brew helps.

* Skip archive task for OSX.

* Refactor homebrew task to make changing the package name easier.

* Revert "See whether updating brew helps."

This reverts commit 8eceb9ef1f.

* Replace xz by gnu-tar.

* Uninstall first.

* Skip iso_extract task for OSX.

* Revert "Restrict to OSX 10.11 tests."

This reverts commit 81823d2f97.

* ci_complete

(cherry picked from commit 106856ed86)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-02 21:55:06 +02:00
patchback[bot]
2917389779 yaml callback: prevent plugin from modifying PyYAML (#3478) (#3494)
* Prevent yaml callback from modifying PyYAML.

* Fix changelog fragment.

* Update changelogs/fragments/3478-yaml-callback.yml

Co-authored-by: Brian Scholer <1260690+briantist@users.noreply.github.com>

Co-authored-by: Brian Scholer <1260690+briantist@users.noreply.github.com>
(cherry picked from commit 5895e50185)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-02 20:22:35 +02:00
patchback[bot]
59af80235b [opentelemetry] minor changes in the import, docs and exception (#3450) (#3491)
* OrderedDict has been added to the Python stdlib since version 2.7

* Docs: cosmetic change in the python lib

* See https://github.com/ansible/ansible/issues/75726

* Add changelog fragment

* Apply suggestions from code review

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

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

Co-authored-by: Victor Martinez <victormartinezrubio@gmail.com>
2021-10-01 15:08:00 +02:00
patchback[bot]
aec52198e3 Update redfish_info.py (#3485) (#3490)
* Update redfish_info.py

* Update plugins/modules/remote_management/redfish/redfish_info.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/remote_management/redfish/redfish_info.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/remote_management/redfish/redfish_info.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/remote_management/redfish/redfish_info.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/remote_management/redfish/redfish_info.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/remote_management/redfish/redfish_info.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/remote_management/redfish/redfish_info.py

* Update plugins/modules/remote_management/redfish/redfish_info.py

* Update plugins/modules/remote_management/redfish/redfish_info.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>
(cherry picked from commit 316e1d6bf2)

Co-authored-by: Rasdva3 <34684695+Rasdva3@users.noreply.github.com>
2021-10-01 15:07:23 +02:00
patchback[bot]
cbe4490c9e devel dropped support for Python 2.6. (#3487) (#3488)
(cherry picked from commit 0d3c4de6a2)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-10-01 13:16:57 +02:00
patchback[bot]
9de059b44d fix structure xcc_redfish_command (#3479) (#3482)
* adhere to proper task structure

* add changelog fragment

* return code formatting to original

* remove unnecessary fragment

(cherry picked from commit a14392fab0)

Co-authored-by: Zach Biles <bile0026@users.noreply.github.com>
2021-09-30 17:24:44 +02:00
patchback[bot]
c72a23a5f1 Stick to community.crypto 1.x.y for ubuntu1604. (#3470) (#3477)
(cherry picked from commit 3fee872d58)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-09-29 20:53:25 +02:00
patchback[bot]
0b9d9c0fdb nmcli: amended the routing-rules4 key values as list (#3401) (#3467)
* Updated nmcli.py

Amended the routing-rules4 values as list. By this we could add the entries for "routing_rules4" in the form of a list .

* Update nmcli.py

Fixed typo in line #1701

* 3395-nmcli-needs-type.yml

routing_rules4 module argument is currently accepting only string elements. In order to accept multiple values, amended the type of routing_rules4 as list.

* nmcli: amended the routing-rules4 key values as list

routing_rules4 module argument is currently accepting only string elements. In the case of adding multiple entries to routing_rules4, we need to accept values as list.

* Added 3401-nmcli-needs-type.yml

routing_rules4 module argument is currently accepting only string elements. In the case of adding multiple entries to routing_rules4, we need to accept values as lists

* Amended type to 'minor_changes'

Amended type to 'minor_changes'  from 'bug_fixes'

* routing_rules4 to a list of element str

nmcli.py - routing_rules4 to a list of element str

* Update changelogs/fragments/3401-nmcli-needs-type.yml

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

* nmcli: allow routing-rules4 key values as list

* nmcli: amended the routing-rules4 key values as list

* nmcli: amended the routing-rules4 key values as list

* nmcli: amended the routing-rules4 key values as list

* test_nmcli: amended whitespaces

* Update 3401-nmcli-needs-type.yml

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

Co-authored-by: Sreekanth H <65583280+sree0744@users.noreply.github.com>
2021-09-29 05:45:08 +00:00
patchback[bot]
67eaf9405f Copy the permissions along with file for jboss module (#3426) (#3469)
* Copy the permissions along with file for jboss module

Issue: The deployment file is copied with file content only. The file
permission is set to 440 and belongs to root user. When the
JBossI(Wildfly) server is running under non root account, it can't read
the deployment file.

With is fix, the correct permission can be set from previous task for JBoss
server to pickup the deployment file.

* Update changelogs/fragments/3426-copy-permissions-along-with-file-for-jboss-module.yml

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit 7cfdc2ce8c)

Co-authored-by: Pan Luo <xcompass@gmail.com>
2021-09-29 05:44:59 +00:00
patchback[bot]
5de05a6243 [PR #3462/845c4064 backport][stable-3] Enable ansibullbot notifications in issues and PRs (#3465)
* Enable ansibullbot notifications in issues and PRs (#3462)

The more recent version of Ansibullbot defaults notifications to false.
We need to set it to true so it can notify contributors and maintainers.

(cherry picked from commit 845c406419)

* Update botmeta sanity test to accept notifications.

(cherry picked from commit 71a655193c)

Co-authored-by: David Moreau Simard <moi@dmsimard.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2021-09-29 06:41:37 +02:00
patchback[bot]
46b4b9a6de Added OpenNebula inventory plugin (#810) (#3460)
* Added OpenNebula inventory plugin

Signed-off-by: Kristián Feldsam <feldsam@gmail.com>

* Apply suggestions from code review

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Apply suggestions from code review

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

* Removed matching inventory yaml files ending with "one"

Too general word

* Apply suggestions from code review

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

* Apply suggestions from code review

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Signed-off-by: Kristian Feldsam <feldsam@gmail.com>

* Added BOTMETA

Signed-off-by: Kristian Feldsam <feldsam@gmail.com>

* Moved import

Signed-off-by: Kristian Feldsam <feldsam@gmail.com>

* Fix indentation problem

Signed-off-by: Kristian Feldsam <feldsam@gmail.com>

* Added group_by_labels, refactored so can be unit tested

Signed-off-by: Kristian Feldsam <feldsam@gmail.com>

* Added unit tests

Signed-off-by: Kristian Feldsam <feldsam@gmail.com>

* Removed blank line

Signed-off-by: Kristian Feldsam <feldsam@gmail.com>

* Apply suggestions from code review

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

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
(cherry picked from commit 806f1ea3c9)

Co-authored-by: Kristian Feldsam <feldsam@gmail.com>
2021-09-28 17:41:54 +02:00
patchback[bot]
10146aae1c Update CI matrix to include ansible-core's stable-2.12 branch (#3445) (#3459)
* Update CI matrix to include ansible-core's stable-2.12 branch.

* Adjust README.

* Fix stage names.

* Avoid requirements clash.

* Thin matrix for older Ansible versions.

(cherry picked from commit d96b85af9f)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-09-28 16:04:46 +02:00
patchback[bot]
d2ec7053c5 Fix require_two_factor_authentication can't be null (#3453) (#3457)
* fix: require_two_factor_authentication default=false

* chore: add changelog fragment

* docs: require_two_factor_authentication default value

* fix: don't send require_two_factor_authentication null value

* chore: fix changelog

(cherry picked from commit 1bb2ff5128)

Co-authored-by: Chris Frage <git@sh0shin.org>
2021-09-27 22:11:54 +02:00
patchback[bot]
51fcacae08 Fix: GitLab API searches always return first found match (#3400) (#3448)
* fix: return correct group id
match only full_path or name

* chore: add changelog fragment

* fix: indentation multiple of four

* refactor: use two loops

* fix: typo of group id

* fix: changelog fragment

(cherry picked from commit b6b7601615)

Co-authored-by: Chris Frage <chris.frage@cancom.de>
2021-09-26 19:49:08 +02:00
patchback[bot]
29211b970c open-iscsi: adding mutual authentication support and updating authentication parameters description (#3422) (#3447)
* Adding mutual athentication support and changing doucumentation about authentication credentials

* Removing blank line with whitspaces

* Update plugins/modules/system/open_iscsi.py

Adding version_added to node_user_in parameter

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update plugins/modules/system/open_iscsi.py

adding version_added attibute to new parameter password_in

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update plugins/modules/system/open_iscsi.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Adding changelog fragment for #3422

* Rename 3422-open-iscsi-mutual-authentication-support.yam to 3422-open-iscsi-mutual-authentication-support.yaml

* Update changelogs/fragments/3422-open-iscsi-mutual-authentication-support.yaml

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update changelogs/fragments/3422-open-iscsi-mutual-authentication-support.yaml

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit 43a9f09a17)

Co-authored-by: Ricardo Sanchez <84853324+ricsanfre@users.noreply.github.com>
2021-09-26 13:49:02 +02:00
patchback[bot]
5c1fa53558 Keycloak: Fix bug on keycloak_authentication, requirement not always updated (#3330) (#3446)
* Fix diff mode when updating authentication flow with keycloak_authentication module

* Update documentation of create_or_update_executions function (return tuple instead of dict)

* Fix: Update requirement when new exex created

* Add changelog fragment

* Update changelogs/fragments/3330-bugfix-keycloak-authentication-flow-requirements-not-set-correctly.yml.yml

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

* Update changelogs/fragments/3330-bugfix-keycloak-authentication-flow-requirements-not-set-correctly.yml.yml

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

* Edit requirement of sublow

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

Co-authored-by: Gaetan2907 <48204380+Gaetan2907@users.noreply.github.com>
2021-09-26 13:48:48 +02:00
patchback[bot]
2348f3d439 Diable netcat conflict in zypper tests as one package seems to be no longer available. (#3438) (#3442)
(cherry picked from commit 3715b6ef46)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-09-25 17:44:53 +02:00
patchback[bot]
46a051d168 grpcio takes 7 minutes to build on Python 3.10 - make sure it's not installed indirectly. (#3435) (#3437)
(cherry picked from commit d0563e34a6)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-09-25 17:07:26 +02:00
patchback[bot]
b2212bc8ef Fix CI (#3430) (#3433)
* Restrict to unit tests with devel (to be reverted later).

* Restrict lxml for Python 2.6.

* Revert "Restrict to unit tests with devel (to be reverted later)."

This reverts commit d0d87a8a0f.

(cherry picked from commit 935348ae78)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-09-25 09:24:01 +02:00
Felix Fontein
e05e3aed67 Prepare ansible-core devel branch version bump that is planned for later today.
(cherry picked from commit 0d2bcf545e)
2021-09-24 18:47:20 +02:00
patchback[bot]
a13541299e mail: adding capability to specify ehlo hostname (#3425) (#3427)
* Adding capability to specify ehlo hostname

* Fixing default for ehlohost

the CI did not like "None" as default in the documentation,
judging from the rest of the definitions omitting that seems to be right

* Update plugins/modules/notification/mail.py

Proper spelling in documentation

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Adding Changelog Fragment

* Update changelogs/fragments/3425-mail_add_configurable_ehlo_hostname.yml

Proper phrasing in changelog

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* integration-test for ehlohost parameter

* proper description, increased async-time

changed body of ehlohost-mail to reflect ehlohost
increased async from 30 to 45 as CI failed because
smtp was already down.

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit ae6cbc2d82)

Co-authored-by: Hartwig Hauschild <hardy+github@foxxnet.de>
2021-09-24 07:41:21 +02:00
Felix Fontein
221067e708 Next expected release is 3.8.0. 2021-09-21 18:49:12 +02:00
Felix Fontein
db6458bd93 Release 3.7.0. 2021-09-21 18:09:31 +02:00
patchback[bot]
f342243fb0 Update README.md (#3402) (#3415)
* Update README.md

* Update README.md

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

* Fix the link

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

Co-authored-by: Andrew Klychkov <aklychko@redhat.com>
2021-09-21 12:16:28 +02:00
Felix Fontein
37f2b06c3c Fix file location. 2021-09-21 09:49:38 +02:00
Felix Fontein
0a8a41966d Prepare 3.7.0 release. 2021-09-21 09:49:00 +02:00
patchback[bot]
263c5ba9de Make ready for split-controller testing in ansible-core (#3345) (#3412)
* Accept context/ in aliases.

* Mark ansible_galaxy_install test as context/controller.

* Fix interfaces_file test.

ci_complete

* Install pyone dependency.

ci_complete

(cherry picked from commit 98d071f61e)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-09-21 09:03:28 +02:00
patchback[bot]
cfc28a3f6a lxd_container: do not ignore volatile configs by option (#3331) (#3411)
* do not ignore volatile - fix #2466

* remove unnecessary checks

* fix ansible-tests sanity

* fix access to the option: ignore_volatile_options

* add fragment

* fix quotation marks error

* fix review findings

* fix sanity error

* fix description - in yaml examples use true not True
comment out the deprecate message

* remove "default=True" at ignore_volatile_options
fix spelling

* fix sanity error that ignore_volatile_options have no default value

* undo changes. add defaut value and remove keyword at dict.get()

* fix sanity error

* small spelling fixes

* change text for fragment

* Fix description sentence.

Co-authored-by: Frank Dornheim <“dornheim@posteo.de@users.noreply.github.com”>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 8e7d49c1c6)

Co-authored-by: Frank Dornheim <524257+conloos@users.noreply.github.com>
2021-09-20 21:40:55 +02:00
patchback[bot]
b495035923 Added redis_data module (#3230) (#3410)
* Added redis_set module

Added redis_set module and unit tests for the new module.
Applied suggested changes and removed redis_del in favor of state
option.
Also added redis utility class that handles connection.

* Typos, added version and BOTMETA

* Fixed import error checking

* Fixed Unit tests

* Docfix and return consistency

* Added Check Mode

* Update plugins/modules/database/misc/redis_data.py

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

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

Co-authored-by: Andreas Botzner <paginabianca66@gmail.com>
2021-09-20 20:31:07 +02:00
patchback[bot]
d4637e9b1c kernel_blacklist - revamped the module (#3329) (#3409)
* kernel_blacklist - revamped the module

* file default and setting "lines" when file does not exist

* added changelog fragment

* added change in arg_spec to the documentation block

* Update plugins/modules/system/kernel_blacklist.py

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

* Update plugins/modules/system/kernel_blacklist.py

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

* Update plugins/modules/system/kernel_blacklist.py

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

* fixed: initialize self.pattern before self.var.is_blacklisted

* File writing recoded

* added try/finally for the file

* multiple changes:

- fixed case when last line of the existing file has no newline char
- added integration tests

* PR: integration test now using remote_tmp_dir

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-09-20 19:58:05 +02:00
patchback[bot]
7842dc0dea Add keycloak_user_federation module (#3340) (#3408)
* new module

* fix unit tests

* fix documentation

* more fixes

* fix linefeeds

* Apply suggestions from code review

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

* use true/false instead of True/False

* Apply suggestions from code review

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

* fix result content + rename variable

* urlencode parameters

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

Co-authored-by: Laurent Paumier <30328363+laurpaum@users.noreply.github.com>
2021-09-20 19:50:03 +02:00
patchback[bot]
314a0bc553 openbsd_pkg: Fix KeyError (#3336) (#3407)
If package installation has an error after the package is install (e.g.
when running tags), then there will be output on stderr and the fallback
regex will match; however, since pkg_add exited non-zero, changed is
never added as a key to the dictionary. As a result the code at the end
of main that checks if anything has changed raises a KeyError.

(cherry picked from commit 02d0e3d286)

Co-authored-by: Matthew Martin <phy1729@gmail.com>
2021-09-20 19:49:52 +02:00
patchback[bot]
34b7876e4f Add require_two_factor_authentication property to gitlab group (#3367) (#3399)
* feat: add require_two_factor_authentication property

* chore: add changelog fragment

* chore: add gitlab_group test tasks

* chore: add gitlab tests

* chore: add gitlab group tests

* docs: apply suggestions

* fix: removing default value

(cherry picked from commit 9ce1009643)

Co-authored-by: Chris Frage <git@sh0shin.org>
2021-09-20 07:18:43 +02:00
patchback[bot]
65c10de630 Add gitlab_project CI/CD properties (#3379) (#3398)
* feat: add ci_config_path property

* feat: add shared_runners_enabled property

* chore: add changelog fragment

* docs: add missing dot

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* docs: ci_config_path change description

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit e48f9fdf74)

Co-authored-by: Chris Frage <git@sh0shin.org>
2021-09-20 07:18:34 +02:00
patchback[bot]
a86f31ac0f Interfaces_file - improvements (#3328) (#3396)
* pythonific!! no camel cases, bitte

* simplified iface attributes parsing

* some improvements, passing tests

* simplified set_interface_option()

* further simplifications

* remove unreachable stmt

* pythonified a file open

* added changelog fragment

* adjustment per PR

* PR: fixed the auto- case

* PR: added testcase and chglog frag for the misleading change report

* extra line removed

* integration is not destructive

(cherry picked from commit 7aae8d5386)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-09-19 14:09:07 +02:00
patchback[bot]
bc82fe36be Icinga2 inventory plugin (#3202) (#3392)
* Added Icinga2 inventory plugin

* Added Icinga2 inventory plugin

* Linting

* Added tests

* Linting

* Linting

* Added tests

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Added tests for icinga2 inventory

* Resolved reviews and added host filters

* Linting

* Fixing yaml for example and updating tests

* Updating test data

* Fixing pep8 indentations

* Missed copywriting

* Missed copywriting

* Updated documentation grammar

* Removing Cacheable class and cleanup

* Update plugins/inventory/icinga2.py

* Update plugins/inventory/icinga2.py

* Bump version number

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

* Update plugins/inventory/icinga2.py

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 8ab96d9533)

Co-authored-by: Cliff Hults <BongoEADGC6@users.noreply.github.com>
2021-09-18 15:34:27 +02:00
patchback[bot]
7c810a6186 Get behavior of gitlab_project_members to the one of gitlab_group_members (#3319) (#3383)
* Initial change to get behaviour of gitlab_project_members like the new gitlab_group_members

* added changelog

* linter: removed trainling whitespaces

* Update plugins/modules/source_control/gitlab/gitlab_project_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_project_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_project_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_project_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_project_members.py

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

* requested changes

* linter fixes

* undoing formatting changes to existing code

Co-authored-by: Max-Florian Bidlingmaier <Max.Bidlingmaier@konsolan.de>
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Max Bidlingmaier <Max-Florian.Bidlingmaier@sap.com>
(cherry picked from commit 7a2efb4775)

Co-authored-by: Max Bidlingmaier <maks@konsolan.de>
2021-09-17 06:59:08 +02:00
patchback[bot]
9d468fb078 redfish_utils: adding "Id" to the add user function (#3343) (#3382)
* Adding "Id" to the add user function

Some implementations of Redfish (e.g. the one in Cisco's CIMC) seem to require the id of the new user for account creation.
I'm not that firm with Python but lines 982 and 983 should fix it.

* changed indention

* created changelog fragment

* Update changelogs/fragments/3343-redfish_utils-addUser-userId.yml

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

* Update change type

* supplemented the description of the ID parameter

* Update plugins/modules/remote_management/redfish/redfish_command.py

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

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

Co-authored-by: Patrick Pfurtscheller <57419021+PfurtschellerP@users.noreply.github.com>
2021-09-16 22:36:27 +02:00
patchback[bot]
2c79d42eb4 opentelemetry callback: context propagation and error exception (#3378) (#3381)
* opentelemetry callback: context propagation and error exception

* Apply suggestions from code review

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

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

Co-authored-by: Victor Martinez <victormartinezrubio@gmail.com>
2021-09-16 22:34:12 +02:00
patchback[bot]
d95c3a738f Install nios test requirements. (#3375) (#3377)
(cherry picked from commit b20fc7a7c3)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-09-15 08:09:37 +02:00
patchback[bot]
839880d711 Add opentelemetry callback plugin (#3091) (#3373)
* Add opentelemetry callback plugin

* Apply suggestions from code review

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

* Formatting (text), booleans and renamed env variables

* This should be done in a future release

* Remove insecure in favour of the OTEL env variable. Add descriptions

* Use OpenTelemetrySource

* Move generate_distributed_traces

* Move update_span_data and set_span_attribute

* Move finish_task

* Move start_task

* Refactor to support UTs

* Add first UT

* Fix codestyle

* opentelemetry callback entry in the botmeta

* Fix linting

* Fix signature

* Mock methods

* Use MagicMock

* Mock the methods

* UT for transform_to_boolean_or_default

* Fix linting

* Set test data

* Mock _time_ns

* Exclude tests for python <= 3.6

* Remove obsoleted setup task type configuration

* Remove unused docs

* Apply suggestions from code review

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

* Fix docs

* unrequired logic that was originally took from https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/callback/junit.py\#L226

* Use raise_from for the required dependencies

* Fix linting

* Add requirements for the UTs

* add missing dependency for the opentelemetry plugin in the UTs

* Add ANSIBLE_ prefix for the ansible specific options

* Add more context in the docs and remove duplicated docs

* As suggested in the code review

* Verify if the OTEL env variables for the endpoint were set

* Fix docs typo

* Fix linting

* Revert "Fix linting"

This reverts commit 3a54c827c5472553a6baf5598bc76a0f63f020c1.

* Revert "Verify if the OTEL env variables for the endpoint were set"

This reverts commit cab9d8648899c28c0345745690c4ec7a41f7e680.

* Remove console_output as suggested

* Apply suggestions from code review

Co-authored-by: flowerysong <junk+github@flowerysong.com>

* Delegate the definition of OTEL_EXPORTER_OTLP_INSECURE to the user

* Move definitions above, close to the class that uses them

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: flowerysong <junk+github@flowerysong.com>
(cherry picked from commit 517570a64f)

Co-authored-by: Victor Martinez <victormartinezrubio@gmail.com>
2021-09-15 07:20:36 +02:00
patchback[bot]
bc0edf7d55 tss: add option for token authorization (#3327) (#3372)
* Added token parameter for AccessTokenAuthorizer

Parameters username and password are not required anymore because of
this.

* Added changelog fragments

* Apply suggestions from code review

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* token authorizer is prioritized

token authorizer is prioritized when token parameter is set

* Apply suggestions from code review

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

* domain optional if token not provided

* Updated examples

- `base_url` is required everywhere
- examples for user, name + domain authorization included
- token authorization included

* Update 3327-tss-token-authorization.yml

* Apply suggestions from code review

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

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit dc8d076a25)

Co-authored-by: Martin Vician <vician@users.noreply.github.com>
2021-09-14 19:49:51 +02:00
patchback[bot]
68458fd8aa Added additional maintainer for the dsv and tss plugins (#3368) (#3369)
(cherry picked from commit 4e39a4b825)

Co-authored-by: Ricky White <ricky@whitelionmedia.com>
2021-09-13 21:35:20 +02:00
patchback[bot]
4aa70ab48f gitlab_runner: Support project-scoped runners registration (#2971) (#3364)
* support project-scoped gitlab.com runners registration

* rename glproject variable to gitlab_project

* update version

* Update plugins/modules/source_control/gitlab/gitlab_runner.py

Co-authored-by: Raphaël Droz <raphael.droz+floss@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 0a5db85ad5)

Co-authored-by: Raphaël Droz <raphael.droz@gmail.com>
2021-09-13 07:35:35 +02:00
patchback[bot]
739210c6b9 pids - refactor module to make version-based behavior consistent (#3315) (#3365)
* Initial commit

* Adding changelog fragment

* Further refactoring

* Fixing bad copy/paste and adding task for psutil >= 5.7.0 install

* Inverting psutil installation order to reduce duplication

* Optimizing regex compilation

(cherry picked from commit 118c040879)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-09-13 07:35:26 +02:00
patchback[bot]
8c23d0e345 New filter plugin - unicode_normalization (#3359) (#3362)
* Initial commit

* Adding maintainer in BOTMETA

* Adding changelog fragment

* Updating filter_guide

* Applying initial review suggestions

(cherry picked from commit 29e4066944)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-09-12 14:40:02 +02:00
patchback[bot]
cde4a1a099 Add ipaselinuxusermaporder option to the ipa_config module (#3178) (#3361)
(cherry picked from commit 612543919e)

Co-authored-by: Roy Lenferink <lenferinkroy@gmail.com>
2021-09-12 12:39:44 +00:00
patchback[bot]
10b3381f21 Adds few more gitlab group options (#3248) (#3360)
* Adds few more gitlab group options

* Update plugins/modules/source_control/gitlab/gitlab_group.py

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

* Removes default for new string options

* Removes default from argument_spec

* Adds changelog fragment

* Update plugins/modules/source_control/gitlab/gitlab_group.py

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

* Update plugins/modules/source_control/gitlab/gitlab_group.py

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

* Update plugins/modules/source_control/gitlab/gitlab_group.py

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

Co-authored-by: Maik Schueller <maik.schueller@sap.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 58d018ebbd)

Co-authored-by: mkschuel <77283980+mkschuel@users.noreply.github.com>
2021-09-10 23:59:16 +02:00
patchback[bot]
0ccd52b63a Adding new maintainer (#3349) (#3355)
(cherry picked from commit 05fe587a3e)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-09-09 08:28:47 -04:00
patchback[bot]
c76e598d61 Improve CI (#3348) (#3351)
* Remove superfluous test.

* Use remote_temp_dir instead of output_dir on remote.

* Read certificate from correct place.

* Adjust more places.

* Fix boolean.

* Improve cryptography setup.

* Fix java_keystore changes.

* Need to copy binary from remote.

* Use correct Python for serve script.

* Sleep before downloading.

* Use correct Python interpreter.

* Avoid failing shebang test.

* Fix permission error with macOS 11.1.

* Avoid shebang trouble.

(cherry picked from commit 7c43cc3faa)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-09-09 08:10:12 +02:00
patchback[bot]
ad3efa9719 Adds redis_data_info module (#3227) (#3346)
* Added redis_data_info module

Added:
  - redis_data_info module and suggested 'exists' return flag.
  - module_utils for redis with a base class that handles database connections.
  - inhereited unit tests and added some new ones for the exit flag

* Docfix and sanity

* typo

* Suggested doc changes and ssl option

* TLS and validate_certs fix

* Set support_check_mode for info plugin

* Docfix and import errors

* Redis versioning Fix

* version bump and append fixes

(cherry picked from commit 6b207bce4c)

Co-authored-by: Andreas Botzner <paginabianca66@gmail.com>
2021-09-08 13:37:11 +02:00
patchback[bot]
b9c8d2bee5 django_manage - split params (#3334) (#3342)
* django_manage - fix fixures

* docs formatting adjustments

* param apps also in need of splitting

* oops, the splitted version was not being properly added to the command args

* added changelog fragment

* check for None

* moving to shlex.split()

* Update changelogs/fragments/3334-django_manage-split-params.yaml

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-09-07 12:40:33 +02:00
patchback[bot]
2c167547f6 Fix default value of new option. (#3338) (#3341)
(cherry picked from commit a20862797e)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-09-07 06:16:30 +02:00
patchback[bot]
73de447489 zpool_facts - pythonification (#3332) (#3339)
* pythonification

* added changelog fragment

* adjustment per PR

(cherry picked from commit 0f9311c3d9)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-09-06 20:27:45 +02:00
patchback[bot]
134f6132ce nmcli: Support GSM connections (#3313) (#3335)
* nmcli: Support GSM connections

* Add GSM support
* Add GSM unit test

* nmcli: Add changelog fragment

* nmcli: Fix GSM unit test

* Fix copy-paste error in test_gsm_mod

* nmcli: Fix yaml formatting

* nmcli: Fix yaml formatting

* nmcli: Fix typeerror

* type must be str not string

* nmcli: Fix gsm_show_output

* gsm.username did not match input

* nmcli: Fix gsm_show_output

* doublechecked generated output with test-client

* nmcli: GSM fix unit test

* Removed `mocked_gsm_connection_unchanged`

* Revert "nmcli: GSM fix unit test"

This reverts commit 2d112b779a.

* nmcli: gsm fix unit test

* Add needed output to `TESTCASE_GSM_SHOW_OUTPUT`
* Move `mocked_gsm_connection_unchanged`to sort correctly

* nmcli: gsm fix _compare_conn_params

* Strip double-qoutes of gsm.apn if exist

* nmcli: GSM apply suggestions from code review

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* nmcli: GSM: Fix documentation

* Shorten too long lines

* nmcli: GSM apply suggestions from code review

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* nmcli: GSM add version

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

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 76317d1f64)

Co-authored-by: Manuel Gayer <85677493+nm-mga@users.noreply.github.com>
2021-09-06 18:43:49 +02:00
patchback[bot]
f229c800da redfish: clean etag of quotes before patch (#3296) (#3326)
* Some vendors surround header etag with quotes, which need to be cleaned before sending a patch

* Minor change fragment

* Add etag strip quote option

* Rebase

* Cleanup fragment

* Apply suggestions from code review

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

* Update plugins/modules/remote_management/redfish/redfish_command.py

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

* Description update

* Update plugins/modules/remote_management/redfish/redfish_config.py

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

Co-authored-by: Kyle Williams <kyle.williams@thetradedesk.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 3502f3b486)

Co-authored-by: Kyle Williams <36274986+kyle-williams-1@users.noreply.github.com>
2021-09-02 06:30:17 +02:00
patchback[bot]
52a0970ef8 Fix copr integration tests (#3237) (#3325)
Fixes: #2084
(cherry picked from commit 7c493eb4e5)

Co-authored-by: Silvie Chlupova <33493796+schlupov@users.noreply.github.com>
2021-09-02 06:30:05 +02:00
patchback[bot]
11e0797650 Fix documentation bugs. (#3321) (#3322)
(cherry picked from commit c121e8685f)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-09-01 07:47:41 +02:00
Felix Fontein
e6bbbac6a0 Next expected release is 3.7.0. 2021-09-01 07:09:44 +02:00
Felix Fontein
d78f3dd7c4 Release 3.6.0. 2021-08-31 18:39:15 +02:00
patchback[bot]
737f8340e4 django_manage: Remove scottanderson42 and tastychutney as maintainers. (#3314) (#3317)
Note: tastychutney is another github account of mine that was also added as a maintainer.
(cherry picked from commit 135faf4421)

Co-authored-by: Scott Anderson <scott@waymark.com>
2021-08-31 18:38:11 +02:00
patchback[bot]
f87ab7046d Enhancement to gitlab_group_members to accept user lists as input (#3047) (#3312)
* - fix to issue 3041
- add func to work with user lists
- add func to set members to the ones give

* Added version_added to new parameter

* fixed elements in definition of gitlab_users nad wrong import in gitlab_users

* linter issues fixed

* added list elelements to argument_spec

* More whitspeaces for the linter

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* adapted changelog

* removed bugfix (other PR), changes due to review

* changed input handling according to review

* Fixed test findings

* Added list of dict to allow for specifying user/access_level tuples

* corrected doc section

* fixed parameter definitions

* removed strange additional import

* Update changelogs/fragments/3041-gitlab_x_members_fix_and_enhancement.yml

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

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_project_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* fixed required if

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* Added suggestions from PR

* fixed identation problem

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

Co-authored-by: Zainab Alsaffar <za5775@rit.edu>

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

Co-authored-by: Zainab Alsaffar <za5775@rit.edu>

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* Recommended changes from discussionst

* Fixed issues from automatic tests

* added missing metaclass due to test finding

* added integration tests

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* fixed optimization for only one user

* Reverted gitlab_project_members to original version - changes will be done in a separate branch

* added examples for new functionality

* - fixed changelog after reverting gitlab_project_memebers
- fully reverted gitlab_project_members

* Fixed error handling: when single users are not updateable in bulk mode the exception should not stop the code flow but document the problem in the result.

* Better error handling

* on error give username, not gitlab numeric userid

* Fixed broken check_mode

* Update plugins/modules/source_control/gitlab/gitlab_group_members.py

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

* Change from review

Co-authored-by: Max Bidlingmaier <Max-Florian.Bidlingmaier@sap.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Zainab Alsaffar <za5775@rit.edu>
(cherry picked from commit fce562ad6d)

Co-authored-by: Max Bidlingmaier <maks@konsolan.de>
2021-08-31 17:27:08 +02:00
patchback[bot]
4c100aef47 open_iscsi - minor refactoring (#3286) (#3310)
* open_iscsi - minor refactoring

* added changelog fragment

(cherry picked from commit 1f5345881d)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-08-31 15:04:39 +02:00
patchback[bot]
2b6bbd9f91 pamd - fixed issue+minor refactorings (#3285) (#3309)
* pamd - fixed issue+minor refactorings

* added changelog fragment

* added unit test suggested in issue

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

* fixed per PR + additional adjustment

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-08-31 12:59:36 +02:00
patchback[bot]
0484abdddd proxmox inventory plugin - Update examples documentation (#3299) (#3307)
* Initial commit

* Update plugins/inventory/proxmox.py

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

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-08-31 11:18:52 +02:00
patchback[bot]
3f119aa9b6 django_manage - added splitting the command parameter for running (#3283) (#3305)
* added splitting the command parameter for running

* added changelog fragment

* refactored variable names for improved readability

(cherry picked from commit b2bb7e3f9c)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-08-31 10:23:04 +02:00
patchback[bot]
277329a6fe zfs.py: treated received properties as local and added diff mode support (#502) (#3304)
* zfs.py: treated received properties as local and added diff mode support

If you use "zfs set" to explicitly set ZFS properties, they are marked as from source "local". If ZFS properties are implicitly set by using "zfs send" and "zfs receive", for example as part of a template based installation, they are marked as from source "received". But as there is no technical difference between both types of them, the “received” ZFS properties should also be considered “local”. Otherwise Ansible would detect changes, which aren’t actual changes. Therefore I changed line 202/207 to reflect this.

For us it’s quite important, that Ansible modules support the diff mode in order to qualify changes. Therefore I added some code lines to address this.

* added changelog fragment for PR #502

* fixed typos in changelog fragment for PR #502

* minor changes in changelog fragment for PR #502

* added link to pull request in changelog fragment for PR #502

* extended the diff data structure to always include the name of the zfs filesystem

* added code to also maintain the diff data structure after a change

* reverted back some code lines for better code readability

* added an extra dict in the diff data structure to hold the zfs properties

(cherry picked from commit baa721ac22)

Co-authored-by: froebela <32922546+froebela@users.noreply.github.com>
2021-08-31 10:22:55 +02:00
patchback[bot]
955eb531a3 Initial commit (#3300) (#3303)
(cherry picked from commit 58c6f6c95a)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-08-31 10:22:47 +02:00
patchback[bot]
9ac2918d49 Keycloak: add identity providers management (#3210) (#3301)
* init new module

* update

* add mappers

* improve mappers

* tests

* fix tests

* fix tests

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

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

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

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

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

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

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

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

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

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

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

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

* fix typos

* update botmeta

* improve change detection

* fix tests

* add integration tests

* remove updateProfileFirstLoginMode parameter

Co-authored-by: Laurent PAUMIER <laurent.paumier@externe.maif.fr>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 97e2c3dec9)

Co-authored-by: Laurent Paumier <30328363+laurpaum@users.noreply.github.com>
2021-08-31 10:22:34 +02:00
patchback[bot]
740180d4a5 udm_dns_record: Fix handling of PTR records (#3244) (#3256) (#3298)
* udm_dns_record: Fix handling of PTR records (#3244)

Before, it was not possible to manage PTR records in Univention DNS,
due to broken zone lookups and improper used parameters of the object.
This patch fixes the PTR handling, allowing both v4 and v6 entries.

* udm_dns_record: [doc] add changelog fragment

* udm_dns_record: [fix] validation errors

* udm_dns_record: import ipaddress module conditionally (#3244)

* udm_dns_record: fix sanity check error, improve doc (#3244)

* udm_dns_record: Improve changes to meet community standards (#3244)

(cherry picked from commit d9dcdcbbe4)

Co-authored-by: Sebastian Damm <SipSeb@users.noreply.github.com>
2021-08-30 19:04:49 +02:00
Felix Fontein
5d6c539373 Prepare 3.6.0 release. 2021-08-29 13:39:30 +02:00
patchback[bot]
09e2f77289 mh CmdMixin - added ArgFormat.BOOLEAN_NOT and logic (#3290) (#3294)
* mh CmdMixin - added ArgFormat.BOOLEAN_NOT and logic

* added changelog fragment

(cherry picked from commit df8fdcda79)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-08-29 13:20:01 +02:00
patchback[bot]
7aaf8cf496 Fix unit tests (#3289) (#3293)
* Force new enough requests version.

* Revert "Force new enough requests version."

This reverts commit 339d40bef7.

* Make sure we don't install a too new python-gitlab for Ansible 2.10.

* Change requirement instead of appending new one.

* Fix quoting.

* Try to skip if import fails.

* Revert "Try to skip if import fails."

This reverts commit 254bbd8548.

* Make other Python versions happy...

* Update tests/utils/shippable/units.sh

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
(cherry picked from commit cf43356753)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-08-29 12:26:47 +02:00
patchback[bot]
664bd70294 snap - improved error handling (#3211) (#3288)
* snap - improved error handling

* added changelog fragment

* removed experiments left overs

* rolled back the smaller list of params for commands other than install

(cherry picked from commit a91eb6ae4f)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-08-28 22:43:49 +02:00
patchback[bot]
9651bca396 openwrt_init - improvements (#3284) (#3287)
* improvements on openwrt_init

* added changelog fragment

(cherry picked from commit 69641d36e1)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-08-28 22:43:33 +02:00
patchback[bot]
f3375c638e Fixed incorrect VMID: cloning to an existing VM (#3266) (#3282)
* Fixed incorrect VMID: cloning to an existing VM

During a cloning operation, if the destination VM already exists the VMID returned is not correct.
The VMID returned should be that of the destination VM and not that of the source VM (consistent with line 1230).
A playbook that relies on the returned VMID, for example, to perform other operations on the destination VM, will not work properly if it is unexpectedly interrupted.

* Add files via upload

* moved 3266-vmid-existing-target-clone.yml to changelogs/fragments/
replaced line separator CRLF -> LF

* storing vmid list in variable to avoid multiple API calls

(cherry picked from commit 4e2d4e3c68)

Co-authored-by: Atlas974 <43972908+Atlas974@users.noreply.github.com>
2021-08-27 19:09:37 +02:00
patchback[bot]
14d663029a Linode Inventory can use full IP data from APIv4 (#3203) (#3278)
* Linode Inventory can use full IP data from APIv4

- The Linode dynamic inventory module does not currently distinguish
  between private and public IP addresses even though the Linode APIv4
  contains this information. This change keeps the current behavior as
  the default and adds an option to set `ip_style: api`. When set, this
  option allows administrators to differentiate between private, public,
  slaac, local_link, and pool network addresses providing a more nuanced
  and granular view of the remote host's network information.

Signed-off-by: Kellin <kellin@retromud.org>

* Review - amend changelog details

- Adds a link back to this pull request
- Uses markdown styles for easier to read publishing in the changelogs
- Amends the wording style to match the existing changelog styles

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

* Add scope to example invocation

- Adds the `community.general` scope to invocation example

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

* Convert lamda to list comprehension

- Change the ip type filter from a lambda to a list comprehension

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

* Add punctuation to description sentence

- Adds a period to the end of the description sentence

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

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

Co-authored-by: Kellin <kellin@retromud.org>
2021-08-27 06:38:22 +02:00
patchback[bot]
9297802089 Fix keycloak_realm module (#3231) (#3277)
* fix events_listeners element type
add events_enabled parameter

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

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

* add changelog

* Update changelogs/fragments/3231-fix-keycloak-realm-events.yml

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

* Update changelogs/fragments/3231-fix-keycloak-realm-events.yml

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

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

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

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

Co-authored-by: Laurent Paumier <30328363+laurpaum@users.noreply.github.com>
2021-08-27 06:32:49 +02:00
patchback[bot]
5b4dc4ace2 parse scw-cli config file for oauth_token (#3250) (#3276)
If `api_token` is not set and config file exists, it will try to fetch
the value from the activated profile and fallback on default.

This should not break existing workflows.

(cherry picked from commit cc458f7c37)

Co-authored-by: Nicolas Karolak <nikaro@users.noreply.github.com>
2021-08-27 06:32:38 +02:00
patchback[bot]
15a72418ac nmcli: Support gre tunnels (#3262) (#3272)
* Add gre tunnel support

* Add gre tunnel support

* Fix Blank Lines

* Fix unit test
Add changelog fragment

* Update plugins/modules/net_tools/nmcli.py

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

* Update Docs

* Update plugins/modules/net_tools/nmcli.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update Docs

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit b8a081b9b2)

Co-authored-by: zerotens <zerotens@users.noreply.github.com>
2021-08-26 08:32:37 +02:00
patchback[bot]
7278bdcf9d Stop notifications for apache2_module for me (#3261) (#3271)
(cherry picked from commit e40aa69e77)

Co-authored-by: Robin Roth <robin@rroth.de>
2021-08-26 08:24:24 +02:00
patchback[bot]
b9aab568f7 Fix apache2_module a2enmod/a2dismod detection and error message if not found. (#3258) (#3263)
(cherry picked from commit f2fa56b485)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-08-25 07:06:23 +02:00
patchback[bot]
e01d014c36 tss_lookup_plugin - Refactor and decoupling (#3252) (#3264)
* Initial commit

* Adding changelog fragment

* Applying initial review suggestions

* Increasing unit coverage

* Removed unneccessary constant

* Improving test readability

* Cleanup constants

(cherry picked from commit cbcb942b0e)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-08-25 07:05:33 +02:00
patchback[bot]
e5bdc028c4 nmcli: allow IPv4/IPv6 configuration on ipip and sit devices (#3239) (#3255)
* Allow IPv4/IPv6 configuration on mode "sit" tunnel devices

* Update Unit Test for Allow IPv4/IPv6 configuration on mode "sit" tunnel devices

* Add changelog for Allow IPv4/IPv6 configuration on mode "sit" tunnel devices

* Update changelogs/fragments/3239-nmcli-sit-ip-config-bugfix.yaml

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Added ip4/ip6 configuration arguments for ipip tunnels

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit 1ca9c35010)

Co-authored-by: zerotens <zerotens@users.noreply.github.com>
2021-08-23 18:38:23 +02:00
patchback[bot]
67f7184234 Add option for retry_servfail (#3247) (#3251)
* Add option for retry_servfail

cf. https://dnspython.readthedocs.io/en/latest/resolver-class.html#dns.resolver.Resolver.retry_servfail

Setting this option to `True` allows for the possibility of the lookup plugin to retry and thereby recover from potentially transient lookup failures, which would otherwise cause the task or play to bail with an unrecoverable exception.

* Create 3247-retry_servfail-for-dig

* documentation for `retry_servfail` option

* Rename 3247-retry_servfail-for-dig to 3247-retry_servfail-for-dig.yaml

* fix whitespace

* Update plugins/lookup/dig.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update plugins/lookup/dig.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* rm try/except block

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit 23e7ef0255)

Co-authored-by: Matt 'Archer' Vaughn <nethershaw@gmail.com>
2021-08-22 11:58:37 +02:00
patchback[bot]
b42ab6b45d nmcli: Disallow Wi-Fi options not supported by nmcli (#3141) (#3249)
* nmcli: Disallow Wi-Fi options not supported by nmcli

By querying nmcli directly

* Added changelog fragment

* Added tests

* Simplify `get_available_options()`

* Update changelogs/fragments/3141-disallow-options-unsupported-by-nmcli.yml

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

* Remove redundant `802-11-wireless` settings from test show outputs

* Update `mocked_wireless_create(mocker)`

* Update plugins/modules/net_tools/nmcli.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Address comment re. creating function & use nmcli naming conventions

I.E. `setting`.`property` = `value`

```
nmcli> help set
set [<setting>.<prop> <value>]  :: set property value

This command sets property value.

Example: nmcli> set con.id My connection
```

* Added `ignore_unsupported_suboptions` option & improved `wifi(_sec)` doc

* Corrected pep8 issues

```
ERROR: Found 2 pep8 issue(s) which need to be resolved:
ERROR: plugins/modules/net_tools/nmcli.py:342:161: E501: line too long
(236 > 160 characters)
ERROR: plugins/modules/net_tools/nmcli.py:359:161: E501: line too long
(237 > 160 characters)
```

* Fixed remaining sanity check issues and added even more docs

* No need to split Note

* Update plugins/modules/net_tools/nmcli.py

3.5.0 has already been released.

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

* Followed uniformity guideline for format macros from Ansible's dev guide

* Addressed comment

https://github.com/ansible-collections/community.general/pull/3141#discussion_r689098383

* Documentation cleanup continuation

* Replace `NM_SETTING_*`s having a description with their numeric value

* Splitting up long paragraphs.

Also removed `wifi`.`seen-bssids` as it "`is only meant for reading`"

* Addressed remaining comments and clarified `wake-on-lan` note

* Update plugins/modules/net_tools/nmcli.py

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

* Update plugins/modules/net_tools/nmcli.py

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

* Update plugins/modules/net_tools/nmcli.py

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

* Update plugins/modules/net_tools/nmcli.py

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

* Finishing addressing documentation comments.

* Update plugins/modules/net_tools/nmcli.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update plugins/modules/net_tools/nmcli.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update nmcli.py

* Added wifi-related `list` type options to `settings_type` method

* Moved `edit_commands` `execution` logic into its own method

* Move `unsupported_property` deletion into `main` function

* Missing `.items()`

* Resolved missing proper `nmcli conn edit` arguments

* Resolve pylint issue `dangerous-default-value`

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
Co-authored-by: David Hummel <dhummel@Fingerling>
(cherry picked from commit 8a62b79ef2)

Co-authored-by: David Hummel <6109326+hummeltech@users.noreply.github.com>
2021-08-20 22:04:38 +02:00
patchback[bot]
67eafdd20b Add option for domain authorization (#3228) (#3246)
Use DomainPasswordGrantAuthorizer if parameter `domain` is used.

(cherry picked from commit bcccf4e388)

Co-authored-by: Martin Vician <vician@users.noreply.github.com>
2021-08-20 16:55:48 +02:00
patchback[bot]
3cc11bfd42 redfish_info: Include Status property for GetChassisThermals (#3233) (#3240)
* redfish_info: Include Status property for GetChassisThermals

Include Status property for Thermal objects when querying Thermal properties
via GetChassisThermals command.

FIXES #3232

* fixup for rename of fragments file

* Update changelogs/fragments/3233-include-thermal-sensor-status-via-redfish_info.yaml

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit c7fccb2c01)

Co-authored-by: Jacob <jyundt@gmail.com>
2021-08-20 13:37:44 +02:00
patchback[bot]
a367fba315 tss: added fix for bug report in issue #3192 (#3199) (#3235)
* Added fix for bug report in issue #3192

* Added changelog fragment

* Typo fix

* Added Importerror to exception - as req by linters

* Moved the conditional import statement to try/except block

(cherry picked from commit 6ac410b3f6)

Co-authored-by: Ricky White <ricky@whitelionmedia.com>
2021-08-18 09:45:30 +02:00
patchback[bot]
00583448e2 module_helper - implemented classmethod to start the module (#3206) (#3225)
* module_helper - implemented classmethod to start the module plus minor change

* rolled back the __changed__() method

* added changelog fragment

* Update plugins/module_utils/mh/base.py

Co-authored-by: Sviatoslav Sydorenko <wk.cvs.github@sydorenko.org.ua>

* no capt Piccards allowed in the base class

* removed extra piccards

Co-authored-by: Sviatoslav Sydorenko <wk.cvs.github@sydorenko.org.ua>
(cherry picked from commit 41101e55a0)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-08-17 11:29:11 +02:00
patchback[bot]
c0cae2b27e Temporarily disable datadog_downtime unit tests. (#3222) (#3224)
(cherry picked from commit f19e191467)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-08-17 06:34:08 +00:00
patchback[bot]
07a9efd54f Linode inventory plugin typo fixes (#3218) (#3221)
- Fix a typo in the Linode inventory plugin unit tests
- Fix some style issues in descriptions where punctuation was missing

Signed-off-by: Kellin <kellin@retromud.org>
(cherry picked from commit fccae19177)

Co-authored-by: Kellin <kellin@retromud.org>
2021-08-17 07:20:29 +02:00
patchback[bot]
9dc8f2b05d slack - minor refactoring and pythonifying (#3205) (#3214)
* slack - minor refactoring and pythonifying

* added changelog fragment

* Update changelogs/fragments/3205-slack-minor-refactor.yaml

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-08-16 12:33:17 +00:00
patchback[bot]
baf726b389 vdo - refactor (#3191) (#3213)
* refactor to vdo

* adjusted if condition

* added changelog fragment

* Update plugins/modules/system/vdo.py

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

* adjustements per the PR

* more occurrences of bool compared with yes or no

* Update changelogs/fragments/3191-vdo-refactor.yml

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-08-16 12:33:09 +00:00
patchback[bot]
2d7302ba12 Add ipv4 example to linode inventory docs (#3200) (#3209)
* Add ipv4 example to linode inventory

* Update plugins/inventory/linode.py

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

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

Co-authored-by: Paul Hauner <paul@paulhauner.com>
2021-08-15 13:33:00 +02:00
patchback[bot]
7caefbd420 ini_file: add multiple options with same name to ini file (#3033) (#3207)
* ini_file - prepare for fixing #273
 - restructure tests
 - fix error message call: fail_json() takes 1 positional argument but 2 were given

* ini_file - multiple values for one option (#273)
  - add module option 'exclusive' (boolean) for the abbility to add
    single option=value entries without overwriting existing options
    with the same name but different values
  - add abbility to define multiple options with the same name but
    different values

* ini_file - add more tests for ini_file

* ini_file - fix sanity tests

* apply suggested changes:

- rename 03-regressions.yml to 03-encoding.yml
- fix typos
- fix documentation

* apply suggested changes:

- test errors also for result is failed

* apply suggested changes:

- make state=absent also work with module option exclusive
- add more tests for state=absent and module option exclusive

* fix sanity test:

- 02-values.yml:251:9: hyphens: too many spaces after hyphen

* apply proposed changes

* apply proposed changes from review
- adjust version_added to 3.6.0
- small syntax change in changelog fragment

(cherry picked from commit 25267b8094)

Co-authored-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2021-08-15 13:23:30 +02:00
patchback[bot]
1a3c221995 [PR #3194/1fec1d0c backport][stable-3] Fix sanity failures (#3195)
* Fix new devel sanity errors. (#3194)

(cherry picked from commit 1fec1d0c81)

* Add two more.

* Fix PR #.

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-08-12 13:46:55 +02:00
patchback[bot]
0eecd48ea8 zypper: support transactional-updates (#3164) (#3193)
* zypper: support transactional-updates

- Check if transactional updates are in use by checking for the
  existence of /var/lib/misc/transactional-update.state
- Prefix zypper-commands with /sbin/transactional-update --continue --drop-if-no-change --quiet run
  if this is the case

fixes ansible-collections/community.general#3159

* re-add get_bin_path for executables

* fix typo

(cherry picked from commit 6033ce695b)

Co-authored-by: Sebastian <sebix@sebix.at>
2021-08-12 08:29:22 +02:00
Felix Fontein
d71c10da27 Next expected release is 3.6.0. 2021-08-10 19:46:33 +02:00
Felix Fontein
664a09b277 Release 3.5.0. 2021-08-10 17:03:35 +02:00
patchback[bot]
e11bf7d788 Support older version of psutil (RHEL7 and RHEL6) (#2808) (#3189)
* Support older version of psutil (RHEL7 and RHEL6)

The psutil python module is a true mess, they changed the API twice. The function arguments, as well as the objects that are returned.
The documentation does not make it clear which version supports what so the safest implementation is this waterfall approach.

A better approach would be to inspect the returned information, rather than trust a version, but that would not be any more efficient.
In the end it is better to have something that at least works out-of-the-box on all platforms than something that requires custom updates to system packages before it works as expected. Especially for something as basic as `pids`.

* A little bit more concise

* Apply suggestions from code review

* Add changelog fragment.

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

Co-authored-by: Dag Wieers <dag@wieers.com>
2021-08-10 08:08:50 +02:00
Felix Fontein
889989aa96 Prepare 3.5.0 release. 2021-08-10 07:52:36 +02:00
patchback[bot]
0feb38f2b1 SAP task list execution (#3169) (#3187)
* add sap task list execute

* Apply suggestions from code review

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

* remove json out

* Apply suggestions from code review

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

* change logic

Co-authored-by: Rainer Leber <rainer.leber@sva.de>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 1705335ba7)

Co-authored-by: rainerleber <39616583+rainerleber@users.noreply.github.com>
2021-08-09 23:12:35 +02:00
patchback[bot]
e6323433ff openbsd_pkg: Fix regexp matching crash (#3161) (#3186)
When a package name contains special characters (e.g. "g++"), they are
interpreted as part of the regexp.

This can lead to a crash with an error in the python re module, for
instance with "g++":

    sre_constants.error: multiple repeat

Fix this by escaping the package name.

Co-authored-by: Baptiste Jonglez <git@bitsofnetworks.org>
(cherry picked from commit 56b5be0630)

Co-authored-by: zorun <github@bitsofnetworks.org>
2021-08-09 23:10:03 +02:00
patchback[bot]
0a9a853abf Update the .gitignore with the latest version (#3177) (#3184)
This because it contains new changes, e.g. ignore development
environments for Python projects.

(cherry picked from commit 429359e977)

Co-authored-by: Roy Lenferink <lenferinkroy@gmail.com>
2021-08-09 17:01:05 +02:00
patchback[bot]
3da1119e41 ini_file: fix empty-value vs. no-value inconsistency (#3074) (#3179)
* fix empty-value vs. no-value inconsistency

* rename changelog fragment

* tests: omit value where there should be no value

* add integration tests

(cherry picked from commit 2831bc45f5)

Co-authored-by: quidame <quidame@poivron.org>
2021-08-08 19:27:32 +02:00
patchback[bot]
4255c0d2fc nmcli: writing secrets to command line is a security hole (#3160) (#3180)
* nmcli: use `stdin` for setting private `wifi_sec` options

I.E.:
* `802-11-wireless-security.leap-password`
* `802-11-wireless-security.psk`
* `802-11-wireless-security.wep-key0`
* `802-11-wireless-security.wep-key1`
* `802-11-wireless-security.wep-key2`
* `802-11-wireless-security.wep-key3`

* Changelog fragement formatting.

* Update changelogs/fragments/3160-pass-wifi-secrets-via-stdin-to-nmcli-module.yml

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

* Make `wifi_sec_secret_options()` into a constant

* Minor cleanup

`'set ' + key + ' ' + value`
=>
`'set %s %s' % (key, value)`

* Change `casing`

* Change `WIFI_SEC_SECRET_OPTIONS` from `list` to `tuple`

* Update `edit_connection()` to not reset `edit_commands`

It will just re`set` them if `edit_connection()` is called more than
once.

* Do not call `edit_connection()` if `connection_update(*)` fails

* Fixed `pep8` issue `E713` in tests

`test for membership should be 'not in'`

* Simplify `create_connection()`/`modify_connection()` logic

* `WIFI_SEC_SECRET_OPTIONS`=>`SECRET_OPTIONS`, options are prefixed

* Moved `if key in self.SECRET_OPTIONS` into `if value is not None` check

We don't need to do anything is the value is None

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

Co-authored-by: David Hummel <6109326+hummeltech@users.noreply.github.com>
2021-08-08 19:27:11 +02:00
patchback[bot]
066975e5d1 mass-added the utf-8 marker (#3163) (#3170)
* added the utf-8 marker

* fixed the utf-8 marker where it was missde before

(cherry picked from commit 771e9de010)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-08-08 11:48:54 +02:00
patchback[bot]
8a59d6306c contributing: make expected behavior clearer (#3168) (#3176)
* contributing: make expected behavior clearer

reformulate the preference of not having squashed commits clearer,
shorter and more precise.

https://github.com/ansible-collections/community.general/pull/3164#discussion_r684644504

* Update CONTRIBUTING.md

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

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

Co-authored-by: Sebastian <sebix@sebix.at>
2021-08-08 11:48:38 +02:00
patchback[bot]
c4dc911d26 Inform contributors on changelog fragments in CONTRIBUTING.md (#3167) (#3173)
* Inform contributors on changelog fragments.

* Mention docs-only PRs as well.

(cherry picked from commit 87ba15fa45)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-08-08 11:48:01 +02:00
patchback[bot]
e30bb0958a fixed the utf-8 marker (#3162) (#3165)
(cherry picked from commit da11a98cb7)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-08-07 15:59:29 +02:00
patchback[bot]
67640e5431 nmcli: Fix change detection for Wi-Fi security options (#3136) (#3166)
* Fixed `wifi_sec` option changes are not detected

Also updated `docs` URL and formatting to match that of the `wifi`
option

* Removed extraneous `appends` to `cmd` in `connection_update`

These really should have only been added to `connection_options` whose
return values get `extended` onto `cmd`

(cherry picked from commit 6bfa6e40f4)

Co-authored-by: David Hummel <6109326+hummeltech@users.noreply.github.com>
2021-08-07 15:39:34 +02:00
patchback[bot]
9e7bcae370 pkgin: display stdout and stderr in case the error occurs (#3148) (#3156)
* pkgin: display stdout and stderr in case the error occurs

* Update changelogs/fragments/pkgin-output-after-error.yml

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

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

Co-authored-by: Bartosz <8199062+bartoszkosiorek@users.noreply.github.com>
2021-08-06 10:22:54 +02:00
patchback[bot]
c461e3cf71 Update AZP config (#3111) (#3154)
* Update AZP config.

* Skip 8.4 as well for django_manage (next to 8.3 and 8.2).

* Temporarily skip 8.4 for yum_versionlock.

(cherry picked from commit 16476f5cb9)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-08-06 08:12:52 +02:00
patchback[bot]
3495823a72 Hana query userstore (#3125) (#3152)
* add hdbuserstore ability

* add description

* fix

* add default

* add description

* add sample

* Apply suggestions from code review

Co-authored-by: quidame <quidame@poivron.org>

* add fragment, fix required if

* remove whitespace

* add coding fragment

* Apply suggestions from code review

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

* added test for userstore

* Update plugins/modules/database/saphana/hana_query.py

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

Co-authored-by: Rainer Leber <rainer.leber@sva.de>
Co-authored-by: quidame <quidame@poivron.org>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit e9494c12f2)

Co-authored-by: rainerleber <39616583+rainerleber@users.noreply.github.com>
2021-08-05 23:03:05 +02:00
patchback[bot]
f493110651 Updated the tss lookup plugin to reflect breaking changes introduced in the underpinning SDK (#3139) (#3150)
* Updated the plugin to reflect breaking changes introduced in the underlying SDK v1.0.0 update.

* Added Changelog fragment

* Updates based on feedback/review

* Added newline to pass CI

* Added whitepace for linter

* Update changelogs/fragments/3139-tss-lookup-plugin-update-to-make-compatible-with-sdk-v1.yml

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit a73720c103)

Co-authored-by: Ricky White <rickywhite@outlook.com>
2021-08-05 22:40:15 +02:00
patchback[bot]
548758a878 nmcli: manage dummy connections (#3132) (#3149)
* manage dummy connections

* add issue reference in changelog fragment

* Update changelogs/fragments/3132-nmcli-dummy.yaml

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* resolve test conflicts

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit 3dba697e33)

Co-authored-by: Reto Kupferschmid <kupferschmid@puzzle.ch>
2021-08-05 18:59:03 +02:00
patchback[bot]
f915cf5df2 redfish_command: allow setting the BootSourceOverrideMode property (#3135) (#3147)
* For #3134

Expose BootOverrideMode parameter to redfish_command to allow setting by user during run.

* Fix trailing whitespace

* Add changelog fragment to contribution.

* Update changelogs/fragments/3135-add-redfish_command-bootoverridemode.yaml

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

* Update plugins/modules/remote_management/redfish/redfish_command.py

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

* Update plugins/modules/remote_management/redfish/redfish_command.py

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

* Update plugins/modules/remote_management/redfish/redfish_command.py

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

* Update plugins/modules/remote_management/redfish/redfish_command.py

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

* Update changelogs/fragments/3135-add-redfish_command-bootoverridemode.yaml

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

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

Co-authored-by: Scott Seekamp <sylgeist@users.noreply.github.com>
2021-08-04 20:07:24 +02:00
patchback[bot]
6d147d748f dnsimple update for python-dnsimple >=2.0.0 (#2946) (#3143)
* update dnsimple module

* dnsimple: fixes for python-dnsimple >= 2.0.0

* Update plugins/modules/net_tools/dnsimple.py

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>

* rewrite module to support dnsimple-python v1 and v2

* add changelog fragment

* fix sanity checks

* python 2 fixes

* fix dnsimple requirement

* add sandbox module parameter

* Update changelogs/fragments/2946-python-dnsimple-v2-rewrite.yml

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

* Update plugins/modules/net_tools/dnsimple.py

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

* return only the first traceback

* Update plugins/modules/net_tools/dnsimple.py

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

* Update plugins/modules/net_tools/dnsimple.py

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

* use separate classes for python-dnsimple 1 and 2

* add basic tests

* fix checks

* skip tests for unsupported python versions

* Update plugins/modules/net_tools/dnsimple.py

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

* fix conditions

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit f2df1a7581)

Co-authored-by: Reto Kupferschmid <kupferschmid@puzzle.ch>
2021-08-04 12:56:52 +02:00
patchback[bot]
1349d38c73 nmcli: Add support for additional Wi-Fi network options (#3081) (#3142)
* nmcli: Add support for additional Wi-Fi network options

* Added `changelog fragment`

* Update changelogs/fragments/3081-add-wifi-option-to-nmcli-module.yml

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit 857d2eee50)

Co-authored-by: David Hummel <6109326+hummeltech@users.noreply.github.com>
2021-08-04 08:30:19 +02:00
patchback[bot]
552207ea13 filesize: overwrite default unsafe_writes documentation (#3126) (#3133)
* overwrite default `unsafe_writes` documentation

* Apply suggestions from code review

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

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

Co-authored-by: quidame <quidame@poivron.org>
2021-08-02 17:30:59 +02:00
patchback[bot]
9cbe572c22 utf8 marker batch1 (#3127) (#3130)
* added utf-8 markers to all .py files in plugins/{action,cache,callback}

* added utf-8 markers to all .py files in plugins/connection

* added utf-8 markers to all .py files in plugins/doc_fragments

(cherry picked from commit 73c27d6a0e)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-08-01 16:01:32 +02:00
patchback[bot]
b485d23a05 uf8 marker batch2 (#3128) (#3131)
* added utf-8 markers to all .py files in plugins/filter

* added utf-8 markers to all .py files in plugins/inventory

* added utf-8 markers to all .py files in plugins/lookup

(cherry picked from commit 047b7ada3c)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-08-01 15:59:11 +02:00
patchback[bot]
a59a15e56c fixed RETURN doc (#3120) (#3123)
(cherry picked from commit 5f8d6a73d3)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-31 09:44:19 +02:00
patchback[bot]
98251abfa9 removed extraneous dependency in integration test (#3119) (#3124)
(cherry picked from commit 789f06dffe)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-31 09:38:34 +02:00
patchback[bot]
e16bd2d015 Feature: implement hpilo_info system power info (#3079) (#3121)
* report power state of host

* Modify sample information

* add changelog fragment

* apply feedback from github community

* apply feedback

Co-authored-by: Yvan E. Watchman <git@yvanwatchman.eu>
(cherry picked from commit 9ccce82113)

Co-authored-by: Yvan Watchman <ik@yvanwatchman.eu>
2021-07-31 09:38:18 +02:00
patchback[bot]
bdafa31851 Keycloak: add client_rolemapping management (#2941) (#3117)
* Add Keycloak kc_client_rolemapping module

* Fix documentation

* Add unit tests for keycloak_client_rolemapping Keycloak module

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

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

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

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

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

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

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

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

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

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

* Fix documentation

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

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

* Minor fix

* Add check mode

* Refactoring: rename function from get_client_roles to get_client_roles_by_id

* BOTMETA.yml: keycloak_client_rolemapping - add myself as maintainer

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

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

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

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

Co-authored-by: Gaetan2907 <48204380+Gaetan2907@users.noreply.github.com>
2021-07-30 18:29:20 +00:00
patchback[bot]
231f9c0283 apache2_module - multiple improvements (#3106) (#3116)
* multiple improvements

* added changelog fragment

* comment and name in int test files

* added notes to the documentation

* removed the extraneous changelog frag

* Update plugins/modules/web_infrastructure/apache2_module.py

* adjusted doc text for sanity check

* Update plugins/modules/web_infrastructure/apache2_module.py

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

* removed extraneous dependency in integration test

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-30 20:03:39 +02:00
patchback[bot]
0a5b29a744 removed extraneous dependency in integration test (#3114) (#3115)
(cherry picked from commit d974ca32ae)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-30 20:03:29 +02:00
patchback[bot]
405b4f34c0 ansible_galaxy_install - new module (#2933) (#3110)
* initial commit

* multiple changes:

- added a proper process_command_output()
- adjusted the output_params fields (and removed other *_params fields)

* added RETURN documentation, plus few adjustments

* fixed sanity tests

* updated BOTMETA.yml

* further adjustments

* integration tests - first commit

* removed unused files from integration test

* added role installation tests

* removed extraneous cmd line option

* added requirement-file installation tests

* adjusted documentation and output variable names

* fixed integration test

* Update plugins/modules/packaging/language/ansible_galaxy_install.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update plugins/modules/packaging/language/ansible_galaxy_install.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update plugins/modules/packaging/language/ansible_galaxy_install.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update plugins/modules/packaging/language/ansible_galaxy_install.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update plugins/modules/packaging/language/ansible_galaxy_install.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update plugins/modules/packaging/language/ansible_galaxy_install.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update plugins/modules/packaging/language/ansible_galaxy_install.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update plugins/modules/packaging/language/ansible_galaxy_install.py

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

* Update tests/integration/targets/ansible_galaxy_install/aliases

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

* Per comments in the PR:

- fixed missing paths case
- fixed install parsing (regexp) for ansible-galaxy collection install in v2.10

* changed the collection installed in test to something unlikely to come embedded in Ansible itself

* fixed logic for Ansible 2.9

* kill trailing whitespace

* changed default language from C.UTF-8 to en_US.UTF-8

* updated c.g version

* skipping test in python 2.6, as ansible-galaxy no longer supports it in devel

* Multiple changes:

- improved docs on ansible 2.9 and python 2.6
- removed method __changed__() - unnecessary since tracking changes in the ansible29_change var
- renamed methods __run29__() and __run210plus__() to __setup29__() and __setup210plus__(), respectively
- ansible 2.9 warning for requirements_file only when type is "both"

* sanity fix

* further adjustments

* removed extraneous doc

* changed method to determine remote ansible version

* do not allow type=both in Ansible 2.9

* Update plugins/modules/packaging/language/ansible_galaxy_install.py

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

* Update plugins/modules/packaging/language/ansible_galaxy_install.py

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

* changed method names per PR

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 2935b011ed)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-29 23:13:09 +02:00
patchback[bot]
c51b10eb9b deploy_helper - changed in-code condition to required_if (#3104) (#3108)
* changed in-code condition to required_if

* added changelog fragment

(cherry picked from commit cde9564163)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-29 08:02:44 +02:00
patchback[bot]
6e172f37af gunicorn - minor refactoring (#3092) (#3103)
* minor refactoring in gunicorn module

* added changelog fragment

* reworked the gunicorn bin path part of the code, per PR

* Update changelogs/fragments/3092-gunicorn-refactor.yaml

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-28 08:55:33 +02:00
patchback[bot]
c31424a924 django_manage - using list instead of string in run_command() (#3098) (#3102)
* django_manage - using list instead of string in run_command()

* added changelog fragment

(cherry picked from commit 0b70b3baff)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-28 08:35:08 +02:00
patchback[bot]
6f0be41e1e ejabberd_user - refactoring and simplification (#3093) (#3100)
* ejabberd_user - refactoring and simplification

* added changelog fragment

* Update changelogs/fragments/3093-ejabberd_user-refactor.yaml

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-28 08:34:56 +02:00
patchback[bot]
8d035be233 Actually enable BOTMETA sanity test to force new plugins/modules to have BOTMETA entry. (#3096) (#3097)
(cherry picked from commit 87baa5860a)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-07-27 20:38:24 +02:00
patchback[bot]
35de2377f2 added supports_check_mode=True to info/facts modules (#3084) (#3094)
* added supports_check_mode=True to info/facts modules

* added changelog fragment

* rolled back vertica_info

* rolled back utm_proxy_*_info

* updated changelog fragment with latest adjustments

* Update changelogs/fragments/3084-info-checkmode.yaml

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

* added check mode to xenserver_facts + oneview_*_info

* added check mode to utm_proxy_*_info

* updated changelog

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-27 17:23:10 +00:00
patchback[bot]
ad8cd8efb3 BOTMETA: enforce entries for new plugins/modules, add documentation for creating new plugins/modules (#3088) (#3090)
* More BOTMETA improvements.

* Improve BOTMETA test, start reporting missing entries for new plugins/modules.

* Add instructions for creating new plugins and modules.

(cherry picked from commit 024e7419da)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-07-27 07:49:57 +02:00
patchback[bot]
1dc03685b5 Update BOTMETA, fix some plugin authors, improve BOTMETA extra sanity test (#3069) (#3087)
* Update BOTMETA, fix some plugin authors, improve BOTMETA extra sanity test.

* Linting.

(cherry picked from commit 4982eaf935)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-07-26 14:13:28 +02:00
patchback[bot]
c81ea00a97 java_cert: import certificate+key bundle from pkcs12 (#3080) (#3086)
* import certificate+key bundle from pkcs12

* fix typo/syntax

* fix variable name

* fix passwords order and improve error handling

* add changelog fragment

* enter keystore pass only once if keystore already exists, and twice at creation

* nomalize tests

- Replace `command` tasks by dedicated (community.crypto) modules.
- Add spaces around jinja2 variable names.
- Call modules by their FQCNs.

* Add tests to check keystore has a private key

fix tests for RedHat/CentOS < 8 (run openssl command as an alternative to
`openssl_pkcs12` module)

(cherry picked from commit 21d5668c97)

Co-authored-by: quidame <quidame@poivron.org>
2021-07-26 12:06:11 +02:00
patchback[bot]
ca39c45bd4 Succesful clone from proxmox_kvm should return new vm id, not id from cloned vm. (#3034) (#3083)
* Clone sucess should return new vm id, not id from cloned vm.

* add changelog fragment

* Update changelogs/fragments/3034-promox-kvm-return-new-id.yaml

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

Co-authored-by: Yvan E. Watchman <git@yvanwatchman.eu>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit ac03881002)

Co-authored-by: Yvan Watchman <ik@yvanwatchman.eu>
2021-07-26 09:07:15 +02:00
patchback[bot]
2326d72cf7 taiga_issue - bugfix + pythonification (#3067) (#3077)
* taiga_issue - bugfix + pythonification

* added changelog fragment

(cherry picked from commit 95ceb53676)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-25 22:28:40 +02:00
patchback[bot]
9bd3627796 supervisorctl - bugfix + using ansible validation + pythonification (#3068) (#3078)
* supervisorctl - bugfix + pythonification

* added changelog fragment

* rollback check on the binpath

(cherry picked from commit c8b2d7c1e5)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-25 22:19:19 +02:00
patchback[bot]
8a8e6c8058 replace NBSP (non-blocking space) character with a regular SPACE char (#3071) (#3073)
(cherry picked from commit 20db4fc560)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-25 14:18:13 +02:00
patchback[bot]
d85d31ba3c Add BOTMETA extra sanity test (#3064) (#3066)
* Add BOTMETA sanity test.

* Make compile with Python 2.6.

(cherry picked from commit dc3e16113d)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-07-25 11:00:56 +02:00
patchback[bot]
15998c9f72 xfconf_info - new module (#3045) (#3063)
* xfconf_info initial commit

* Update plugins/modules/system/xfconf_info.py

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

* Update plugins/modules/system/xfconf_info.py

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

* Update plugins/modules/system/xfconf_info.py

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

* added register to all examples

* Update plugins/modules/system/xfconf_info.py

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-24 22:40:48 +02:00
patchback[bot]
93027a33b9 archive - fixing determination of archive root when root is '/' (#3036) (#3062)
* Initial commit

* Fixing units and path joins

* Ensuring paths are consistently ordered

* Adding changelog fragment

* Using os.path.join to ensure trailing slashes are present

* optimizing use of root in add_targets

* Applying initial review suggestions

(cherry picked from commit 31189e9645)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-07-24 22:23:20 +02:00
patchback[bot]
c5f17f2184 gitlab_group_members/gitlab_project_members - fix pagination issue (#3054) (#3061)
* Fix

* fixed linter stuff

* typo in section name of changlog fragment

Co-authored-by: Max Bidlingmaier <Max-Florian.Bidlingmaier@sap.com>
(cherry picked from commit d057b2e3b2)

Co-authored-by: Max Bidlingmaier <maks@konsolan.de>
2021-07-24 21:24:18 +02:00
patchback[bot]
172e8bb161 proxmox inventory plugin: Easy fix (#3052) (#3059)
* Don't know why this works but it does.

Plugin was crashing on this line on Python 3.9.2 deployed on qemu image with debian bullseye. It doesn't crash anymore.

* Create 3052_proxmox_inventory_plugin.yml

* Update changelogs/fragments/3052_proxmox_inventory_plugin.yml

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit 99c28313e4)

Co-authored-by: The Right Honourable Reverend <samueljsmith@gmail.com>
2021-07-24 20:58:17 +02:00
patchback[bot]
8da1ff3c90 fixed doc in xfconf (#3050) (#3056)
(cherry picked from commit 9631de4939)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-23 09:34:52 +02:00
patchback[bot]
7aa1c1a338 missed composer when created commments in ignore files (#3051) (#3053)
(cherry picked from commit 35e0a61217)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-23 09:34:22 +02:00
patchback[bot]
378687503c Proxmox inventory: Added snapshots fact (#3044) (#3048)
* Added snapshots fact

* Added changelog

* Made linter happy again

* Processed feedback

* Fix changelog type

* Punctuation ;-)

* Punctuation ;-), take 2

(cherry picked from commit 32e9a0c250)

Co-authored-by: Jeffrey van Pelt <jeff@vanpelt.one>
2021-07-22 23:19:39 +02:00
patchback[bot]
90be1cc838 github_repo: support GitHub on premise installations (#3039) (#3046)
* added possibility to manage on prem github

* added changelog

* fixed module tests

* Update changelogs/fragments/3038-enhance_github_repo_api_url.yml

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

* Update plugins/modules/source_control/github/github_repo.py

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

Co-authored-by: Max Bidlingmaier <Max-Florian.Bidlingmaier@sap.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 38e70ae0e4)

Co-authored-by: Max Bidlingmaier <maks@konsolan.de>
2021-07-22 17:11:22 +02:00
Felix Fontein
8cee29b8f6 Next expected release is 3.5.0. 2021-07-20 14:26:38 +02:00
Felix Fontein
5a71909770 Release 3.4.0. 2021-07-19 23:59:45 +02:00
patchback[bot]
9d0af30702 Keycloak: add clientscope management (#2905) (#3037)
* Add new keycloak_clienscope module

* Add description and protocol parameter + Indentation Fix

* Add protocolMappers parameter

* Add documentation and Fix updatating of protocolMappers

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

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

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

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

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

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

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

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

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

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

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

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

* Add sanitize_cr(clientscoperep) function to sanitize the clientscope representation

* Add unit tests for clientscope Keycloak module

* Apply suggestions from code review

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

Co-authored-by: Gaetan2907 <48204380+Gaetan2907@users.noreply.github.com>
2021-07-19 23:58:26 +02:00
patchback[bot]
9dc21447cc Add Keycloak roles module (#2930) (#3035)
* implement simple realm and client role

* fix documentation

* code cleanup

* separate realm and client roles functions

* remove blank lines

* add tests

* fix linefeeds

* fix indentation

* fix error message

* fix documentation

* fix documentation

* keycloak_role integration tests

* keycloak_role integration tests

* remove extra blank line

* add version_added tag

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

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

Co-authored-by: Laurent Paumier <30328363+laurpaum@users.noreply.github.com>
2021-07-19 23:38:51 +02:00
patchback[bot]
940130c959 Feature/gitlab project configuration (#3002) (#3032)
* added
-         only_allow_merge_if_all_discussions_are_resolved
- only_allow_merge_if_all_discussions_are_resolved
- only_allow_merge_if_pipeline_succeeds
- only_allow_merge_if_pipeline_succeeds
- packages_enabled
- remove_source_branch_after_merge
- squash_option

* minor fix

* added changelog

* Fixedlinter findings

* changed version_added to 3.4 -> check requires to do so

* Update changelogs/fragments/3001-enhance_gitlab_module.yml

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

* Update plugins/modules/source_control/gitlab/gitlab_project.py

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

* Update plugins/modules/source_control/gitlab/gitlab_project.py

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

* Update plugins/modules/source_control/gitlab/gitlab_project.py

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

* Update plugins/modules/source_control/gitlab/gitlab_project.py

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

* Update plugins/modules/source_control/gitlab/gitlab_project.py

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

* Update plugins/modules/source_control/gitlab/gitlab_project.py

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

* rework due to review of felixfontein:
- changed option description to full sentences
- change default behaviour of new properties

* Requested changes

Co-authored-by: Max Bidlingmaier <Max-Florian.Bidlingmaier@sap.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit a3607a745e)

Co-authored-by: suukit <maks@konsolan.de>
2021-07-19 12:04:06 +02:00
patchback[bot]
0b239199e7 archive - staging idempotency fix (#2987) (#3030)
* Initial Commit

* Fixing PY26 filter

* Adding changelog fragment

* Removing checksum related code

* Removing list comparisons due to Jinja errors

* Applying review suggestions

* Applying review suggestions - typos

(cherry picked from commit 9fd2ba60df)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-07-19 09:40:26 +02:00
patchback[bot]
f0d6fcb3fa Fix snap's channel option. (#3028) (#3029)
(cherry picked from commit 7b9687f758)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-07-19 09:40:11 +02:00
Felix Fontein
e1aad0db30 Prepare 3.4.0 release. 2021-07-17 15:33:34 +02:00
patchback[bot]
7701ea0293 Added module for creating protected branches (#2781) (#3024)
* Added module for creating protected branches

* Applied some changes due to comments and added a test that currently fails

* Changing no_access to nobody due to comment on PR

* Changing the description to clarify it a bit more

* Added working tests for module 'gitlab_protected_branch'

* Fixing lint issues

* Added doc that minimum of v2.3.0 is needed to work correctly

* Fixed the requirements notation

* Check the version of the module

* Hopefully fixed the tests by skipping it when lower version of 2.3.0 is installed

* Fix lint issues

* Applying changes due to comments in PR

* Remove commented code

* Removing the trailing dot ...

Co-authored-by: jenkins-x-bot <jenkins-x@googlegroups.com>
Co-authored-by: Werner Dijkerman <iam@werner-dijkerman.nl>
(cherry picked from commit 7734430f23)

Co-authored-by: Werner Dijkerman <werner@dj-wasabi.nl>
2021-07-17 10:46:42 +02:00
patchback[bot]
9afb84c8f3 Check targets (#3019) (#3022)
* Add extra sanity test to check aliases files.

* Remove invalid target name.

(cherry picked from commit 27ba98a68e)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-07-16 20:13:19 +02:00
patchback[bot]
1746d11749 Enable tests (#3015) (#3018)
* Enable tests.

* Fix error message check.

* Fix boolean tests.

* Adjust to Python version.

(cherry picked from commit 9b1c6f0743)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-07-16 20:06:35 +02:00
patchback[bot]
ea3b8eeee7 Redfish Bootoverride Disable behaves incorrectly (#3006) (#3017)
* https://github.com/ansible-collections/community.general/issues/3005

Bypass the boot device argument check when the command is: DisableBootOverride
as it isn't needed to perform this operation.

* Add changelog fragment

(cherry picked from commit ea822c7bdd)

Co-authored-by: Scott Seekamp <sylgeist@users.noreply.github.com>
2021-07-16 19:18:46 +02:00
patchback[bot]
8c9add3d15 rax_mon_notification_plan - fixed validation check (#2955) (#2977)
* fixed validation-modules for plugins/modules/cloud/rackspace/rax_mon_notification_plan.py

* fixed sanity check

* added changelog fragment

(cherry picked from commit 0e90ff48b5)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-16 14:17:06 +02:00
patchback[bot]
9244d0ae47 pamd - fixed single line issue (#2989) (#3013)
* fixed pamd single line issue

* added changelog fragment

* supported case for 0 lines, improved test

(cherry picked from commit a3a40f6de3)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-14 13:21:57 +02:00
patchback[bot]
22591fb6e1 Update README.md (#3003) (#3010)
(cherry picked from commit 28193b699b)

Co-authored-by: Andrew Klychkov <aklychko@redhat.com>
2021-07-14 08:46:23 +02:00
patchback[bot]
166fa1a7fa [nmcli] add runner and runner-hwaddr-policy for network teaming (#2901) (#3008)
* [nmcli] add runner and runner-hwaddr-policy for network teaming

* [nmcli] delete extra space

* Update plugins/modules/net_tools/nmcli.py

* Update plugins/modules/net_tools/nmcli.py

* [nmcli] add changelog fragment

* Update plugins/modules/net_tools/nmcli.py

Co-authored-by: Amin Vakil <info@aminvakil.com>

Co-authored-by: Oriol MULA VALLS <oriol.mula@lxp.lu>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit 9ffc1ef393)

Co-authored-by: omula <joriol.mula@gmail.com>
2021-07-14 08:46:13 +02:00
patchback[bot]
9e541a6f11 Keycloak: Improve diff mode on keycloak_authentication module (#2963) (#3000)
* Fix diff mode when updating authentication flow with keycloak_authentication module

* Add changelog fragment

* Fix unit test

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

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update changelogs/fragments/2963-improve-diff-mode-on-keycloak_authentication.yml

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update documentation of create_or_update_executions function (return tuple instead of dict)

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

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

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

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit 3fc97bf80a)

Co-authored-by: Gaetan2907 <48204380+Gaetan2907@users.noreply.github.com>
2021-07-13 12:13:25 +02:00
patchback[bot]
dbb37194d4 added missing copyright notes to MH integration tests (#2990) (#2993)
(cherry picked from commit d56d34bce6)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-11 16:52:55 +02:00
patchback[bot]
3cd7b0ec25 module_helper cmd - added feature flag to control whether CmdMixin adds rc, out and err t… (#2922) (#2988)
* added feature flag to control whether CmdMixin adds rc, out and err to the result of the module

* added changelog fragment

* changed from a global flag to parameters in run_command

* updated changelog

* fixed brainless copy-paste of yours truly

(cherry picked from commit c5cbe2943b)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-11 16:25:32 +02:00
patchback[bot]
1c84389f50 feat: support datadog_monitor composite type (#2958) (#2986)
* feat: support datadog_monitor composite type

* docs: note support for composite types

* lint

* lint: line lengths

* doc: changelog frag

(cherry picked from commit 7a41833e59)

Co-authored-by: Tyler Schwend <tyler.schwend@placeexchange.com>
2021-07-10 20:40:43 +02:00
patchback[bot]
61de9ce51c filesystem: extend support for FreeBSD (#2902) (#2983)
* extend support for FreeBSD

* Check if FS exists with `fstyp` if `blkid` fails to find FS signature
  (fix a potential data loss)
* Add support for FreeBSD special devices (character devices).
* Add support for FreeBSD native fstype (UFS).
* Update DOCUMENTATION accordingly.

* add/update integration tests

* Add tests for `fstype=ufs` on FreeBSD.
* Run `remove_fs` tests (`state=absent`) on FreeBSD.
* Run `overwrite_another_fs` tests on FreeBSD.

* add a changelog fragment

* fix indentation

* restrict new tests to regular files

* fix typo

* fix searching of providersize (block count)

* add '-y' option to growfs command

* remove references to versions older than the collection itself

* bump version adding new feats to 3.4.0

* reformat *collection* and *version added* for better DOCUMENTATION parsing

* skip tests for FreeBSD < 12.2

* run tests for FreeBSD >= 12.2

* re-enable tests for FreeBSD < 12.2 and give it a try with group1

* util-linux not available on FreeBSD < 12.2

(cherry picked from commit 9023d4dba1)

Co-authored-by: quidame <quidame@poivron.org>
2021-07-10 16:56:09 +02:00
patchback[bot]
7ccd5c9116 proxmox inventory - fix parsing for offline nodes (#2967) (#2985)
* Initial commit

* Adding changelog fragment

* Applying initial review suggestions

(cherry picked from commit 111c5de550)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-07-10 16:55:57 +02:00
patchback[bot]
e3cea35f2c Temporarily disable passwordstore lookup tests on macOS and OSX. (#2979) (#2982)
(cherry picked from commit 4ae392e5de)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-07-10 13:49:12 +02:00
patchback[bot]
94f58d1920 launchd - fixed validation check (#2960) (#2976)
* replaced use of expanduser() with value from HOME var

* fixed sanity check

* added changelog fragment

(cherry picked from commit 1990f79d8a)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-10 13:22:41 +02:00
patchback[bot]
0f884bbadc added comments to the ignore files (#2972) (#2974)
(cherry picked from commit ad8c4e4de6)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-10 13:21:03 +02:00
patchback[bot]
6ca3e78d11 archive - adding dest_state return value and enhancing integration tests. (#2913) (#2973)
* Initial commit

* Adding changelog fragment

* fixing changelog fragment

* Updating documentation

* Applying review suggestions

(cherry picked from commit 288fe1cfc6)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-07-10 13:19:53 +02:00
John R Barker
a09d70daa0 Update commit-rights.md (#2964)
aminvakil is no longer involved with the Ansible Community due to United
States export controls and economic sanctions laws apply to U.S.
persons, entities, and controlled software and technology that is of
U.S. origin or that enters the U.S., including open source software.

(cherry picked from commit 518ace2562)
2021-07-09 13:00:11 +01:00
patchback[bot]
c2a3cf35c7 jenkins_job_info: Remove necessities of password or token. (#2948) (#2961)
* Remove necessities on password or token.

* Upper case letter -> Lower case letter

Co-authored-by: Amin Vakil <info@aminvakil.com>

* Documentation update.

* C -> I

Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit d97a9b5961)

Co-authored-by: Tong He <68936428+unnecessary-username@users.noreply.github.com>
2021-07-09 08:52:10 +02:00
patchback[bot]
ee5ff3b31b Add option to the keycloak_client module (#2949) (#2962)
* Add authentication_flow_binding_overrides option to the keycloak_client module

* Add changelog fragment

* Update changelogs/fragments/2949-add_authentication-flow-binding_keycloak-client.yml

Co-authored-by: Amin Vakil <info@aminvakil.com>

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

Co-authored-by: Amin Vakil <info@aminvakil.com>

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

Co-authored-by: Amin Vakil <info@aminvakil.com>

* Add unit test authentication_flow_binding_overrides feature on keycloak_client module

Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit 1b80a9c587)

Co-authored-by: Gaetan2907 <48204380+Gaetan2907@users.noreply.github.com>
2021-07-09 08:51:55 +02:00
Felix Fontein
18b7333f93 Next expected release is 3.4.0. 2021-07-08 11:02:27 +02:00
Felix Fontein
3197ef2e38 Release 3.3.2. 2021-07-08 08:43:16 +02:00
patchback[bot]
5f971e677a MH - dicts and lists change-tracking is fixed (#2951) (#2952)
* dicts and lists change-tracking is fixed

* added changelog fragment

* fixed sanity check

(cherry picked from commit 56acd4356f)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-08 07:52:51 +02:00
Felix Fontein
1b5d91153b Prepare 3.3.2 release. 2021-07-08 07:27:20 +02:00
patchback[bot]
2ce9ea8c54 pacman: fix changed status when ignorepkg has been defined (#2936) (#2945)
* pacman: fix returned code when ignorepkg has been defined

* add changelog

* make ignored check preciser

(cherry picked from commit c0740ca398)

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-07-07 06:53:37 +02:00
patchback[bot]
eec4861c36 lvol: honor check_mode on thinpool (#2935) (#2939)
* lvol: support check_mode on thinpool

* add changelog

* Add %s when needed

* correct changelog sentence

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

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

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-07-05 21:03:12 +02:00
patchback[bot]
82e7e931a8 snap - fixed param order (#2918) (#2932)
* fixed param order

* added changelog fragment

* rebased and uncommented tests per PR

* added /snap link in RH

* typo in tests

* Update tests/integration/targets/snap/tasks/default.yml

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-07-03 17:04:42 +02:00
patchback[bot]
4b59174063 npm - fix installing from package.json (#2924) (#2929)
correctly handle cases where a dependency does not have a `version` property because it is either missing or invalid

(cherry picked from commit a0915036f9)

Co-authored-by: Shahar Mor <shaharmor1@gmail.com>
2021-07-02 21:59:41 +02:00
patchback[bot]
58d8469759 archive - fix removal failures for nested files with tar archives (#2923) (#2927)
* Initial commit

* Adding changelog fragment

(cherry picked from commit ffe505a798)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-07-02 21:55:15 +02:00
patchback[bot]
6d5dbfd455 Add integration test for classic snap (#2920) (#2921)
* Add integration test for classic snap

* Add comments and check remove without classic

* Comment new tests for now

(cherry picked from commit 00aa1250ee)

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-07-02 13:31:29 +00:00
Felix Fontein
6357048068 Next expected release is 3.4.0. 2021-07-01 20:44:51 +02:00
Felix Fontein
a861149a0e Release 3.3.1. 2021-07-01 19:55:52 +02:00
patchback[bot]
9a9b0b04a5 Fix snap module, and module helper behavior on rc != 0 in output (#2912) (#2915)
* Try some snap fixes.

* Fix logic.

* Try to run tests privileged.

* Prevent failure on rc != 0.

* Fix formatting.

* Revert "Try to run tests privileged."

This reverts commit 77ca91f502.

* Try to run tests on RHEL instead.

* Make sure that snapd is running.

* Add changelog fragment.

* str -> to_native.

* Make sure that installed binary is actually found.

* Add check mode tests.

* Mention #2835 in changelog fragment.

(cherry picked from commit c63dc624b7)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-07-01 19:33:47 +02:00
Felix Fontein
0a4e9379e2 Prepare 3.3.1. 2021-07-01 07:10:37 +02:00
patchback[bot]
7d1abf5d6a Fix bug when 2 identical executions in same auth flow (#2904) (#2908)
* Fix bug when 2 identical executions in same auth flow

* Add changelog fragment

* Fix unit tests

* Update changelogs/fragments/2904-fix-bug-when-2-identical-executions-in-same-auth-flow.yml

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

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

Co-authored-by: Gaetan2907 <48204380+Gaetan2907@users.noreply.github.com>
2021-06-30 15:22:29 +02:00
patchback[bot]
7ef25be10c Add integration tests for snap (#2907) (#2909)
* Add integration tests for snap

* Also test on fedora and remove snapd if it was not installed

* disable test for now

(cherry picked from commit a97d82be88)

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-06-30 15:22:18 +02:00
Felix Fontein
0d0194fdf8 Next expected release is 3.4.0. 2021-06-30 13:16:52 +02:00
Felix Fontein
36f64367cf Release 3.3.0. 2021-06-29 12:16:58 +02:00
patchback[bot]
d827601c95 Add fallback url for jenkins plugin (#1334) (#2903)
* uncoupled updates_url from plugin download urls
added new parameters: versioned_plugins_url, latest_plugins_url

* parameters updates_url, latest_plugins_url and versioned_plugins_url changed type to list of strings to implement fallback URLs usage
added type conversion if they are string (backward compatibility)

* removed type conversion this is handled by ansible validation
fix: dont fail if first url fails

* added fallback: if installation from plugin manager fails, try downloading the plugin manually

* fixed test failures

* PEP8 indent fix

* changelog fragment

* added debug outputs for new url fallback behavior

* added version_added in description for latest_plugins_url

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

* added version_added in description for versioned_plugins_url

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

* Update changelogs/fragments/1334-jenkins-plugin-fallback-urls.yaml

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

* improve backwards-compatibility
add optional arg to allow custom update-center.json targets

* pep8 fixes

* fix inconsistency in argument documentation

* Apply suggestions from code review

Co-authored-by: Amin Vakil <info@aminvakil.com>

* add unit tests

* fix pep8

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit 9c7b539ef6)

Co-authored-by: NivKeidan <51288016+NivKeidan@users.noreply.github.com>
2021-06-29 09:02:35 +00:00
patchback[bot]
2efd31bacf [nmcli] add connection.slave-type for teamed devices (#2827) (#2900)
* [nmcli] add connection.slave-type for teamed devices

* [nmcli] add fragment with changes for #2827

* [nmcli] add tests for network team

* [nmcli] fix testing

Co-authored-by: Oriol MULA VALLS <oriol.mula@lxp.lu>
(cherry picked from commit 2d1527a564)

Co-authored-by: omula <joriol.mula@gmail.com>
2021-06-28 21:13:14 +02:00
Felix Fontein
6eaf047739 Prepare 3.3.0 release. 2021-06-28 07:04:02 +02:00
patchback[bot]
80268b0828 pacman: Descriptive state documentation (#2894) (#2898)
* pacman: Descriptive state documentation

* Update plugins/modules/packaging/os/pacman.py

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

Co-authored-by: Martin Rys <martin@rys.pw>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit debb15efbe)

Co-authored-by: Martin <spleefer90@gmail.com>
2021-06-27 19:05:33 +02:00
patchback[bot]
1e848c56f2 yum_versionlock: fix idempotency when using wildcard (asterisk) (#2787) (#2896)
* Check idempotency on yum_versionlock

* Lock packages wildcard

* fix formatting

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

* Fix formatting in asserts

* little closer but not still there

* Import fnmatch

* Change check_mode logic

* Add check_mode for add

* Add changelog

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

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-06-27 17:00:05 +02:00
patchback[bot]
f74756d7fc gitlab_project - Add ability to create project under a user (#2824) (#2895)
* Add ability to create project under a user

* Add changelog

* Add username option

* Update changelogs/fragments/2824-gitlab_project-project-under-user.yml

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

* Make group and username mutually exclusive

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

Co-authored-by: Stef Graces <stef.graces@nubera.eu>
2021-06-27 16:34:18 +02:00
patchback[bot]
138b57230a java_keystore: fix keystore type (#2516) (#2893)
* fix keystore type; update unit tests

* add changelog fragment

* document new param 'keystore_type'

* add keystore_type support (backward compatible)

* check JKS format with magic bytes
* update integration tests
* revert first changes in unit tests
* update changelog fragment

* fix magic bytes for python2/python3

* fix integration tests (irrelevant check_mode)

* fix unit test (keystore removed before failure => changed=true)

* fix typo

* fix spelling

* shorten a branch

* mock is_jks_or_pkcs12

* fix function path in unit tests

* Apply suggestions from code review (spelling)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* rename a method (module + unit tests)

* move ArgumentSpec class content to main()

* refactor create() to not loose existing keystore in case of error

* update unit tests

* add integration test (error handling)

* fix keystore backup cleanup

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
(cherry picked from commit 199ead85d0)

Co-authored-by: quidame <quidame@poivron.org>
2021-06-27 15:44:31 +02:00
patchback[bot]
d32193afef Fix/gitlab project user workspace (#2881) (#2891)
* Add ability to create project under a user

* Add changelog

* Change minor_changes in changelog

As suggested in this comment https://github.com/ansible-collections/community.general/pull/2824#discussion_r653411741

* Fix user's namespace

* Delete changelog

* Add changelog

* Fix changelog

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Amin Vakil <info@aminvakil.com>

* Change user_group_id to namespace_group_id

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

* Change to namespace_id

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit 2fb0877577)

Co-authored-by: Stef Graces <stef.graces@nubera.eu>
2021-06-27 14:43:44 +02:00
patchback[bot]
ef8aa73dab terraform - added check_destroy (#2874) (#2888)
* added check_destroy

This is based on the work done in PR 398. Authors from that PR:

Co-authored-by: effaamponsah <kamponsah.amponsah@gmail.com>
Co-authored-by: m-yosefpor
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* added changelog fragment

* Update plugins/modules/cloud/misc/terraform.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update changelogs/fragments/2874-terraform-check-destroy.yml

Co-authored-by: Amin Vakil <info@aminvakil.com>

Co-authored-by: effaamponsah <kamponsah.amponsah@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>
Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit 9dd91f949a)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-06-27 13:00:50 +02:00
patchback[bot]
28007079a4 ini_file: fix regression reported in #2578 (#2875) (#2887)
* Add regression test.

* Add more Unicode tests.

* Add fix.

* Add changelog.

* Work completely with Unicode.

* Update plugins/modules/files/ini_file.py

Co-authored-by: quidame <quidame@poivron.org>

Co-authored-by: quidame <quidame@poivron.org>
(cherry picked from commit 147425ef93)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-27 10:26:27 +02:00
patchback[bot]
f0b7233e8d Add option type validation. (#2878) (#2886)
(cherry picked from commit 1b94d09209)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-27 10:24:38 +02:00
Felix Fontein
48cc39a2b1 _mount module utils - fixed sanity checks (#2883) (#2884)
* updated _mount.py, removed ignore lines

* added changelog fragment

(cherry picked from commit acf7b106c9)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-06-27 09:59:19 +02:00
Felix Fontein
c34dc24d3a Replace ansible.module_utils._text by ansible.module_utils.common.text.converters (#2877) (#2882)
* Replace ansible.module_utils._text by ansible.module_utils.common.text.converters.

* Also adjust tests.

(cherry picked from commit fafabed9e6)
2021-06-27 09:39:18 +02:00
patchback[bot]
0760f60ca5 modprobe - fix task status when module cannot be loaded (#2843) (#2880)
* Initial Commit

* Adding changelog fragment

* Ensured params are present during verbose output and enhanced check_mode

* Making specific to builtins

* Removing unneccessary external call

* Acutal bugfix

(cherry picked from commit d180390dbc)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-06-26 13:45:13 +02:00
patchback[bot]
48b1bc7d47 Adjust example to remove unnecessary offensive language. (#2869) (#2872)
(cherry picked from commit d2a984ded1)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-25 06:49:14 +02:00
patchback[bot]
769233808d Redis: slave -> replica (#2867) (#2868)
* Redis: slave -> replica

* Fallback for old Redis versions in CI.

(cherry picked from commit 2d1f5408d3)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-24 22:50:16 +02:00
patchback[bot]
7361ca5430 archive - refactor and bugfix (#2816) (#2863)
* Initial Commit

* Further refinement

* Fixing archive name distortion for single file zips

* Applying initial review suggestions

* Updating path value for single target

* Adding test case for single target zip archiving

* Fixing integration for RHEL/FreeBSD on ansible 2.x

* Fixing integration second attempt

* Adding changelog fragment

* Updating changelog fragment

(cherry picked from commit 24dabda95b)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-06-24 19:15:03 +02:00
patchback[bot]
2322937a4a Keycloak: add authentication management (#2456) (#2864)
* Allow keycloak_group.py to take token as parameter for the authentification

Refactor get_token to pass module.params + Documentation

Fix unit test and add new one for token as param

Fix identation

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

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

Update plugins/modules/identity/keycloak/keycloak_clienttemplate.py

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

Allow keycloak_group.py to take token as parameter for the authentification

Refactor get_token to pass module.params + Documentation

* Update plugins/module_utils/identity/keycloak/keycloak.py

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

Check if base_url is None before to check format

Update plugins/module_utils/identity/keycloak/keycloak.py

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

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

Co-authored-by: Amin Vakil <info@aminvakil.com>

Update plugins/modules/identity/keycloak/keycloak_clienttemplate.py

Co-authored-by: Amin Vakil <info@aminvakil.com>

Switch to modern syntax for the documentation (e.g. community.general.keycloak_client)

Update keycloak_client.py

Update keycloak_clienttemplate.py

Add keycloak_authentication module to manage authentication

Minor fixex

Fix indent

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

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

Update plugins/modules/identity/keycloak/keycloak_authentication.py

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

Update plugins/modules/identity/keycloak/keycloak_authentication.py

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

Update plugins/modules/identity/keycloak/keycloak_authentication.py

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

Update plugins/modules/identity/keycloak/keycloak_authentication.py

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

Removing variable ANSIBLE_METADATA from beginning of file

Minor fix

Refactoring create_or_update_executions :add change_execution_priority function

Refactoring create_or_update_executions :add create_execution function

Refactoring create_or_update_executions: add create_subflow

Refactoring create_or_update_executions: add update_authentication_executions function

Minor fix

* Using FQCN for the examples

Minor fix

Update plugins/module_utils/identity/keycloak/keycloak.py

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

Update plugins/module_utils/identity/keycloak/keycloak.py

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

Update plugins/module_utils/identity/keycloak/keycloak.py

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

Update plugins/module_utils/identity/keycloak/keycloak.py

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

Update plugins/module_utils/identity/keycloak/keycloak.py

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

Update plugins/module_utils/identity/keycloak/keycloak.py

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

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

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

Update plugins/modules/identity/keycloak/keycloak_authentication.py

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

Refactoring: rename isDictEquals into is_dict_equals

Refactoring: rename variable as authentication_flow

Refactoring: rename variable as new_name

Refactoring: rename variable as flow_list

Refactoring: rename variable as new_flow

Refactoring: changing construction of dict newAuthenticationRepresentation and renaming as new_auth_repr

Minor fix

* Refactoring: rename variables with correct Python syntax (auth_repr, exec_repr)

Move create_or_update_executions function from keycloak.py to keycloak_authentication.py

Minor fix

Remove mock_create_or_update_executions not needed anymore

Fix unit test

Update plugins/module_utils/identity/keycloak/keycloak.py

is_dict_equals function return True if value1 empty

Update plugins/module_utils/identity/keycloak/keycloak.py

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

Rename is_dict_equal as is_struct_included and rename params as struct1 and struct2

Rename variables according to Python naming conventions

Refactoring: add find_exec_in_executions function in keycloak_authentication to remove code duplication

typo

Add blank line

Add required parameter, either creds or token

Typo

try/except only surround for loop containing struct2[key]

Add sub-options to meta_args

assigment of result['changed'] after if-elif-else block

Fix CI error: parameter-type-not-in-doc

Fix unit test: none value excluded from comparison

Minor fix

Simplify is_struct_included function

Replace 'type(..) is' by isinstance(..)

Remove redundant required=True and redundant parenthesis

Add check_mode, check if value is None (None value added by argument spec checker)

Apply suggestions from code review

Update plugins/modules/identity/keycloak/keycloak_authentication.py

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

* Add index paramter to configure the priority order of the execution

* Minor fix: authenticationConfig dict instead of str

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

Co-authored-by: Gaetan2907 <48204380+Gaetan2907@users.noreply.github.com>
2021-06-24 19:14:46 +02:00
patchback[bot]
82225e5850 jenkins_build: Support stop a running Jenkins build (#2850) (#2861)
* Support stop a running Jenkins build. Meanwhile enrich document content and test cases.

* Fix the inconsistencies regarding the function name.

* Submit the changelog and fix a PEP8 issue.

* Remedy whitespace related PEP8 issues.

* Implement the idempotent test case for the stop build function.

* Make sure it returns proper changed status when we stop a build repeatedly.

* Fix incorrect usages on comparison with True or False and incorrect usages on validating the changed status.

* In this mocking situation, adjust the mock return value and test case to perform unit testing.

* Implement JenkinsMockIdempotent() to mock return value in idempotent test cases.

* Fix issues reported by CI.

* Refactor the code to avoid CI exception and remove get_build_status() from mock function as they should not be there.

* Update plugins/modules/web_infrastructure/jenkins_build.py

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

Co-authored-by: Tong He <68936428+unnecessary-username@users.noreply.github.com>
2021-06-24 05:22:41 +00:00
patchback[bot]
2d237987ae snap - revamp + implementing enabled/disabled states (#2411) (#2542)
* revamp of snap module

* added changelog fragment

* fixed description

* Update changelogs/fragments/2411-snap-revamp-enabled-disabled-states.yml

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-06-22 19:21:29 +02:00
patchback[bot]
dc14070e08 Dynamically add meta/runtime.yml redirects before integration tests. (#2633) (#2855)
ci_coverage

(cherry picked from commit 07085785a3)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-22 10:06:33 +02:00
patchback[bot]
feb1c1081e gitlab_user: add support for identity provider (#2691) (#2852)
* Add identity functionality

* Add functionality for user without provider or extern_uid

* Fix missing key error and documentation

* Fix failing tests

* Update docs

* Add changelog fragment

* Update plugins/modules/source_control/gitlab/gitlab_user.py

Add version

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

* Update plugins/modules/source_control/gitlab/gitlab_user.py

Update boolean default

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

* Update plugins/modules/source_control/gitlab/gitlab_user.py

Fix syntax

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

* Update plugins/modules/source_control/gitlab/gitlab_user.py

Remove no_log

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

* Update changelogs/fragments/2691-gitlab_user-support-identity-provider.yml

Update syntax

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

* Update plugins/modules/source_control/gitlab/gitlab_user.py

Update syntax

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

* Update docs

* Add functionality to add multiple identities at once

* Fix identity example

* Add suboptions

* Add elements

* Update plugins/modules/source_control/gitlab/gitlab_user.py

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

* Apply comma's at the end of dictionaries

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

* Add check mode

* Change checkmode for user add and identity delete

* Update plugins/modules/source_control/gitlab/gitlab_user.py

* Update changelogs/fragments/2691-gitlab_user-support-identity-provider.yml

Add more features to changelog as suggested here https://github.com/ansible-collections/community.general/pull/2691#discussion_r653250717

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

* Add better description for identities list and overwrite_identities boolean

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

Co-authored-by: lennert.mertens <lennert.mertens@nubera.eu>
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: stef.graces <stef.graces@nubera.eu>
Co-authored-by: Stef Graces <stefgraces@hotmail.com>
Co-authored-by: Stef Graces <sgraces@sofico.be>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
(cherry picked from commit d6d0b6f0c1)

Co-authored-by: Lennert Mertens <lennert.mertens@gmail.com>
2021-06-21 21:55:34 +02:00
patchback[bot]
20bda07aaf gem_module: Add bindir option (#2837) (#2851)
* gem_module: Add bindir option

This option allows to specify directory to install executables, e.g.
`/home/user/bin` or `/home/user/.local/bin`. This comes especially handy
when used with user_install option as the default path of executables is
not in PATH.

* Update changelogs/fragments/gem_module_add_bindir_option.yml

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* gem_module: Integration tests for bindir option

* gem_module: Update Integration tests for bindir option

* gem_module: Update Integration tests for bindir option

Make sure gist is not installed system-wide prior the tests

* Revert "gem_module: Update Integration tests for bindir option"

This reverts commit 04eec6db27.

* Do not check "install_gem_result is changed" for ansible develop on openSUSE

* Revert "Do not check "install_gem_result is changed" for ansible develop on openSUSE"

This reverts commit 48ecb27889.

* gem_module: Use --norc to avoid surprises

Run install and uninstall actions with `--norc`. This way ansible has
more control over the way gems are installed.

* Revert "gem_module: Use --norc to avoid surprises"

This reverts commit 66f40bcfe6.

* gem_module: bindir - Ignore openSUSE Leap

* Update plugins/modules/packaging/language/gem.py

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

* gem_module: Use --norc to avoid surprises

Run install and uninstall actions with `--norc` when supported (rubygems >= 2.5.2).
This way ansible has more control over the way gems are installed.

* Try distutils.version instead of packaging

* ver is an list, not string

* ver is not list either but tuple

* Update changelogs/fragments/gem_module_add_bindir_option.yml

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* ver can be None (when can this happen?)

* gem: Add norc option

* Apply suggestions from code review

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

* Update plugins/modules/packaging/language/gem.py

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

* Use tuples to compare versions

* Apply suggestions from code review

Co-authored-by: Amin Vakil <info@aminvakil.com>

* Update plugins/modules/packaging/language/gem.py

Co-authored-by: Amin Vakil <info@aminvakil.com>

* lost norc option check is back

* Move handling norc option to separate function

* cosmetic

* fix for the previos commit

* Apply suggestions from code review

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

* Cache result of get_rubygems_version

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit ce35d88094)

Co-authored-by: Stanislav German-Evtushenko <ginermail@gmail.com>
2021-06-21 12:41:40 +02:00
patchback[bot]
1f6aa62210 serverless - deprecating unused param (#2845) (#2847)
* deprecating unused param

* added changelog fragment

* deprecate param in arg_spec

* Update plugins/modules/cloud/misc/serverless.py

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-06-20 12:14:37 +00:00
patchback[bot]
5308f61b78 ali_instance_info - marked parameters for deprecation in c.g. 5.0.0 (#2844) (#2848)
* marked parameters for deprecation in c.g. 5.0.0

* added changelog fragment

* deprecate params in arg_spec

* doc adjusment per PR

(cherry picked from commit 519411e026)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-06-20 12:14:28 +00:00
patchback[bot]
29636c1cc8 proxmox_kvm: Fix ZFS device string parsing (#2841) (#2846)
ZFS-backed block devices may contain just the bare device name and
not have extra options like `,size=foo`, `,format=qcow2` etc. This
breaks an assumption in existing regex (which expects a comma).

Support such device strings and add a couple of testcases to validate.

(cherry picked from commit db713bd0f5)

Co-authored-by: Anup Chenthamarakshan <anupcshan@users.noreply.github.com>
2021-06-20 13:05:16 +02:00
patchback[bot]
830734d6cf Nmcli add options (#2732) (#2842)
* [nmcli] add new network configuration options

* [nmcli_add_options] add documentation for new parameters nad add disabled method for IPv6

* [nmcli] fix and version adding. Add changelog fragment

* Update plugins/modules/net_tools/nmcli.py

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

* Update changelogs/fragments/2732-nmcli_add_options.yml

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

* Update changelogs/fragments/2732-nmcli_add_options.yml

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

* [nmcli_add_options] fix testing

* Update plugins/modules/net_tools/nmcli.py

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

* Update plugins/modules/net_tools/nmcli.py

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

* Update changelogs/fragments/2732-nmcli_add_options.yml

Co-authored-by: Amin Vakil <info@aminvakil.com>

* Update plugins/modules/net_tools/nmcli.py

Co-authored-by: Amin Vakil <info@aminvakil.com>

* Update plugins/modules/net_tools/nmcli.py

Co-authored-by: Amin Vakil <info@aminvakil.com>

* Update plugins/modules/net_tools/nmcli.py

Co-authored-by: Amin Vakil <info@aminvakil.com>

Co-authored-by: Oriol MULA VALLS <oriol.mula@lxp.lu>
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit 67cabcb2aa)

Co-authored-by: omula <joriol.mula@gmail.com>
2021-06-19 15:00:21 +02:00
patchback[bot]
0296c200c7 npm - fix updating version specific modules (#2830) (#2839)
* npm - fix updating version specific modules

if a version specific module is used, the comparison will be used with the version and not only by name

* Update plugins/modules/packaging/language/npm.py

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update changelogs/fragments/2830-npm-version-update.yml

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>

* Update changelogs/fragments/2830-npm-version-update.yml

Co-authored-by: Amin Vakil <info@aminvakil.com>

* Update changelogs/fragments/2830-npm-version-update.yml

Co-authored-by: Amin Vakil <info@aminvakil.com>

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit 1ed4394c5e)

Co-authored-by: Shahar Mor <shaharmor1@gmail.com>
2021-06-18 22:50:24 +02:00
patchback[bot]
2b435a591d fix sudorule_add_allow_command_group (#2821) (#2833)
* fix sudorule_add_allow_command_group

fix sudorule_add_allow_command_group is not working on freeIPA 4.8.7 at least, sudorule_add_allow_command should be used instead with item sudocmdgroup

* Added changelog fragment

(cherry picked from commit ee23c26150)

Co-authored-by: TizeN85 <tenou.sylvain@outlook.com>
2021-06-17 19:43:12 +02:00
patchback[bot]
ec2c793b08 datadog_event : Adding api_host as an optional parameter (#2775) (#2831)
* 2774 Module datadog_event _ Adding api_host as an optional parameter

* Update changelogs/fragments/2774-datadog_event_api_parameter.yml

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

* Update plugins/modules/monitoring/datadog/datadog_event.py

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

* Update datadog_event.py

* Update datadog_event.py

* Update datadog_event.py

* Update datadog_event.py

* Update datadog_event.py

* Update datadog_event.py

* Update datadog_event.py

* Update datadog_event.py

* Update plugins/modules/monitoring/datadog/datadog_event.py

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

* Update plugins/modules/monitoring/datadog/datadog_event.py

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

* Update plugins/modules/monitoring/datadog/datadog_event.py

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

* Update plugins/modules/monitoring/datadog/datadog_event.py

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

* Update plugins/modules/monitoring/datadog/datadog_event.py

Co-authored-by: Amin Vakil <info@aminvakil.com>

* Update plugins/modules/monitoring/datadog/datadog_event.py

Co-authored-by: Amin Vakil <info@aminvakil.com>

Co-authored-by: Anas Hamadeh <anas.hamadeh@klarna.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit c9cf641188)

Co-authored-by: Anas <anas.flm.h@hotmail.com>
2021-06-17 19:43:02 +02:00
patchback[bot]
a6bffa274c flatpak - allow to add/remove multiple flatpaks at once (#2521) (#2822)
* reviving flatpack PR

* added changelog fragment

* adjusted integration tests per PR

* adjusted examples to use the full name of the module

* Use new local artifacts.

* Re-add StrictVersion import.

* Try to clean up PR.

* ...

* Use original name in installed/not installed list.

* More fixes.

* Work around flatpak bug.

* Fix bug I introduced.

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-06-17 19:05:05 +02:00
patchback[bot]
b653a9a84a Update README (#2802) (#2829)
* Update README

* Update README.md

Co-authored-by: Amin Vakil <info@aminvakil.com>

* Change

* Fix

* Update README.md

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

* Update README.md

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

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Update README.md

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

Co-authored-by: Amin Vakil <info@aminvakil.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit e9f3455b62)

Co-authored-by: Andrew Klychkov <aklychko@redhat.com>
2021-06-17 13:39:03 +02:00
patchback[bot]
8c209bdedc Rename test_pr_quick_start_guide.rst to test_pr_locally_guide.rst (#2823) (#2826)
(cherry picked from commit 13ab8f412d)

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-06-17 13:38:27 +02:00
patchback[bot]
d4b4370ec4 pamd: Add a note in docs about authselect profiles (#2815) (#2820)
pamd module does not handle or modify authselect profiles
which are basically template files for authselect. The autheselect
generates pam.d files from these profiles.

Fixes: #1954

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
(cherry picked from commit 4a47d121aa)

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2021-06-16 22:25:39 +02:00
patchback[bot]
e34276fa92 callback_splunk - Add user-configurable event correlation id (#2790) (#2817)
* Initial commit

* Adding changelog fragment

* Updating batch description

* Update plugins/callback/splunk.py

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

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

Co-authored-by: Ajpantuso <ajpantuso.github@gmail.com>
2021-06-16 21:02:00 +02:00
patchback[bot]
59d7850900 redhat_subscription: Add server_prefix and server_port as supported arguments (#2779) (#2814)
* Add server_prefix and server_port as supported arguments for the redhat_subscription module.

* Adjust the argument sequence in the test case to be consistent with the original code in line 364 in redhat_subscription.py and add the changelog fragment.

* Grammatical changes such as adding full stops and using 'an HTTP' instead of 'a HTTP'.

* Commit the suggested changelog update.

Co-authored-by: Amin Vakil <info@aminvakil.com>

* Fix typo.

Co-authored-by: Amin Vakil <info@aminvakil.com>

Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit 2f2f384b4e)

Co-authored-by: Tong He <68936428+unnecessary-username@users.noreply.github.com>
2021-06-16 09:39:52 +02:00
patchback[bot]
151b482fe6 Add Test PRs locally section to CONTRIBUTING.md (#2738) (#2813)
* Add Test PRs locally section to CONTRIBUTING.md

* fix formatting

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

* Adjust PR now that ansible-collections/community-docs#16 has been merged

* improve sentence

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>
(cherry picked from commit adf50b106a)

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-06-15 20:20:36 +02:00
patchback[bot]
ea04bb97cb BOTMETA.yml: grant supershipit (#2807) (#2811)
(cherry picked from commit b1b34ee12e)

Co-authored-by: Andrew Klychkov <aklychko@redhat.com>
2021-06-15 19:11:27 +02:00
patchback[bot]
5dd64a45de BOTMETA.yml: supershipit to quidame (#2801) (#2806)
(cherry picked from commit bccf317814)

Co-authored-by: Andrew Klychkov <aklychko@redhat.com>
2021-06-14 21:00:13 +02:00
patchback[bot]
4df33d26b1 timezone: change warning to debug (#2789) (#2803)
* timezone: change warning to debug

Convert warning message to debug when timedatectl found but not usable.

Fixes: #1942

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>

* add changelog entry

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
(cherry picked from commit 0bd345bfb0)

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2021-06-14 19:11:39 +02:00
patchback[bot]
766f2dfe46 Make extra sanity test runner produce ansibullbot and JUnit output. (#2794) (#2800)
(cherry picked from commit a55c96d5c1)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-14 07:57:43 +02:00
patchback[bot]
8a7128997d CI: Remove scripts that are no longer needed (#2793) (#2796)
* Remove scripts that are no longer needed.

ci_complete

* Remove sanity ignores.

(cherry picked from commit d4c4d00ad1)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-14 04:09:27 +00:00
patchback[bot]
b598ca28f9 Documentation fix for access_level parameter of gitlab_runner (#2788) (#2792)
* * Documentation fix for access_level parameter of gitlab_runner

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Address reviewer's comments

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>
(cherry picked from commit 343339655d)

Co-authored-by: Alina Buzachis <abuzachis@redhat.com>
2021-06-13 09:08:36 +02:00
patchback[bot]
c943f7aa56 scaleway: Misc doc changes (#2776) (#2786)
* Updated example section for ``variables``
* Added link about token generation
* Misc changes in doc

Fixes: #467

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
(cherry picked from commit 4b37b1bca6)

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2021-06-11 19:29:02 +02:00
patchback[bot]
9565be5e50 yum_versionlock: enable fedora34 integration test (#2543) (#2784)
* Re-enable Fedora 34

* Update procps-ng before anything in yum_versionlock integration test

* Move procps-ng installation to block

* Revert "Move procps-ng installation to block"

This reverts commit 3aa873a110.

* Update procps-ng only on Fedora 34

(cherry picked from commit 19549058ce)

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-06-11 19:28:48 +02:00
patchback[bot]
725e670b47 [scaleway inventory] Fix JSON object must be str, not 'bytes' (#2771) (#2783)
* Fix JSON object decoding

* Code improvement : python 3.5 fix

* Add changelog fragment

* Update changelogs/fragments/2771-scaleway_inventory_json_accept_byte_array.yml

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

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

Co-authored-by: Loïc <loic.latreille@gmail.com>
2021-06-11 13:23:41 +02:00
patchback[bot]
ffdef00a6a add inventory plugin unit test test_verify_file (#2773) (#2777)
* add inventory plugin unit test `test_verify_file`

* fix typos in `test_verify_file_bad_config` unit test

(cherry picked from commit f44300cec5)

Co-authored-by: Rémy Keil <remy.keil@gmail.com>
2021-06-10 22:26:28 +02:00
Felix Fontein
92ccc6f013 Next expected release is 3.3.0. 2021-06-08 15:24:40 +02:00
Felix Fontein
f0c1b1065a Release 3.2.0. 2021-06-08 14:47:09 +02:00
patchback[bot]
a44356c966 Add domain option to onepassword lookup (#2735) (#2760)
* Add domain to onepassword lookup

* Add changelog

* Add default to domain documentation

* Improve format

* Fix sanity issue

* Add option type to documentation

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

* Add domain to init

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

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-06-08 12:09:49 +02:00
patchback[bot]
33f9f0b05f with great powers come great responsibility (#2755) (#2759)
(cherry picked from commit eef645c3f7)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-06-08 10:59:02 +02:00
patchback[bot]
f0f0704d64 Fixed sanity checks for cloud/scaleway/ modules (#2678) (#2756)
* fixed validation-modules for plugins/modules/cloud/scaleway/scaleway_image_info.py

* fixed validation-modules for plugins/modules/cloud/scaleway/scaleway_ip_info.py

* fixed validation-modules for plugins/modules/cloud/scaleway/scaleway_security_group_info.py

* fixed validation-modules for plugins/modules/cloud/scaleway/scaleway_server_info.py

* fixed validation-modules for plugins/modules/cloud/scaleway/scaleway_snapshot_info.py

* fixed validation-modules for plugins/modules/cloud/scaleway/scaleway_volume_info.py

* sanity fix

(cherry picked from commit 9f344d7165)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-06-08 10:58:36 +02:00
Felix Fontein
55fe140230 Prepare 3.2.0 release. 2021-06-08 09:27:27 +02:00
patchback[bot]
ac543f5ef0 flatpak: add tests in CI, add no_dependencies parameter (#2751) (#2754)
* Similar version restrictions than flatpak_remote tests.

* ...

* Try to work around missing dependencies.

* Revert "Try to work around missing dependencies."

This reverts commit 66a4e38566.

* Add changelog.

* App8 -> App2; make sure that there are two apps App1 and App2.

* Fix forgotten variabe.

* Remove test notices.

* Seems like flatpak no longer supports file:// URLs.

The tests would need to be rewritten to offer the URL via http:// instead.

* Try local HTTP server for URL tests.

* ...

* Lint, add status check.

* Add boilerplate.

* Add 'ps aux'.

* Surrender to -f.

* Work around apparent flatpak bug.

* Fix YAML.

* Improve condition.

* Make sure test reruns behave better.

(cherry picked from commit bb37b67166)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-08 09:14:10 +02:00
patchback[bot]
dbc0fe8859 zypper_repository: fix idempotency on adding repo with releasever and basearch variables (#2722) (#2753)
* zypper_repository: Check idempotency on adding repo with releasever

* Name required when adding non-repo files.

* Initial try to fix releasever

* Replace re.sub with .replace

* name releaseverrepo releaseverrepo

* Change  to ansible_distribution_version for removing repo

* improve asserts format

* add changelog

* Fix changelog formatting

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

* improve command used for retrieving releasever variable

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

* add basearch replace

* Add basearch to changelog fragment

* Check for releasever and basearch only when they are there

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

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-06-08 08:47:15 +02:00
patchback[bot]
42a1318fe3 Re-enable flatpak_remote tests (#2747) (#2749)
* Automate test repo creation, re-enable flatpak_remote tests.

* Linting.

* Another try.

(cherry picked from commit 4c50f1add7)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-07 21:39:17 +02:00
patchback[bot]
d25352dc06 Remove aminvakil from supershipit section as it is not needed anymore (#2743) (#2746)
(cherry picked from commit 7c3f2ae4af)

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-06-07 17:02:17 +02:00
patchback[bot]
55682c52df Add aminvakil to committers (#2739) (#2742)
(cherry picked from commit 1e34df7ca0)

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-06-07 16:01:30 +02:00
patchback[bot]
46781d9fd1 [PR #2731/6a41fba2 backport][stable-3] ModuleHelper - also uses LC_ALL to force language (#2736)
* ModuleHelper - also uses LC_ALL to force language (#2731)

* also uses LC_ALL to force language

* adjusted test_xfconf and test_cpanm

* added changelog fragment

* Update changelogs/fragments/2731-mh-cmd-locale.yml

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

* adjusted chglog frag per PR

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

* snap revamp hasn't been backported yet.

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-07 13:27:30 +02:00
patchback[bot]
4545d1c91e Bugfix + sanity checks for stacki_host (#2681) (#2733)
* fixed validation-modules for plugins/modules/remote_management/stacki/stacki_host.py

* sanity fix

* added changelog fragment

* extra fix to the documentation

* Update plugins/modules/remote_management/stacki/stacki_host.py

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

* Update plugins/modules/remote_management/stacki/stacki_host.py

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

* rollback params

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-06-07 08:17:04 +02:00
patchback[bot]
6570dfeb7d iptables_state: fix async status call (-> action plugin) (#2711) (#2729)
* fix call to async_status (-> action plugin)

* add changelog fragment

* Apply suggestions from code review

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

* rename a local variable for readability

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

Co-authored-by: quidame <quidame@poivron.org>
2021-06-06 18:10:29 +02:00
patchback[bot]
94c368f7df open_iscsi: allow same target selected portals login and override (#2684) (#2727)
* fix: include portal and port for logged on check

* refactor: remove extra space

* fix: allow None portal and port on target_loggedon test

* add auto_portal_startup argument

* fix: change param name for automatic_portal

* add changelog fragment

* refactor: Update changelogs/fragments/2684-open_iscsi-single-target-multiple-portal-overrides.yml

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

* add version added info to auto_portal_startup arg

* add example for auto_portal_startup

* fix: remove alias for auto_portal form arg_spec as well

* refactor: elaborate in fragment changelogs

Elaborate change

Co-authored-by: Amin Vakil <info@aminvakil.com>

* open_iscsi: elaborate changelog fragment

* Update plugins/modules/system/open_iscsi.py

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

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit 9d8bea9d36)

Co-authored-by: The Binary <binary4bytes@gmail.com>
2021-06-05 23:04:03 +02:00
patchback[bot]
4cba1e60d9 Wire token param into consul_api #2124 (#2126) (#2726)
* Wire token param into consul_api #2124

* Update changelogs/fragments/2124-consul_kv-pass-token.yml

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* #2124 renamed release fragment to match pr, removed parse_params.

* putting look back in, do some linting   #2124

* try more linting

* linting

* try overwriting defaults in parse_params with get_option vals, instead of removing that function completely.

* Revert "back to start, from 2nd approach: allow keyword arguments via parse_params for compatibility."

This reverts commit 748be8e366.

* Revert " linting"

This reverts commit 1d57374c3e.

* Revert " try more linting"

This reverts commit 91c8d06e6a.

* Revert "putting look back in, do some linting   #2124"

This reverts commit 87eeec7180.

* Revert " #2124 renamed release fragment to match pr, removed parse_params."

This reverts commit d2869b2f22.

* Revert "Update changelogs/fragments/2124-consul_kv-pass-token.yml"

This reverts commit c50b1cf9d4.

* Revert "Wire token param into consul_api #2124"

This reverts commit b60b6433a8.

* minimal chnages for this PR relative to current upstream.

* superfluous newline in changlog fragment.

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
(cherry picked from commit 0e6d70697c)

Co-authored-by: fkuep <flo.kuepper@gmail.com>
2021-06-05 23:03:53 +02:00
patchback[bot]
321fb6c974 Reduce stormssh searches based on host (#2568) (#2724)
* Reduce stormssh searches based on host

Due to the stormssh searches in the whole config values, we need to reduce the search results based on the full matching of the hosts

* Removed whitespaces in the blank line

* Added changelog fragment and tests for the fix.

* Added newline at the end of the changelog fragment

* Added newline at the end of the tests

* Fixed bug with name in tests

* Changed assertion for the existing host

* Update changelogs/fragments/2568-ssh_config-reduce-stormssh-searches-based-on-host.yml

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

* Adjusted tests

* New line at the end of the tests

Co-authored-by: Anton Nikolaev <anikolaev@apple.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 1a4af9bfc3)

Co-authored-by: Anton Nikolaev <drenout@gmail.com>
2021-06-05 18:03:14 +02:00
patchback[bot]
eb4d7a4199 Terraform: ensure workspace is reset to current value (#2634) (#2720)
* fix: ensure workspace is reset to current value

* chore: linter

* chore: changelog

(cherry picked from commit c49a384a65)

Co-authored-by: christophemorio <49184206+christophemorio@users.noreply.github.com>
2021-06-04 21:12:53 +02:00
patchback[bot]
4b07d45b7e Fix repeated word in description of fs_type (#2717) (#2719)
(cherry picked from commit a343756e6f)

Co-authored-by: Alex Willmer <al.willmer@cgi.com>
2021-06-04 21:12:40 +02:00
Felix Fontein
d4a33433b4 Mention removal version more prominently. 2021-06-04 12:37:04 +02:00
patchback[bot]
e30b91cb8d Add new module/plugin maintainers to BOTMETA. (#2708) (#2712)
(cherry picked from commit d49783280e)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-04 11:13:32 +02:00
patchback[bot]
b2b65c431b Fix action plugin BOTMETA entries. (#2707) (#2714)
(cherry picked from commit 4396ec9631)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-04 11:13:22 +02:00
Felix Fontein
9ade4f6dd6 Announce script removal. (#2697) 2021-06-04 10:38:04 +02:00
patchback[bot]
635d4f2138 Fix spurious test errors. (#2709) (#2710)
(cherry picked from commit 2e8746a8aa)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-04 10:24:55 +02:00
patchback[bot]
6549e41ab8 Add module sapcar_extract to make SAP administration easier. (#2596) (#2705)
* add sapcar

* integrate test

* test integration

* Revert "integrate test"

This reverts commit 17cbff4f02.

* add requiered

* change test

* change binary

* test

* add bin bath

* change future

* change download logic

* change logic

* sanity

* Apply suggestions from code review

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

* add url and error handling

* sanity

* Apply suggestions from code review

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Apply suggestions from code review

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

* cleanup and fixes

* sanity

* add sec library

* add description

* remove blanks

* sanity

* Apply suggestions from code review

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

Co-authored-by: Rainer Leber <rainer.leber@sva.de>
Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>
(cherry picked from commit a4f46b881a)

Co-authored-by: rainerleber <39616583+rainerleber@users.noreply.github.com>
2021-06-04 07:55:41 +02:00
patchback[bot]
6faface39e add module pacman_key (#778) (#2704)
* add module pacman_key

* add symlink and fix documentation for pacman_key

* documentation fix for pacman_key

* improve logic around user input

* Update plugins/modules/packaging/os/pacman_key.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/packaging/os/pacman_key.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/packaging/os/pacman_key.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/packaging/os/pacman_key.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/packaging/os/pacman_key.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/packaging/os/pacman_key.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/packaging/os/pacman_key.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/packaging/os/pacman_key.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/packaging/os/pacman_key.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Update plugins/modules/packaging/os/pacman_key.py

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>

* Improve parameter checking

required_one_of=[] is neat.

Co-authored-by: Alexei Znamensky

* Revert "Improve parameter checking"

This reverts commit 044b0cbc85.

* Simplify a bunch of code.

* fix typos pointed out by yan12125

* replaced manual checks with required-if invocation

* added default keyring to documentation

* some initial tests

* updated metadata

* refactored to make sanity tests pass

* refactor to make sanity tests pass ... part deux

* refactor: simplify run_command invocations

* test: cover check-mode and some normal operation

* docs: fix grammatical errors

* rip out fingerprint code

a full length (40 characters) key ID is equivalent to the fingerprint.

* refactor tests, add a couple more

* test: added testcase for method: data

* Update plugins/modules/packaging/os/pacman_key.py

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>

* docs: correct yaml boolean type

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

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 5ddf0041ec)

Co-authored-by: George Rawlinson <george@rawlinson.net.nz>
2021-06-04 07:36:29 +02:00
patchback[bot]
3b893ec421 BOTMETA.yml: remove myself from zypper_repository (#2701) (#2703)
(cherry picked from commit d93bc039b2)

Co-authored-by: Matthias Vogelgesang <matthias.vogelgesang@gmail.com>
2021-06-04 04:40:31 +00:00
patchback[bot]
65805e2dd6 keycloak_realm.py: Mark 'reset_password_allowed' as no_log=False (#2694) (#2698)
* keycloak_realm.py: Mark 'reset_password_allowed' as no_log=False

This value is not sensitive but Ansible will complain about it otherwise

* fixup! keycloak_realm.py: Mark 'reset_password_allowed' as no_log=False

* Apply all suggestions from code review

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

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

Co-authored-by: Benjamin Schubert <contact@benschubert.me>
2021-06-03 22:17:50 +02:00
patchback[bot]
297b50fb96 keycloak_realm.py: Fix the ssl_required parameter according to the API (#2693) (#2699)
* keycloak_realm.py: Fix the `ssl_required` parameter according to the API

The `ssl_required` parameter is a string and must be one of 'all',
'external' or 'none'. Passing a bool will make the server return a 500.

* fixup! keycloak_realm.py: Fix the `ssl_required` parameter according to the API

* Update changelogs/fragments/keycloak_realm_ssl_required.yml

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

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

Co-authored-by: Benjamin Schubert <contact@benschubert.me>
2021-06-03 22:14:59 +02:00
patchback[bot]
2edadb42fb Added SHA1 option to maven_artifact (#2662) (#2690)
* Added SHA1 option

* Add changelog fragment

* Update plugins/modules/packaging/language/maven_artifact.py

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

* Update plugins/modules/packaging/language/maven_artifact.py

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

* Combined hash functions

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

* Update plugins/modules/packaging/language/maven_artifact.py

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

* Update plugins/modules/packaging/language/maven_artifact.py

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

* Removed unused functions (rolled into _local_checksum)

* Update changelogs/fragments/2661-maven_artifact-add-sha1-option.yml

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

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

Co-authored-by: Gene Gotimer <eugene.gotimer@steampunk.com>
2021-06-01 22:23:08 +02:00
patchback[bot]
4e1bf2d4ba nmcli: new arguments to ignore automatic dns servers and gateways (#2635) (#2689)
* nmcli: new arguments to ignore automatic dns servers and gateways

Closes #1087

* Add changelog fragment

* Address review comments

(cherry picked from commit 1ad85849af)

Co-authored-by: Chih-Hsuan Yen <yan12125@gmail.com>
2021-06-01 22:17:19 +02:00
patchback[bot]
b1a4a0ff21 Add filter docs (#2680) (#2687)
* Began with filter docs.

* Add more filters.

* Add time unit filters.

* Add TOC and filters to create identifiers.

* Add more filters.

* Add documentation from ansible/ansible for json_query and random_mac.

* Update docs/docsite/rst/filter_guide.rst

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
(cherry picked from commit 3516acf8d4)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-06-01 20:38:12 +02:00
patchback[bot]
e74ea7c8b8 archive - Adding exclusion_patterns option (#2616) (#2686)
* Adding exclusion_patterns option

* Adding changelog fragment and Python 2.6 compatability

* Minor refactoring for readability

* Removing unneccessary conditional

* Applying initial review suggestions

* Adding missed review suggestion

(cherry picked from commit b6c0cc0b61)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-05-31 08:16:40 +02:00
patchback[bot]
6590f5e082 Fixed sanity checks for cloud/online/ modules (#2677) (#2679)
* fixed validation-modules for plugins/modules/cloud/online/online_server_info.py

* fixed validation-modules for plugins/modules/cloud/online/online_user_info.py

* sanity fix

(cherry picked from commit bef3c04d1c)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-29 17:08:56 +02:00
patchback[bot]
7483f71d31 iptables_state: fix broken query of async_status result (#2671) (#2676)
* use get() rather than querying the key directly

* add a changelog fragment

* re-enable CI tests

* Update changelog fragment

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

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

Co-authored-by: quidame <quidame@poivron.org>
2021-05-29 13:58:03 +02:00
patchback[bot]
6b215e3a9c proxmox_kvm - Fixed vmid result when VM with name exists (#2648) (#2674)
* Fixed vmid result when VM with name exists

* Adding changelog fragment

(cherry picked from commit b281d3d699)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-05-29 10:50:11 +02:00
patchback[bot]
3723e458d3 composer: add composer_executable (#2650) (#2670)
* composer: add composer_executable

* Add changelog

* Improve documentation thanks to felixfontein

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

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

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-05-28 13:24:44 +02:00
patchback[bot]
0f8bb43723 Stop mentioning Freenode. We're on Libera.chat. (#2666) (#2669)
(cherry picked from commit 14813a6287)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-28 07:29:02 +02:00
patchback[bot]
f33530dd61 Add extra docs tests (#2663) (#2665)
* Add extra docs tests.

* Linting.

* Fix copy'n'paste error.

(cherry picked from commit 14f13904d6)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-28 06:49:01 +02:00
patchback[bot]
8f3043058e Fix drain example with correct wait values (#2603) (#2658)
(cherry picked from commit 95794f31e3)

Co-authored-by: Merouane Atig <merwan@users.noreply.github.com>
2021-05-27 20:18:19 +02:00
patchback[bot]
3987b8a291 xml: Add an example for absent (#2644) (#2656)
Element node can be deleted based upon the attribute
value.

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
(cherry picked from commit 795125fec4)

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2021-05-27 20:18:07 +02:00
patchback[bot]
f7403a0b34 random_string: a new lookup plugin (#2572) (#2659)
New lookup plugin to generate random string based upon
constraints.

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
(cherry picked from commit 43c12b82fa)

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2021-05-27 20:16:50 +02:00
patchback[bot]
0a676406b3 minor refactors on plugins/modules/cloud/misc (#2557) (#2660)
* minor refactors on plugins/modules/cloud/misc

* added changelog fragment

* removed unreachable statement

* Update plugins/modules/cloud/misc/terraform.py

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

* Update plugins/modules/cloud/misc/rhevm.py

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

* adjusted per PR comment

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-27 20:15:49 +02:00
patchback[bot]
5a7d234d80 Terraform overwrite init (#2573) (#2654)
* feat: implement overwrite_init option

* chore: changelog

(cherry picked from commit 285639a4f9)

Co-authored-by: christophemorio <49184206+christophemorio@users.noreply.github.com>
2021-05-27 20:15:33 +02:00
patchback[bot]
fb9730f75e meta/runtime.yml and __init__.py cleanup (#2632) (#2653)
* Remove superfluous __init__.py files.

* Reformat and sort meta/runtime.yml.

* The ovirt modules have been removed.

* Add changelog entry.

(cherry picked from commit 7cd96d963e)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-27 20:15:22 +02:00
patchback[bot]
928aeafe1d hana_query module: add a maintainer (#2647) (#2652)
(cherry picked from commit dc793ea32b)

Co-authored-by: Andrew Klychkov <aklychko@redhat.com>
2021-05-27 19:07:11 +02:00
patchback[bot]
5b68665571 Add module hana_query to make SAP HANA administration easier. (#2623) (#2651)
* new

* move link

* Apply suggestions from code review

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

* add more interesting return value in test

* remove unused objects

* removed unneeded function

* extend test output

* Update tests/unit/plugins/modules/database/saphana/test_hana_query.py

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

Co-authored-by: Rainer Leber <rainer.leber@sva.de>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit b79969da68)

Co-authored-by: rainerleber <39616583+rainerleber@users.noreply.github.com>
2021-05-27 19:07:04 +02:00
patchback[bot]
e6b84acd1e fix a regression in initialization_from_null_state() (iptables-nft > 1.8.2) (#2604) (#2646)
(cherry picked from commit 909e9fe950)

Co-authored-by: quidame <quidame@poivron.org>
2021-05-27 07:16:36 +00:00
patchback[bot]
c242993291 Temporarily disable iptables_state tests. (#2641) (#2643)
(cherry picked from commit b45298bc43)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-27 08:28:45 +02:00
patchback[bot]
4f3de5658e Add one-liner lookup example (#2615) (#2638)
* Add one-liner lookup example

* Remove trailing whitespace

* Update plugins/lookup/tss.py

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

* Update plugins/lookup/tss.py

Co-authored-by: Amin Vakil <info@aminvakil.com>

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit 26757edfb2)

Co-authored-by: Sylvia van Os <sylvia@hackerchick.me>
2021-05-27 08:25:49 +02:00
patchback[bot]
301fcc3b7e influxdb_user: Fix bug introduced by PR 2499 (#2614) (#2640)
* Update influxdb_user.py

Fixed function name

* Create 2614-influxdb_user-fix-issue-introduced-in-PR#2499

Added changelog

* Rename 2614-influxdb_user-fix-issue-introduced-in-PR#2499 to 2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml

Fixed extension

* Update changelogs/fragments/2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml

Co-authored-by: Amin Vakil <info@aminvakil.com>

Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit 4aa50962cb)

Co-authored-by: sgalea87 <43749726+sgalea87@users.noreply.github.com>
2021-05-27 08:23:21 +02:00
patchback[bot]
0f0e9b2dca Use become test framework for sudosu tests. (#2629) (#2631)
(cherry picked from commit 0b4a2bea01)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-26 10:48:33 +02:00
patchback[bot]
ed0636dc27 redis cache - better parsing of connection uri (#2579) (#2622)
* better parsing of connection uri

* added changelog fragment

* fixed tests for ansible 2.9

* Update tests/unit/plugins/cache/test_redis.py

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

* Update tests/unit/plugins/cache/test_redis.py

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

* Adjustments from PR

* Update test_redis.py

* Update test_redis.py

* Update plugins/cache/redis.py

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

* Update plugins/cache/redis.py

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

* Update tests/unit/plugins/cache/test_redis.py

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-26 10:00:02 +02:00
patchback[bot]
057321c6c6 Add CONTRIBUTING.md (#2602) (#2626)
* Initial file shamelessly copied from community.mysql

* Add some notes on pull requests

* Add CONTRIBUTING.md link to README.md

* Add quick-start development guide link

* Apply felixfontein's suggestions

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

* add note about rebasing and merge commits

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

* add note about easyfix and waiting_on_contributor tags

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

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

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-05-26 09:59:52 +02:00
patchback[bot]
1a4814de53 ini_file - added note in documentation for utf-8 bom (#2599) (#2620)
* added note in documentation for utf-8 bom

* Update plugins/modules/files/ini_file.py

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-26 07:29:19 +02:00
patchback[bot]
89b67a014b jenkins_plugin: HTTP Error 405: Method Not Allowed on disable/enable plugin #2510 (#2511) (#2619)
* define POST method for pluginManager api requests

Jenkins makeEnable/makeDisable api requests requires to use POST method

* add changelog fragment

* fix my yoda lang thx to aminvakil

Co-authored-by: Amin Vakil <info@aminvakil.com>

* update changelog fragment

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

Co-authored-by: Amin Vakil <info@aminvakil.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 6df3685d42)

Co-authored-by: Alexander Moiseenko <brainsam@yandex.ru>
2021-05-26 07:22:03 +02:00
patchback[bot]
57bfbdc407 Use str() to get exception message (#2590) (#2611)
(cherry picked from commit 63012eef82)

Co-authored-by: DasSkelett <dasskelett@gmail.com>
2021-05-25 13:59:54 +02:00
patchback[bot]
e19dffbf29 json_query, no more 'unknown type' errors (#2607) (#2613)
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
(cherry picked from commit d871399220)

Co-authored-by: Brian Coca <bcoca@users.noreply.github.com>
2021-05-25 13:59:42 +02:00
patchback[bot]
113e7cdfa0 rhsm_release: Fix the issue that rhsm_release module considers 8, 7Client and 7Workstation as invalid releases (#2571) (#2606)
* rhsm_release: Fix the issue that rhsm_release module considers 8, 7Client and 7Workstation as invalid releases.

* Fix the unit test error: The new release_matcher could pass a wider range of patterns but that would not cause extra issue to the whole module.

* Submit the changelog fragment.

* Update changelogs/fragments/2571-rhsm_release-fix-release_matcher.yaml

Co-authored-by: Amin Vakil <info@aminvakil.com>

Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit 593d622438)

Co-authored-by: Tong He <68936428+unnecessary-username@users.noreply.github.com>
2021-05-24 20:28:18 +00:00
patchback[bot]
c12be67a69 ini_file - opening file as utf-8-sig (#2578) (#2591)
* opening file as utf-8-sig

* added changelog fragment

* using io.open()

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

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-22 22:42:02 +02:00
patchback[bot]
3a076fd585 Massive adjustment in integration tests for changed and failed (#2577) (#2584)
* Replaced ".changed ==" with "is [not] changed". Same for failed

* Mr Quote refused to go

(cherry picked from commit d7e55db99b)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-22 14:53:16 +02:00
patchback[bot]
4ef05a6483 ovir4 inventory script (#2461) (#2583)
* update configparser

* changelog

* handle multiple python version

* Update changelogs/fragments/2461-ovirt4-fix-configparser.yml

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

* Update ovirt4.py

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

Co-authored-by: abikouo <79859644+abikouo@users.noreply.github.com>
2021-05-22 14:36:50 +02:00
patchback[bot]
936dd28395 java_cert - fix incorrect certificate alias on pkcs12 import (#2560) (#2581)
* fix wrong certificate alias used when importing pkcs12, modify error output, stdout is more relevant than stderr

* add changelog fragment

* fix changelog fragment

(cherry picked from commit 8f083d5d85)

Co-authored-by: absynth76 <58172580+absynth76@users.noreply.github.com>
2021-05-22 13:46:32 +02:00
patchback[bot]
e3b47899c5 Add missing author name (#2570) (#2576)
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
(cherry picked from commit 852e240525)

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2021-05-21 19:44:08 +02:00
patchback[bot]
fd8193e0bd Add comment_visibility parameter for comment operation for jira module (#2556) (#2566)
* Add comment_visibility parameter for comment operation for jira module

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

* Update plugins/modules/web_infrastructure/jira.py

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

* Update plugins/modules/web_infrastructure/jira.py

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

* addressed pep8 E711

* Added missing parameter.

* params is not in use anymore.

* It appears other modules are using options, where in documentation they use suboptions. Inconsistancy?

* adjusted indentation

* tweaked suboptions, fixed documentation

* Added fragment

* Update changelogs/fragments/2556-add-comment_visibility-parameter-for-comment-operation-of-jira-module.yml

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

* Update plugins/modules/web_infrastructure/jira.py

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

Co-authored-by: felixfontein <felix@fontein.de>
(cherry picked from commit 7a169af053)

Co-authored-by: momcilo78 <momcilo@majic.rs>
2021-05-20 23:18:41 +02:00
patchback[bot]
fa477ebb35 ModuleHelper: CmdMixin custom function for processing cmd results (#2564) (#2565)
* MH: custom function for processing cmd results

* added changelog fragment

* removed case of process_output being a str

(cherry picked from commit 1403f5edcc)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-20 20:11:08 +02:00
patchback[bot]
43e766dd44 removed supporting code for testing module "nuage" - no longer exists here (#2559) (#2563)
(cherry picked from commit 452a185a23)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-19 22:23:36 +02:00
Felix Fontein
b25e0f360c Next release will be 3.2.0. 2021-05-18 15:00:48 +02:00
Felix Fontein
658e95c5ca Release 3.1.0. 2021-05-18 13:09:47 +02:00
patchback[bot]
26c2876f50 pacman: add 'executable' option to use an alternative pacman binary (#2524) (#2554)
* Add 'bin' option to use an alternative pacman binary

* Add changelog entry

* Incorporate recommendations

* Update plugins/modules/packaging/os/pacman.py

* Apply suggestions from code review

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

Co-authored-by: Andre Lehmann <aisberg@posteo.de>
2021-05-18 13:08:06 +02:00
patchback[bot]
62043463f3 iptables_state: fix per-table initialization command (#2525) (#2553)
* refactor initialize_from_null_state()

* Use a more neutral command (iptables -L) to load per-table needed modules.

* fix 'FutureWarning: Possible nested set at position ...' (re.sub)

* fix pylints (module + action plugin)

* unsubscriptable-object
* superfluous-parens
* consider-using-in
* unused-variable
* unused-import
* no-else-break

* cleanup other internal module_args if they exist

* add changelog fragment

* Apply suggestions from code review (changelog fragment)

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

* Remove useless plugin type in changelog fragment

Co-authored-by: Amin Vakil <info@aminvakil.com>

Co-authored-by: Felix Fontein <felix@fontein.de>
Co-authored-by: Amin Vakil <info@aminvakil.com>
(cherry picked from commit 2c1ab2d384)

Co-authored-by: quidame <quidame@poivron.org>
2021-05-18 12:27:31 +02:00
Felix Fontein
f1dab6d4a7 Prepare 3.1.0 release. 2021-05-18 11:57:35 +02:00
patchback[bot]
d43764da79 filesystem: revamp module (#2472) (#2550)
* revamp filesystem module to prepare next steps

* pass all commands to module.run_command() as lists
* refactor grow() and grow_cmd() to not need to override them so much
* refactor all existing get_fs_size() overrides to raise a ValueError if
  not able to parse command output and return an integer.
* override MKFS_FORCE_FLAGS the same way for all fstypes that require it
* improve documentation of limitations of the module regarding FreeBSD
* fix indentation in DOCUMENTATION
* add/update function/method docstrings
* fix pylint hints

filesystem: refactor integration tests

* Include *reiserfs* and *swap* in tests.
* Fix reiserfs related code and tests accordingly.
* Replace "other fs" (unhandled by this module), from *swap* to *minix*
  (both mkswap and mkfs.minix being provided by util-linux).
* Replace *dd* commands by *filesize* dedicated module.
* Use FQCNs and name the tasks.
* Update main tests conditionals.

* add a changelog fragment

* Apply suggestions from code review

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

* declare variables as lists when lists are needed

* fix construction without useless conversion

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

Co-authored-by: quidame <quidame@poivron.org>
2021-05-18 10:49:12 +02:00
patchback[bot]
de2feb2567 ModuleHelper - cmd params now taken from self.vars instead of self.module.params (#2517) (#2549)
* cmd params now taken from self.vars instead of self.module.params

* added changelog fragment

* Update changelogs/fragments/2517-cmd-params-from-vars.yml

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-18 06:36:02 +02:00
patchback[bot]
6e56bae0f3 influxdb_user: allow creation of first user with auth enabled (#2364) (#2368) (#2548)
* influxdb_user: allow creation of first user with auth enabled (#2364)

* handle potential exceptions while parsing influxdb client error

* fix changelog

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

* influxdb_user: use generic exceptions to be compatible with python 2.7

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

Co-authored-by: Xabier Napal <xabiernapal@pm.me>
2021-05-17 19:18:33 +00:00
patchback[bot]
1f7047e725 ModuleHelper - better mechanism for customizing "changed" behaviour (#2514) (#2546)
* better mechanism for customizing "changed" behaviour

* dont drink and code: silly mistake from late at night

* added changelog fragment

(cherry picked from commit 2a376642dd)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-17 20:50:43 +02:00
patchback[bot]
b2e4485567 java_keystore: pass in secret to keytool via stdin (#2526) (#2545)
* java_keystore: pass in secret to keytool via stdin

* add changelog fragment

(cherry picked from commit 2b1eff2783)

Co-authored-by: quidame <quidame@poivron.org>
2021-05-17 20:24:09 +02:00
patchback[bot]
b78254fe24 zfs_delegate_admin: drop choices from permissions (#2540) (#2544)
instead of whitelisting some subset of known existing permissions, just
allow any string to be used as permissions. this way, any permission
supported by the underlying zfs commands can be used, eg. 'bookmark',
'load-key', 'change-key' and all property permissions, which were
missing from the choices list.

(cherry picked from commit dc0a56141f)

Co-authored-by: Lauri Tirkkonen <lauri@hacktheplanet.fi>
2021-05-17 18:02:13 +00:00
patchback[bot]
38aa0ec8ad Add option missing to passwordstore lookup (#2500) (#2541)
Add ability to ignore error on missing pass file to allow processing the
output further via another filters (mainly the default filter) without
updating the pass file itself.

It also contains the option to create the pass file, like the option
create=true does.

Finally, it also allows to issue a warning only, if the pass file is not
found.

(cherry picked from commit 350380ba8c)

Co-authored-by: Jan Baier <7996094+baierjan@users.noreply.github.com>
2021-05-17 14:14:44 +02:00
patchback[bot]
42f28048a8 yum_versionlock: disable fedora34 integration test (#2536) (#2538)
* Disable yum_versionlock integration test on Fedora 34

* Remove --assumeyes and add a comment regarding this

* Update update task name

(cherry picked from commit da7e4e1dc2)

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-05-17 10:36:36 +02:00
patchback[bot]
b699aaff7b Use --assumeyes with explicit yum call. (#2533) (#2535)
(cherry picked from commit 2cc848fe1a)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-17 08:27:25 +02:00
patchback[bot]
af85b6c203 fix error when cache is disabled (#2518) (#2532)
(cherry picked from commit 448b8cbcda)

Co-authored-by: Dennis Israelsson <dennis.israelsson@gmail.com>
2021-05-17 08:09:58 +02:00
patchback[bot]
ec2e7cad3e Update influxdb_user.py Fixed Multiple No Privileges (#2499) (#2530)
* Update influxdb_user.py

Fixed Multiple No Privileges

* Update influxdb_user.py

Fixed line spaces

* Update influxdb_user.py

Fixed whitespace

* Create 2499-influxdb_user-fix-multiple-no-privileges.yml

Added changelog

(cherry picked from commit ea200c9d8c)

Co-authored-by: sgalea87 <43749726+sgalea87@users.noreply.github.com>
2021-05-17 08:09:48 +02:00
patchback[bot]
7753fa4219 1085 updating the hcl whitelist to include all supported options (#2495) (#2528)
* 1085 updating the hcl whitelist to include all supported options

* Update changelogs/fragments/1085-consul-acl-hcl-whitelist-update.yml

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

Co-authored-by: Dillon Gilmore <dgilmor@rei.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 5b77515308)

Co-authored-by: iridian <442359+iridian-ks@users.noreply.github.com>
2021-05-17 08:09:21 +02:00
patchback[bot]
69ea487005 Cleanup connections plugins (#2520) (#2522)
* minor refactors

* minor refactors in plugins/connection/saltstack.py

* minor refactors in plugins/connection/qubes.py

* minor refactor in plugins/connection/lxc.py

* minor refactors in plugins/connection/chroot.py

* minor refactors in plugins/connection/funcd.py

* minor refactors in plugins/connection/iocage.py

* minor refactors in plugins/connection/jail.py

* added changelog fragment

(cherry picked from commit c8f402806f)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-16 13:45:26 +02:00
patchback[bot]
048f15fe68 java_keystore: New ssl_backend option for cryptography (#2485) (#2513)
* Adding cryptography as a backend for OpenSSL operations

* Updating unit tests and adding changelog fragment

* Allowing private key password option when using unprotected key

* Incorporating suggestions from initial review

* Centralizing module exit path

(cherry picked from commit a385cbb11d)

Co-authored-by: Ajpantuso <ajpantuso@gmail.com>
2021-05-14 22:47:26 +02:00
patchback[bot]
aa1aa1d540 random_pet: Random pet name generator (#2479) (#2509)
A lookup plugin to generate random pet names based
upon criteria.

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
(cherry picked from commit 5d0a7f40f2)

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2021-05-14 16:25:40 +02:00
patchback[bot]
e78517ca93 proxmox_nic: set mtu on interface even if it's not virtio (#2505) (#2507)
* Set mtu on interface whatsoever

* add changelog fragment

* Revert "add changelog fragment"

This reverts commit 5f2f1e7feb.

(cherry picked from commit e2dfd42dd4)

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-05-14 16:24:47 +02:00
patchback[bot]
bf185573a6 gitlab_user: add expires_at option (#2450) (#2506)
* gitlab_user: add expires_at option

* Add changelog

* Add integration test

* Add expires_at to addSshKeyToUser function

* password is required if state is set to present

* Check expires_at will not be added to a present ssh key

* add documentation about present ssh key

* add expires_at to unit tests

* Improve documentation

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

* Only pass expires_at to api when it is not None

* Emphasize on SSH public key

* Apply felixfontein suggestion

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

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

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-05-14 10:34:47 +02:00
patchback[bot]
145435cdd9 Deprecate nios content (#2458) (#2504)
* Deprecate nios content.

* Make 2.9's ansible-test happy.

* Add module_utils deprecation.

(cherry picked from commit ee9770cff7)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-14 09:55:46 +02:00
patchback[bot]
6013c77c2b Add groupby_as_dict filter (#2323) (#2503)
* Add groupby_as_dict filter.

* Test all error cases.

(cherry picked from commit 384655e15c)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-14 09:47:53 +02:00
patchback[bot]
ad5482f63d Add proxmox_nic module (#2449) (#2502)
* Add proxmox_nic module

Add proxmox_nic module to manage NIC's on Qemu(KVM) VM's in a Proxmox VE
cluster.
Update proxmox integration tests and add tests for proxmox_nic module.

This partially solves https://github.com/ansible-collections/community.general/issues/1964#issuecomment-790499397
and allows for adding/updating/deleting network interface cards after
creating/cloning a VM.

The proxmox_nic module will keep MAC-addresses the same when updating a
NIC. It only changes when explicitly setting a MAC-address.

* Apply suggestions from code review

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

* Add check_mode and implement review comments

- check_mode added
- some documentation updates
- when MTU is set, check if the model is virtio, else fail
- trunks can now be provided as list of ints instead of vlanid[;vlanid...]

* Make returns on update_nic and delete_nic more readable

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

* Increase readability on update_nic and delete_nic

* Implement check in get_vmid

- get_vmid will now fail when multiple vmid's are returned as proxmox
  doesn't guarantee uniqueness
- remove an unused import
- fix a typo in an error message

* Add some error checking to get_vmid

- get_vmid will now return the error message when proxmoxer fails
- get_vmid will return the vmid directly instead of a list of one
- Some minor documentation updates

* Warn instead of fail when setting mtu on unsupported nic

- When setting the MTU on an unsupported NIC model (virtio is the only
  supported model) this module will now print a warning instead of
  failing.
- Some minor documentation updates.

* Take advantage of proxmox_auth_argument_spec

Make use of proxmox_auth_argument_spec from plugins/module_utils/proxmox.py
This provides some extra environment fallbacks.

* Add blank line to conform with pep8

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

Co-authored-by: Kogelvis <github@ar-ix.net>
2021-05-14 09:47:39 +02:00
patchback[bot]
f5594aefd5 influxdb_retention_policy - add state argument to module spec (#2383) (#2385) (#2497)
* influxdb_retention_policy: add state option to module argument spec

* influxdb_retention_policy: simplify duration parsing logic (suggested in #2284)

* add changelog

* fix documentation and changelog

* add constants for duration and sgduration validations

* restyle ansible module spec

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

* improve changelog

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

* set changed result in check mode for state absent

* remove required flag in optional module arguments

* influxdb_retention_policy: improve examples readability

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

Co-authored-by: Xabier Napal <xabiernapal@pm.me>
2021-05-12 18:19:03 +02:00
patchback[bot]
ab5b379b30 linode - docs/validation changes + minor refactorings (#2410) (#2498)
* multiple changes:

- documentation fixes
- minor refactorings

* added param deprecation note to the documentation

* added changelog fragment

* Update changelogs/fragments/2410-linode-improvements.yml

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

* Update changelogs/fragments/2410-linode-improvements.yml

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

* Update plugins/modules/cloud/linode/linode.py

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-12 18:17:40 +02:00
patchback[bot]
1c5e44c649 nmcli: Remove dead code, 'options' never contains keys from 'param_alias' (#2417) (#2494)
* nmcli: Remove dead code, 'options' never contains keys from 'param_alias'

* Update changelogs/fragments/2417-nmcli_remove_dead_code.yml

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

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

Co-authored-by: spike77453 <spike77453@users.noreply.github.com>
2021-05-11 20:22:13 +02:00
patchback[bot]
23da67cc72 Add dependent lookup plugin (#2164) (#2490)
* Add dependent lookup plugin.

* Use correct YAML booleans.

* Began complete rewrite.

* Only match start of error msg.

* Improve tests.

* Work around old Jinja2 versions.

* Fix metadata.

* Fix filter name.

(cherry picked from commit eea4f45965)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-11 20:14:30 +02:00
patchback[bot]
4032dd6b08 discord.py: Add new module for discord notifications (#2398) (#2493)
* first push: add discord module and test for notifications

* fix the yaml docs and edit the result output

* add link

* fix link

* fix docs and remove required=False in argument spec

* add elements specd and more info about embeds

* called str...

* elements for embeds oc.

* fix typo's in description and set checkmode to false

* edit docs and module return

* support checkmode with get method

* fix unit test

* handle exception and add new example for embeds

* quote line

* fix typos

* fix yaml

(cherry picked from commit 0912e8cc7a)

Co-authored-by: CWollinger <CWollinger@web.de>
2021-05-11 20:05:59 +02:00
patchback[bot]
4cb6f39a80 module_helper.py Breakdown (#2393) (#2492)
* break down of module_helper into smaller pieces, keeping compatibility

* removed abc.ABC (py3 only) from code + fixed reference to vars.py

* multiple changes:

- mh.base - moved more functionalities to ModuleHelperBase
- mh.mixins.(cmd, state) - CmdMixin no longer inherits from ModuleHelperBase
- mh.mixins.deps - DependencyMixin now overrides run() method to test dependency
- mh.mixins.vars - created class VarsMixin
- mh.module_helper - moved functions to base class, added VarsMixin
- module_helper - importing AnsibleModule as well, for backward compatibility in test

* removed unnecessary __all__

* make pylint happy

* PR adjustments + bot config + changelog frag

* Update plugins/module_utils/mh/module_helper.py

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

* Update plugins/module_utils/mh/module_helper.py

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-11 20:05:42 +02:00
patchback[bot]
3539957bac modified redfish_config and idrac_redfish_config to skip incorrect attributes (#2334) (#2491)
* modified redfish_config and idrac_redfish_config to skip incorrect attributes

Signed-off-by: Trevor Squillario Trevor_Squillario@Dell.com

* modified redfish_utils.py and idrac_redfish_config.py to return empty warning message

* modified redfish_config.py and idrac_redfish_config.py to use module.warn()

* updated changelog fragment for pr 2334

(cherry picked from commit 9d46ccf1b2)

Co-authored-by: TrevorSquillario <72882537+TrevorSquillario@users.noreply.github.com>
2021-05-11 20:05:24 +02:00
Felix Fontein
e05769d4bf Deprecate vendored ipaddress copy. (#2459) 2021-05-11 19:27:46 +02:00
Felix Fontein
19c03cff96 Revert "Revert "spotinst_aws_elastigroup - fixed elements for many lists (#2355) (#2363)"" (#2428)
This reverts commit 5b15e4089a.
2021-05-11 19:27:36 +02:00
patchback[bot]
703660c81d Run unit tests also with Python 3.10. (#2486) (#2488)
ci_complete

(cherry picked from commit 624eb7171e)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-11 08:27:35 +02:00
Felix Fontein
fd32af1ac3 Next expected release will be 3.1.0. 2021-05-11 08:15:11 +02:00
Felix Fontein
80fbcf2f98 Release 3.0.2. 2021-05-11 07:08:11 +02:00
patchback[bot]
a722e038cc Avoid incorrectly marking zfs tasks as changed (#2454) (#2484)
* Avoid incorrectly marking zfs tasks as changed

The zfs module will incorrectly mark certain tasks as having been
changed. For example, if a dataset has a quota of "1G" and the user
changes it to "1024M", the actual quota vale has not changed, but since
the module is doing a simple string comparison between "1G" and "1024M",
it marks the step as "changed".

Instead of trying to handle all the corner cases of zfs (another example
is when the zpool "altroot" property has been set), this change simply
compares the output of "zfs-get" from before and after "zfs-set" is
called

* update changelog format

* Update changelogs/fragments/2454-detect_zfs_changed.yml

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

* add note about check_mode

* Update plugins/modules/storage/zfs/zfs.py

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

* Update plugins/modules/storage/zfs/zfs.py

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

* clarify check mode qualifications

* rephrase to avoid hypothetical

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

Co-authored-by: sam-lunt <samuel.j.lunt@gmail.com>
2021-05-10 18:17:03 +02:00
Felix Fontein
19c8d2164d Prepare 3.0.2 release. 2021-05-10 18:00:08 +02:00
patchback[bot]
d4656ffca2 Clarify Windows (non-)support. (#2476) (#2482)
(cherry picked from commit 2e58dfe52a)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-10 17:14:34 +02:00
patchback[bot]
b49607f12d fix stackpath_compute validate_config (#2448) (#2475)
* fix stackpath_compute validate_config

get the lenght for the client_id / client_secret to validate inventory configuration

* Add changelog fragment.

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

Co-authored-by: vbarba <victor.barba@gmail.com>
2021-05-09 22:46:17 +02:00
patchback[bot]
af0ce4284f Small Documentation Example Of Cask Leveraging (#2462) (#2470)
* Small Documentation Example Of Cask Leveraging

- Just a lil' demo showing that we can utilize homebrew/cask/foo syntax
for given name of package to grab associated cask pacakge

Resolves: patch/sml-doc-example-update

* Slight Documentation Example Edit

- adjusting documentation example to provide better info surrounding installing
a given formula from brew via cask

Resolves: patch/sml-doc-example-update

* Small Edits To Make PEP8 Happy

- format code with autopep8 in vs code

Resolves: patch/sml-doc-example-update

* Only Making Small PEP8 Change

- reverting previous mass PEP8 format, focus on trimming whitespace on
doc example entry

Resolves: patch/sml-doc-example-update

* Remove Trailing Whitespace PEP8

- removed trailing whitespace on doc example chunk

Resolves: patch/sml-doc-example-update
(cherry picked from commit 7386326258)

Co-authored-by: Mike Russell <michael.j.russell.email@gmail.com>
2021-05-08 12:18:28 +02:00
patchback[bot]
f5f862617a Add more plugin authors to BOTMETA. (#2451) (#2453)
(cherry picked from commit 188a4eeb0c)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-05 07:52:09 +02:00
Felix Fontein
a1a4ba4337 Next expected release is 3.0.2 next week. 2021-05-04 13:21:05 +02:00
Felix Fontein
b0b783f8ff Release 3.0.1. 2021-05-04 12:45:19 +02:00
patchback[bot]
e670ca666a OpenNebula one_vm.py: Fix missing keys (#2435) (#2447)
* OpenNebula one_vm.py: Fix missing keys

* fixup OpenNebula one_vm.py: Fix missing keys

(cherry picked from commit aaa561163b)

Co-authored-by: Jan Orel <jorel@opennebula.io>
2021-05-04 12:43:25 +02:00
patchback[bot]
49b991527e Remove shippable config. (#2440) (#2444)
(cherry picked from commit 1f41e66f09)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-03 22:56:40 +02:00
patchback[bot]
e6cc671a0d lvol - bug fix - Convert units to lowercase when using LVS or VGS command (#2369) (#2439)
* Added lower call for units when checking lvs/vgs size

* Changelog

* Size roudning correction

* Rounding

* Changelog

* Remove whitespace

(cherry picked from commit 06bdabcad9)

Co-authored-by: zigaSRC <65527456+zigaSRC@users.noreply.github.com>
2021-05-03 22:07:52 +02:00
patchback[bot]
797ea23e50 Clean up test entries from sysrc tests (#2330) (#2438)
* Clean up test entries from sysrc tests

* sysrc: enable tests

* sysrc: cache the files to be changed and restore them

* Update the ezjail archive host and remove obsolete file

* sysrc: set ezjail to use archives for 12.0 or less

* sysrc: Detect the version to use ftp vs ftp-archive using http

* sysrc: Skip ezjail test on FreeBSD 12.0

(cherry picked from commit 7007c68ab7)

Co-authored-by: David Lundgren <dlundgren@syberisle.net>
2021-05-03 21:34:19 +02:00
patchback[bot]
4d23b7a48b linode_v4 - fixed error message (#2430) (#2433)
* fixed error message

* added changelog fragment

(cherry picked from commit 5064aa8ec6)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-05-03 13:51:38 +02:00
patchback[bot]
020b47a1a9 Make plugins pass validation. (#2414) (#2431)
(cherry picked from commit 6a72c3b338)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-03 13:51:10 +02:00
patchback[bot]
0da9d956a0 nmcli: Compare MAC addresses case insensitively (#2416) (#2425)
* nmcli: Compare MAC addresses case insensitively

* Update changelogs/fragments/2416-nmcli_compare_mac_addresses_case_insensitively.yml

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

* Update plugins/modules/net_tools/nmcli.py

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

* Add mac to TESTCASE_BRIDGE so test_bridge_connection_unchanged covers case sensitive mac address comparison

* Update plugins/modules/net_tools/nmcli.py

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

* Convert current_value to uppercase as well in case nmcli changes behaviour

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

Co-authored-by: spike77453 <spike77453@users.noreply.github.com>
2021-05-03 08:17:32 +02:00
patchback[bot]
5691e3aff3 nmcli: Add 'slave-type bridge' to nmcli command if type is bridge-slave (#2409) (#2423)
(cherry picked from commit b5f8ae4320)

Co-authored-by: spike77453 <spike77453@users.noreply.github.com>
2021-05-03 08:16:19 +02:00
patchback[bot]
007333dbfe 📝 Document nested node addition with "_" in xml module (#2371) (#2427)
* 📝 Document nested node addition with "_" in xml module

Nested node addition using "_" to indicate sub nodes, and attributes are only documented in tests and issues, where is hard to find.

* 🚨 Fix trailing space

* Apply suggestions from code review

Add missing collection prefix for modules.

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

* Add missing comments

* Update xml.py

* Fix linter warnings

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

Co-authored-by: Daniel-Sanchez-Fabregas <33929811+Daniel-Sanchez-Fabregas@users.noreply.github.com>
2021-05-03 08:12:31 +02:00
patchback[bot]
05666b0e4d puppet - replace stdout with console in logdest option (#2407) (#2421)
* Change stdout to console

* readd stdout, resulting in console

* add changelog

* readd stdout to docs and add a warning when it is used

* version of what???

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

* postpone deprecation in another PR

* remove console option, so it can be backported

* change changelog respectively

* Fix changelog formatting

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

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

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-05-03 07:59:33 +02:00
patchback[bot]
c934d9aeb5 Fix #2373 - TypeError: a bytes-like object is required, not 'str' (#2375) (#2419)
* Fix #2373

* Changelog fragment for #2373

* Update changelogs/fragments/2373-svr4pkg-fix-typeerror.yml

Co-authored-by: Amin Vakil <info@aminvakil.com>

* Update changelogs/fragments/2373-svr4pkg-fix-typeerror.yml

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

Co-authored-by: Amin Vakil <info@aminvakil.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit cd957fae4c)

Co-authored-by: Daniel Werner <srmlsrml@gmail.com>
2021-05-03 07:56:05 +02:00
Felix Fontein
5b15e4089a Revert "spotinst_aws_elastigroup - fixed elements for many lists (#2355) (#2363)"
This reverts commit ea42b75378.

(Will be re-reverted after the 3.0.1 release.)
2021-05-03 07:48:12 +02:00
Felix Fontein
a6379e45ce Prepare 3.0.1 release. 2021-05-03 07:47:48 +02:00
Felix Fontein
b95176dbc8 Copy schedule to stable branches. 2021-05-02 13:35:45 +02:00
patchback[bot]
b752fea121 BOTMETA.yml: terraform - add a new maintainer (#2290) (#2413)
(cherry picked from commit c0221b75af)

Co-authored-by: Andrew Klychkov <aklychko@redhat.com>
2021-05-02 13:27:43 +02:00
patchback[bot]
cf50990fed Add ansible-test config file. (#2404) (#2406)
(cherry picked from commit 4e90ee752e)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-01 22:54:44 +02:00
patchback[bot]
45343e6bc0 composer: --no-interaction when discovering available options (#2348) (#2403)
The composer module always uses the no-interaction option if it
discovers it _after_ calling "composer help ..." but not on the help
call itself. The lack of this option caused composer to not exit when
called through the ansible module.

The same example command when ran interactively does not prompt for user
interaction and exits immediately. It is therefore currently unknown why
the same command hangs when called through the ansible composer module
or even directly with the command module.

Example command which hangs:
php /usr/local/bin/composer help install --format=json

(cherry picked from commit eb455c69a2)

Co-authored-by: George Angelopoulos <george@usermod.net>
2021-05-01 18:46:16 +02:00
patchback[bot]
51540f6345 influxdb_retention_policy: fix duration parsing to support INF values (#2396) (#2401)
* influxdb_retention_policy: fix duration parsing to support INF values

* add changelog

(cherry picked from commit 26c3bd25f6)

Co-authored-by: Xabier Napal <xabiernapal@pm.me>
2021-05-01 14:37:19 +02:00
patchback[bot]
74eba52028 Remove resmo as composer maintainer. (#2392) (#2395)
(cherry picked from commit 276880aac1)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-05-01 14:11:16 +02:00
patchback[bot]
b920e8abf2 Add Fedora 34 to CI (#2384) (#2391)
* Add fedora 34 and fix typo

* Remove Fedora 32 from devel testing

* Use one newer version of Fedora for fixed ansible versions

* Revert "Use one newer version of Fedora for fixed ansible versions"

This reverts commit cbd006bd38.

* Try to skip task.

* Revert "Try to skip task."

This reverts commit ff0c899a86.

* Temporary disable Fedora 34 on setup_postgresql_db

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

Co-authored-by: Amin Vakil <info@aminvakil.com>
2021-05-01 14:10:07 +02:00
patchback[bot]
75c0004e1e Use Ansible's codecov uploader. (#2377) (#2380)
(cherry picked from commit b3f436aa63)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-04-30 05:32:23 +02:00
patchback[bot]
be42fd4af7 No longer required for devel's ansible-test. (#2365) (#2367)
ci_complete

(cherry picked from commit 77d4bc2942)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-04-27 22:44:21 +02:00
patchback[bot]
1c05908ff6 BOTMETA.yml: team_suse - add a maintainer (#2354) (#2362)
(cherry picked from commit 9d13acd68e)

Co-authored-by: Andrew Klychkov <aklychko@redhat.com>
2021-04-27 13:46:28 +02:00
patchback[bot]
ea42b75378 spotinst_aws_elastigroup - fixed elements for many lists (#2355) (#2363)
* fixed elements for many lists

* added changelog fragment

* Removed verbose types in description - still missing formatting and properly documenting dicts

(cherry picked from commit 48ef05def3)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-04-27 11:46:17 +00:00
patchback[bot]
0330f4b52c Make inventory scripts executable (#2337) (#2359)
* Make inventory scripts executable

* Mark inventory scripts in vault folder as executable

* Add changelog entry for making inventory scripts exectuable

* Update changelogs/fragments/2337-mark-inventory-scripts-executable.yml

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

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

Co-authored-by: Alan Rominger <arominge@redhat.com>
2021-04-26 22:24:42 +02:00
Felix Fontein
1d8c659ba2 Next expected release is 3.0.0. 2021-04-26 21:19:55 +02:00
Felix Fontein
e784254679 Release 3.0.0. 2021-04-26 18:40:14 +02:00
Felix Fontein
d5e1edd284 Add release summary. 2021-04-26 18:38:45 +02:00
343 changed files with 29413 additions and 6455 deletions

View File

@@ -209,8 +209,8 @@ stages:
test: macos/11.1
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 8.4
test: rhel/8.4
- name: RHEL 8.5
test: rhel/8.5
- name: FreeBSD 12.2
test: freebsd/12.2
- name: FreeBSD 13.0

48
.github/BOTMETA.yml vendored
View File

@@ -175,8 +175,6 @@ files:
labels: lookups
$lookups/cartesian.py: {}
$lookups/chef_databag.py: {}
$lookups/collection_version.py:
maintainers: felixfontein
$lookups/consul_kv.py: {}
$lookups/credstash.py: {}
$lookups/cyberarkpassword.py:
@@ -207,6 +205,9 @@ files:
$lookups/manifold.py:
maintainers: galanoff
labels: manifold
$lookups/nios:
maintainers: $team_networking sganesh-infoblox
labels: infoblox networking
$lookups/onepass:
maintainers: samdoran
labels: onepassword
@@ -219,8 +220,6 @@ files:
maintainers: Akasurde
$lookups/random_string.py:
maintainers: Akasurde
$lookups/random_words.py:
maintainers: konstruktoid
$lookups/redis.py:
maintainers: $team_ansible_core jpmens
$lookups/shelvefile.py: {}
@@ -254,6 +253,9 @@ files:
$module_utils/module_helper.py:
maintainers: russoz
labels: module_helper
$module_utils/net_tools/nios/api.py:
maintainers: $team_networking sganesh-infoblox
labels: infoblox networking
$module_utils/oracle/oci_utils.py:
maintainers: $team_oracle
labels: cloud
@@ -475,16 +477,11 @@ files:
maintainers: paginabianca
$modules/database/misc/redis_data.py:
maintainers: paginabianca
$modules/database/misc/redis_data_incr.py:
maintainers: paginabianca
$modules/database/misc/riak.py:
maintainers: drewkerrigan jsmartin
$modules/database/mssql/mssql_db.py:
maintainers: vedit Jmainguy kenichi-ogawa-1988
labels: mssql_db
$modules/database/mssql/mssql_script.py:
maintainers: kbudde
labels: mssql_script
$modules/database/saphana/hana_query.py:
maintainers: rainerleber
$modules/database/vertica/:
@@ -650,6 +647,31 @@ files:
maintainers: amasolov nerzhul
$modules/net_tools/pritunl/:
maintainers: Lowess
$modules/net_tools/nios/:
maintainers: $team_networking
labels: infoblox networking
$modules/net_tools/nios/nios_a_record.py:
maintainers: brampling
$modules/net_tools/nios/nios_aaaa_record.py:
maintainers: brampling
$modules/net_tools/nios/nios_cname_record.py:
maintainers: brampling
$modules/net_tools/nios/nios_fixed_address.py:
maintainers: sjaiswal
$modules/net_tools/nios/nios_member.py:
maintainers: krisvasudevan
$modules/net_tools/nios/nios_mx_record.py:
maintainers: brampling
$modules/net_tools/nios/nios_naptr_record.py:
maintainers: brampling
$modules/net_tools/nios/nios_nsgroup.py:
maintainers: ebirn sjaiswal
$modules/net_tools/nios/nios_ptr_record.py:
maintainers: clementtrebuchet
$modules/net_tools/nios/nios_srv_record.py:
maintainers: brampling
$modules/net_tools/nios/nios_txt_record.py:
maintainers: coreywan
$modules/net_tools/nmcli.py:
maintainers: alcamie101
$modules/net_tools/snmp_facts.py:
@@ -753,8 +775,6 @@ files:
maintainers: evgkrsk
$modules/packaging/os/copr.py:
maintainers: schlupov
$modules/packaging/os/dnf_versionlock.py:
maintainers: moreda
$modules/packaging/os/flatpak.py:
maintainers: $team_flatpak
$modules/packaging/os/flatpak_remote.py:
@@ -851,9 +871,6 @@ files:
$modules/packaging/os/snap.py:
maintainers: angristan vcarceler
labels: snap
$modules/packaging/os/snap_alias.py:
maintainers: russoz
labels: snap
$modules/packaging/os/sorcery.py:
maintainers: vaygr
$modules/packaging/os/svr4pkg.py:
@@ -1171,8 +1188,6 @@ files:
maintainers: inetfuture mattupstate
$modules/web_infrastructure/taiga_issue.py:
maintainers: lekum
$tests/a_module.py:
maintainers: felixfontein
#########################
tests/:
labels: tests
@@ -1199,7 +1214,6 @@ macros:
module_utils: plugins/module_utils
modules: plugins/modules
terminals: plugins/terminal
tests: plugins/test
team_ansible_core:
team_aix: MorrisA bcoca d-little flynn1973 gforster kairoaraujo marvin-sinister mator molekuul ramooncamacho wtcross
team_bsd: JoergFiedler MacLemon bcoca dch jasperla mekanix opoplawski overhacked tuxillo

View File

@@ -62,20 +62,6 @@ body:
validations:
required: true
- type: textarea
attributes:
label: Community.general Version
description: >-
Paste verbatim output from "ansible-galaxy collection list community.general"
between tripple backticks.
value: |
```console (paste below)
$ ansible-galaxy collection list community.general
```
validations:
required: true
- type: textarea
attributes:
label: Configuration

View File

@@ -62,20 +62,6 @@ body:
validations:
required: false
- type: textarea
attributes:
label: Community.general Version
description: >-
Paste verbatim output from "ansible-galaxy collection list community.general"
between tripple backticks.
value: |
```console (paste below)
$ ansible-galaxy collection list community.general
```
validations:
required: true
- type: textarea
attributes:
label: Configuration

View File

@@ -21,7 +21,7 @@ body:
placeholder: >-
I am trying to do X with the collection from the main branch on GitHub and
I think that implementing a feature Y would be very helpful for me and
every other user of community.general because of Z.
every other user of ansible-core because of Z.
validations:
required: true

View File

@@ -1,6 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
interval:
schedule: "weekly"

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
# Community General Collection
[![Build Status](https://dev.azure.com/ansible/community.general/_apis/build/status/CI?branchName=stable-4)](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
[![Build Status](https://dev.azure.com/ansible/community.general/_apis/build/status/CI?branchName=stable-3)](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
[![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.general)](https://codecov.io/gh/ansible-collections/community.general)
This repository contains the `community.general` Ansible Collection. The collection is a part of the Ansible package and includes many modules and plugins supported by Ansible community which are not part of more specialized community collections.
@@ -64,13 +64,13 @@ We are actively accepting new contributors.
All types of contributions are very welcome.
You don't know how to start? Refer to our [contribution guide](https://github.com/ansible-collections/community.general/blob/stable-4/CONTRIBUTING.md)!
You don't know how to start? Refer to our [contribution guide](https://github.com/ansible-collections/community.general/blob/main/CONTRIBUTING.md)!
The current maintainers are listed in the [commit-rights.md](https://github.com/ansible-collections/community.general/blob/stable-4/commit-rights.md#people) file. If you have questions or need help, feel free to mention them in the proposals.
The current maintainers are listed in the [commit-rights.md](https://github.com/ansible-collections/community.general/blob/main/commit-rights.md#people) file. If you have questions or need help, feel free to mention them in the proposals.
You can find more information in the [developer guide for collections](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections.html#contributing-to-collections), and in the [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html).
Also for some notes specific to this collection see [our CONTRIBUTING documentation](https://github.com/ansible-collections/community.general/blob/stable-4/CONTRIBUTING.md).
Also for some notes specific to this collection see [our CONTRIBUTING documentation](https://github.com/ansible-collections/community.general/blob/main/CONTRIBUTING.md).
### Running tests
@@ -80,7 +80,7 @@ See [here](https://docs.ansible.com/ansible/devel/dev_guide/developing_collectio
To learn how to maintain / become a maintainer of this collection, refer to:
* [Committer guidelines](https://github.com/ansible-collections/community.general/blob/stable-4/commit-rights.md).
* [Committer guidelines](https://github.com/ansible-collections/community.general/blob/main/commit-rights.md).
* [Maintainer guidelines](https://github.com/ansible/community-docs/blob/main/maintaining.rst).
It is necessary for maintainers of this collection to be subscribed to:
@@ -108,7 +108,7 @@ See the [Releasing guidelines](https://github.com/ansible/community-docs/blob/ma
## Release notes
See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-4/CHANGELOG.rst).
See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-3/CHANGELOG.rst).
## Roadmap

File diff suppressed because it is too large Load Diff

View File

@@ -3,4 +3,3 @@ sections:
- title: Guides
toctree:
- filter_guide
- test_guide

View File

@@ -1,28 +0,0 @@
.. _ansible_collections.community.general.docsite.test_guide:
community.general Test (Plugin) Guide
=====================================
The :ref:`community.general collection <plugins_in_community.general>` offers currently one test plugin.
.. contents:: Topics
Feature Tests
-------------
The ``a_module`` test allows to check whether a given string refers to an existing module or action plugin. This can be useful in roles, which can use this to ensure that required modules are present ahead of time.
.. code-block:: yaml+jinja
- name: Make sure that community.aws.route53 is available
assert:
that:
- >
'community.aws.route53' is community.general.a_module
- name: Make sure that community.general.does_not_exist is not a module or action plugin
assert:
that:
- "'community.general.does_not_exist' is not community.general.a_module"
.. versionadded:: 4.0.0

View File

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

View File

@@ -12,11 +12,20 @@ plugin_routing:
hashi_vault:
redirect: community.hashi_vault.hashi_vault
nios:
redirect: infoblox.nios_modules.nios_lookup
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios lookup plugin has been deprecated.
Please use infoblox.nios_modules.nios_lookup instead.
nios_next_ip:
redirect: infoblox.nios_modules.nios_next_ip
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_next_ip lookup plugin has been deprecated.
Please use infoblox.nios_modules.nios_next_ip instead.
nios_next_network:
redirect: infoblox.nios_modules.nios_next_network
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_next_network lookup plugin has been
deprecated. Please use infoblox.nios_modules.nios_next_network instead.
modules:
ali_instance_facts:
tombstone:
@@ -257,37 +266,85 @@ plugin_routing:
removal_version: 3.0.0
warning_text: Use community.general.nginx_status_info instead.
nios_a_record:
redirect: infoblox.nios_modules.nios_a_record
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_a_record module has been deprecated.
Please use infoblox.nios_modules.nios_a_record instead.
nios_aaaa_record:
redirect: infoblox.nios_modules.nios_aaaa_record
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_aaaa_record module has been deprecated.
Please use infoblox.nios_modules.nios_aaaa_record instead.
nios_cname_record:
redirect: infoblox.nios_modules.nios_cname_record
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_cname_record module has been deprecated.
Please use infoblox.nios_modules.nios_cname_record instead.
nios_dns_view:
redirect: infoblox.nios_modules.nios_dns_view
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_dns_view module has been deprecated.
Please use infoblox.nios_modules.nios_dns_view instead.
nios_fixed_address:
redirect: infoblox.nios_modules.nios_fixed_address
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_fixed_address module has been deprecated.
Please use infoblox.nios_modules.nios_fixed_address instead.
nios_host_record:
redirect: infoblox.nios_modules.nios_host_record
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_host_record module has been deprecated.
Please use infoblox.nios_modules.nios_host_record instead.
nios_member:
redirect: infoblox.nios_modules.nios_member
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_member module has been deprecated.
Please use infoblox.nios_modules.nios_member instead.
nios_mx_record:
redirect: infoblox.nios_modules.nios_mx_record
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_mx_record module has been deprecated.
Please use infoblox.nios_modules.nios_mx_record instead.
nios_naptr_record:
redirect: infoblox.nios_modules.nios_naptr_record
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_naptr_record module has been deprecated.
Please use infoblox.nios_modules.nios_naptr_record instead.
nios_network:
redirect: infoblox.nios_modules.nios_network
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_network module has been deprecated.
Please use infoblox.nios_modules.nios_network instead.
nios_network_view:
redirect: infoblox.nios_modules.nios_network_view
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_network_view module has been deprecated.
Please use infoblox.nios_modules.nios_network_view instead.
nios_nsgroup:
redirect: infoblox.nios_modules.nios_nsgroup
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_nsgroup module has been deprecated.
Please use infoblox.nios_modules.nios_nsgroup instead.
nios_ptr_record:
redirect: infoblox.nios_modules.nios_ptr_record
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_ptr_record module has been deprecated.
Please use infoblox.nios_modules.nios_ptr_record instead.
nios_srv_record:
redirect: infoblox.nios_modules.nios_srv_record
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_srv_record module has been deprecated.
Please use infoblox.nios_modules.nios_srv_record instead.
nios_txt_record:
redirect: infoblox.nios_modules.nios_txt_record
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_txt_record module has been deprecated.
Please use infoblox.nios_modules.nios_txt_record instead.
nios_zone:
redirect: infoblox.nios_modules.nios_zone
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios_zone module has been deprecated.
Please use infoblox.nios_modules.nios_zone instead.
ome_device_info:
redirect: dellemc.openmanage.ome_device_info
one_image_facts:
@@ -571,7 +628,10 @@ plugin_routing:
kubevirt_vm_options:
redirect: community.kubevirt.kubevirt_vm_options
nios:
redirect: infoblox.nios_modules.nios
deprecation:
removal_version: 5.0.0
warning_text: The community.general.nios document fragment has been deprecated.
Please use infoblox.nios_modules.nios instead.
postgresql:
redirect: community.postgresql.postgresql
module_utils:
@@ -590,7 +650,10 @@ plugin_routing:
kubevirt:
redirect: community.kubevirt.kubevirt
net_tools.nios.api:
redirect: infoblox.nios_modules.api
deprecation:
removal_version: 5.0.0
warning_text: The community.general.net_tools.nios.api module_utils has been
deprecated. Please use infoblox.nios_modules.api instead.
postgresql:
redirect: community.postgresql.postgresql
remote_management.dellemc.dellemc_idrac:

View File

@@ -226,15 +226,18 @@ class ElasticSource(object):
message = "success"
status = "success"
enriched_error_message = None
if host_data.status == 'included':
rc = 0
else:
res = host_data.result._result
rc = res.get('rc', 0)
if host_data.status == 'failed':
message = self.get_error_message(res)
enriched_error_message = self.enrich_error_message(res)
if res.get('exception') is not None:
message = res['exception'].strip().split('\n')[-1]
elif 'msg' in res:
message = res['msg']
else:
message = 'failed'
status = "failure"
elif host_data.status == 'skipped':
if 'skip_reason' in res:
@@ -256,7 +259,7 @@ class ElasticSource(object):
"ansible.task.host.status": host_data.status}) as span:
span.outcome = status
if 'failure' in status:
exception = AnsibleRuntimeError(message="{0}: {1} failed with error message {2}".format(task_data.action, name, enriched_error_message))
exception = AnsibleRuntimeError(message="{0}: {1} failed with error message {2}".format(task_data.action, name, message))
apm_cli.capture_exception(exc_info=(type(exception), exception, exception.__traceback__), handled=True)
def init_apm_client(self, apm_server_url, apm_service_name, apm_verify_server_cert, apm_secret_token, apm_api_key):
@@ -269,24 +272,6 @@ class ElasticSource(object):
use_elastic_traceparent_header=True,
debug=True)
@staticmethod
def get_error_message(result):
if result.get('exception') is not None:
return ElasticSource._last_line(result['exception'])
return result.get('msg', 'failed')
@staticmethod
def _last_line(text):
lines = text.strip().split('\n')
return lines[-1]
@staticmethod
def enrich_error_message(result):
message = result.get('msg', 'failed')
exception = result.get('exception')
stderr = result.get('stderr')
return ('message: "{0}"\nexception: "{1}"\nstderr: "{2}"').format(message, exception, stderr)
class CallbackModule(CallbackBase):
"""

View File

@@ -79,7 +79,6 @@ from os.path import basename
from ansible.errors import AnsibleError
from ansible.module_utils.six import raise_from
from ansible.module_utils.six.moves.urllib.parse import urlparse
from ansible.plugins.callback import CallbackBase
try:
@@ -91,6 +90,8 @@ try:
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
ConsoleSpanExporter,
SimpleSpanProcessor,
BatchSpanProcessor
)
from opentelemetry.util._time import _time_ns
@@ -178,7 +179,7 @@ class OpenTelemetrySource(object):
args = None
if not task.no_log and not hide_task_arguments:
args = task.args
args = ', '.join(('%s=%s' % a for a in task.args.items()))
tasks_data[uuid] = TaskData(uuid, name, path, play_name, action, args)
@@ -245,43 +246,32 @@ class OpenTelemetrySource(object):
name = '[%s] %s: %s' % (host_data.name, task_data.play, task_data.name)
message = 'success'
res = {}
rc = 0
status = Status(status_code=StatusCode.OK)
if host_data.status != 'included':
# Support loops
if 'results' in host_data.result._result:
if host_data.status == 'failed':
message = self.get_error_message_from_results(host_data.result._result['results'], task_data.action)
enriched_error_message = self.enrich_error_message_from_results(host_data.result._result['results'], task_data.action)
else:
res = host_data.result._result
rc = res.get('rc', 0)
message = self.get_error_message(res)
enriched_error_message = self.enrich_error_message(res)
if host_data.status == 'included':
rc = 0
else:
res = host_data.result._result
rc = res.get('rc', 0)
if host_data.status == 'failed':
message = self.get_error_message(res)
status = Status(status_code=StatusCode.ERROR, description=message)
# Record an exception with the task message
span.record_exception(BaseException(enriched_error_message))
span.record_exception(BaseException(self.enrich_error_message(res)))
elif host_data.status == 'skipped':
message = res['skip_reason'] if 'skip_reason' in res else 'skipped'
if 'skip_reason' in res:
message = res['skip_reason']
else:
message = 'skipped'
status = Status(status_code=StatusCode.UNSET)
span.set_status(status)
if isinstance(task_data.args, dict) and "gather_facts" not in task_data.action:
names = tuple(self.transform_ansible_unicode_to_str(k) for k in task_data.args.keys())
values = tuple(self.transform_ansible_unicode_to_str(k) for k in task_data.args.values())
self.set_span_attribute(span, ("ansible.task.args.name"), names)
self.set_span_attribute(span, ("ansible.task.args.value"), values)
self.set_span_attribute(span, "ansible.task.args", task_data.args)
self.set_span_attribute(span, "ansible.task.module", task_data.action)
self.set_span_attribute(span, "ansible.task.message", message)
self.set_span_attribute(span, "ansible.task.name", name)
self.set_span_attribute(span, "ansible.task.result", rc)
self.set_span_attribute(span, "ansible.task.host.name", host_data.name)
self.set_span_attribute(span, "ansible.task.host.status", host_data.status)
# This will allow to enrich the service map
self.add_attributes_for_service_map_if_possible(span, task_data)
span.end(end_time=host_data.finish)
def set_span_attribute(self, span, attributeName, attributeValue):
@@ -293,64 +283,12 @@ class OpenTelemetrySource(object):
if attributeValue is not None:
span.set_attribute(attributeName, attributeValue)
def add_attributes_for_service_map_if_possible(self, span, task_data):
"""Update the span attributes with the service that the task interacted with, if possible."""
redacted_url = self.parse_and_redact_url_if_possible(task_data.args)
if redacted_url:
self.set_span_attribute(span, "http.url", redacted_url.geturl())
@staticmethod
def parse_and_redact_url_if_possible(args):
"""Parse and redact the url, if possible."""
try:
parsed_url = urlparse(OpenTelemetrySource.url_from_args(args))
except ValueError:
return None
if OpenTelemetrySource.is_valid_url(parsed_url):
return OpenTelemetrySource.redact_user_password(parsed_url)
return None
@staticmethod
def url_from_args(args):
# the order matters
url_args = ("url", "api_url", "baseurl", "repo", "server_url", "chart_repo_url")
for arg in url_args:
if args.get(arg):
return args.get(arg)
return ""
@staticmethod
def redact_user_password(url):
return url._replace(netloc=url.hostname) if url.password else url
@staticmethod
def is_valid_url(url):
if all([url.scheme, url.netloc, url.hostname]):
return "{{" not in url.hostname
return False
@staticmethod
def transform_ansible_unicode_to_str(value):
parsed_url = urlparse(str(value))
if OpenTelemetrySource.is_valid_url(parsed_url):
return OpenTelemetrySource.redact_user_password(parsed_url).geturl()
return str(value)
@staticmethod
def get_error_message(result):
if result.get('exception') is not None:
return OpenTelemetrySource._last_line(result['exception'])
return result.get('msg', 'failed')
@staticmethod
def get_error_message_from_results(results, action):
for result in results:
if result.get('failed', False):
return ('{0}({1}) - {2}').format(action, result.get('item', 'none'), OpenTelemetrySource.get_error_message(result))
@staticmethod
def _last_line(text):
lines = text.strip().split('\n')
@@ -363,14 +301,6 @@ class OpenTelemetrySource(object):
stderr = result.get('stderr')
return ('message: "{0}"\nexception: "{1}"\nstderr: "{2}"').format(message, exception, stderr)
@staticmethod
def enrich_error_message_from_results(results, action):
message = ""
for result in results:
if result.get('failed', False):
message = ('{0}({1}) - {2}\n{3}').format(action, result.get('item', 'none'), OpenTelemetrySource.enrich_error_message(result), message)
return message
class CallbackModule(CallbackBase):
"""

View File

@@ -0,0 +1,138 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2018, Sumit Kumar <sumit4@netapp.com>, chris Archibald <carchi@netapp.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
class ModuleDocFragment(object):
DOCUMENTATION = r'''
options:
- See respective platform section for more details
requirements:
- See respective platform section for more details
notes:
- Ansible modules are available for the following NetApp Storage Platforms: E-Series, ONTAP, SolidFire
'''
# Documentation fragment for ONTAP (na_cdot)
ONTAP = r'''
options:
hostname:
required: true
description:
- The hostname or IP address of the ONTAP instance.
username:
required: true
description:
- This can be a Cluster-scoped or SVM-scoped account, depending on whether a Cluster-level or SVM-level API is required.
For more information, please read the documentation U(https://mysupport.netapp.com/NOW/download/software/nmsdk/9.4/).
aliases: ['user']
password:
required: true
description:
- Password for the specified user.
aliases: ['pass']
requirements:
- A physical or virtual clustered Data ONTAP system. The modules were developed with Clustered Data ONTAP 8.3
- Ansible 2.2
- netapp-lib (2015.9.25). Install using 'pip install netapp-lib'
notes:
- The modules prefixed with na\\_cdot are built to support the ONTAP storage platform.
'''
# Documentation fragment for SolidFire
SOLIDFIRE = r'''
options:
hostname:
required: true
description:
- The hostname or IP address of the SolidFire cluster.
username:
required: true
description:
- Please ensure that the user has the adequate permissions. For more information, please read the official documentation
U(https://mysupport.netapp.com/documentation/docweb/index.html?productID=62636&language=en-US).
aliases: ['user']
password:
required: true
description:
- Password for the specified user.
aliases: ['pass']
requirements:
- The modules were developed with SolidFire 10.1
- solidfire-sdk-python (1.1.0.92) or greater. Install using 'pip install solidfire-sdk-python'
notes:
- The modules prefixed with na\\_elementsw are built to support the SolidFire storage platform.
'''
# Documentation fragment for ONTAP (na_ontap)
NA_ONTAP = r'''
options:
hostname:
description:
- The hostname or IP address of the ONTAP instance.
type: str
required: true
username:
description:
- This can be a Cluster-scoped or SVM-scoped account, depending on whether a Cluster-level or SVM-level API is required.
For more information, please read the documentation U(https://mysupport.netapp.com/NOW/download/software/nmsdk/9.4/).
type: str
required: true
aliases: [ user ]
password:
description:
- Password for the specified user.
type: str
required: true
aliases: [ pass ]
https:
description:
- Enable and disable https
type: bool
default: no
validate_certs:
description:
- If set to C(no), the SSL certificates will not be validated.
- This should only set to C(False) used on personally controlled sites using self-signed certificates.
type: bool
default: yes
http_port:
description:
- Override the default port (80 or 443) with this port
type: int
ontapi:
description:
- The ontap api version to use
type: int
use_rest:
description:
- REST API if supported by the target system for all the resources and attributes the module requires. Otherwise will revert to ZAPI.
- Always -- will always use the REST API
- Never -- will always use the ZAPI
- Auto -- will try to use the REST Api
default: Auto
choices: ['Never', 'Always', 'Auto']
type: str
requirements:
- A physical or virtual clustered Data ONTAP system. The modules support Data ONTAP 9.1 and onward
- Ansible 2.6
- Python2 netapp-lib (2017.10.30) or later. Install using 'pip install netapp-lib'
- Python3 netapp-lib (2018.11.13) or later. Install using 'pip install netapp-lib'
- To enable http on the cluster you must run the following commands 'set -privilege advanced;' 'system services web modify -http-enabled true;'
notes:
- The modules prefixed with na\\_ontap are built to support the ONTAP storage platform.
'''

View File

@@ -1,41 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Evgeniy Krysanov <evgeniy.krysanov@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
class ModuleDocFragment(object):
# Standard documentation fragment
DOCUMENTATION = r'''
options:
client_id:
description:
- The OAuth consumer key.
- If not set the environment variable C(BITBUCKET_CLIENT_ID) will be used.
type: str
client_secret:
description:
- The OAuth consumer secret.
- If not set the environment variable C(BITBUCKET_CLIENT_SECRET) will be used.
type: str
user:
description:
- The username.
- If not set the environment variable C(BITBUCKET_USERNAME) will be used.
type: str
version_added: 4.0.0
password:
description:
- The App password.
- If not set the environment variable C(BITBUCKET_PASSWORD) will be used.
type: str
version_added: 4.0.0
notes:
- Bitbucket OAuth consumer key and secret can be obtained from Bitbucket profile -> Settings -> Access Management -> OAuth.
- Bitbucket App password can be created from Bitbucket profile -> Personal Settings -> App passwords.
- If both OAuth and Basic Auth credentials are passed, OAuth credentials take precedence.
'''

View File

@@ -0,0 +1,103 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2015, Peter Sprygada <psprygada@ansible.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
class ModuleDocFragment(object):
# Standard files documentation fragment
DOCUMENTATION = r'''
options:
provider:
description:
- A dict object containing connection details.
type: dict
suboptions:
host:
description:
- Specifies the DNS host name or address for connecting to the remote
instance of NIOS WAPI over REST
- Value can also be specified using C(INFOBLOX_HOST) environment
variable.
type: str
username:
description:
- Configures the username to use to authenticate the connection to
the remote instance of NIOS.
- Value can also be specified using C(INFOBLOX_USERNAME) environment
variable.
type: str
password:
description:
- Specifies the password to use to authenticate the connection to
the remote instance of NIOS.
- Value can also be specified using C(INFOBLOX_PASSWORD) environment
variable.
type: str
validate_certs:
description:
- Boolean value to enable or disable verifying SSL certificates
- Value can also be specified using C(INFOBLOX_SSL_VERIFY) environment
variable.
type: bool
default: no
aliases: [ ssl_verify ]
http_request_timeout:
description:
- The amount of time before to wait before receiving a response
- Value can also be specified using C(INFOBLOX_HTTP_REQUEST_TIMEOUT) environment
variable.
type: int
default: 10
max_retries:
description:
- Configures the number of attempted retries before the connection
is declared usable
- Value can also be specified using C(INFOBLOX_MAX_RETRIES) environment
variable.
type: int
default: 3
wapi_version:
description:
- Specifies the version of WAPI to use
- Value can also be specified using C(INFOBLOX_WAP_VERSION) environment
variable.
- Until ansible 2.8 the default WAPI was 1.4
type: str
default: '2.1'
max_results:
description:
- Specifies the maximum number of objects to be returned,
if set to a negative number the appliance will return an error when the
number of returned objects would exceed the setting.
- Value can also be specified using C(INFOBLOX_MAX_RESULTS) environment
variable.
type: int
default: 1000
http_pool_connections:
description:
- Number of pools to be used by the C(infoblox_client.Connector) object.
- This is passed as-is to the underlying C(requests.adapters.HTTPAdapter) class.
type: int
default: 10
http_pool_maxsize:
description:
- Maximum number of connections per pool to be used by the C(infoblox_client.Connector) object.
- This is passed as-is to the underlying C(requests.adapters.HTTPAdapter) class.
type: int
default: 10
silent_ssl_warnings:
description:
- Disable C(urllib3) SSL warnings in the C(infoblox_client.Connector) object.
- This is passed as-is to the underlying C(requests.adapters.HTTPAdapter) class.
type: bool
default: true
notes:
- "This module must be run locally, which can be achieved by specifying C(connection: local)."
- Please read the :ref:`nios_guide` for more detailed information on how to use Infoblox with Ansible.
'''

View File

@@ -13,8 +13,6 @@ DOCUMENTATION = r'''
- Uses a YAML configuration file that ends with 'lxd.(yml|yaml)'.
version_added: "3.0.0"
author: "Frank Dornheim (@conloos)"
requirements:
- ipaddress
options:
plugin:
description: Token that ensures this is a source file for the 'lxd' plugin.
@@ -126,17 +124,10 @@ import socket
from ansible.plugins.inventory import BaseInventoryPlugin
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.module_utils.common.dict_transformations import dict_merge
from ansible.module_utils.six import raise_from
from ansible.errors import AnsibleError, AnsibleParserError
from ansible_collections.community.general.plugins.module_utils.compat import ipaddress
from ansible_collections.community.general.plugins.module_utils.lxd import LXDClient, LXDClientException
try:
import ipaddress
except ImportError as exc:
IPADDRESS_IMPORT_ERROR = exc
else:
IPADDRESS_IMPORT_ERROR = None
class InventoryModule(BaseInventoryPlugin):
DEBUG = 4
@@ -933,10 +924,6 @@ class InventoryModule(BaseInventoryPlugin):
AnsibleParserError
Returns:
None"""
if IPADDRESS_IMPORT_ERROR:
raise_from(
AnsibleError('another_library must be installed to use this plugin'),
IPADDRESS_IMPORT_ERROR)
super(InventoryModule, self).parse(inventory, loader, path, cache=False)
# Read the inventory YAML file

View File

@@ -1,138 +0,0 @@
# (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)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = """
name: collection_version
author: Felix Fontein (@felixfontein)
version_added: "4.0.0"
short_description: Retrieves the version of an installed collection
description:
- This lookup allows to query the version of an installed collection, and to determine whether a
collection is installed at all.
- By default it returns C(none) for non-existing collections and C(*) for collections without a
version number. The latter should only happen in development environments, or when installing
a collection from git which has no version in its C(galaxy.yml). This behavior can be adjusted
by providing other values with I(result_not_found) and I(result_no_version).
options:
_terms:
description:
- The collections to look for.
- For example C(community.general).
type: list
elements: str
required: true
result_not_found:
description:
- The value to return when the collection could not be found.
- By default, C(none) is returned.
type: string
default: ~
result_no_version:
description:
- The value to return when the collection has no version number.
- This can happen for collections installed from git which do not have a version number
in C(galaxy.yml).
- By default, C(*) is returned.
type: string
default: '*'
"""
EXAMPLES = """
- name: Check version of community.general
ansible.builtin.debug:
msg: "community.general version {{ lookup('community.general.collection_version', 'community.general') }}"
"""
RETURN = """
_raw:
description:
- The version number of the collections listed as input.
- If a collection can not be found, it will return the value provided in I(result_not_found).
By default, this is C(none).
- If a collection can be found, but the version not identified, it will return the value provided in
I(result_no_version). By default, this is C(*). This can happen for collections installed
from git which do not have a version number in C(galaxy.yml).
type: list
elements: str
"""
import json
import os
import re
import yaml
from ansible.errors import AnsibleLookupError
from ansible.module_utils.compat.importlib import import_module
from ansible.plugins.lookup import LookupBase
FQCN_RE = re.compile(r'^[A-Za-z0-9_]+\.[A-Za-z0-9_]+$')
def load_collection_meta_manifest(manifest_path):
with open(manifest_path, 'rb') as f:
meta = json.load(f)
return {
'version': meta['collection_info']['version'],
}
def load_collection_meta_galaxy(galaxy_path, no_version='*'):
with open(galaxy_path, 'rb') as f:
meta = yaml.safe_load(f)
return {
'version': meta.get('version') or no_version,
}
def load_collection_meta(collection_pkg, no_version='*'):
path = os.path.dirname(collection_pkg.__file__)
# Try to load MANIFEST.json
manifest_path = os.path.join(path, 'MANIFEST.json')
if os.path.exists(manifest_path):
return load_collection_meta_manifest(manifest_path)
# Try to load galaxy.y(a)ml
galaxy_path = os.path.join(path, 'galaxy.yml')
galaxy_alt_path = os.path.join(path, 'galaxy.yaml')
# galaxy.yaml was only supported in ansible-base 2.10 and ansible-core 2.11. Support was removed
# in https://github.com/ansible/ansible/commit/595413d11346b6f26bb3d9df2d8e05f2747508a3 for
# ansible-core 2.12.
for path in (galaxy_path, galaxy_alt_path):
if os.path.exists(path):
return load_collection_meta_galaxy(path, no_version=no_version)
return {}
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
result = []
self.set_options(var_options=variables, direct=kwargs)
not_found = self.get_option('result_not_found')
no_version = self.get_option('result_no_version')
for term in terms:
if not FQCN_RE.match(term):
raise AnsibleLookupError('"{term}" is not a FQCN'.format(term=term))
try:
collection_pkg = import_module('ansible_collections.{fqcn}'.format(fqcn=term))
except ImportError:
# Collection not found
result.append(not_found)
continue
try:
data = load_collection_meta(collection_pkg, no_version=no_version)
except Exception as exc:
raise AnsibleLookupError('Error while loading metadata for {fqcn}: {error}'.format(fqcn=term, error=exc))
result.append(data.get('version', no_version))
return result

126
plugins/lookup/nios.py Normal file
View File

@@ -0,0 +1,126 @@
# -*- coding: utf-8 -*-
#
# Copyright 2018 Red Hat | Ansible
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = '''
---
author: Unknown (!UNKNOWN)
name: nios
short_description: Query Infoblox NIOS objects
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding lookup from it.
alternative: infoblox.nios_modules.nios_lookup
removed_in: 5.0.0
description:
- Uses the Infoblox WAPI API to fetch NIOS specified objects. This lookup
supports adding additional keywords to filter the return data and specify
the desired set of returned fields.
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
_terms:
description: The name of the object to return from NIOS
required: True
return_fields:
description: The list of field names to return for the specified object.
filter:
description: a dict object that is used to filter the return objects
extattrs:
description: a dict object that is used to filter on extattrs
'''
EXAMPLES = """
- name: fetch all networkview objects
ansible.builtin.set_fact:
networkviews: "{{ lookup('community.general.nios', 'networkview',
provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}"
- name: fetch the default dns view
ansible.builtin.set_fact:
dns_views: "{{ lookup('community.general.nios', 'view', filter={'name': 'default'},
provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}"
# all of the examples below use credentials that are set using env variables
# export INFOBLOX_HOST=nios01
# export INFOBLOX_USERNAME=admin
# export INFOBLOX_PASSWORD=admin
- name: fetch all host records and include extended attributes
ansible.builtin.set_fact:
host_records: "{{ lookup('community.general.nios', 'record:host', return_fields=['extattrs', 'name', 'view', 'comment']}) }}"
- name: use env variables to pass credentials
ansible.builtin.set_fact:
networkviews: "{{ lookup('community.general.nios', 'networkview') }}"
- name: get a host record
ansible.builtin.set_fact:
host: "{{ lookup('community.general.nios', 'record:host', filter={'name': 'hostname.ansible.com'}) }}"
- name: get the authoritative zone from a non default dns view
ansible.builtin.set_fact:
host: "{{ lookup('community.general.nios', 'zone_auth', filter={'fqdn': 'ansible.com', 'view': 'ansible-dns'}) }}"
"""
RETURN = """
obj_type:
description:
- The object type specified in the terms argument
type: dictionary
contains:
obj_field:
description:
- One or more obj_type fields as specified by return_fields argument or
the default set of fields as per the object type
"""
from ansible.plugins.lookup import LookupBase
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiLookup
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_extattrs, flatten_extattrs
from ansible.errors import AnsibleError
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
try:
obj_type = terms[0]
except IndexError:
raise AnsibleError('the object_type must be specified')
return_fields = kwargs.pop('return_fields', None)
filter_data = kwargs.pop('filter', {})
extattrs = normalize_extattrs(kwargs.pop('extattrs', {}))
provider = kwargs.pop('provider', {})
wapi = WapiLookup(provider)
res = wapi.get_object(obj_type, filter_data, return_fields=return_fields, extattrs=extattrs)
if res is not None:
for obj in res:
if 'extattrs' in obj:
obj['extattrs'] = flatten_extattrs(obj['extattrs'])
else:
res = []
return res

View File

@@ -0,0 +1,105 @@
# -*- coding: utf-8 -*-
#
# Copyright 2018 Red Hat | Ansible
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = '''
---
author: Unknown (!UNKNOWN)
name: nios_next_ip
short_description: Return the next available IP address for a network
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding lookup from it.
alternative: infoblox.nios_modules.nios_next_ip
removed_in: 5.0.0
description:
- Uses the Infoblox WAPI API to return the next available IP addresses
for a given network CIDR
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
_terms:
description: The CIDR network to retrieve the next addresses from
required: True
num:
description: The number of IP addresses to return
required: false
default: 1
exclude:
description: List of IP's that need to be excluded from returned IP addresses
required: false
'''
EXAMPLES = """
- name: return next available IP address for network 192.168.10.0/24
ansible.builtin.set_fact:
ipaddr: "{{ lookup('community.general.nios_next_ip', '192.168.10.0/24', provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}"
- name: return the next 3 available IP addresses for network 192.168.10.0/24
ansible.builtin.set_fact:
ipaddr: "{{ lookup('community.general.nios_next_ip', '192.168.10.0/24', num=3, provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}"
- name: return the next 3 available IP addresses for network 192.168.10.0/24 excluding ip addresses - ['192.168.10.1', '192.168.10.2']
ansible.builtin.set_fact:
ipaddr: "{{ lookup('community.general.nios_next_ip', '192.168.10.0/24', num=3, exclude=['192.168.10.1', '192.168.10.2'],
provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}"
"""
RETURN = """
_list:
description:
- The list of next IP addresses available
type: list
"""
from ansible.plugins.lookup import LookupBase
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiLookup
from ansible.module_utils.common.text.converters import to_text
from ansible.errors import AnsibleError
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
try:
network = terms[0]
except IndexError:
raise AnsibleError('missing argument in the form of A.B.C.D/E')
provider = kwargs.pop('provider', {})
wapi = WapiLookup(provider)
network_obj = wapi.get_object('network', {'network': network})
if network_obj is None:
raise AnsibleError('unable to find network object %s' % network)
num = kwargs.get('num', 1)
exclude_ip = kwargs.get('exclude', [])
try:
ref = network_obj[0]['_ref']
avail_ips = wapi.call_func('next_available_ip', ref, {'num': num, 'exclude': exclude_ip})
return [avail_ips['ips']]
except Exception as exc:
raise AnsibleError(to_text(exc))

View File

@@ -0,0 +1,118 @@
# -*- coding: utf-8 -*-
#
# Copyright 2018 Red Hat | Ansible
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = '''
---
author: Unknown (!UNKNOWN)
name: nios_next_network
short_description: Return the next available network range for a network-container
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding lookup from it.
alternative: infoblox.nios_modules.nios_next_network
removed_in: 5.0.0
description:
- Uses the Infoblox WAPI API to return the next available network addresses for
a given network CIDR
requirements:
- infoblox_client
extends_documentation_fragment:
- community.general.nios
options:
_terms:
description: The CIDR network to retrieve the next network from next available network within the specified
container.
required: True
cidr:
description:
- 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
default: 1
exclude:
description: Network addresses returned from network-container excluding list of user's input network range
required: false
default: ''
'''
EXAMPLES = """
- name: return next available network for network-container 192.168.10.0/24
ansible.builtin.set_fact:
networkaddr: "{{ lookup('community.general.nios_next_network', '192.168.10.0/24', cidr=25,
provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}"
- name: return the next 2 available network addresses for network-container 192.168.10.0/24
ansible.builtin.set_fact:
networkaddr: "{{ lookup('community.general.nios_next_network', '192.168.10.0/24', cidr=25, num=2,
provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}"
- name: return the available network addresses for network-container 192.168.10.0/24 excluding network range '192.168.10.0/25'
ansible.builtin.set_fact:
networkaddr: "{{ lookup('community.general.nios_next_network', '192.168.10.0/24', cidr=25, exclude=['192.168.10.0/25'],
provider={'host': 'nios01', 'username': 'admin', 'password': 'password'}) }}"
"""
RETURN = """
_list:
description:
- The list of next network addresses available
type: list
"""
from ansible.plugins.lookup import LookupBase
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiLookup
from ansible.module_utils.common.text.converters import to_text
from ansible.errors import AnsibleError
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
try:
network = terms[0]
except IndexError:
raise AnsibleError('missing network argument in the form of A.B.C.D/E')
try:
cidr = kwargs.get('cidr', 24)
except IndexError:
raise AnsibleError('missing CIDR argument in the form of xx')
provider = kwargs.pop('provider', {})
wapi = WapiLookup(provider)
network_obj = wapi.get_object('networkcontainer', {'network': network})
if network_obj is None:
raise AnsibleError('unable to find network-container object %s' % network)
num = kwargs.get('num', 1)
exclude_ip = kwargs.get('exclude', [])
try:
ref = network_obj[0]['_ref']
avail_nets = wapi.call_func('next_available_network', ref, {'cidr': cidr, 'num': num, 'exclude': exclude_ip})
return [avail_nets['networks']]
except Exception as exc:
raise AnsibleError(to_text(exc))

View File

@@ -1,119 +0,0 @@
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""The community.general.random_words Ansible lookup plugin."""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r"""
name: random_words
author:
- Thomas Sjögren (@konstruktoid)
short_description: Return a number of random words
version_added: "4.0.0"
requirements:
- xkcdpass U(https://github.com/redacted/XKCD-password-generator)
description:
- Returns a number of random words. The output can for example be used for
passwords.
- See U(https://xkcd.com/936/) for background.
options:
numwords:
description:
- The number of words.
default: 6
type: int
min_length:
description:
- Minimum length of words to make password.
default: 5
type: int
max_length:
description:
- Maximum length of words to make password.
default: 9
type: int
delimiter:
description:
- The delimiter character between words.
default: " "
type: str
case:
description:
- The method for setting the case of each word in the passphrase.
choices: ["alternating", "upper", "lower", "random", "capitalize"]
default: "lower"
type: str
"""
EXAMPLES = r"""
- name: Generate password with default settings
ansible.builtin.debug:
var: lookup('community.general.random_words')
# Example result: 'traitor gigabyte cesarean unless aspect clear'
- name: Generate password with six, five character, words
ansible.builtin.debug:
var: lookup('community.general.random_words', min_length=5, max_length=5)
# Example result: 'brink banjo getup staff trump comfy'
- name: Generate password with three capitalized words and the '-' delimiter
ansible.builtin.debug:
var: lookup('community.general.random_words', numwords=3, delimiter='-', case='capitalize')
# Example result: 'Overlabor-Faucet-Coastline'
- name: Generate password with three words without any delimiter
ansible.builtin.debug:
var: lookup('community.general.random_words', numwords=3, delimiter='')
# Example result: 'deskworkmonopolystriking'
# https://www.ncsc.gov.uk/blog-post/the-logic-behind-three-random-words
"""
RETURN = r"""
_raw:
description: A single-element list containing random words.
type: list
elements: str
"""
from ansible.errors import AnsibleLookupError
from ansible.plugins.lookup import LookupBase
try:
from xkcdpass import xkcd_password as xp
HAS_XKCDPASS = True
except ImportError:
HAS_XKCDPASS = False
class LookupModule(LookupBase):
"""The random_words Ansible lookup class."""
def run(self, terms, variables=None, **kwargs):
if not HAS_XKCDPASS:
raise AnsibleLookupError(
"Python xkcdpass library is required. "
'Please install using "pip install xkcdpass"'
)
self.set_options(var_options=variables, direct=kwargs)
method = self.get_option("case")
delimiter = self.get_option("delimiter")
max_length = self.get_option("max_length")
min_length = self.get_option("min_length")
numwords = self.get_option("numwords")
words = xp.locate_wordfile()
wordlist = xp.generate_wordlist(
max_length=max_length, min_length=min_length, wordfile=words
)
values = xp.generate_xkcdpassword(
wordlist, case=method, delimiter=delimiter, numwords=numwords
)
return [values]

View File

@@ -0,0 +1,748 @@
# -*- coding: utf-8 -*-
# This code is part of Ansible, but is an independent component.
# This particular file snippet, and this file snippet only, is BSD licensed.
# Modules you write using this snippet, which is embedded dynamically by Ansible
# still belong to the author of the module, and may assign their own license
# to the complete work.
#
# Copyright (c) 2017, Sumit Kumar <sumit4@netapp.com>
# Copyright (c) 2017, Michael Price <michael.price@netapp.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import json
import os
import random
import mimetypes
from pprint import pformat
from ansible.module_utils import six
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError
from ansible.module_utils.urls import open_url
from ansible.module_utils.api import basic_auth_argument_spec
from ansible.module_utils.common.text.converters import to_native
try:
from ansible.module_utils.ansible_release import __version__ as ansible_version
except ImportError:
ansible_version = 'unknown'
try:
from netapp_lib.api.zapi import zapi
HAS_NETAPP_LIB = True
except ImportError:
HAS_NETAPP_LIB = False
try:
import requests
HAS_REQUESTS = True
except ImportError:
HAS_REQUESTS = False
import ssl
try:
from urlparse import urlparse, urlunparse
except ImportError:
from urllib.parse import urlparse, urlunparse
HAS_SF_SDK = False
SF_BYTE_MAP = dict(
# Management GUI displays 1024 ** 3 as 1.1 GB, thus use 1000.
bytes=1,
b=1,
kb=1000,
mb=1000 ** 2,
gb=1000 ** 3,
tb=1000 ** 4,
pb=1000 ** 5,
eb=1000 ** 6,
zb=1000 ** 7,
yb=1000 ** 8
)
POW2_BYTE_MAP = dict(
# Here, 1 kb = 1024
bytes=1,
b=1,
kb=1024,
mb=1024 ** 2,
gb=1024 ** 3,
tb=1024 ** 4,
pb=1024 ** 5,
eb=1024 ** 6,
zb=1024 ** 7,
yb=1024 ** 8
)
try:
from solidfire.factory import ElementFactory
from solidfire.custom.models import TimeIntervalFrequency
from solidfire.models import Schedule, ScheduleInfo
HAS_SF_SDK = True
except Exception:
HAS_SF_SDK = False
def has_netapp_lib():
return HAS_NETAPP_LIB
def has_sf_sdk():
return HAS_SF_SDK
def na_ontap_host_argument_spec():
return dict(
hostname=dict(required=True, type='str'),
username=dict(required=True, type='str', aliases=['user']),
password=dict(required=True, type='str', aliases=['pass'], no_log=True),
https=dict(required=False, type='bool', default=False),
validate_certs=dict(required=False, type='bool', default=True),
http_port=dict(required=False, type='int'),
ontapi=dict(required=False, type='int'),
use_rest=dict(required=False, type='str', default='Auto', choices=['Never', 'Always', 'Auto'])
)
def ontap_sf_host_argument_spec():
return dict(
hostname=dict(required=True, type='str'),
username=dict(required=True, type='str', aliases=['user']),
password=dict(required=True, type='str', aliases=['pass'], no_log=True)
)
def aws_cvs_host_argument_spec():
return dict(
api_url=dict(required=True, type='str'),
validate_certs=dict(required=False, type='bool', default=True),
api_key=dict(required=True, type='str', no_log=True),
secret_key=dict(required=True, type='str', no_log=True)
)
def create_sf_connection(module, port=None):
hostname = module.params['hostname']
username = module.params['username']
password = module.params['password']
if HAS_SF_SDK and hostname and username and password:
try:
return_val = ElementFactory.create(hostname, username, password, port=port)
return return_val
except Exception:
raise Exception("Unable to create SF connection")
else:
module.fail_json(msg="the python SolidFire SDK module is required")
def setup_na_ontap_zapi(module, vserver=None):
hostname = module.params['hostname']
username = module.params['username']
password = module.params['password']
https = module.params['https']
validate_certs = module.params['validate_certs']
port = module.params['http_port']
version = module.params['ontapi']
if HAS_NETAPP_LIB:
# set up zapi
server = zapi.NaServer(hostname)
server.set_username(username)
server.set_password(password)
if vserver:
server.set_vserver(vserver)
if version:
minor = version
else:
minor = 110
server.set_api_version(major=1, minor=minor)
# default is HTTP
if https:
if port is None:
port = 443
transport_type = 'HTTPS'
# HACK to bypass certificate verification
if validate_certs is False:
if not os.environ.get('PYTHONHTTPSVERIFY', '') and getattr(ssl, '_create_unverified_context', None):
ssl._create_default_https_context = ssl._create_unverified_context
else:
if port is None:
port = 80
transport_type = 'HTTP'
server.set_transport_type(transport_type)
server.set_port(port)
server.set_server_type('FILER')
return server
else:
module.fail_json(msg="the python NetApp-Lib module is required")
def setup_ontap_zapi(module, vserver=None):
hostname = module.params['hostname']
username = module.params['username']
password = module.params['password']
if HAS_NETAPP_LIB:
# set up zapi
server = zapi.NaServer(hostname)
server.set_username(username)
server.set_password(password)
if vserver:
server.set_vserver(vserver)
# Todo : Replace hard-coded values with configurable parameters.
server.set_api_version(major=1, minor=110)
server.set_port(80)
server.set_server_type('FILER')
server.set_transport_type('HTTP')
return server
else:
module.fail_json(msg="the python NetApp-Lib module is required")
def eseries_host_argument_spec():
"""Retrieve a base argument specification common to all NetApp E-Series modules"""
argument_spec = basic_auth_argument_spec()
argument_spec.update(dict(
api_username=dict(type='str', required=True),
api_password=dict(type='str', required=True, no_log=True),
api_url=dict(type='str', required=True),
ssid=dict(type='str', required=False, default='1'),
validate_certs=dict(type='bool', required=False, default=True)
))
return argument_spec
class NetAppESeriesModule(object):
"""Base class for all NetApp E-Series modules.
Provides a set of common methods for NetApp E-Series modules, including version checking, mode (proxy, embedded)
verification, http requests, secure http redirection for embedded web services, and logging setup.
Be sure to add the following lines in the module's documentation section:
extends_documentation_fragment:
- netapp.eseries
:param dict(dict) ansible_options: dictionary of ansible option definitions
:param str web_services_version: minimally required web services rest api version (default value: "02.00.0000.0000")
:param bool supports_check_mode: whether the module will support the check_mode capabilities (default=False)
:param list(list) mutually_exclusive: list containing list(s) of mutually exclusive options (optional)
:param list(list) required_if: list containing list(s) containing the option, the option value, and then
a list of required options. (optional)
:param list(list) required_one_of: list containing list(s) of options for which at least one is required. (optional)
:param list(list) required_together: list containing list(s) of options that are required together. (optional)
:param bool log_requests: controls whether to log each request (default: True)
"""
DEFAULT_TIMEOUT = 60
DEFAULT_SECURE_PORT = "8443"
DEFAULT_REST_API_PATH = "devmgr/v2/"
DEFAULT_REST_API_ABOUT_PATH = "devmgr/utils/about"
DEFAULT_HEADERS = {"Content-Type": "application/json", "Accept": "application/json",
"netapp-client-type": "Ansible-%s" % ansible_version}
HTTP_AGENT = "Ansible / %s" % ansible_version
SIZE_UNIT_MAP = dict(bytes=1, b=1, kb=1024, mb=1024**2, gb=1024**3, tb=1024**4,
pb=1024**5, eb=1024**6, zb=1024**7, yb=1024**8)
def __init__(self, ansible_options, web_services_version=None, supports_check_mode=False,
mutually_exclusive=None, required_if=None, required_one_of=None, required_together=None,
log_requests=True):
argument_spec = eseries_host_argument_spec()
argument_spec.update(ansible_options)
self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=supports_check_mode,
mutually_exclusive=mutually_exclusive, required_if=required_if,
required_one_of=required_one_of, required_together=required_together)
args = self.module.params
self.web_services_version = web_services_version if web_services_version else "02.00.0000.0000"
self.ssid = args["ssid"]
self.url = args["api_url"]
self.log_requests = log_requests
self.creds = dict(url_username=args["api_username"],
url_password=args["api_password"],
validate_certs=args["validate_certs"])
if not self.url.endswith("/"):
self.url += "/"
self.is_embedded_mode = None
self.is_web_services_valid_cache = None
def _check_web_services_version(self):
"""Verify proxy or embedded web services meets minimum version required for module.
The minimum required web services version is evaluated against version supplied through the web services rest
api. AnsibleFailJson exception will be raised when the minimum is not met or exceeded.
This helper function will update the supplied api url if secure http is not used for embedded web services
:raise AnsibleFailJson: raised when the contacted api service does not meet the minimum required version.
"""
if not self.is_web_services_valid_cache:
url_parts = urlparse(self.url)
if not url_parts.scheme or not url_parts.netloc:
self.module.fail_json(msg="Failed to provide valid API URL. Example: https://192.168.1.100:8443/devmgr/v2. URL [%s]." % self.url)
if url_parts.scheme not in ["http", "https"]:
self.module.fail_json(msg="Protocol must be http or https. URL [%s]." % self.url)
self.url = "%s://%s/" % (url_parts.scheme, url_parts.netloc)
about_url = self.url + self.DEFAULT_REST_API_ABOUT_PATH
rc, data = request(about_url, timeout=self.DEFAULT_TIMEOUT, headers=self.DEFAULT_HEADERS, ignore_errors=True, **self.creds)
if rc != 200:
self.module.warn("Failed to retrieve web services about information! Retrying with secure ports. Array Id [%s]." % self.ssid)
self.url = "https://%s:8443/" % url_parts.netloc.split(":")[0]
about_url = self.url + self.DEFAULT_REST_API_ABOUT_PATH
try:
rc, data = request(about_url, timeout=self.DEFAULT_TIMEOUT, headers=self.DEFAULT_HEADERS, **self.creds)
except Exception as error:
self.module.fail_json(msg="Failed to retrieve the webservices about information! Array Id [%s]. Error [%s]."
% (self.ssid, to_native(error)))
major, minor, other, revision = data["version"].split(".")
minimum_major, minimum_minor, other, minimum_revision = self.web_services_version.split(".")
if not (major > minimum_major or
(major == minimum_major and minor > minimum_minor) or
(major == minimum_major and minor == minimum_minor and revision >= minimum_revision)):
self.module.fail_json(msg="Web services version does not meet minimum version required. Current version: [%s]."
" Version required: [%s]." % (data["version"], self.web_services_version))
self.module.log("Web services rest api version met the minimum required version.")
self.is_web_services_valid_cache = True
def is_embedded(self):
"""Determine whether web services server is the embedded web services.
If web services about endpoint fails based on an URLError then the request will be attempted again using
secure http.
:raise AnsibleFailJson: raised when web services about endpoint failed to be contacted.
:return bool: whether contacted web services is running from storage array (embedded) or from a proxy.
"""
self._check_web_services_version()
if self.is_embedded_mode is None:
about_url = self.url + self.DEFAULT_REST_API_ABOUT_PATH
try:
rc, data = request(about_url, timeout=self.DEFAULT_TIMEOUT, headers=self.DEFAULT_HEADERS, **self.creds)
self.is_embedded_mode = not data["runningAsProxy"]
except Exception as error:
self.module.fail_json(msg="Failed to retrieve the webservices about information! Array Id [%s]. Error [%s]."
% (self.ssid, to_native(error)))
return self.is_embedded_mode
def request(self, path, data=None, method='GET', headers=None, ignore_errors=False):
"""Issue an HTTP request to a url, retrieving an optional JSON response.
:param str path: web services rest api endpoint path (Example: storage-systems/1/graph). Note that when the
full url path is specified then that will be used without supplying the protocol, hostname, port and rest path.
:param data: data required for the request (data may be json or any python structured data)
:param str method: request method such as GET, POST, DELETE.
:param dict headers: dictionary containing request headers.
:param bool ignore_errors: forces the request to ignore any raised exceptions.
"""
self._check_web_services_version()
if headers is None:
headers = self.DEFAULT_HEADERS
if not isinstance(data, str) and headers["Content-Type"] == "application/json":
data = json.dumps(data)
if path.startswith("/"):
path = path[1:]
request_url = self.url + self.DEFAULT_REST_API_PATH + path
# if self.log_requests:
self.module.log(pformat(dict(url=request_url, data=data, method=method)))
return request(url=request_url, data=data, method=method, headers=headers, use_proxy=True, force=False, last_mod_time=None,
timeout=self.DEFAULT_TIMEOUT, http_agent=self.HTTP_AGENT, force_basic_auth=True, ignore_errors=ignore_errors, **self.creds)
def create_multipart_formdata(files, fields=None, send_8kb=False):
"""Create the data for a multipart/form request.
:param list(list) files: list of lists each containing (name, filename, path).
:param list(list) fields: list of lists each containing (key, value).
:param bool send_8kb: only sends the first 8kb of the files (default: False).
"""
boundary = "---------------------------" + "".join([str(random.randint(0, 9)) for x in range(27)])
data_parts = list()
data = None
if six.PY2: # Generate payload for Python 2
newline = "\r\n"
if fields is not None:
for key, value in fields:
data_parts.extend(["--%s" % boundary,
'Content-Disposition: form-data; name="%s"' % key,
"",
value])
for name, filename, path in files:
with open(path, "rb") as fh:
value = fh.read(8192) if send_8kb else fh.read()
data_parts.extend(["--%s" % boundary,
'Content-Disposition: form-data; name="%s"; filename="%s"' % (name, filename),
"Content-Type: %s" % (mimetypes.guess_type(path)[0] or "application/octet-stream"),
"",
value])
data_parts.extend(["--%s--" % boundary, ""])
data = newline.join(data_parts)
else:
newline = six.b("\r\n")
if fields is not None:
for key, value in fields:
data_parts.extend([six.b("--%s" % boundary),
six.b('Content-Disposition: form-data; name="%s"' % key),
six.b(""),
six.b(value)])
for name, filename, path in files:
with open(path, "rb") as fh:
value = fh.read(8192) if send_8kb else fh.read()
data_parts.extend([six.b("--%s" % boundary),
six.b('Content-Disposition: form-data; name="%s"; filename="%s"' % (name, filename)),
six.b("Content-Type: %s" % (mimetypes.guess_type(path)[0] or "application/octet-stream")),
six.b(""),
value])
data_parts.extend([six.b("--%s--" % boundary), b""])
data = newline.join(data_parts)
headers = {
"Content-Type": "multipart/form-data; boundary=%s" % boundary,
"Content-Length": str(len(data))}
return headers, data
def request(url, data=None, headers=None, method='GET', use_proxy=True,
force=False, last_mod_time=None, timeout=10, validate_certs=True,
url_username=None, url_password=None, http_agent=None, force_basic_auth=True, ignore_errors=False):
"""Issue an HTTP request to a url, retrieving an optional JSON response."""
if headers is None:
headers = {"Content-Type": "application/json", "Accept": "application/json"}
headers.update({"netapp-client-type": "Ansible-%s" % ansible_version})
if not http_agent:
http_agent = "Ansible / %s" % ansible_version
try:
r = open_url(url=url, data=data, headers=headers, method=method, use_proxy=use_proxy,
force=force, last_mod_time=last_mod_time, timeout=timeout, validate_certs=validate_certs,
url_username=url_username, url_password=url_password, http_agent=http_agent,
force_basic_auth=force_basic_auth)
except HTTPError as err:
r = err.fp
try:
raw_data = r.read()
if raw_data:
data = json.loads(raw_data)
else:
raw_data = None
except Exception:
if ignore_errors:
pass
else:
raise Exception(raw_data)
resp_code = r.getcode()
if resp_code >= 400 and not ignore_errors:
raise Exception(resp_code, data)
else:
return resp_code, data
def ems_log_event(source, server, name="Ansible", id="12345", version=ansible_version,
category="Information", event="setup", autosupport="false"):
ems_log = zapi.NaElement('ems-autosupport-log')
# Host name invoking the API.
ems_log.add_new_child("computer-name", name)
# ID of event. A user defined event-id, range [0..2^32-2].
ems_log.add_new_child("event-id", id)
# Name of the application invoking the API.
ems_log.add_new_child("event-source", source)
# Version of application invoking the API.
ems_log.add_new_child("app-version", version)
# Application defined category of the event.
ems_log.add_new_child("category", category)
# Description of event to log. An application defined message to log.
ems_log.add_new_child("event-description", event)
ems_log.add_new_child("log-level", "6")
ems_log.add_new_child("auto-support", autosupport)
server.invoke_successfully(ems_log, True)
def get_cserver_zapi(server):
vserver_info = zapi.NaElement('vserver-get-iter')
query_details = zapi.NaElement.create_node_with_children('vserver-info', **{'vserver-type': 'admin'})
query = zapi.NaElement('query')
query.add_child_elem(query_details)
vserver_info.add_child_elem(query)
result = server.invoke_successfully(vserver_info,
enable_tunneling=False)
attribute_list = result.get_child_by_name('attributes-list')
vserver_list = attribute_list.get_child_by_name('vserver-info')
return vserver_list.get_child_content('vserver-name')
def get_cserver(connection, is_rest=False):
if not is_rest:
return get_cserver_zapi(connection)
params = {'fields': 'type'}
api = "private/cli/vserver"
json, error = connection.get(api, params)
if json is None or error is not None:
# exit if there is an error or no data
return None
vservers = json.get('records')
if vservers is not None:
for vserver in vservers:
if vserver['type'] == 'admin': # cluster admin
return vserver['vserver']
if len(vservers) == 1: # assume vserver admin
return vservers[0]['vserver']
return None
class OntapRestAPI(object):
def __init__(self, module, timeout=60):
self.module = module
self.username = self.module.params['username']
self.password = self.module.params['password']
self.hostname = self.module.params['hostname']
self.use_rest = self.module.params['use_rest']
self.verify = self.module.params['validate_certs']
self.timeout = timeout
self.url = 'https://' + self.hostname + '/api/'
self.errors = list()
self.debug_logs = list()
self.check_required_library()
def check_required_library(self):
if not HAS_REQUESTS:
self.module.fail_json(msg=missing_required_lib('requests'))
def send_request(self, method, api, params, json=None, return_status_code=False):
''' send http request and process reponse, including error conditions '''
url = self.url + api
status_code = None
content = None
json_dict = None
json_error = None
error_details = None
def get_json(response):
''' extract json, and error message if present '''
try:
json = response.json()
except ValueError:
return None, None
error = json.get('error')
return json, error
try:
response = requests.request(method, url, verify=self.verify, auth=(self.username, self.password), params=params, timeout=self.timeout, json=json)
content = response.content # for debug purposes
status_code = response.status_code
# If the response was successful, no Exception will be raised
response.raise_for_status()
json_dict, json_error = get_json(response)
except requests.exceptions.HTTPError as err:
__, json_error = get_json(response)
if json_error is None:
self.log_error(status_code, 'HTTP error: %s' % err)
error_details = str(err)
# If an error was reported in the json payload, it is handled below
except requests.exceptions.ConnectionError as err:
self.log_error(status_code, 'Connection error: %s' % err)
error_details = str(err)
except Exception as err:
self.log_error(status_code, 'Other error: %s' % err)
error_details = str(err)
if json_error is not None:
self.log_error(status_code, 'Endpoint error: %d: %s' % (status_code, json_error))
error_details = json_error
self.log_debug(status_code, content)
if return_status_code:
return status_code, error_details
return json_dict, error_details
def get(self, api, params):
method = 'GET'
return self.send_request(method, api, params)
def post(self, api, data, params=None):
method = 'POST'
return self.send_request(method, api, params, json=data)
def patch(self, api, data, params=None):
method = 'PATCH'
return self.send_request(method, api, params, json=data)
def delete(self, api, data, params=None):
method = 'DELETE'
return self.send_request(method, api, params, json=data)
def _is_rest(self, used_unsupported_rest_properties=None):
if self.use_rest == "Always":
if used_unsupported_rest_properties:
error = "REST API currently does not support '%s'" % \
', '.join(used_unsupported_rest_properties)
return True, error
else:
return True, None
if self.use_rest == 'Never' or used_unsupported_rest_properties:
# force ZAPI if requested or if some parameter requires it
return False, None
method = 'HEAD'
api = 'cluster/software'
status_code, __ = self.send_request(method, api, params=None, return_status_code=True)
if status_code == 200:
return True, None
return False, None
def is_rest(self, used_unsupported_rest_properties=None):
''' only return error if there is a reason to '''
use_rest, error = self._is_rest(used_unsupported_rest_properties)
if used_unsupported_rest_properties is None:
return use_rest
return use_rest, error
def log_error(self, status_code, message):
self.errors.append(message)
self.debug_logs.append((status_code, message))
def log_debug(self, status_code, content):
self.debug_logs.append((status_code, content))
class AwsCvsRestAPI(object):
def __init__(self, module, timeout=60):
self.module = module
self.api_key = self.module.params['api_key']
self.secret_key = self.module.params['secret_key']
self.api_url = self.module.params['api_url']
self.verify = self.module.params['validate_certs']
self.timeout = timeout
self.url = 'https://' + self.api_url + '/v1/'
self.check_required_library()
def check_required_library(self):
if not HAS_REQUESTS:
self.module.fail_json(msg=missing_required_lib('requests'))
def send_request(self, method, api, params, json=None):
''' send http request and process reponse, including error conditions '''
url = self.url + api
status_code = None
content = None
json_dict = None
json_error = None
error_details = None
headers = {
'Content-type': "application/json",
'api-key': self.api_key,
'secret-key': self.secret_key,
'Cache-Control': "no-cache",
}
def get_json(response):
''' extract json, and error message if present '''
try:
json = response.json()
except ValueError:
return None, None
success_code = [200, 201, 202]
if response.status_code not in success_code:
error = json.get('message')
else:
error = None
return json, error
try:
response = requests.request(method, url, headers=headers, timeout=self.timeout, json=json)
status_code = response.status_code
# If the response was successful, no Exception will be raised
json_dict, json_error = get_json(response)
except requests.exceptions.HTTPError as err:
__, json_error = get_json(response)
if json_error is None:
error_details = str(err)
except requests.exceptions.ConnectionError as err:
error_details = str(err)
except Exception as err:
error_details = str(err)
if json_error is not None:
error_details = json_error
return json_dict, error_details
# If an error was reported in the json payload, it is handled below
def get(self, api, params=None):
method = 'GET'
return self.send_request(method, api, params)
def post(self, api, data, params=None):
method = 'POST'
return self.send_request(method, api, params, json=data)
def patch(self, api, data, params=None):
method = 'PATCH'
return self.send_request(method, api, params, json=data)
def put(self, api, data, params=None):
method = 'PUT'
return self.send_request(method, api, params, json=data)
def delete(self, api, data, params=None):
method = 'DELETE'
return self.send_request(method, api, params, json=data)
def get_state(self, jobId):
""" Method to get the state of the job """
method = 'GET'
response, status_code = self.get('Jobs/%s' % jobId)
while str(response['state']) not in 'done':
response, status_code = self.get('Jobs/%s' % jobId)
return 'done'

File diff suppressed because it is too large Load Diff

View File

@@ -179,10 +179,10 @@ class IPAClient(object):
result.append(key)
return result
def modify_if_diff(self, name, ipa_list, module_list, add_method, remove_method, item=None, append=None):
def modify_if_diff(self, name, ipa_list, module_list, add_method, remove_method, item=None):
changed = False
diff = list(set(ipa_list) - set(module_list))
if append is not True and len(diff) > 0:
if len(diff) > 0:
changed = True
if not self.module.check_mode:
if item:

View File

@@ -141,7 +141,11 @@ class CmdMixin(object):
fmt = find_format(param)
value = extra_params[param]
else:
raise self.ModuleHelperException('Cannot determine value for parameter: {0}'.format(param))
self.module.deprecate("Cannot determine value for parameter: {0}. "
"From version 4.0.0 onwards this will generate an exception".format(param),
version="4.0.0", collection_name="community.general")
continue
else:
raise self.ModuleHelperException("run_command parameter must be either a str or a dict: {0}".format(param))
cmd_args = add_arg_formatted_param(cmd_args, fmt, value)
@@ -158,9 +162,8 @@ class CmdMixin(object):
publish_rc=True,
publish_out=True,
publish_err=True,
publish_cmd=True,
*args, **kwargs):
cmd_args = self._calculate_args(extra_params, params)
self.vars.cmd_args = self._calculate_args(extra_params, params)
options = dict(self.run_command_fixed_options)
options['check_rc'] = options.get('check_rc', self.check_rc)
options.update(kwargs)
@@ -172,15 +175,13 @@ class CmdMixin(object):
})
self.update_output(force_lang=self.force_lang)
options['environ_update'] = env_update
rc, out, err = self.module.run_command(cmd_args, *args, **options)
rc, out, err = self.module.run_command(self.vars.cmd_args, *args, **options)
if publish_rc:
self.update_output(rc=rc)
if publish_out:
self.update_output(stdout=out)
if publish_err:
self.update_output(stderr=err)
if publish_cmd:
self.update_output(cmd_args=cmd_args)
if process_output is None:
_process = self.process_command_output
else:

View File

@@ -0,0 +1,598 @@
# -*- coding: utf-8 -*-
# This code is part of Ansible, but is an independent component.
# This particular file snippet, and this file snippet only, is BSD licensed.
# Modules you write using this snippet, which is embedded dynamically by Ansible
# still belong to the author of the module, and may assign their own license
# to the complete work.
#
# (c) 2018 Red Hat Inc.
#
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
from functools import partial
from ansible.module_utils.common.text.converters import to_native
from ansible.module_utils.six import iteritems
from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.basic import env_fallback
from ansible.module_utils.common.validation import check_type_dict
try:
from infoblox_client.connector import Connector
from infoblox_client.exceptions import InfobloxException
HAS_INFOBLOX_CLIENT = True
except ImportError:
HAS_INFOBLOX_CLIENT = False
# defining nios constants
NIOS_DNS_VIEW = 'view'
NIOS_NETWORK_VIEW = 'networkview'
NIOS_HOST_RECORD = 'record:host'
NIOS_IPV4_NETWORK = 'network'
NIOS_IPV6_NETWORK = 'ipv6network'
NIOS_ZONE = 'zone_auth'
NIOS_PTR_RECORD = 'record:ptr'
NIOS_A_RECORD = 'record:a'
NIOS_AAAA_RECORD = 'record:aaaa'
NIOS_CNAME_RECORD = 'record:cname'
NIOS_MX_RECORD = 'record:mx'
NIOS_SRV_RECORD = 'record:srv'
NIOS_NAPTR_RECORD = 'record:naptr'
NIOS_TXT_RECORD = 'record:txt'
NIOS_NSGROUP = 'nsgroup'
NIOS_IPV4_FIXED_ADDRESS = 'fixedaddress'
NIOS_IPV6_FIXED_ADDRESS = 'ipv6fixedaddress'
NIOS_NEXT_AVAILABLE_IP = 'func:nextavailableip'
NIOS_IPV4_NETWORK_CONTAINER = 'networkcontainer'
NIOS_IPV6_NETWORK_CONTAINER = 'ipv6networkcontainer'
NIOS_MEMBER = 'member'
NIOS_PROVIDER_SPEC = {
'host': dict(fallback=(env_fallback, ['INFOBLOX_HOST'])),
'username': dict(fallback=(env_fallback, ['INFOBLOX_USERNAME'])),
'password': dict(fallback=(env_fallback, ['INFOBLOX_PASSWORD']), no_log=True),
'validate_certs': dict(type='bool', default=False, fallback=(env_fallback, ['INFOBLOX_SSL_VERIFY']), aliases=['ssl_verify']),
'silent_ssl_warnings': dict(type='bool', default=True),
'http_request_timeout': dict(type='int', default=10, fallback=(env_fallback, ['INFOBLOX_HTTP_REQUEST_TIMEOUT'])),
'http_pool_connections': dict(type='int', default=10),
'http_pool_maxsize': dict(type='int', default=10),
'max_retries': dict(type='int', default=3, fallback=(env_fallback, ['INFOBLOX_MAX_RETRIES'])),
'wapi_version': dict(default='2.1', fallback=(env_fallback, ['INFOBLOX_WAP_VERSION'])),
'max_results': dict(type='int', default=1000, fallback=(env_fallback, ['INFOBLOX_MAX_RETRIES']))
}
def get_connector(*args, **kwargs):
''' Returns an instance of infoblox_client.connector.Connector
:params args: positional arguments are silently ignored
:params kwargs: dict that is passed to Connector init
:returns: Connector
'''
if not HAS_INFOBLOX_CLIENT:
raise Exception('infoblox-client is required but does not appear '
'to be installed. It can be installed using the '
'command `pip install infoblox-client`')
if not set(kwargs.keys()).issubset(list(NIOS_PROVIDER_SPEC.keys()) + ['ssl_verify']):
raise Exception('invalid or unsupported keyword argument for connector')
for key, value in iteritems(NIOS_PROVIDER_SPEC):
if key not in kwargs:
# apply default values from NIOS_PROVIDER_SPEC since we cannot just
# assume the provider values are coming from AnsibleModule
if 'default' in value:
kwargs[key] = value['default']
# override any values with env variables unless they were
# explicitly set
env = ('INFOBLOX_%s' % key).upper()
if env in os.environ:
kwargs[key] = os.environ.get(env)
if 'validate_certs' in kwargs.keys():
kwargs['ssl_verify'] = kwargs['validate_certs']
kwargs.pop('validate_certs', None)
return Connector(kwargs)
def normalize_extattrs(value):
''' Normalize extattrs field to expected format
The module accepts extattrs as key/value pairs. This method will
transform the key/value pairs into a structure suitable for
sending across WAPI in the format of:
extattrs: {
key: {
value: <value>
}
}
'''
return dict([(k, {'value': v}) for k, v in iteritems(value)])
def flatten_extattrs(value):
''' Flatten the key/value struct for extattrs
WAPI returns extattrs field as a dict in form of:
extattrs: {
key: {
value: <value>
}
}
This method will flatten the structure to:
extattrs: {
key: value
}
'''
return dict([(k, v['value']) for k, v in iteritems(value)])
def member_normalize(member_spec):
''' Transforms the member module arguments into a valid WAPI struct
This function will transform the arguments into a structure that
is a valid WAPI structure in the format of:
{
key: <value>,
}
It will remove any arguments that are set to None since WAPI will error on
that condition.
The remainder of the value validation is performed by WAPI
Some parameters in ib_spec are passed as a list in order to pass the validation for elements.
In this function, they are converted to dictionary.
'''
member_elements = ['vip_setting', 'ipv6_setting', 'lan2_port_setting', 'mgmt_port_setting',
'pre_provisioning', 'network_setting', 'v6_network_setting',
'ha_port_setting', 'lan_port_setting', 'lan2_physical_setting',
'lan_ha_port_setting', 'mgmt_network_setting', 'v6_mgmt_network_setting']
for key in list(member_spec.keys()):
if key in member_elements and member_spec[key] is not None:
member_spec[key] = member_spec[key][0]
if isinstance(member_spec[key], dict):
member_spec[key] = member_normalize(member_spec[key])
elif isinstance(member_spec[key], list):
for x in member_spec[key]:
if isinstance(x, dict):
x = member_normalize(x)
elif member_spec[key] is None:
del member_spec[key]
return member_spec
def normalize_ib_spec(ib_spec):
result = {}
for arg in ib_spec:
result[arg] = dict([(k, v)
for k, v in iteritems(ib_spec[arg])
if k not in ('ib_req', 'transform', 'update')])
return result
class WapiBase(object):
''' Base class for implementing Infoblox WAPI API '''
provider_spec = {'provider': dict(type='dict', options=NIOS_PROVIDER_SPEC)}
def __init__(self, provider):
self.connector = get_connector(**provider)
def __getattr__(self, name):
try:
return self.__dict__[name]
except KeyError:
if name.startswith('_'):
raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, name))
return partial(self._invoke_method, name)
def _invoke_method(self, name, *args, **kwargs):
try:
method = getattr(self.connector, name)
return method(*args, **kwargs)
except InfobloxException as exc:
if hasattr(self, 'handle_exception'):
self.handle_exception(name, exc)
else:
raise
class WapiLookup(WapiBase):
''' Implements WapiBase for lookup plugins '''
def handle_exception(self, method_name, exc):
if ('text' in exc.response):
raise Exception(exc.response['text'])
else:
raise Exception(exc)
class WapiInventory(WapiBase):
''' Implements WapiBase for dynamic inventory script '''
pass
class WapiModule(WapiBase):
''' Implements WapiBase for executing a NIOS module '''
def __init__(self, module):
self.module = module
provider = module.params['provider']
try:
super(WapiModule, self).__init__(provider)
except Exception as exc:
self.module.fail_json(msg=to_text(exc))
def handle_exception(self, method_name, exc):
''' Handles any exceptions raised
This method will be called if an InfobloxException is raised for
any call to the instance of Connector and also, in case of generic
exception. This method will then gracefully fail the module.
:args exc: instance of InfobloxException
'''
if ('text' in exc.response):
self.module.fail_json(
msg=exc.response['text'],
type=exc.response['Error'].split(':')[0],
code=exc.response.get('code'),
operation=method_name
)
else:
self.module.fail_json(msg=to_native(exc))
def run(self, ib_obj_type, ib_spec):
''' Runs the module and performans configuration tasks
:args ib_obj_type: the WAPI object type to operate against
:args ib_spec: the specification for the WAPI object as a dict
:returns: a results dict
'''
update = new_name = None
state = self.module.params['state']
if state not in ('present', 'absent'):
self.module.fail_json(msg='state must be one of `present`, `absent`, got `%s`' % state)
result = {'changed': False}
obj_filter = dict([(k, self.module.params[k]) for k, v in iteritems(ib_spec) if v.get('ib_req')])
# get object reference
ib_obj_ref, update, new_name = self.get_object_ref(self.module, ib_obj_type, obj_filter, ib_spec)
proposed_object = {}
for key, value in iteritems(ib_spec):
if self.module.params[key] is not None:
if 'transform' in value:
proposed_object[key] = value['transform'](self.module)
else:
proposed_object[key] = self.module.params[key]
# If configure_by_dns is set to False and view is 'default', then delete the default dns
if not proposed_object.get('configure_for_dns') and proposed_object.get('view') == 'default'\
and ib_obj_type == NIOS_HOST_RECORD:
del proposed_object['view']
if ib_obj_ref:
if len(ib_obj_ref) > 1:
for each in ib_obj_ref:
# To check for existing A_record with same name with input A_record by IP
if each.get('ipv4addr') and each.get('ipv4addr') == proposed_object.get('ipv4addr'):
current_object = each
# To check for existing Host_record with same name with input Host_record by IP
elif each.get('ipv4addrs')[0].get('ipv4addr') and each.get('ipv4addrs')[0].get('ipv4addr')\
== proposed_object.get('ipv4addrs')[0].get('ipv4addr'):
current_object = each
# Else set the current_object with input value
else:
current_object = obj_filter
ref = None
else:
current_object = ib_obj_ref[0]
if 'extattrs' in current_object:
current_object['extattrs'] = flatten_extattrs(current_object['extattrs'])
if current_object.get('_ref'):
ref = current_object.pop('_ref')
else:
current_object = obj_filter
ref = None
# checks if the object type is member to normalize the attributes being passed
if (ib_obj_type == NIOS_MEMBER):
proposed_object = member_normalize(proposed_object)
# checks if the name's field has been updated
if update and new_name:
proposed_object['name'] = new_name
check_remove = []
if (ib_obj_type == NIOS_HOST_RECORD):
# this check is for idempotency, as if the same ip address shall be passed
# add param will be removed, and same exists true for remove case as well.
if 'ipv4addrs' in [current_object and proposed_object]:
for each in current_object['ipv4addrs']:
if each['ipv4addr'] == proposed_object['ipv4addrs'][0]['ipv4addr']:
if 'add' in proposed_object['ipv4addrs'][0]:
del proposed_object['ipv4addrs'][0]['add']
break
check_remove += each.values()
if proposed_object['ipv4addrs'][0]['ipv4addr'] not in check_remove:
if 'remove' in proposed_object['ipv4addrs'][0]:
del proposed_object['ipv4addrs'][0]['remove']
res = None
modified = not self.compare_objects(current_object, proposed_object)
if 'extattrs' in proposed_object:
proposed_object['extattrs'] = normalize_extattrs(proposed_object['extattrs'])
# Checks if nios_next_ip param is passed in ipv4addrs/ipv4addr args
proposed_object = self.check_if_nios_next_ip_exists(proposed_object)
if state == 'present':
if ref is None:
if not self.module.check_mode:
self.create_object(ib_obj_type, proposed_object)
result['changed'] = True
# Check if NIOS_MEMBER and the flag to call function create_token is set
elif (ib_obj_type == NIOS_MEMBER) and (proposed_object['create_token']):
proposed_object = None
# the function creates a token that can be used by a pre-provisioned member to join the grid
result['api_results'] = self.call_func('create_token', ref, proposed_object)
result['changed'] = True
elif modified:
if 'ipv4addrs' in proposed_object:
if ('add' not in proposed_object['ipv4addrs'][0]) and ('remove' not in proposed_object['ipv4addrs'][0]):
self.check_if_recordname_exists(obj_filter, ib_obj_ref, ib_obj_type, current_object, proposed_object)
if (ib_obj_type in (NIOS_HOST_RECORD, NIOS_NETWORK_VIEW, NIOS_DNS_VIEW)):
run_update = True
proposed_object = self.on_update(proposed_object, ib_spec)
if 'ipv4addrs' in proposed_object:
if ('add' or 'remove') in proposed_object['ipv4addrs'][0]:
run_update, proposed_object = self.check_if_add_remove_ip_arg_exists(proposed_object)
if run_update:
res = self.update_object(ref, proposed_object)
result['changed'] = True
else:
res = ref
if (ib_obj_type in (NIOS_A_RECORD, NIOS_AAAA_RECORD, NIOS_PTR_RECORD, NIOS_SRV_RECORD)):
# popping 'view' key as update of 'view' is not supported with respect to a:record/aaaa:record/srv:record/ptr:record
proposed_object = self.on_update(proposed_object, ib_spec)
del proposed_object['view']
if not self.module.check_mode:
res = self.update_object(ref, proposed_object)
result['changed'] = True
elif 'network_view' in proposed_object:
proposed_object.pop('network_view')
result['changed'] = True
if not self.module.check_mode and res is None:
proposed_object = self.on_update(proposed_object, ib_spec)
self.update_object(ref, proposed_object)
result['changed'] = True
elif state == 'absent':
if ref is not None:
if 'ipv4addrs' in proposed_object:
if 'remove' in proposed_object['ipv4addrs'][0]:
self.check_if_add_remove_ip_arg_exists(proposed_object)
self.update_object(ref, proposed_object)
result['changed'] = True
elif not self.module.check_mode:
self.delete_object(ref)
result['changed'] = True
return result
def check_if_recordname_exists(self, obj_filter, ib_obj_ref, ib_obj_type, current_object, proposed_object):
''' Send POST request if host record input name and retrieved ref name is same,
but input IP and retrieved IP is different'''
if 'name' in (obj_filter and ib_obj_ref[0]) and ib_obj_type == NIOS_HOST_RECORD:
obj_host_name = obj_filter['name']
ref_host_name = ib_obj_ref[0]['name']
if 'ipv4addrs' in (current_object and proposed_object):
current_ip_addr = current_object['ipv4addrs'][0]['ipv4addr']
proposed_ip_addr = proposed_object['ipv4addrs'][0]['ipv4addr']
elif 'ipv6addrs' in (current_object and proposed_object):
current_ip_addr = current_object['ipv6addrs'][0]['ipv6addr']
proposed_ip_addr = proposed_object['ipv6addrs'][0]['ipv6addr']
if obj_host_name == ref_host_name and current_ip_addr != proposed_ip_addr:
self.create_object(ib_obj_type, proposed_object)
def check_if_nios_next_ip_exists(self, proposed_object):
''' Check if nios_next_ip argument is passed in ipaddr while creating
host record, if yes then format proposed object ipv4addrs and pass
func:nextavailableip and ipaddr range to create hostrecord with next
available ip in one call to avoid any race condition '''
if 'ipv4addrs' in proposed_object:
if 'nios_next_ip' in proposed_object['ipv4addrs'][0]['ipv4addr']:
ip_range = check_type_dict(proposed_object['ipv4addrs'][0]['ipv4addr'])['nios_next_ip']
proposed_object['ipv4addrs'][0]['ipv4addr'] = NIOS_NEXT_AVAILABLE_IP + ':' + ip_range
elif 'ipv4addr' in proposed_object:
if 'nios_next_ip' in proposed_object['ipv4addr']:
ip_range = check_type_dict(proposed_object['ipv4addr'])['nios_next_ip']
proposed_object['ipv4addr'] = NIOS_NEXT_AVAILABLE_IP + ':' + ip_range
return proposed_object
def check_if_add_remove_ip_arg_exists(self, proposed_object):
'''
This function shall check if add/remove param is set to true and
is passed in the args, then we will update the proposed dictionary
to add/remove IP to existing host_record, if the user passes false
param with the argument nothing shall be done.
:returns: True if param is changed based on add/remove, and also the
changed proposed_object.
'''
update = False
if 'add' in proposed_object['ipv4addrs'][0]:
if proposed_object['ipv4addrs'][0]['add']:
proposed_object['ipv4addrs+'] = proposed_object['ipv4addrs']
del proposed_object['ipv4addrs']
del proposed_object['ipv4addrs+'][0]['add']
update = True
else:
del proposed_object['ipv4addrs'][0]['add']
elif 'remove' in proposed_object['ipv4addrs'][0]:
if proposed_object['ipv4addrs'][0]['remove']:
proposed_object['ipv4addrs-'] = proposed_object['ipv4addrs']
del proposed_object['ipv4addrs']
del proposed_object['ipv4addrs-'][0]['remove']
update = True
else:
del proposed_object['ipv4addrs'][0]['remove']
return update, proposed_object
def issubset(self, item, objects):
''' Checks if item is a subset of objects
:args item: the subset item to validate
:args objects: superset list of objects to validate against
:returns: True if item is a subset of one entry in objects otherwise
this method will return None
'''
for obj in objects:
if isinstance(item, dict):
if all(entry in obj.items() for entry in item.items()):
return True
else:
if item in obj:
return True
def compare_objects(self, current_object, proposed_object):
for key, proposed_item in iteritems(proposed_object):
current_item = current_object.get(key)
# if proposed has a key that current doesn't then the objects are
# not equal and False will be immediately returned
if current_item is None:
return False
elif isinstance(proposed_item, list):
if key == 'aliases':
if set(current_item) != set(proposed_item):
return False
for subitem in proposed_item:
if not self.issubset(subitem, current_item):
return False
elif isinstance(proposed_item, dict):
return self.compare_objects(current_item, proposed_item)
else:
if current_item != proposed_item:
return False
return True
def get_object_ref(self, module, ib_obj_type, obj_filter, ib_spec):
''' this function gets the reference object of pre-existing nios objects '''
update = False
old_name = new_name = None
if ('name' in obj_filter):
# gets and returns the current object based on name/old_name passed
try:
name_obj = check_type_dict(obj_filter['name'])
old_name = name_obj['old_name']
new_name = name_obj['new_name']
except TypeError:
name = obj_filter['name']
if old_name and new_name:
if (ib_obj_type == NIOS_HOST_RECORD):
test_obj_filter = dict([('name', old_name), ('view', obj_filter['view'])])
elif (ib_obj_type in (NIOS_AAAA_RECORD, NIOS_A_RECORD)):
test_obj_filter = obj_filter
else:
test_obj_filter = dict([('name', old_name)])
# get the object reference
ib_obj = self.get_object(ib_obj_type, test_obj_filter, return_fields=list(ib_spec.keys()))
if ib_obj:
obj_filter['name'] = new_name
else:
test_obj_filter['name'] = new_name
ib_obj = self.get_object(ib_obj_type, test_obj_filter, return_fields=list(ib_spec.keys()))
update = True
return ib_obj, update, new_name
if (ib_obj_type == NIOS_HOST_RECORD):
# to check only by name if dns bypassing is set
if not obj_filter['configure_for_dns']:
test_obj_filter = dict([('name', name)])
else:
test_obj_filter = dict([('name', name), ('view', obj_filter['view'])])
elif (ib_obj_type == NIOS_IPV4_FIXED_ADDRESS or ib_obj_type == NIOS_IPV6_FIXED_ADDRESS and 'mac' in obj_filter):
test_obj_filter = dict([['mac', obj_filter['mac']]])
elif (ib_obj_type == NIOS_A_RECORD):
# resolves issue where a_record with uppercase name was returning null and was failing
test_obj_filter = obj_filter
test_obj_filter['name'] = test_obj_filter['name'].lower()
# resolves issue where multiple a_records with same name and different IP address
try:
ipaddr_obj = check_type_dict(obj_filter['ipv4addr'])
ipaddr = ipaddr_obj['old_ipv4addr']
except TypeError:
ipaddr = obj_filter['ipv4addr']
test_obj_filter['ipv4addr'] = ipaddr
elif (ib_obj_type == NIOS_TXT_RECORD):
# resolves issue where multiple txt_records with same name and different text
test_obj_filter = obj_filter
try:
text_obj = check_type_dict(obj_filter['text'])
txt = text_obj['old_text']
except TypeError:
txt = obj_filter['text']
test_obj_filter['text'] = txt
# check if test_obj_filter is empty copy passed obj_filter
else:
test_obj_filter = obj_filter
ib_obj = self.get_object(ib_obj_type, test_obj_filter.copy(), return_fields=list(ib_spec.keys()))
elif (ib_obj_type == NIOS_A_RECORD):
# resolves issue where multiple a_records with same name and different IP address
test_obj_filter = obj_filter
try:
ipaddr_obj = check_type_dict(obj_filter['ipv4addr'])
ipaddr = ipaddr_obj['old_ipv4addr']
except TypeError:
ipaddr = obj_filter['ipv4addr']
test_obj_filter['ipv4addr'] = ipaddr
ib_obj = self.get_object(ib_obj_type, test_obj_filter.copy(), return_fields=list(ib_spec.keys()))
elif (ib_obj_type == NIOS_TXT_RECORD):
# resolves issue where multiple txt_records with same name and different text
test_obj_filter = obj_filter
try:
text_obj = check_type_dict(obj_filter['text'])
txt = text_obj['old_text']
except TypeError:
txt = obj_filter['text']
test_obj_filter['text'] = txt
ib_obj = self.get_object(ib_obj_type, test_obj_filter.copy(), return_fields=list(ib_spec.keys()))
elif (ib_obj_type == NIOS_ZONE):
# del key 'restart_if_needed' as nios_zone get_object fails with the key present
temp = ib_spec['restart_if_needed']
del ib_spec['restart_if_needed']
ib_obj = self.get_object(ib_obj_type, obj_filter.copy(), return_fields=list(ib_spec.keys()))
# reinstate restart_if_needed if ib_obj is none, meaning there's no existing nios_zone ref
if not ib_obj:
ib_spec['restart_if_needed'] = temp
elif (ib_obj_type == NIOS_MEMBER):
# del key 'create_token' as nios_member get_object fails with the key present
temp = ib_spec['create_token']
del ib_spec['create_token']
ib_obj = self.get_object(ib_obj_type, obj_filter.copy(), return_fields=list(ib_spec.keys()))
if temp:
# reinstate 'create_token' key
ib_spec['create_token'] = temp
else:
ib_obj = self.get_object(ib_obj_type, obj_filter.copy(), return_fields=list(ib_spec.keys()))
return ib_obj, update, new_name
def on_update(self, proposed_object, ib_spec):
''' Event called before the update is sent to the API endpoing
This method will allow the final proposed object to be changed
and/or keys filtered before it is sent to the API endpoint to
be processed.
:args proposed_object: A dict item that will be encoded and sent
the API endpoint with the updated data structure
:returns: updated object to be sent to API endpoint
'''
keys = set()
for key, value in iteritems(proposed_object):
update = ib_spec[key].get('update', True)
if not update:
keys.add(key)
return dict([(k, v) for k, v in iteritems(proposed_object) if k not in keys])

View File

@@ -15,6 +15,13 @@ from ansible.module_utils.urls import fetch_url, basic_auth_header
class BitbucketHelper:
BITBUCKET_API_URL = 'https://api.bitbucket.org'
error_messages = {
'required_client_id': '`client_id` must be specified as a parameter or '
'BITBUCKET_CLIENT_ID environment variable',
'required_client_secret': '`client_secret` must be specified as a parameter or '
'BITBUCKET_CLIENT_SECRET environment variable',
}
def __init__(self, module):
self.module = module
self.access_token = None
@@ -22,40 +29,35 @@ class BitbucketHelper:
@staticmethod
def bitbucket_argument_spec():
return dict(
client_id=dict(type='str', fallback=(env_fallback, ['BITBUCKET_CLIENT_ID'])),
client_id=dict(type='str', no_log=True, fallback=(env_fallback, ['BITBUCKET_CLIENT_ID'])),
client_secret=dict(type='str', no_log=True, fallback=(env_fallback, ['BITBUCKET_CLIENT_SECRET'])),
# TODO:
# - Rename user to username once current usage of username is removed
# - Alias user to username and deprecate it
user=dict(type='str', fallback=(env_fallback, ['BITBUCKET_USERNAME'])),
password=dict(type='str', no_log=True, fallback=(env_fallback, ['BITBUCKET_PASSWORD'])),
)
@staticmethod
def bitbucket_required_one_of():
return [['client_id', 'client_secret', 'user', 'password']]
def check_arguments(self):
if self.module.params['client_id'] is None:
self.module.fail_json(msg=self.error_messages['required_client_id'])
@staticmethod
def bitbucket_required_together():
return [['client_id', 'client_secret'], ['user', 'password']]
if self.module.params['client_secret'] is None:
self.module.fail_json(msg=self.error_messages['required_client_secret'])
def fetch_access_token(self):
if self.module.params['client_id'] and self.module.params['client_secret']:
headers = {
'Authorization': basic_auth_header(self.module.params['client_id'], self.module.params['client_secret']),
}
self.check_arguments()
info, content = self.request(
api_url='https://bitbucket.org/site/oauth2/access_token',
method='POST',
data='grant_type=client_credentials',
headers=headers,
)
headers = {
'Authorization': basic_auth_header(self.module.params['client_id'], self.module.params['client_secret'])
}
if info['status'] == 200:
self.access_token = content['access_token']
else:
self.module.fail_json(msg='Failed to retrieve access token: {0}'.format(info))
info, content = self.request(
api_url='https://bitbucket.org/site/oauth2/access_token',
method='POST',
data='grant_type=client_credentials',
headers=headers,
)
if info['status'] == 200:
self.access_token = content['access_token']
else:
self.module.fail_json(msg='Failed to retrieve access token: {0}'.format(info))
def request(self, api_url, method, data=None, headers=None):
headers = headers or {}
@@ -64,10 +66,6 @@ class BitbucketHelper:
headers.update({
'Authorization': 'Bearer {0}'.format(self.access_token),
})
elif self.module.params['user'] and self.module.params['password']:
headers.update({
'Authorization': basic_auth_header(self.module.params['user'], self.module.params['password']),
})
if isinstance(data, dict):
data = self.module.jsonify(data)

View File

@@ -43,9 +43,10 @@ options:
- If set to C(true), options starting with C(volatile.) are ignored. As a result,
they are reapplied for each execution.
- This default behavior can be changed by setting this option to C(false).
- The current default value C(true) is deprecated since community.general 4.0.0,
and will change to C(false) in community.general 6.0.0.
- The default value C(true) will be deprecated in community.general 4.0.0,
and will change to C(false) in community.general 5.0.0.
type: bool
default: true
required: false
version_added: 3.7.0
profiles:
@@ -673,6 +674,7 @@ def main():
),
ignore_volatile_options=dict(
type='bool',
default=True
),
devices=dict(
type='dict',
@@ -726,16 +728,13 @@ def main():
),
supports_check_mode=False,
)
if module.params['ignore_volatile_options'] is None:
module.params['ignore_volatile_options'] = True
module.deprecate(
'If the keyword "volatile" is used in a playbook in the config'
'section, a "changed" message will appear with every run, even without a change'
'to the playbook.'
'This will change in the future. Please test your scripts'
'by "ignore_volatile_options: false". To keep the old behavior, set that option explicitly to "true"',
version='6.0.0', collection_name='community.general')
# if module.params['ignore_volatile_options'] is None:
# module.params['ignore_volatile_options'] = True
# module.deprecate(
# 'If the keyword "volatile" is used in a playbook in the config section, a
# "changed" message will appear with every run, even without a change to the playbook.
# This will change in the future.
# Please test your scripts by "ignore_volatile_options: false"', version='5.0.0', collection_name='community.general')
lxd_manage = LXDContainerManagement(module=module)
lxd_manage.run()

View File

@@ -13,7 +13,7 @@ short_description: management of instances in Proxmox VE cluster
description:
- allows you to create/delete/stop instances in Proxmox VE cluster
- Starting in Ansible 2.1, it automatically detects containerization type (lxc for PVE 4, openvz for older)
- Since community.general 4.0.0 on, there are no more default values, see I(proxmox_default_behavior).
- From community.general 4.0.0 on, there will be no default values, see I(proxmox_default_behavior).
options:
password:
description:
@@ -40,27 +40,37 @@ options:
comma-delimited list C([volume=]<volume> [,acl=<1|0>] [,mountoptions=<opt[;opt...]>] [,quota=<1|0>]
[,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=<DiskSize>])."
- See U(https://pve.proxmox.com/wiki/Linux_Container) for a full description.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(3).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(3). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: str
cores:
description:
- Specify number of cores per socket.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(1).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(1). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: int
cpus:
description:
- numbers of allocated cpus for instance
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(1).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(1). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: int
memory:
description:
- memory size in MB for instance
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(512).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(512). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: int
swap:
description:
- swap memory size in MB for instance
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(0).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(0). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: int
netif:
description:
@@ -84,7 +94,9 @@ options:
onboot:
description:
- specifies whether a VM will be started during system bootup
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(no).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(no). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: bool
storage:
description:
@@ -94,7 +106,9 @@ options:
cpuunits:
description:
- CPU weight for a VM
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(1000).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(1000). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: int
nameserver:
description:
@@ -154,15 +168,16 @@ options:
version_added: '0.2.0'
proxmox_default_behavior:
description:
- As of community.general 4.0.0, various options no longer have default values.
These default values caused problems when users expected different behavior from Proxmox
by default or filled options which caused problems when set.
- The value C(compatibility) (default before community.general 4.0.0) will ensure that the default values
are used when the values are not explicitly specified by the user. The new default is C(no_defaults),
which makes sure these options have no defaults.
- Various module options used to have default values. This cause problems when
user expects different behavior from proxmox by default or fill options which cause
problems when they have been set.
- The default value is C(compatibility), which will ensure that the default values
are used when the values are not explicitly specified by the user.
- From community.general 4.0.0 on, the default value will switch to C(no_defaults). To avoid
deprecation warnings, please set I(proxmox_default_behavior) to an explicit
value.
- This affects the I(disk), I(cores), I(cpus), I(memory), I(onboot), I(swap), I(cpuunits) options.
type: str
default: no_defaults
choices:
- compatibility
- no_defaults
@@ -514,7 +529,7 @@ def main():
unprivileged=dict(type='bool', default=False),
description=dict(type='str'),
hookscript=dict(type='str'),
proxmox_default_behavior=dict(type='str', default='no_defaults', choices=['compatibility', 'no_defaults']),
proxmox_default_behavior=dict(type='str', choices=['compatibility', 'no_defaults']),
),
required_if=[('state', 'present', ['node', 'hostname', 'ostemplate'])],
required_together=[('api_token_id', 'api_token_secret')],
@@ -543,6 +558,13 @@ def main():
template_store = module.params['ostemplate'].split(":")[0]
timeout = module.params['timeout']
if module.params['proxmox_default_behavior'] is None:
module.params['proxmox_default_behavior'] = 'compatibility'
module.deprecate(
'The proxmox_default_behavior option will change its default value from "compatibility" to '
'"no_defaults" in community.general 4.0.0. To remove this warning, please specify an explicit value for it now',
version='4.0.0', collection_name='community.general'
)
if module.params['proxmox_default_behavior'] == 'compatibility':
old_default_values = dict(
disk="3",

View File

@@ -13,13 +13,15 @@ module: proxmox_kvm
short_description: Management of Qemu(KVM) Virtual Machines in Proxmox VE cluster.
description:
- Allows you to create/delete/stop Qemu(KVM) Virtual Machines in Proxmox VE cluster.
- Since community.general 4.0.0 on, there are no more default values, see I(proxmox_default_behavior).
- From community.general 4.0.0 on, there will be no default values, see I(proxmox_default_behavior).
author: "Abdoul Bah (@helldorado) <bahabdoul at gmail.com>"
options:
acpi:
description:
- Specify if ACPI should be enabled/disabled.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(yes).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(yes). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: bool
agent:
description:
@@ -29,19 +31,24 @@ options:
description:
- Pass arbitrary arguments to kvm.
- This option is for experts only!
- If I(proxmox_default_behavior) is set to C(compatiblity), this option has a default of
C(-serial unix:/var/run/qemu-server/<vmid>.serial,server,nowait).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(-serial unix:/var/run/qemu-server/<vmid>.serial,server,nowait).
Note that the default value of I(proxmox_default_behavior) changes in community.general 4.0.0.
type: str
autostart:
description:
- Specify if the VM should be automatically restarted after crash (currently ignored in PVE API).
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(no).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(no). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: bool
balloon:
description:
- Specify the amount of RAM for the VM in MB.
- Using zero disables the balloon driver.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(0).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(0). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: int
bios:
description:
@@ -52,7 +59,9 @@ options:
description:
- Specify the boot order -> boot on floppy C(a), hard disk C(c), CD-ROM C(d), or network C(n).
- You can combine to set order.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(cnd).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(cnd). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: str
bootdisk:
description:
@@ -88,12 +97,16 @@ options:
cores:
description:
- Specify number of cores per socket.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(1).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(1). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: int
cpu:
description:
- Specify emulated CPU type.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(kvm64).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(kvm64). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: str
cpulimit:
description:
@@ -104,7 +117,9 @@ options:
description:
- Specify CPU weight for a VM.
- You can disable fair-scheduler configuration by setting this to 0
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(1000).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(1000). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: int
delete:
description:
@@ -124,15 +139,19 @@ options:
description:
- Allow to force stop VM.
- Can be used with states C(stopped), C(restarted) and C(absent).
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(no).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(no). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: bool
format:
description:
- Target drive's backing file's data format.
- Used only with clone
- Use I(format=unspecified) and I(full=false) for a linked clone.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(qcow2).
If I(proxmox_default_behavior) is set to C(no_defaults), not specifying this option is equivalent to setting it to C(unspecified).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(qcow2). If I(proxmox_default_behavior) is set to C(no_defaults),
not specifying this option is equivalent to setting it to C(unspecified).
Note that the default value of I(proxmox_default_behavior) changes in community.general 4.0.0.
type: str
choices: [ "cloop", "cow", "qcow", "qcow2", "qed", "raw", "vmdk", "unspecified" ]
freeze:
@@ -197,7 +216,9 @@ options:
kvm:
description:
- Enable/disable KVM hardware virtualization.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(yes).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(yes). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: bool
localtime:
description:
@@ -217,7 +238,9 @@ options:
memory:
description:
- Memory size in MB for instance.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(512).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(512). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: int
migrate_downtime:
description:
@@ -273,13 +296,17 @@ options:
onboot:
description:
- Specifies whether a VM will be started during system bootup.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(yes).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(yes). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: bool
ostype:
description:
- Specifies guest operating system. This is used to enable special optimization/features for specific operating systems.
- The l26 is Linux 2.6/3.X Kernel.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(l26).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(l26). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: str
choices: ['other', 'wxp', 'w2k', 'w2k3', 'w2k8', 'wvista', 'win7', 'win8', 'win10', 'l24', 'l26', 'solaris']
parallel:
@@ -360,7 +387,9 @@ options:
sockets:
description:
- Sets the number of CPU sockets. (1 - N).
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(1).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(1). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: int
sshkeys:
description:
@@ -392,7 +421,9 @@ options:
tablet:
description:
- Enables/disables the USB tablet device.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(no).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(no). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: bool
tags:
description:
@@ -414,7 +445,9 @@ options:
template:
description:
- Enables/disables the template.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(no).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(no). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: bool
timeout:
description:
@@ -436,7 +469,9 @@ options:
vga:
description:
- Select VGA type. If you want to use high resolution modes (>= 1280x1024x16) then you should use option 'std' or 'vmware'.
- This option has no default unless I(proxmox_default_behavior) is set to C(compatiblity); then the default is C(std).
- If I(proxmox_default_behavior) is set to C(compatiblity) (the default value), this
option has a default of C(std). Note that the default value of I(proxmox_default_behavior)
changes in community.general 4.0.0.
type: str
choices: ['std', 'cirrus', 'vmware', 'qxl', 'serial0', 'serial1', 'serial2', 'serial3', 'qxl2', 'qxl3', 'qxl4']
virtio:
@@ -454,17 +489,18 @@ options:
type: str
proxmox_default_behavior:
description:
- As of community.general 4.0.0, various options no longer have default values.
These default values caused problems when users expected different behavior from Proxmox
by default or filled options which caused problems when set.
- The value C(compatibility) (default before community.general 4.0.0) will ensure that the default values
are used when the values are not explicitly specified by the user. The new default is C(no_defaults),
which makes sure these options have no defaults.
- Various module options used to have default values. This cause problems when
user expects different behavior from proxmox by default or fill options which cause
problems when they have been set.
- The default value is C(compatibility), which will ensure that the default values
are used when the values are not explicitly specified by the user.
- From community.general 4.0.0 on, the default value will switch to C(no_defaults). To avoid
deprecation warnings, please set I(proxmox_default_behavior) to an explicit
value.
- This affects the I(acpi), I(autostart), I(balloon), I(boot), I(cores), I(cpu),
I(cpuunits), I(force), I(format), I(kvm), I(memory), I(onboot), I(ostype), I(sockets),
I(tablet), I(template), I(vga), options.
type: str
default: no_defaults
choices:
- compatibility
- no_defaults
@@ -1055,7 +1091,7 @@ def main():
virtio=dict(type='dict'),
vmid=dict(type='int'),
watchdog=dict(),
proxmox_default_behavior=dict(type='str', default='no_defaults', choices=['compatibility', 'no_defaults']),
proxmox_default_behavior=dict(type='str', choices=['compatibility', 'no_defaults']),
),
mutually_exclusive=[('delete', 'revert'), ('delete', 'update'), ('revert', 'update'), ('clone', 'update'), ('clone', 'delete'), ('clone', 'revert')],
required_together=[('api_token_id', 'api_token_secret')],
@@ -1086,6 +1122,13 @@ def main():
vmid = module.params['vmid']
validate_certs = module.params['validate_certs']
if module.params['proxmox_default_behavior'] is None:
module.params['proxmox_default_behavior'] = 'compatibility'
module.deprecate(
'The proxmox_default_behavior option will change its default value from "compatibility" to '
'"no_defaults" in community.general 4.0.0. To remove this warning, please specify an explicit value for it now',
version='4.0.0', collection_name='community.general'
)
if module.params['proxmox_default_behavior'] == 'compatibility':
old_default_values = dict(
acpi=True,

View File

@@ -319,11 +319,25 @@ def remove_workspace(bin_path, project_path, workspace):
_workspace_cmd(bin_path, project_path, 'delete', workspace)
def build_plan(command, project_path, variables_args, state_file, targets, state, plan_path=None):
def build_plan(command, project_path, variables_args, state_file, targets, state, apply_args, plan_path=None):
if plan_path is None:
f, plan_path = tempfile.mkstemp(suffix='.tfplan')
plan_command = [command[0], 'plan', '-input=false', '-no-color', '-detailed-exitcode', '-out', plan_path]
local_command = command.copy()
plan_command = [command[0], 'plan']
if state == "planned":
for c in local_command[1:]:
plan_command.append(c)
if state == "present":
for a in apply_args:
local_command.remove(a)
for c in local_command[1:]:
plan_command.append(c)
plan_command.extend(['-input=false', '-no-color', '-detailed-exitcode', '-out', plan_path])
for t in targets:
plan_command.extend(['-target', t])
@@ -461,7 +475,7 @@ def main():
module.fail_json(msg='Could not find plan_file "{0}", check the path and try again.'.format(plan_file))
else:
plan_file, needs_application, out, err, command = build_plan(command, project_path, variables_args, state_file,
module.params.get('targets'), state, plan_file)
module.params.get('targets'), state, APPLY_ARGS, plan_file)
if state == 'present' and check_destroy and '- destroy' in out:
module.fail_json(msg="Aborting command because it would destroy some resources. "
"Consider switching the 'check_destroy' to false to suppress this error")

View File

@@ -18,12 +18,11 @@ module: scaleway_security_group_rule
short_description: Scaleway Security Group Rule management module
author: Antoine Barbare (@abarbare)
description:
- This module manages Security Group Rule on Scaleway account
U(https://developer.scaleway.com)
- This module manages Security Group Rule on Scaleway account
U(https://developer.scaleway.com)
extends_documentation_fragment:
- community.general.scaleway
requirements:
- ipaddress
- community.general.scaleway
options:
state:
@@ -131,19 +130,10 @@ data:
}
'''
import traceback
from ansible_collections.community.general.plugins.module_utils.scaleway import SCALEWAY_LOCATION, scaleway_argument_spec, Scaleway, payload_from_object
from ansible_collections.community.general.plugins.module_utils.compat.ipaddress import ip_network
from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
try:
from ipaddress import ip_network
except ImportError:
IPADDRESS_IMP_ERR = traceback.format_exc()
HAS_IPADDRESS = False
else:
HAS_IPADDRESS = True
from ansible.module_utils.basic import AnsibleModule
def get_sgr_from_api(security_group_rules, security_group_rule):
@@ -266,8 +256,6 @@ def main():
argument_spec=argument_spec,
supports_check_mode=True,
)
if not HAS_IPADDRESS:
module.fail_json(msg=missing_required_lib('ipaddress'), exception=IPADDRESS_IMP_ERR)
core(module)

View File

@@ -1,187 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2021, Andreas Botzner <andreas at botzner dot com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: redis_data_incr
short_description: Increment keys in Redis
version_added: 4.0.0
description:
- Increment integers or float keys in Redis database and get new value.
- Default increment for all keys is 1. For specific increments use the
I(increment_int) and I(increment_float) options.
- When using I(check_mode) the module will try to calculate the value that
Redis would return. If the key is not present, 0.0 is used as value.
author: "Andreas Botzner (@paginabianca)"
options:
key:
description:
- Database key.
type: str
required: true
increment_int:
description:
- Integer amount to increment the key by.
required: false
type: int
increment_float:
description:
- Float amount to increment the key by.
- This only works with keys that contain float values
in their string representation.
type: float
required: false
extends_documentation_fragment:
- community.general.redis.documentation
notes:
- For C(check_mode) to work, the specified I(redis_user) needs permission to
run the C(GET) command on the key, otherwise the module will fail.
seealso:
- module: community.general.redis_set
- module: community.general.redis_data_info
- module: community.general.redis
'''
EXAMPLES = '''
- name: Increment integer key foo on localhost with no username and print new value
community.general.redis_data_incr:
login_host: localhost
login_password: supersecret
key: foo
increment_int: 1
register: result
- name: Print new value
debug:
var: result.value
- name: Increment float key foo by 20.4
community.general.redis_data_incr:
login_host: redishost
login_user: redisuser
login_password: somepass
key: foo
increment_float: '20.4'
'''
RETURN = '''
value:
description: Incremented value of key
returned: on success
type: float
sample: '4039.4'
msg:
description: A short message.
returned: always
type: str
sample: 'Incremented key: foo by 20.4 to 65.9'
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.redis import (
fail_imports, redis_auth_argument_spec, RedisAnsible)
def main():
redis_auth_args = redis_auth_argument_spec()
module_args = dict(
key=dict(type='str', required=True, no_log=False),
increment_int=dict(type='int', required=False),
increment_float=dict(type='float', required=False),
)
module_args.update(redis_auth_args)
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True,
mutually_exclusive=[['increment_int', 'increment_float']],
)
fail_imports(module)
redis = RedisAnsible(module)
key = module.params['key']
increment_float = module.params['increment_float']
increment_int = module.params['increment_int']
increment = 1
if increment_float is not None:
increment = increment_float
elif increment_int is not None:
increment = increment_int
result = {'changed': False}
if module.check_mode:
value = 0.0
try:
res = redis.connection.get(key)
if res is not None:
value = float(res)
except ValueError as e:
msg = 'Value: {0} of key: {1} is not incrementable(int or float)'.format(
res, key)
result['msg'] = msg
module.fail_json(**result)
except Exception as e:
msg = 'Failed to get value of key: {0} with exception: {1}'.format(
key, str(e))
result['msg'] = msg
module.fail_json(**result)
msg = 'Incremented key: {0} by {1} to {2}'.format(
key, increment, value + increment)
result['msg'] = msg
result['value'] = float(value + increment)
module.exit_json(**result)
if increment_float is not None:
try:
value = redis.connection.incrbyfloat(key, increment)
msg = 'Incremented key: {0} by {1} to {2}'.format(
key, increment, value)
result['msg'] = msg
result['value'] = float(value)
result['changed'] = True
module.exit_json(**result)
except Exception as e:
msg = 'Failed to increment key: {0} by {1} with exception: {2}'.format(
key, increment, str(e))
result['msg'] = msg
module.fail_json(**result)
elif increment_int is not None:
try:
value = redis.connection.incrby(key, increment)
msg = 'Incremented key: {0} by {1} to {2}'.format(
key, increment, value)
result['msg'] = msg
result['value'] = float(value)
result['changed'] = True
module.exit_json(**result)
except Exception as e:
msg = 'Failed to increment key: {0} by {1} with exception: {2}'.format(
key, increment, str(e))
result['msg'] = msg
module.fail_json(**result)
else:
try:
value = redis.connection.incr(key)
msg = 'Incremented key: {0} to {1}'.format(key, value)
result['msg'] = msg
result['value'] = float(value)
result['changed'] = True
module.exit_json(**result)
except Exception as e:
msg = 'Failed to increment key: {0} with exception: {1}'.format(
key, str(e))
result['msg'] = msg
module.fail_json(**result)
if __name__ == '__main__':
main()

View File

@@ -1,301 +0,0 @@
#!/usr/bin/python
# Copyright: (c) 2021, Kris Budde <kris@budd.ee
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r'''
---
module: mssql_script
short_description: Execute SQL scripts on a MSSQL database
version_added: "4.0.0"
description:
- Execute SQL scripts on a MSSQL database.
options:
name:
description: Database to run script against.
aliases: [ db ]
default: ''
type: str
login_user:
description: The username used to authenticate with.
type: str
login_password:
description: The password used to authenticate with.
type: str
login_host:
description: Host running the database.
type: str
required: true
login_port:
description: Port of the MSSQL server. Requires I(login_host) be defined as well.
default: 1433
type: int
script:
description:
- The SQL script to be executed.
- Script can contain multiple SQL statements. Multiple Batches can be separated by C(GO) command.
- Each batch must return at least one result set.
required: true
type: str
output:
description:
- With C(default) each row will be returned as a list of values. See C(query_results).
- Output format C(dict) will return dictionary with the column names as keys. See C(query_results_dict).
- C(dict) requires named columns to be returned by each query otherwise an error is thrown.
choices: [ "dict", "default" ]
default: 'default'
type: str
params:
description: |
Parameters passed to the script as SQL parameters. ('SELECT %(name)s"' with C(example: '{"name": "John Doe"}).)'
type: dict
notes:
- Requires the pymssql Python package on the remote host. For Ubuntu, this
is as easy as C(pip install pymssql) (See M(ansible.builtin.pip).)
requirements:
- python >= 2.7
- pymssql
author:
- Kris Budde (@kbudde)
'''
EXAMPLES = r'''
- name: Check DB connection
community.general.mssql_script:
login_user: "{{ mssql_login_user }}"
login_password: "{{ mssql_login_password }}"
login_host: "{{ mssql_host }}"
login_port: "{{ mssql_port }}"
db: master
script: "SELECT 1"
- name: Query with parameter
community.general.mssql_script:
login_user: "{{ mssql_login_user }}"
login_password: "{{ mssql_login_password }}"
login_host: "{{ mssql_host }}"
login_port: "{{ mssql_port }}"
script: |
SELECT name, state_desc FROM sys.databases WHERE name = %(dbname)s
params:
dbname: msdb
register: result_params
- assert:
that:
- result_params.query_results[0][0][0][0] == 'msdb'
- result_params.query_results[0][0][0][1] == 'ONLINE'
- name: two batches with default output
community.general.mssql_script:
login_user: "{{ mssql_login_user }}"
login_password: "{{ mssql_login_password }}"
login_host: "{{ mssql_host }}"
login_port: "{{ mssql_port }}"
script: |
SELECT 'Batch 0 - Select 0'
SELECT 'Batch 0 - Select 1'
GO
SELECT 'Batch 1 - Select 0'
register: result_batches
- assert:
that:
- result_batches.query_results | length == 2 # two batch results
- result_batches.query_results[0] | length == 2 # two selects in first batch
- result_batches.query_results[0][0] | length == 1 # one row in first select
- result_batches.query_results[0][0][0] | length == 1 # one column in first row
- result_batches.query_results[0][0][0][0] == 'Batch 0 - Select 0' # each row contains a list of values.
- name: two batches with dict output
community.general.mssql_script:
login_user: "{{ mssql_login_user }}"
login_password: "{{ mssql_login_password }}"
login_host: "{{ mssql_host }}"
login_port: "{{ mssql_port }}"
output: dict
script: |
SELECT 'Batch 0 - Select 0' as b0s0
SELECT 'Batch 0 - Select 1' as b0s1
GO
SELECT 'Batch 1 - Select 0' as b1s0
register: result_batches_dict
- assert:
that:
- result_batches_dict.query_results_dict | length == 2 # two batch results
- result_batches_dict.query_results_dict[0] | length == 2 # two selects in first batch
- result_batches_dict.query_results_dict[0][0] | length == 1 # one row in first select
- result_batches_dict.query_results_dict[0][0][0]['b0s0'] == 'Batch 0 - Select 0' # column 'b0s0' of first row
'''
RETURN = r'''
query_results:
description: List of batches (queries separated by C(GO) keyword).
type: list
elements: list
returned: success and I(output=default)
sample: [[[["Batch 0 - Select 0"]], [["Batch 0 - Select 1"]]], [[["Batch 1 - Select 0"]]]]
contains:
queries:
description:
- List of result sets of each query.
- If a query returns no results, the results of this and all the following queries will not be included in the output.
- Use the C(GO) keyword in I(script) to separate queries.
type: list
elements: list
contains:
rows:
description: List of rows returned by query.
type: list
elements: list
contains:
column_value:
description:
- List of column values.
- Any non-standard JSON type is converted to string.
type: list
example: ["Batch 0 - Select 0"]
returned: success, if output is default
query_results_dict:
description: List of batches (queries separated by C(GO) keyword).
type: list
elements: list
returned: success and I(output=dict)
sample: [[[["Batch 0 - Select 0"]], [["Batch 0 - Select 1"]]], [[["Batch 1 - Select 0"]]]]
contains:
queries:
description:
- List of result sets of each query.
- If a query returns no results, the results of this and all the following queries will not be included in the output.
Use 'GO' keyword to separate queries.
type: list
elements: list
contains:
rows:
description: List of rows returned by query.
type: list
elements: list
contains:
column_dict:
description:
- Dictionary of column names and values.
- Any non-standard JSON type is converted to string.
type: dict
example: {"col_name": "Batch 0 - Select 0"}
returned: success, if output is dict
'''
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
import traceback
import json
PYMSSQL_IMP_ERR = None
try:
import pymssql
except ImportError:
PYMSSQL_IMP_ERR = traceback.format_exc()
MSSQL_FOUND = False
else:
MSSQL_FOUND = True
def clean_output(o):
return str(o)
def run_module():
module_args = dict(
name=dict(required=False, aliases=['db'], default=''),
login_user=dict(),
login_password=dict(no_log=True),
login_host=dict(required=True),
login_port=dict(type='int', default=1433),
script=dict(required=True),
output=dict(default='default', choices=['dict', 'default']),
params=dict(type='dict'),
)
result = dict(
changed=False,
)
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True
)
if not MSSQL_FOUND:
module.fail_json(msg=missing_required_lib(
'pymssql'), exception=PYMSSQL_IMP_ERR)
db = module.params['name']
login_user = module.params['login_user']
login_password = module.params['login_password']
login_host = module.params['login_host']
login_port = module.params['login_port']
script = module.params['script']
output = module.params['output']
sql_params = module.params['params']
login_querystring = login_host
if login_port != 1433:
login_querystring = "%s:%s" % (login_host, login_port)
if login_user is not None and login_password is None:
module.fail_json(
msg="when supplying login_user argument, login_password must also be provided")
try:
conn = pymssql.connect(
user=login_user, password=login_password, host=login_querystring, database=db)
cursor = conn.cursor()
except Exception as e:
if "Unknown database" in str(e):
errno, errstr = e.args
module.fail_json(msg="ERROR: %s %s" % (errno, errstr))
else:
module.fail_json(msg="unable to connect, check login_user and login_password are correct, or alternatively check your "
"@sysconfdir@/freetds.conf / ${HOME}/.freetds.conf")
conn.autocommit(True)
query_results_key = 'query_results'
if output == 'dict':
cursor = conn.cursor(as_dict=True)
query_results_key = 'query_results_dict'
queries = script.split('\nGO\n')
result['changed'] = True
if module.check_mode:
module.exit_json(**result)
query_results = []
try:
for query in queries:
cursor.execute(query, sql_params)
qry_result = []
rows = cursor.fetchall()
while rows:
qry_result.append(rows)
rows = cursor.fetchall()
query_results.append(qry_result)
except Exception as e:
return module.fail_json(msg="query failed", query=query, error=str(e), **result)
# ensure that the result is json serializable
qry_results = json.loads(json.dumps(query_results, default=clean_output))
result[query_results_key] = qry_results
module.exit_json(**result)
def main():
run_module()
if __name__ == '__main__':
main()

View File

@@ -1 +0,0 @@
./packaging/os/dnf_versionlock.py

View File

@@ -182,7 +182,6 @@ import zipfile
from fnmatch import fnmatch
from sys import version_info
from traceback import format_exc
from zlib import crc32
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.common.text.converters import to_bytes, to_native
@@ -235,6 +234,10 @@ def expand_paths(paths):
return expanded_path, is_globby
def legacy_filter(path, exclusion_patterns):
return matches_exclusion_patterns(path, exclusion_patterns)
def matches_exclusion_patterns(path, exclusion_patterns):
return any(fnmatch(path, p) for p in exclusion_patterns)
@@ -310,7 +313,6 @@ class Archive(object):
if self.remove:
self._check_removal_safety()
self.original_checksums = self.destination_checksums()
self.original_size = self.destination_size()
def add(self, path, archive_name):
@@ -375,16 +377,8 @@ class Archive(object):
msg='Errors when writing archive at %s: %s' % (_to_native(self.destination), '; '.join(self.errors))
)
def is_different_from_original(self):
if self.original_checksums is None:
return self.original_size != self.destination_size()
else:
return self.original_checksums != self.destination_checksums()
def destination_checksums(self):
if self.destination_exists() and self.destination_readable():
return self._get_checksums(self.destination)
return None
def compare_with_original(self):
self.changed |= self.original_size != self.destination_size()
def destination_exists(self):
return self.destination and os.path.exists(self.destination)
@@ -500,10 +494,6 @@ class Archive(object):
def _add(self, path, archive_name):
pass
@abc.abstractmethod
def _get_checksums(self, path):
pass
class ZipArchive(Archive):
def __init__(self, module):
@@ -523,18 +513,9 @@ class ZipArchive(Archive):
self.file = zipfile.ZipFile(_to_native_ascii(self.destination), 'w', zipfile.ZIP_DEFLATED, True)
def _add(self, path, archive_name):
if not matches_exclusion_patterns(path, self.exclusion_patterns):
if not legacy_filter(path, self.exclusion_patterns):
self.file.write(path, archive_name)
def _get_checksums(self, path):
try:
archive = zipfile.ZipFile(_to_native_ascii(path), 'r')
checksums = set((info.filename, info.CRC) for info in archive.infolist())
archive.close()
except zipfile.BadZipfile:
checksums = set()
return checksums
class TarArchive(Archive):
def __init__(self, module):
@@ -573,35 +554,13 @@ class TarArchive(Archive):
return None if matches_exclusion_patterns(tarinfo.name, self.exclusion_patterns) else tarinfo
def py26_filter(path):
return matches_exclusion_patterns(path, self.exclusion_patterns)
return legacy_filter(path, self.exclusion_patterns)
if PY27:
self.file.add(path, archive_name, recursive=False, filter=py27_filter)
else:
self.file.add(path, archive_name, recursive=False, exclude=py26_filter)
def _get_checksums(self, path):
try:
if self.format == 'xz':
with lzma.open(_to_native_ascii(path), 'r') as f:
archive = tarfile.open(fileobj=f)
checksums = set((info.name, info.chksum) for info in archive.getmembers())
archive.close()
else:
archive = tarfile.open(_to_native_ascii(path), 'r|' + self.format)
checksums = set((info.name, info.chksum) for info in archive.getmembers())
archive.close()
except (lzma.LZMAError, tarfile.ReadError, tarfile.CompressionError):
try:
# The python implementations of gzip, bz2, and lzma do not support restoring compressed files
# to their original names so only file checksum is returned
f = self._open_compressed_file(_to_native_ascii(path), 'r')
checksums = set([(b'', crc32(f.read()))])
f.close()
except Exception:
checksums = set()
return checksums
def get_archive(module):
if module.params['format'] == 'zip':
@@ -644,7 +603,7 @@ def main():
else:
archive.add_targets()
archive.destination_state = STATE_INCOMPLETE if archive.has_unfound_targets() else STATE_ARCHIVED
archive.changed |= archive.is_different_from_original()
archive.compare_with_original()
if archive.remove:
archive.remove_targets()
else:
@@ -654,7 +613,7 @@ def main():
else:
path = archive.paths[0]
archive.add_single_target(path)
archive.changed |= archive.is_different_from_original()
archive.compare_with_original()
if archive.remove:
archive.remove_single_target(path)

View File

@@ -14,13 +14,6 @@ short_description: Manage FreeIPA group
description:
- Add, modify and delete group within IPA server
options:
append:
description:
- If C(yes), add the listed I(user) and I(group) to the group members.
- If C(no), only the listed I(user) and I(group) will be group members, removing any other members.
default: no
type: bool
version_added: 4.0.0
cn:
description:
- Canonical name.
@@ -44,10 +37,9 @@ options:
group:
description:
- List of group names assigned to this group.
- If I(append=no) and an empty list is passed all groups will be removed from this group.
- Groups that are already assigned but not passed will be removed.
- If I(append=yes) the listed groups will be assigned without removing other groups.
- If an empty list is passed all groups will be removed from this group.
- If option is omitted assigned groups will not be checked or changed.
- Groups that are already assigned but not passed will be removed.
type: list
elements: str
nonposix:
@@ -57,10 +49,9 @@ options:
user:
description:
- List of user names assigned to this group.
- If I(append=no) and an empty list is passed all users will be removed from this group.
- Users that are already assigned but not passed will be removed.
- If I(append=yes) the listed users will be assigned without removing other users.
- If an empty list is passed all users will be removed from this group.
- If option is omitted assigned users will not be checked or changed.
- Users that are already assigned but not passed will be removed.
type: list
elements: str
state:
@@ -104,17 +95,6 @@ EXAMPLES = r'''
ipa_user: admin
ipa_pass: topsecret
- name: Ensure that new starter named john is member of the group, without removing other members
community.general.ipa_group:
name: developers
user:
- john
append: yes
state: present
ipa_host: ipa.example.com
ipa_user: admin
ipa_pass: topsecret
- name: Ensure group is absent
community.general.ipa_group:
name: sysops
@@ -207,7 +187,6 @@ def ensure(module, client):
name = module.params['cn']
group = module.params['group']
user = module.params['user']
append = module.params['append']
module_group = get_group_dict(description=module.params['description'], external=module.params['external'],
gid=module.params['gidnumber'], nonposix=module.params['nonposix'])
@@ -232,14 +211,12 @@ def ensure(module, client):
if group is not None:
changed = client.modify_if_diff(name, ipa_group.get('member_group', []), group,
client.group_add_member_group,
client.group_remove_member_group,
append=append) or changed
client.group_remove_member_group) or changed
if user is not None:
changed = client.modify_if_diff(name, ipa_group.get('member_user', []), user,
client.group_add_member_user,
client.group_remove_member_user,
append=append) or changed
client.group_remove_member_user) or changed
else:
if ipa_group:
@@ -259,8 +236,7 @@ def main():
group=dict(type='list', elements='str'),
nonposix=dict(type='bool'),
state=dict(type='str', default='present', choices=['present', 'absent']),
user=dict(type='list', elements='str'),
append=dict(type='bool', default=False))
user=dict(type='list', elements='str'))
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True,

View File

@@ -9,15 +9,11 @@ __metaclass__ = type
DOCUMENTATION = '''
---
module: keycloak_authentication
short_description: Configure authentication in Keycloak
description:
- This module actually can only make a copy of an existing authentication flow, add an execution to it and configure it.
- It can also delete the flow.
version_added: "3.3.0"
options:
realm:
description:
@@ -83,7 +79,6 @@ options:
default: false
description:
- If C(true), allows to remove the authentication flow and recreate it.
extends_documentation_fragment:
- community.general.keycloak
@@ -167,74 +162,10 @@ EXAMPLES = '''
'''
RETURN = '''
msg:
description: Message as to what action was taken.
returned: always
type: str
flow:
description:
- JSON representation for the authentication.
- Deprecated return value, it will be removed in community.general 6.0.0. Please use the return value I(end_state) instead.
returned: on success
type: dict
sample: {
"alias": "Copy of first broker login",
"authenticationExecutions": [
{
"alias": "review profile config",
"authenticationConfig": {
"alias": "review profile config",
"config": { "update.profile.on.first.login": "missing" },
"id": "6f09e4fb-aad4-496a-b873-7fa9779df6d7"
},
"configurable": true,
"displayName": "Review Profile",
"id": "8f77dab8-2008-416f-989e-88b09ccf0b4c",
"index": 0,
"level": 0,
"providerId": "idp-review-profile",
"requirement": "REQUIRED",
"requirementChoices": [ "REQUIRED", "ALTERNATIVE", "DISABLED" ]
}
],
"builtIn": false,
"description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
"id": "bc228863-5887-4297-b898-4d988f8eaa5c",
"providerId": "basic-flow",
"topLevel": true
}
end_state:
description: Representation of the authentication after module execution.
returned: on success
type: dict
sample: {
"alias": "Copy of first broker login",
"authenticationExecutions": [
{
"alias": "review profile config",
"authenticationConfig": {
"alias": "review profile config",
"config": { "update.profile.on.first.login": "missing" },
"id": "6f09e4fb-aad4-496a-b873-7fa9779df6d7"
},
"configurable": true,
"displayName": "Review Profile",
"id": "8f77dab8-2008-416f-989e-88b09ccf0b4c",
"index": 0,
"level": 0,
"providerId": "idp-review-profile",
"requirement": "REQUIRED",
"requirementChoices": [ "REQUIRED", "ALTERNATIVE", "DISABLED" ]
}
],
"builtIn": false,
"description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
"id": "bc228863-5887-4297-b898-4d988f8eaa5c",
"providerId": "basic-flow",
"topLevel": true
}
description: JSON representation for the authentication.
returned: on success
type: dict
'''
from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak \
@@ -340,11 +271,9 @@ def create_or_update_executions(kc, config, realm='master'):
def main():
"""
Module execution
:return:
"""
argument_spec = keycloak_argument_spec()
meta_args = dict(
realm=dict(type='str', required=True),
alias=dict(type='str', required=True),
@@ -363,7 +292,6 @@ def main():
state=dict(choices=["absent", "present"], default='present'),
force=dict(type='bool', default=False),
)
argument_spec.update(meta_args)
module = AnsibleModule(argument_spec=argument_spec,
@@ -373,7 +301,6 @@ def main():
)
result = dict(changed=False, msg='', flow={})
# Obtain access token, initialize API
try:
connection_header = get_token(module.params)
@@ -381,7 +308,6 @@ def main():
module.fail_json(msg=str(e))
kc = KeycloakAPI(module, connection_header)
realm = module.params.get('realm')
state = module.params.get('state')
force = module.params.get('force')
@@ -397,54 +323,35 @@ def main():
}
auth_repr = kc.get_authentication_flow_by_alias(alias=new_auth_repr["alias"], realm=realm)
# Cater for when it doesn't exist (an empty dict)
if not auth_repr:
if state == 'absent':
# Do nothing and exit
if module._diff:
result['diff'] = dict(before='', after='')
result['changed'] = False
result['end_state'] = {}
result['flow'] = result['end_state']
result['msg'] = new_auth_repr["alias"] + ' absent'
module.exit_json(**result)
elif state == 'present':
# Process a creation
if auth_repr == {}: # Authentication flow does not exist
if state == 'present': # If desired state is present
result['changed'] = True
if module._diff:
result['diff'] = dict(before='', after=new_auth_repr)
if module.check_mode:
module.exit_json(**result)
# If copyFrom is defined, create authentication flow from a copy
if "copyFrom" in new_auth_repr and new_auth_repr["copyFrom"] is not None:
auth_repr = kc.copy_auth_flow(config=new_auth_repr, realm=realm)
else: # Create an empty authentication flow
auth_repr = kc.create_empty_auth_flow(config=new_auth_repr, realm=realm)
# If the authentication still not exist on the server, raise an exception.
if auth_repr is None:
result['msg'] = "Authentication just created not found: " + str(new_auth_repr)
module.fail_json(**result)
# Configure the executions for the flow
create_or_update_executions(kc=kc, config=new_auth_repr, realm=realm)
# Get executions created
exec_repr = kc.get_executions_representation(config=new_auth_repr, realm=realm)
if exec_repr is not None:
auth_repr["authenticationExecutions"] = exec_repr
result['end_state'] = auth_repr
result['flow'] = result['end_state']
else:
if state == 'present':
# Process an update
result['flow'] = auth_repr
elif state == 'absent': # If desired state is absent.
if module._diff:
result['diff'] = dict(before='', after='')
result['msg'] = new_auth_repr["alias"] + ' absent'
else: # The authentication flow already exist
if state == 'present': # if desired state is present
if force: # If force option is true
# Delete the actual authentication flow
result['changed'] = True
@@ -463,35 +370,25 @@ def main():
result['msg'] = "Authentication just created not found: " + str(new_auth_repr)
module.fail_json(**result)
# Configure the executions for the flow
if module.check_mode:
module.exit_json(**result)
changed, diff = create_or_update_executions(kc=kc, config=new_auth_repr, realm=realm)
result['changed'] |= changed
if module._diff:
result['diff'] = diff
# Get executions created
exec_repr = kc.get_executions_representation(config=new_auth_repr, realm=realm)
if exec_repr is not None:
auth_repr["authenticationExecutions"] = exec_repr
result['end_state'] = auth_repr
result['flow'] = result['end_state']
else:
# Process a deletion (because state was not 'present')
result['flow'] = auth_repr
elif state == 'absent': # If desired state is absent
result['changed'] = True
# Delete the authentication flow alias.
if module._diff:
result['diff'] = dict(before=auth_repr, after='')
if module.check_mode:
module.exit_json(**result)
# delete it
kc.delete_authentication_flow_by_id(id=auth_repr["id"], realm=realm)
result['msg'] = 'Authentication flow: {alias} id: {id} is deleted'.format(alias=new_auth_repr['alias'],
id=auth_repr["id"])

View File

@@ -62,17 +62,17 @@ options:
name:
description:
- Name of the client (this is not the same as I(client_id)).
- Name of the client (this is not the same as I(client_id))
type: str
description:
description:
- Description of the client in Keycloak.
- Description of the client in Keycloak
type: str
root_url:
description:
- Root URL appended to relative URLs for this client.
- Root URL appended to relative URLs for this client
This is 'rootUrl' in the Keycloak REST API.
aliases:
- rootUrl
@@ -80,7 +80,7 @@ options:
admin_url:
description:
- URL to the admin interface of the client.
- URL to the admin interface of the client
This is 'adminUrl' in the Keycloak REST API.
aliases:
- adminUrl
@@ -357,7 +357,7 @@ options:
protocol:
description:
- This is either C(openid-connect) or C(saml), this specifies for which protocol this protocol mapper.
- This is either C(openid-connect) or C(saml), this specifies for which protocol this protocol mapper
is active.
choices: ['openid-connect', 'saml']
type: str
@@ -513,6 +513,7 @@ options:
extends_documentation_fragment:
- community.general.keycloak
author:
- Eike Frost (@eikef)
'''
@@ -644,21 +645,20 @@ EXAMPLES = '''
RETURN = '''
msg:
description: Message as to what action was taken.
returned: always
type: str
sample: "Client testclient has been updated"
description: Message as to what action was taken
returned: always
type: str
sample: "Client testclient has been updated"
proposed:
description: Representation of proposed client.
description: client representation of proposed changes to client
returned: always
type: dict
sample: {
clientId: "test"
}
existing:
description: Representation of existing client (sample is truncated).
description: client representation of existing client (sample is truncated)
returned: always
type: dict
sample: {
@@ -667,10 +667,9 @@ existing:
"request.object.signature.alg": "RS256",
}
}
end_state:
description: Representation of client after module execution (sample is truncated).
returned: on success
description: client representation of client after module execution (sample is truncated)
returned: always
type: dict
sample: {
"adminUrl": "http://www.example.com/admin_url",
@@ -685,38 +684,8 @@ from ansible_collections.community.general.plugins.module_utils.identity.keycloa
from ansible.module_utils.basic import AnsibleModule
def normalise_cr(clientrep, remove_ids=False):
""" Re-sorts any properties where the order so that diff's is minimised, and adds default values where appropriate so that the
the change detection is more effective.
:param clientrep: the clientrep dict to be sanitized
:param remove_ids: If set to true, then the unique ID's of objects is removed to make the diff and checks for changed
not alert when the ID's of objects are not usually known, (e.g. for protocol_mappers)
:return: normalised clientrep dict
"""
# Avoid the dict passed in to be modified
clientrep = clientrep.copy()
if 'attributes' in clientrep:
clientrep['attributes'] = list(sorted(clientrep['attributes']))
if 'redirectUris' in clientrep:
clientrep['redirectUris'] = list(sorted(clientrep['redirectUris']))
if 'protocolMappers' in clientrep:
clientrep['protocolMappers'] = sorted(clientrep['protocolMappers'], key=lambda x: (x.get('name'), x.get('protocol'), x.get('protocolMapper')))
for mapper in clientrep['protocolMappers']:
if remove_ids:
mapper.pop('id', None)
# Set to a default value.
mapper['consentRequired'] = mapper.get('consentRequired', False)
return clientrep
def sanitize_cr(clientrep):
""" Removes probably sensitive details from a client representation.
""" Removes probably sensitive details from a client representation
:param clientrep: the clientrep dict to be sanitized
:return: sanitized clientrep dict
@@ -727,7 +696,7 @@ def sanitize_cr(clientrep):
if 'attributes' in result:
if 'saml.signing.private.key' in result['attributes']:
result['attributes']['saml.signing.private.key'] = 'no_log'
return normalise_cr(result)
return result
def main():
@@ -790,7 +759,6 @@ def main():
protocol_mappers=dict(type='list', elements='dict', options=protmapper_spec, aliases=['protocolMappers']),
authorization_settings=dict(type='dict', aliases=['authorizationSettings']),
)
argument_spec.update(meta_args)
module = AnsibleModule(argument_spec=argument_spec,
@@ -813,12 +781,12 @@ def main():
cid = module.params.get('id')
state = module.params.get('state')
# Filter and map the parameters names that apply to the client
# convert module parameters to client representation parameters (if they belong in there)
client_params = [x for x in module.params
if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm'] and
module.params.get(x) is not None]
# See if it already exists in Keycloak
keycloak_argument_spec().keys()
# See whether the client already exists in Keycloak
if cid is None:
before_client = kc.get_client_by_clientid(module.params.get('client_id'), realm=realm)
if before_client is not None:
@@ -827,10 +795,10 @@ def main():
before_client = kc.get_client_by_id(cid, realm=realm)
if before_client is None:
before_client = {}
before_client = dict()
# Build a proposed changeset from parameters given to this module
changeset = {}
changeset = dict()
for client_param in client_params:
new_param_value = module.params.get(client_param)
@@ -849,63 +817,54 @@ def main():
changeset[camel(client_param)] = new_param_value
# Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis)
desired_client = before_client.copy()
desired_client.update(changeset)
# Whether creating or updating a client, take the before-state and merge the changeset into it
updated_client = before_client.copy()
updated_client.update(changeset)
result['proposed'] = sanitize_cr(changeset)
result['existing'] = sanitize_cr(before_client)
# Cater for when it doesn't exist (an empty dict)
if not before_client:
# If the client does not exist yet, before_client is still empty
if before_client == dict():
if state == 'absent':
# Do nothing and exit
# do nothing and exit
if module._diff:
result['diff'] = dict(before='', after='')
result['changed'] = False
result['end_state'] = {}
result['msg'] = 'Client does not exist; doing nothing.'
result['msg'] = 'Client does not exist, doing nothing.'
module.exit_json(**result)
# Process a creation
# create new client
result['changed'] = True
if 'clientId' not in desired_client:
if 'clientId' not in updated_client:
module.fail_json(msg='client_id needs to be specified when creating a new client')
if module._diff:
result['diff'] = dict(before='', after=sanitize_cr(desired_client))
result['diff'] = dict(before='', after=sanitize_cr(updated_client))
if module.check_mode:
module.exit_json(**result)
# create it
kc.create_client(desired_client, realm=realm)
after_client = kc.get_client_by_clientid(desired_client['clientId'], realm=realm)
kc.create_client(updated_client, realm=realm)
after_client = kc.get_client_by_clientid(updated_client['clientId'], realm=realm)
result['end_state'] = sanitize_cr(after_client)
result['msg'] = 'Client %s has been created.' % desired_client['clientId']
result['msg'] = 'Client %s has been created.' % updated_client['clientId']
module.exit_json(**result)
else:
if state == 'present':
# Process an update
# update existing client
result['changed'] = True
if module.check_mode:
# We can only compare the current client with the proposed updates we have
before_norm = normalise_cr(before_client, remove_ids=True)
desired_norm = normalise_cr(desired_client, remove_ids=True)
if module._diff:
result['diff'] = dict(before=sanitize_cr(before_norm),
after=sanitize_cr(desired_norm))
result['changed'] = (before_norm != desired_norm)
result['diff'] = dict(before=sanitize_cr(before_client),
after=sanitize_cr(updated_client))
result['changed'] = (before_client != updated_client)
module.exit_json(**result)
# do the update
kc.update_client(cid, desired_client, realm=realm)
kc.update_client(cid, updated_client, realm=realm)
after_client = kc.get_client_by_id(cid, realm=realm)
if before_client == after_client:
@@ -913,29 +872,25 @@ def main():
if module._diff:
result['diff'] = dict(before=sanitize_cr(before_client),
after=sanitize_cr(after_client))
result['end_state'] = sanitize_cr(after_client)
result['msg'] = 'Client %s has been updated.' % desired_client['clientId']
result['msg'] = 'Client %s has been updated.' % updated_client['clientId']
module.exit_json(**result)
else:
# Process a deletion (because state was not 'present')
# Delete existing client
result['changed'] = True
if module._diff:
result['diff'] = dict(before=sanitize_cr(before_client), after='')
result['diff']['before'] = sanitize_cr(before_client)
result['diff']['after'] = ''
if module.check_mode:
module.exit_json(**result)
# delete it
kc.delete_client(cid, realm=realm)
result['proposed'] = {}
result['end_state'] = {}
result['proposed'] = dict()
result['end_state'] = dict()
result['msg'] = 'Client %s has been deleted.' % before_client['clientId']
module.exit_json(**result)
module.exit_json(**result)

View File

@@ -11,7 +11,6 @@ DOCUMENTATION = '''
module: keycloak_client_rolemapping
short_description: Allows administration of Keycloak client_rolemapping with the Keycloak API
version_added: 3.5.0
description:
@@ -159,22 +158,21 @@ EXAMPLES = '''
RETURN = '''
msg:
description: Message as to what action was taken.
returned: always
type: str
sample: "Role role1 assigned to group group1."
description: Message as to what action was taken
returned: always
type: str
sample: "Role role1 assigned to group group1."
proposed:
description: Representation of proposed client role mapping.
description: role_representation representation of proposed changes to client_rolemapping.
returned: always
type: dict
sample: {
clientId: "test"
}
existing:
description:
- Representation of existing client role mapping.
- role_representation representation of existing role_representation.
- The sample is truncated.
returned: always
type: dict
@@ -184,12 +182,11 @@ existing:
"request.object.signature.alg": "RS256",
}
}
end_state:
description:
- Representation of client role mapping after module execution.
- role_representation representation of role_representation after module execution.
- The sample is truncated.
returned: on success
returned: always
type: dict
sample: {
"adminUrl": "http://www.example.com/admin_url",

View File

@@ -86,7 +86,7 @@ options:
suboptions:
protocol:
description:
- This specifies for which protocol this protocol mapper.
- This specifies for which protocol this protocol mapper
- is active.
choices: ['openid-connect', 'saml', 'wsfed']
type: str
@@ -256,21 +256,20 @@ EXAMPLES = '''
RETURN = '''
msg:
description: Message as to what action was taken.
returned: always
type: str
sample: "Client_scope testclientscope has been updated"
description: Message as to what action was taken
returned: always
type: str
sample: "Client_scope testclientscope has been updated"
proposed:
description: Representation of proposed client scope.
description: client_scope representation of proposed changes to client_scope
returned: always
type: dict
sample: {
clientId: "test"
}
existing:
description: Representation of existing client scope (sample is truncated).
description: client_scope representation of existing client_scope (sample is truncated)
returned: always
type: dict
sample: {
@@ -279,10 +278,9 @@ existing:
"request.object.signature.alg": "RS256",
}
}
end_state:
description: Representation of client scope after module execution (sample is truncated).
returned: on success
description: client_scope representation of client_scope after module execution (sample is truncated)
returned: always
type: dict
sample: {
"adminUrl": "http://www.example.com/admin_url",
@@ -298,7 +296,7 @@ from ansible.module_utils.basic import AnsibleModule
def sanitize_cr(clientscoperep):
""" Removes probably sensitive details from a clientscoperep representation.
""" Removes probably sensitive details from a clientscoperep representation
:param clientscoperep: the clientscoperep dict to be sanitized
:return: sanitized clientrep dict
@@ -363,22 +361,22 @@ def main():
name = module.params.get('name')
protocol_mappers = module.params.get('protocol_mappers')
# Filter and map the parameters names that apply to the client scope
clientscope_params = [x for x in module.params
if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm'] and
module.params.get(x) is not None]
before_clientscope = None # current state of the clientscope, for merging.
# See if it already exists in Keycloak
# does the clientscope already exist?
if cid is None:
before_clientscope = kc.get_clientscope_by_name(name, realm=realm)
else:
before_clientscope = kc.get_clientscope_by_clientscopeid(cid, realm=realm)
if before_clientscope is None:
before_clientscope = {}
before_clientscope = {} if before_clientscope is None else before_clientscope
clientscope_params = [x for x in module.params
if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm'] and
module.params.get(x) is not None]
# Build a proposed changeset from parameters given to this module
changeset = {}
changeset = dict()
for clientscope_param in clientscope_params:
new_param_value = module.params.get(clientscope_param)
@@ -396,87 +394,81 @@ def main():
new_param_value = [dict((k, v) for k, v in x.items() if x[k] is not None) for x in new_param_value]
changeset[camel(clientscope_param)] = new_param_value
# Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis)
desired_clientscope = before_clientscope.copy()
desired_clientscope.update(changeset)
# prepare the new clientscope
updated_clientscope = before_clientscope.copy()
updated_clientscope.update(changeset)
# Cater for when it doesn't exist (an empty dict)
if not before_clientscope:
# if before_clientscope is none, the clientscope doesn't exist.
if before_clientscope == {}:
if state == 'absent':
# Do nothing and exit
# nothing to do.
if module._diff:
result['diff'] = dict(before='', after='')
result['changed'] = False
result['end_state'] = {}
result['msg'] = 'Clientscope does not exist; doing nothing.'
result['end_state'] = dict()
module.exit_json(**result)
# Process a creation
# for 'present', create a new clientscope.
result['changed'] = True
if name is None:
module.fail_json(msg='name must be specified when creating a new clientscope')
if module._diff:
result['diff'] = dict(before='', after=sanitize_cr(desired_clientscope))
result['diff'] = dict(before='', after=sanitize_cr(updated_clientscope))
if module.check_mode:
module.exit_json(**result)
# create it
kc.create_clientscope(desired_clientscope, realm=realm)
# do it for real!
kc.create_clientscope(updated_clientscope, realm=realm)
after_clientscope = kc.get_clientscope_by_name(name, realm)
result['end_state'] = sanitize_cr(after_clientscope)
result['msg'] = 'Clientscope {name} has been created with ID {id}'.format(name=after_clientscope['name'],
id=after_clientscope['id'])
else:
if state == 'present':
# Process an update
# no changes
if desired_clientscope == before_clientscope:
if updated_clientscope == before_clientscope:
result['changed'] = False
result['end_state'] = sanitize_cr(desired_clientscope)
result['end_state'] = sanitize_cr(updated_clientscope)
result['msg'] = "No changes required to clientscope {name}.".format(name=before_clientscope['name'])
module.exit_json(**result)
# doing an update
# update the existing clientscope
result['changed'] = True
if module._diff:
result['diff'] = dict(before=sanitize_cr(before_clientscope), after=sanitize_cr(desired_clientscope))
result['diff'] = dict(before=sanitize_cr(before_clientscope), after=sanitize_cr(updated_clientscope))
if module.check_mode:
module.exit_json(**result)
# do the update
kc.update_clientscope(desired_clientscope, realm=realm)
# do the clientscope update
kc.update_clientscope(updated_clientscope, realm=realm)
# do the protocolmappers update
if protocol_mappers is not None:
for protocol_mapper in protocol_mappers:
# update if protocolmapper exist
current_protocolmapper = kc.get_clientscope_protocolmapper_by_name(desired_clientscope['id'], protocol_mapper['name'], realm=realm)
current_protocolmapper = kc.get_clientscope_protocolmapper_by_name(updated_clientscope['id'], protocol_mapper['name'], realm=realm)
if current_protocolmapper is not None:
protocol_mapper['id'] = current_protocolmapper['id']
kc.update_clientscope_protocolmappers(desired_clientscope['id'], protocol_mapper, realm=realm)
kc.update_clientscope_protocolmappers(updated_clientscope['id'], protocol_mapper, realm=realm)
# create otherwise
else:
kc.create_clientscope_protocolmapper(desired_clientscope['id'], protocol_mapper, realm=realm)
kc.create_clientscope_protocolmapper(updated_clientscope['id'], protocol_mapper, realm=realm)
after_clientscope = kc.get_clientscope_by_clientscopeid(desired_clientscope['id'], realm=realm)
after_clientscope = kc.get_clientscope_by_clientscopeid(updated_clientscope['id'], realm=realm)
result['end_state'] = after_clientscope
result['msg'] = "Clientscope {id} has been updated".format(id=after_clientscope['id'])
module.exit_json(**result)
else:
# Process a deletion (because state was not 'present')
result['changed'] = True
elif state == 'absent':
result['end_state'] = dict()
if module._diff:
result['diff'] = dict(before=sanitize_cr(before_clientscope), after='')
@@ -484,14 +476,15 @@ def main():
if module.check_mode:
module.exit_json(**result)
# delete it
# delete for real
cid = before_clientscope['id']
kc.delete_clientscope(cid=cid, realm=realm)
result['end_state'] = {}
result['changed'] = True
result['msg'] = "Clientscope {name} has been deleted".format(name=before_clientscope['name'])
module.exit_json(**result)
module.exit_json(**result)

View File

@@ -31,7 +31,7 @@ description:
options:
state:
description:
- State of the client template.
- State of the client template
- On C(present), the client template will be created (or updated if it exists already).
- On C(absent), the client template will be removed if it exists
choices: ['present', 'absent']
@@ -51,12 +51,12 @@ options:
name:
description:
- Name of the client template.
- Name of the client template
type: str
description:
description:
- Description of the client template in Keycloak.
- Description of the client template in Keycloak
type: str
protocol:
@@ -100,7 +100,7 @@ options:
protocol:
description:
- This is either C(openid-connect) or C(saml), this specifies for which protocol this protocol mapper.
- is either 'openid-connect' or 'saml', this specifies for which protocol this protocol mapper
is active.
choices: ['openid-connect', 'saml']
type: str
@@ -143,7 +143,7 @@ options:
contents differ depending on the value of I(protocolMapper) and are not documented
other than by the source of the mappers and its parent class(es). An example is given
below. It is easiest to obtain valid config values by dumping an already-existing
protocol mapper configuration through check-mode in the I(existing) field.
protocol mapper configuration through check-mode in the "existing" field.
type: dict
attributes:
@@ -163,6 +163,7 @@ notes:
extends_documentation_fragment:
- community.general.keycloak
author:
- Eike Frost (@eikef)
'''
@@ -230,21 +231,20 @@ EXAMPLES = '''
RETURN = '''
msg:
description: Message as to what action was taken.
returned: always
type: str
sample: "Client template testclient has been updated"
description: Message as to what action was taken
returned: always
type: str
sample: "Client template testclient has been updated"
proposed:
description: Representation of proposed client template.
description: client template representation of proposed changes to client template
returned: always
type: dict
sample: {
name: "test01"
}
existing:
description: Representation of existing client template (sample is truncated).
description: client template representation of existing client template (sample is truncated)
returned: always
type: dict
sample: {
@@ -254,10 +254,9 @@ existing:
"name": "test01",
"protocol": "saml"
}
end_state:
description: Representation of client template after module execution (sample is truncated).
returned: on success
description: client template representation of client template after module execution (sample is truncated)
returned: always
type: dict
sample: {
"description": "test01",
@@ -303,7 +302,6 @@ def main():
full_scope_allowed=dict(type='bool'),
protocol_mappers=dict(type='list', elements='dict', options=protmapper_spec),
)
argument_spec.update(meta_args)
module = AnsibleModule(argument_spec=argument_spec,
@@ -319,20 +317,19 @@ def main():
connection_header = get_token(module.params)
except KeycloakError as e:
module.fail_json(msg=str(e))
kc = KeycloakAPI(module, connection_header)
realm = module.params.get('realm')
state = module.params.get('state')
cid = module.params.get('id')
# Filter and map the parameters names that apply to the client template
# convert module parameters to client representation parameters (if they belong in there)
clientt_params = [x for x in module.params
if x not in ['state', 'auth_keycloak_url', 'auth_client_id', 'auth_realm',
'auth_client_secret', 'auth_username', 'auth_password',
'validate_certs', 'realm'] and module.params.get(x) is not None]
# See if it already exists in Keycloak
# See whether the client template already exists in Keycloak
if cid is None:
before_clientt = kc.get_client_template_by_name(module.params.get('name'), realm=realm)
if before_clientt is not None:
@@ -341,12 +338,12 @@ def main():
before_clientt = kc.get_client_template_by_id(cid, realm=realm)
if before_clientt is None:
before_clientt = {}
before_clientt = dict()
result['existing'] = before_clientt
# Build a proposed changeset from parameters given to this module
changeset = {}
changeset = dict()
for clientt_param in clientt_params:
# lists in the Keycloak API are sorted
@@ -358,89 +355,78 @@ def main():
pass
changeset[camel(clientt_param)] = new_param_value
# Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis)
desired_clientt = before_clientt.copy()
desired_clientt.update(changeset)
# Whether creating or updating a client, take the before-state and merge the changeset into it
updated_clientt = before_clientt.copy()
updated_clientt.update(changeset)
result['proposed'] = changeset
# Cater for when it doesn't exist (an empty dict)
if not before_clientt:
# If the client template does not exist yet, before_client is still empty
if before_clientt == dict():
if state == 'absent':
# Do nothing and exit
# do nothing and exit
if module._diff:
result['diff'] = dict(before='', after='')
result['changed'] = False
result['end_state'] = {}
result['msg'] = 'Client template does not exist, doing nothing.'
module.exit_json(**result)
# Process a creation
# create new client template
result['changed'] = True
if 'name' not in desired_clientt:
if 'name' not in updated_clientt:
module.fail_json(msg='name needs to be specified when creating a new client')
if module._diff:
result['diff'] = dict(before='', after=desired_clientt)
result['diff'] = dict(before='', after=updated_clientt)
if module.check_mode:
module.exit_json(**result)
# create it
kc.create_client_template(desired_clientt, realm=realm)
after_clientt = kc.get_client_template_by_name(desired_clientt['name'], realm=realm)
kc.create_client_template(updated_clientt, realm=realm)
after_clientt = kc.get_client_template_by_name(updated_clientt['name'], realm=realm)
result['end_state'] = after_clientt
result['msg'] = 'Client template %s has been created.' % desired_clientt['name']
result['msg'] = 'Client template %s has been created.' % updated_clientt['name']
module.exit_json(**result)
else:
if state == 'present':
# Process an update
# update existing client template
result['changed'] = True
if module.check_mode:
# We can only compare the current client template with the proposed updates we have
if module._diff:
result['diff'] = dict(before=before_clientt,
after=desired_clientt)
after=updated_clientt)
module.exit_json(**result)
# do the update
kc.update_client_template(cid, desired_clientt, realm=realm)
kc.update_client_template(cid, updated_clientt, realm=realm)
after_clientt = kc.get_client_template_by_id(cid, realm=realm)
if before_clientt == after_clientt:
result['changed'] = False
if module._diff:
result['diff'] = dict(before=before_clientt,
after=after_clientt)
result['end_state'] = after_clientt
if module._diff:
result['diff'] = dict(before=before_clientt, after=after_clientt)
result['msg'] = 'Client template %s has been updated.' % desired_clientt['name']
result['msg'] = 'Client template %s has been updated.' % updated_clientt['name']
module.exit_json(**result)
else:
# Process a deletion (because state was not 'present')
# Delete existing client
result['changed'] = True
if module._diff:
result['diff'] = dict(before=before_clientt, after='')
result['diff']['before'] = before_clientt
result['diff']['after'] = ''
if module.check_mode:
module.exit_json(**result)
# delete it
kc.delete_client_template(cid, realm=realm)
result['proposed'] = {}
result['end_state'] = {}
result['proposed'] = dict()
result['end_state'] = dict()
result['msg'] = 'Client template %s has been deleted.' % before_clientt['name']
module.exit_json(**result)
module.exit_json(**result)

View File

@@ -159,91 +159,34 @@ EXAMPLES = '''
'''
RETURN = '''
msg:
description: Message as to what action was taken.
returned: always
type: str
end_state:
description: Representation of the group after module execution (sample is truncated).
returned: on success
type: complex
contains:
id:
description: GUID that identifies the group.
type: str
returned: always
sample: 23f38145-3195-462c-97e7-97041ccea73e
name:
description: Name of the group.
type: str
returned: always
sample: grp-test-123
attributes:
description: Attributes applied to this group.
type: dict
returned: always
sample:
attr1: ["val1", "val2", "val3"]
path:
description: URI path to the group.
type: str
returned: always
sample: /grp-test-123
realmRoles:
description: An array of the realm-level roles granted to this group.
type: list
returned: always
sample: []
subGroups:
description: A list of groups that are children of this group. These groups will have the same parameters as
documented here.
type: list
returned: always
clientRoles:
description: A list of client-level roles granted to this group.
type: list
returned: always
sample: []
access:
description: A dict describing the accesses you have to this group based on the credentials used.
type: dict
returned: always
sample:
manage: true
manageMembership: true
view: true
group:
description:
- Representation of the group after module execution.
- Deprecated return value, it will be removed in community.general 6.0.0. Please use the return value I(end_state) instead.
description: Group representation of the group after module execution (sample is truncated).
returned: always
type: complex
contains:
id:
description: GUID that identifies the group.
description: GUID that identifies the group
type: str
returned: always
sample: 23f38145-3195-462c-97e7-97041ccea73e
name:
description: Name of the group.
description: Name of the group
type: str
returned: always
sample: grp-test-123
attributes:
description: Attributes applied to this group.
description: Attributes applied to this group
type: dict
returned: always
sample:
attr1: ["val1", "val2", "val3"]
path:
description: URI path to the group.
description: URI path to the group
type: str
returned: always
sample: /grp-test-123
realmRoles:
description: An array of the realm-level roles granted to this group.
description: An array of the realm-level roles granted to this group
type: list
returned: always
sample: []
@@ -253,7 +196,7 @@ group:
type: list
returned: always
clientRoles:
description: A list of client-level roles granted to this group.
description: A list of client-level roles granted to this group
type: list
returned: always
sample: []
@@ -265,7 +208,6 @@ group:
manage: true
manageMembership: true
view: true
'''
from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import KeycloakAPI, camel, \
@@ -280,7 +222,6 @@ def main():
:return:
"""
argument_spec = keycloak_argument_spec()
meta_args = dict(
state=dict(default='present', choices=['present', 'absent']),
realm=dict(default='master'),
@@ -313,6 +254,16 @@ def main():
name = module.params.get('name')
attributes = module.params.get('attributes')
before_group = None # current state of the group, for merging.
# does the group already exist?
if gid is None:
before_group = kc.get_group_by_name(name, realm=realm)
else:
before_group = kc.get_group_by_groupid(gid, realm=realm)
before_group = {} if before_group is None else before_group
# attributes in Keycloak have their values returned as lists
# via the API. attributes is a dict, so we'll transparently convert
# the values to lists.
@@ -320,103 +271,81 @@ def main():
for key, val in module.params['attributes'].items():
module.params['attributes'][key] = [val] if not isinstance(val, list) else val
# Filter and map the parameters names that apply to the group
group_params = [x for x in module.params
if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm'] and
module.params.get(x) is not None]
# See if it already exists in Keycloak
if gid is None:
before_group = kc.get_group_by_name(name, realm=realm)
else:
before_group = kc.get_group_by_groupid(gid, realm=realm)
if before_group is None:
before_group = {}
# Build a proposed changeset from parameters given to this module
# build a changeset
changeset = {}
for param in group_params:
new_param_value = module.params.get(param)
old_value = before_group[param] if param in before_group else None
if new_param_value != old_value:
changeset[camel(param)] = new_param_value
# Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis)
desired_group = before_group.copy()
desired_group.update(changeset)
# prepare the new group
updated_group = before_group.copy()
updated_group.update(changeset)
# Cater for when it doesn't exist (an empty dict)
if not before_group:
# if before_group is none, the group doesn't exist.
if before_group == {}:
if state == 'absent':
# Do nothing and exit
# nothing to do.
if module._diff:
result['diff'] = dict(before='', after='')
result['changed'] = False
result['end_state'] = {}
result['group'] = result['end_state']
result['msg'] = 'Group does not exist; doing nothing.'
result['group'] = dict()
module.exit_json(**result)
# Process a creation
# for 'present', create a new group.
result['changed'] = True
if name is None:
module.fail_json(msg='name must be specified when creating a new group')
if module._diff:
result['diff'] = dict(before='', after=desired_group)
result['diff'] = dict(before='', after=updated_group)
if module.check_mode:
module.exit_json(**result)
# create it
kc.create_group(desired_group, realm=realm)
# do it for real!
kc.create_group(updated_group, realm=realm)
after_group = kc.get_group_by_name(name, realm)
result['end_state'] = after_group
result['group'] = result['end_state']
result['group'] = after_group
result['msg'] = 'Group {name} has been created with ID {id}'.format(name=after_group['name'],
id=after_group['id'])
module.exit_json(**result)
else:
if state == 'present':
# Process an update
# no changes
if desired_group == before_group:
if updated_group == before_group:
result['changed'] = False
result['end_state'] = desired_group
result['group'] = result['end_state']
result['group'] = updated_group
result['msg'] = "No changes required to group {name}.".format(name=before_group['name'])
module.exit_json(**result)
# doing an update
# update the existing group
result['changed'] = True
if module._diff:
result['diff'] = dict(before=before_group, after=desired_group)
result['diff'] = dict(before=before_group, after=updated_group)
if module.check_mode:
module.exit_json(**result)
# do the update
kc.update_group(desired_group, realm=realm)
kc.update_group(updated_group, realm=realm)
after_group = kc.get_group_by_groupid(desired_group['id'], realm=realm)
result['end_state'] = after_group
result['group'] = result['end_state']
after_group = kc.get_group_by_groupid(updated_group['id'], realm=realm)
result['group'] = after_group
result['msg'] = "Group {id} has been updated".format(id=after_group['id'])
module.exit_json(**result)
else:
# Process a deletion (because state was not 'present')
result['changed'] = True
elif state == 'absent':
result['group'] = dict()
if module._diff:
result['diff'] = dict(before=before_group, after='')
@@ -424,15 +353,15 @@ def main():
if module.check_mode:
module.exit_json(**result)
# delete it
# delete for real
gid = before_group['id']
kc.delete_group(groupid=gid, realm=realm)
result['end_state'] = {}
result['group'] = result['end_state']
result['changed'] = True
result['msg'] = "Group {name} has been deleted".format(name=before_group['name'])
module.exit_json(**result)
module.exit_json(**result)

View File

@@ -339,13 +339,13 @@ EXAMPLES = '''
RETURN = '''
msg:
description: Message as to what action was taken.
returned: always
type: str
sample: "Identity provider my-idp has been created"
description: Message as to what action was taken
returned: always
type: str
sample: "Identity provider my-idp has been created"
proposed:
description: Representation of proposed identity provider.
description: Representation of proposed changes to identity provider
returned: always
type: dict
sample: {
@@ -363,7 +363,7 @@ proposed:
}
existing:
description: Representation of existing identity provider.
description: Representation of existing identity provider
returned: always
type: dict
sample: {
@@ -391,8 +391,8 @@ existing:
}
end_state:
description: Representation of identity provider after module execution.
returned: on success
description: Representation of identity provider after module execution
returned: always
type: dict
sample: {
"addReadTokenRoleOnCreate": false,
@@ -416,6 +416,7 @@ end_state:
"storeToken": false,
"trustEmail": false,
}
'''
from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import KeycloakAPI, camel, \
@@ -437,7 +438,7 @@ def get_identity_provider_with_mappers(kc, alias, realm):
if idp is not None:
idp['mappers'] = sorted(kc.get_identity_provider_mappers(alias, realm), key=lambda x: x.get('name'))
if idp is None:
idp = {}
idp = dict()
return idp
@@ -496,16 +497,16 @@ def main():
alias = module.params.get('alias')
state = module.params.get('state')
# Filter and map the parameters names that apply to the identity provider.
# convert module parameters to client representation parameters (if they belong in there)
idp_params = [x for x in module.params
if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm', 'mappers'] and
module.params.get(x) is not None]
# See if it already exists in Keycloak
# does the identity provider already exist?
before_idp = get_identity_provider_with_mappers(kc, alias, realm)
# Build a proposed changeset from parameters given to this module
changeset = {}
# build a changeset
changeset = dict()
for param in idp_params:
new_param_value = module.params.get(param)
@@ -538,37 +539,37 @@ def main():
changeset['mappers'] = list()
changeset['mappers'].append(new_mapper)
# Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis)
desired_idp = before_idp.copy()
desired_idp.update(changeset)
# prepare the new representation
updated_idp = before_idp.copy()
updated_idp.update(changeset)
result['proposed'] = sanitize(changeset)
result['existing'] = sanitize(before_idp)
# Cater for when it doesn't exist (an empty dict)
if not before_idp:
# if before_idp is none, the identity provider doesn't exist.
if before_idp == dict():
if state == 'absent':
# Do nothing and exit
# nothing to do.
if module._diff:
result['diff'] = dict(before='', after='')
result['changed'] = False
result['end_state'] = {}
result['end_state'] = dict()
result['msg'] = 'Identity provider does not exist; doing nothing.'
module.exit_json(**result)
# Process a creation
# for 'present', create a new identity provider.
result['changed'] = True
if module._diff:
result['diff'] = dict(before='', after=sanitize(desired_idp))
result['diff'] = dict(before='', after=sanitize(updated_idp))
if module.check_mode:
module.exit_json(**result)
# create it
desired_idp = desired_idp.copy()
mappers = desired_idp.pop('mappers', [])
kc.create_identity_provider(desired_idp, realm)
# do it for real!
updated_idp = updated_idp.copy()
mappers = updated_idp.pop('mappers', [])
kc.create_identity_provider(updated_idp, realm)
for mapper in mappers:
if mapper.get('identityProviderAlias') is None:
mapper['identityProviderAlias'] = alias
@@ -582,28 +583,26 @@ def main():
else:
if state == 'present':
# Process an update
# no changes
if desired_idp == before_idp:
if updated_idp == before_idp:
result['changed'] = False
result['end_state'] = sanitize(desired_idp)
result['end_state'] = sanitize(updated_idp)
result['msg'] = "No changes required to identity provider {alias}.".format(alias=alias)
module.exit_json(**result)
# doing an update
# update the existing role
result['changed'] = True
if module._diff:
result['diff'] = dict(before=sanitize(before_idp), after=sanitize(desired_idp))
result['diff'] = dict(before=sanitize(before_idp), after=sanitize(updated_idp))
if module.check_mode:
module.exit_json(**result)
# do the update
desired_idp = desired_idp.copy()
updated_mappers = desired_idp.pop('mappers', [])
kc.update_identity_provider(desired_idp, realm)
updated_idp = updated_idp.copy()
updated_mappers = updated_idp.pop('mappers', [])
kc.update_identity_provider(updated_idp, realm)
for mapper in updated_mappers:
if mapper.get('id') is not None:
kc.update_identity_provider_mapper(mapper, alias, realm)
@@ -623,7 +622,6 @@ def main():
module.exit_json(**result)
elif state == 'absent':
# Process a deletion
result['changed'] = True
if module._diff:
@@ -632,12 +630,13 @@ def main():
if module.check_mode:
module.exit_json(**result)
# delete it
# delete for real
kc.delete_identity_provider(alias, realm)
result['end_state'] = {}
result['end_state'] = dict()
result['msg'] = "Identity provider {alias} has been deleted".format(alias=alias)
module.exit_json(**result)
module.exit_json(**result)

View File

@@ -13,7 +13,6 @@ DOCUMENTATION = '''
module: keycloak_realm
short_description: Allows administration of Keycloak realm via Keycloak API
version_added: 3.0.0
@@ -534,21 +533,20 @@ EXAMPLES = '''
RETURN = '''
msg:
description: Message as to what action was taken.
returned: always
type: str
sample: "Realm testrealm has been updated"
description: Message as to what action was taken
returned: always
type: str
sample: "Realm testrealm has been updated"
proposed:
description: Representation of proposed realm.
description: realm representation of proposed changes to realm
returned: always
type: dict
sample: {
id: "test"
}
existing:
description: Representation of existing realm (sample is truncated).
description: realm representation of existing realm (sample is truncated)
returned: always
type: dict
sample: {
@@ -557,10 +555,9 @@ existing:
"request.object.signature.alg": "RS256",
}
}
end_state:
description: Representation of realm after module execution (sample is truncated).
returned: on success
description: realm representation of realm after module execution (sample is truncated)
returned: always
type: dict
sample: {
"adminUrl": "http://www.example.com/admin_url",
@@ -576,7 +573,7 @@ from ansible.module_utils.basic import AnsibleModule
def sanitize_cr(realmrep):
""" Removes probably sensitive details from a realm representation.
""" Removes probably sensitive details from a realm representation
:param realmrep: the realmrep dict to be sanitized
:return: sanitized realmrep dict
@@ -679,7 +676,6 @@ def main():
verify_email=dict(type='bool', aliases=['verifyEmail']),
wait_increment_seconds=dict(type='int', aliases=['waitIncrementSeconds']),
)
argument_spec.update(meta_args)
module = AnsibleModule(argument_spec=argument_spec,
@@ -703,114 +699,95 @@ def main():
# convert module parameters to realm representation parameters (if they belong in there)
params_to_ignore = list(keycloak_argument_spec().keys()) + ['state']
# Filter and map the parameters names that apply to the role
realm_params = [x for x in module.params
if x not in params_to_ignore and
module.params.get(x) is not None]
# See whether the realm already exists in Keycloak
before_realm = kc.get_realm_by_id(realm=realm)
if before_realm is None:
before_realm = {}
before_realm = kc.get_realm_by_id(realm=realm) or {}
# Build a proposed changeset from parameters given to this module
changeset = {}
changeset = dict()
for realm_param in realm_params:
new_param_value = module.params.get(realm_param)
changeset[camel(realm_param)] = new_param_value
# Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis)
desired_realm = before_realm.copy()
desired_realm.update(changeset)
# Whether creating or updating a realm, take the before-state and merge the changeset into it
updated_realm = before_realm.copy()
updated_realm.update(changeset)
result['proposed'] = sanitize_cr(changeset)
before_realm_sanitized = sanitize_cr(before_realm)
result['existing'] = before_realm_sanitized
# Cater for when it doesn't exist (an empty dict)
# If the realm does not exist yet, before_realm is still empty
if not before_realm:
if state == 'absent':
# Do nothing and exit
# do nothing and exit
if module._diff:
result['diff'] = dict(before='', after='')
result['changed'] = False
result['end_state'] = {}
result['msg'] = 'Realm does not exist, doing nothing.'
module.exit_json(**result)
# Process a creation
# create new realm
result['changed'] = True
if 'id' not in desired_realm:
if 'id' not in updated_realm:
module.fail_json(msg='id needs to be specified when creating a new realm')
if module._diff:
result['diff'] = dict(before='', after=sanitize_cr(desired_realm))
result['diff'] = dict(before='', after=sanitize_cr(updated_realm))
if module.check_mode:
module.exit_json(**result)
# create it
kc.create_realm(desired_realm)
after_realm = kc.get_realm_by_id(desired_realm['id'])
kc.create_realm(updated_realm)
after_realm = kc.get_realm_by_id(updated_realm['id'])
result['end_state'] = sanitize_cr(after_realm)
result['msg'] = 'Realm %s has been created.' % desired_realm['id']
result['msg'] = 'Realm %s has been created.' % updated_realm['id']
module.exit_json(**result)
else:
if state == 'present':
# Process an update
# doing an update
# update existing realm
result['changed'] = True
if module.check_mode:
# We can only compare the current realm with the proposed updates we have
if module._diff:
result['diff'] = dict(before=before_realm_sanitized,
after=sanitize_cr(desired_realm))
result['changed'] = (before_realm != desired_realm)
after=sanitize_cr(updated_realm))
result['changed'] = (before_realm != updated_realm)
module.exit_json(**result)
# do the update
kc.update_realm(desired_realm, realm=realm)
kc.update_realm(updated_realm, realm=realm)
after_realm = kc.get_realm_by_id(realm=realm)
if before_realm == after_realm:
result['changed'] = False
result['end_state'] = sanitize_cr(after_realm)
if module._diff:
result['diff'] = dict(before=before_realm_sanitized,
after=sanitize_cr(after_realm))
result['end_state'] = sanitize_cr(after_realm)
result['msg'] = 'Realm %s has been updated.' % desired_realm['id']
result['msg'] = 'Realm %s has been updated.' % updated_realm['id']
module.exit_json(**result)
else:
# Process a deletion (because state was not 'present')
# Delete existing realm
result['changed'] = True
if module._diff:
result['diff'] = dict(before=before_realm_sanitized, after='')
result['diff']['before'] = before_realm_sanitized
result['diff']['after'] = ''
if module.check_mode:
module.exit_json(**result)
# delete it
kc.delete_realm(realm=realm)
result['proposed'] = {}
result['end_state'] = {}
result['proposed'] = dict()
result['end_state'] = dict()
result['msg'] = 'Realm %s has been deleted.' % before_realm['id']
module.exit_json(**result)
module.exit_json(**result)

View File

@@ -149,21 +149,20 @@ EXAMPLES = '''
RETURN = '''
msg:
description: Message as to what action was taken.
returned: always
type: str
sample: "Role myrole has been updated"
description: Message as to what action was taken
returned: always
type: str
sample: "Role myrole has been updated"
proposed:
description: Representation of proposed role.
description: Role representation of proposed changes to role
returned: always
type: dict
sample: {
"description": "My updated test description"
}
existing:
description: Representation of existing role.
description: Role representation of existing role
returned: always
type: dict
sample: {
@@ -175,10 +174,9 @@ existing:
"id": "561703dd-0f38-45ff-9a5a-0c978f794547",
"name": "myrole"
}
end_state:
description: Representation of role after module execution (sample is truncated).
returned: on success
description: Role representation of role after module execution (sample is truncated)
returned: always
type: dict
sample: {
"attributes": {},
@@ -203,7 +201,6 @@ def main():
:return:
"""
argument_spec = keycloak_argument_spec()
meta_args = dict(
state=dict(type='str', default='present', choices=['present', 'absent']),
name=dict(type='str', required=True),
@@ -242,22 +239,22 @@ def main():
for key, val in module.params['attributes'].items():
module.params['attributes'][key] = [val] if not isinstance(val, list) else val
# Filter and map the parameters names that apply to the role
# convert module parameters to client representation parameters (if they belong in there)
role_params = [x for x in module.params
if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm', 'client_id', 'composites'] and
module.params.get(x) is not None]
# See if it already exists in Keycloak
# does the role already exist?
if clientid is None:
before_role = kc.get_realm_role(name, realm)
else:
before_role = kc.get_client_role(name, clientid, realm)
if before_role is None:
before_role = {}
before_role = dict()
# Build a proposed changeset from parameters given to this module
changeset = {}
# build a changeset
changeset = dict()
for param in role_params:
new_param_value = module.params.get(param)
@@ -265,42 +262,42 @@ def main():
if new_param_value != old_value:
changeset[camel(param)] = new_param_value
# Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis)
desired_role = before_role.copy()
desired_role.update(changeset)
# prepare the new role
updated_role = before_role.copy()
updated_role.update(changeset)
result['proposed'] = changeset
result['existing'] = before_role
# Cater for when it doesn't exist (an empty dict)
if not before_role:
# if before_role is none, the role doesn't exist.
if before_role == dict():
if state == 'absent':
# Do nothing and exit
# nothing to do.
if module._diff:
result['diff'] = dict(before='', after='')
result['changed'] = False
result['end_state'] = {}
result['msg'] = 'Role does not exist, doing nothing.'
result['end_state'] = dict()
result['msg'] = 'Role does not exist; doing nothing.'
module.exit_json(**result)
# Process a creation
# for 'present', create a new role.
result['changed'] = True
if name is None:
module.fail_json(msg='name must be specified when creating a new role')
if module._diff:
result['diff'] = dict(before='', after=desired_role)
result['diff'] = dict(before='', after=updated_role)
if module.check_mode:
module.exit_json(**result)
# create it
# do it for real!
if clientid is None:
kc.create_realm_role(desired_role, realm)
kc.create_realm_role(updated_role, realm)
after_role = kc.get_realm_role(name, realm)
else:
kc.create_client_role(desired_role, clientid, realm)
kc.create_client_role(updated_role, clientid, realm)
after_role = kc.get_client_role(name, clientid, realm)
result['end_state'] = after_role
@@ -310,30 +307,28 @@ def main():
else:
if state == 'present':
# Process an update
# no changes
if desired_role == before_role:
if updated_role == before_role:
result['changed'] = False
result['end_state'] = desired_role
result['end_state'] = updated_role
result['msg'] = "No changes required to role {name}.".format(name=name)
module.exit_json(**result)
# doing an update
# update the existing role
result['changed'] = True
if module._diff:
result['diff'] = dict(before=before_role, after=desired_role)
result['diff'] = dict(before=before_role, after=updated_role)
if module.check_mode:
module.exit_json(**result)
# do the update
if clientid is None:
kc.update_realm_role(desired_role, realm)
kc.update_realm_role(updated_role, realm)
after_role = kc.get_realm_role(name, realm)
else:
kc.update_client_role(desired_role, clientid, realm)
kc.update_client_role(updated_role, clientid, realm)
after_role = kc.get_client_role(name, clientid, realm)
result['end_state'] = after_role
@@ -341,8 +336,7 @@ def main():
result['msg'] = "Role {name} has been updated".format(name=name)
module.exit_json(**result)
else:
# Process a deletion (because state was not 'present')
elif state == 'absent':
result['changed'] = True
if module._diff:
@@ -351,15 +345,16 @@ def main():
if module.check_mode:
module.exit_json(**result)
# delete it
# delete for real
if clientid is None:
kc.delete_realm_role(name, realm)
else:
kc.delete_client_role(name, clientid, realm)
result['end_state'] = {}
result['end_state'] = dict()
result['msg'] = "Role {name} has been deleted".format(name=name)
module.exit_json(**result)
module.exit_json(**result)

View File

@@ -182,7 +182,7 @@ options:
description:
- For one level, the search applies only for users in the DNs specified by User DNs.
For subtree, the search applies to the whole subtree. See LDAP documentation for
more details.
more details
default: '1'
type: str
choices:
@@ -551,7 +551,7 @@ msg:
sample: "No changes required to user federation 164bb483-c613-482e-80fe-7f1431308799."
proposed:
description: Representation of proposed user federation.
description: Representation of proposed changes to user federation.
returned: always
type: dict
sample: {
@@ -648,7 +648,7 @@ existing:
end_state:
description: Representation of user federation after module execution.
returned: on success
returned: always
type: dict
sample: {
"config": {
@@ -668,6 +668,7 @@ end_state:
"providerId": "kerberos",
"providerType": "org.keycloak.storage.UserStorageProvider"
}
'''
from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import KeycloakAPI, camel, \
@@ -807,12 +808,12 @@ def main():
mapper['config'] = dict((k, [str(v).lower() if not isinstance(v, str) else v])
for k, v in mapper['config'].items() if mapper['config'][k] is not None)
# Filter and map the parameters names that apply
# convert module parameters to client representation parameters (if they belong in there)
comp_params = [x for x in module.params
if x not in list(keycloak_argument_spec().keys()) + ['state', 'realm', 'mappers'] and
module.params.get(x) is not None]
# See if it already exists in Keycloak
# does the user federation already exist?
if cid is None:
found = kc.get_components(urlencode(dict(type='org.keycloak.storage.UserStorageProvider', parent=realm, name=name)), realm)
if len(found) > 1:
@@ -824,14 +825,14 @@ def main():
before_comp = kc.get_component(cid, realm)
if before_comp is None:
before_comp = {}
before_comp = dict()
# if user federation exists, get associated mappers
if cid is not None:
before_comp['mappers'] = sorted(kc.get_components(urlencode(dict(parent=cid)), realm), key=lambda x: x.get('name'))
# Build a proposed changeset from parameters given to this module
changeset = {}
# build a changeset
changeset = dict()
for param in comp_params:
new_param_value = module.params.get(param)
@@ -850,11 +851,11 @@ def main():
if change.get('id') is None and change.get('name') is None:
module.fail_json(msg='Either `name` or `id` has to be specified on each mapper.')
if cid is None:
old_mapper = {}
old_mapper = dict()
elif change.get('id') is not None:
old_mapper = kc.get_component(change['id'], realm)
if old_mapper is None:
old_mapper = {}
old_mapper = dict()
else:
found = kc.get_components(urlencode(dict(parent=cid, name=change['name'])), realm)
if len(found) > 1:
@@ -862,7 +863,7 @@ def main():
if len(found) == 1:
old_mapper = found[0]
else:
old_mapper = {}
old_mapper = dict()
new_mapper = old_mapper.copy()
new_mapper.update(change)
if new_mapper != old_mapper:
@@ -870,37 +871,37 @@ def main():
changeset['mappers'] = list()
changeset['mappers'].append(new_mapper)
# Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis)
desired_comp = before_comp.copy()
desired_comp.update(changeset)
# prepare the new representation
updated_comp = before_comp.copy()
updated_comp.update(changeset)
result['proposed'] = sanitize(changeset)
result['existing'] = sanitize(before_comp)
# Cater for when it doesn't exist (an empty dict)
if not before_comp:
# if before_comp is none, the user federation doesn't exist.
if before_comp == dict():
if state == 'absent':
# Do nothing and exit
# nothing to do.
if module._diff:
result['diff'] = dict(before='', after='')
result['changed'] = False
result['end_state'] = {}
result['end_state'] = dict()
result['msg'] = 'User federation does not exist; doing nothing.'
module.exit_json(**result)
# Process a creation
# for 'present', create a new user federation.
result['changed'] = True
if module._diff:
result['diff'] = dict(before='', after=sanitize(desired_comp))
result['diff'] = dict(before='', after=sanitize(updated_comp))
if module.check_mode:
module.exit_json(**result)
# create it
desired_comp = desired_comp.copy()
updated_mappers = desired_comp.pop('mappers', [])
after_comp = kc.create_component(desired_comp, realm)
# do it for real!
updated_comp = updated_comp.copy()
updated_mappers = updated_comp.pop('mappers', [])
after_comp = kc.create_component(updated_comp, realm)
for mapper in updated_mappers:
if mapper.get('id') is not None:
@@ -918,28 +919,26 @@ def main():
else:
if state == 'present':
# Process an update
# no changes
if desired_comp == before_comp:
if updated_comp == before_comp:
result['changed'] = False
result['end_state'] = sanitize(desired_comp)
result['end_state'] = sanitize(updated_comp)
result['msg'] = "No changes required to user federation {id}.".format(id=cid)
module.exit_json(**result)
# doing an update
# update the existing role
result['changed'] = True
if module._diff:
result['diff'] = dict(before=sanitize(before_comp), after=sanitize(desired_comp))
result['diff'] = dict(before=sanitize(before_comp), after=sanitize(updated_comp))
if module.check_mode:
module.exit_json(**result)
# do the update
desired_comp = desired_comp.copy()
updated_mappers = desired_comp.pop('mappers', [])
kc.update_component(desired_comp, realm)
updated_comp = updated_comp.copy()
updated_mappers = updated_comp.pop('mappers', [])
kc.update_component(updated_comp, realm)
after_comp = kc.get_component(cid, realm)
for mapper in updated_mappers:
@@ -947,7 +946,7 @@ def main():
kc.update_component(mapper, realm)
else:
if mapper.get('parentId') is None:
mapper['parentId'] = desired_comp['id']
mapper['parentId'] = updated_comp['id']
mapper = kc.create_component(mapper, realm)
after_comp['mappers'] = updated_mappers
@@ -957,7 +956,6 @@ def main():
module.exit_json(**result)
elif state == 'absent':
# Process a deletion
result['changed'] = True
if module._diff:
@@ -966,12 +964,13 @@ def main():
if module.check_mode:
module.exit_json(**result)
# delete it
# delete for real
kc.delete_component(cid, realm)
result['end_state'] = {}
result['end_state'] = dict()
result['msg'] = "User federation {id} has been deleted".format(id=cid)
module.exit_json(**result)
module.exit_json(**result)

View File

@@ -1 +0,0 @@
./database/mssql/mssql_script.py

View File

@@ -82,8 +82,6 @@ options:
version_added: 3.5.0
requirements:
- "dnsimple >= 1.0.0"
notes:
- "Support for C(dnsimple < 2) is deprecated and will be removed in community.general 5.0.0."
author: "Alex Coomans (@drcapulet)"
'''
@@ -397,11 +395,6 @@ def main():
if DNSIMPLE_MAJOR_VERSION > 1:
ds = DNSimpleV2(account_email, account_api_token, sandbox, module)
else:
module.deprecate(
'Support for python-dnsimple < 2 is deprecated. '
'Update python-dnsimple to version >= 2.0.0',
version='5.0.0', collection_name='community.general'
)
ds = DNSimpleV1(account_email, account_api_token, sandbox, module)
# Let's figure out what operation we want to do
# No domain, return a list

View File

@@ -0,0 +1,179 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_a_record
author: "Blair Rampling (@brampling)"
short_description: Configure Infoblox NIOS A records
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_a_record
removed_in: 5.0.0
description:
- Adds and/or removes instances of A record objects from
Infoblox NIOS servers. This module manages NIOS C(record:a) objects
using the Infoblox WAPI interface over REST.
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
name:
description:
- Specifies the fully qualified hostname to add or remove from
the system
required: true
type: str
view:
description:
- Sets the DNS view to associate this A record with. The DNS
view must already be configured on the system
default: default
aliases:
- dns_view
type: str
ipv4addr:
description:
- Configures the IPv4 address for this A record. Users can dynamically
allocate ipv4 address to A record by passing dictionary containing,
I(nios_next_ip) and I(CIDR network range). See example
aliases:
- ipv4
type: str
ttl:
description:
- Configures the TTL to be associated with this A record
type: int
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Configure an A record
community.general.nios_a_record:
name: a.ansible.com
ipv4: 192.168.10.1
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Add a comment to an existing A record
community.general.nios_a_record:
name: a.ansible.com
ipv4: 192.168.10.1
comment: this is a test comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove an A record from the system
community.general.nios_a_record:
name: a.ansible.com
ipv4: 192.168.10.1
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Update an A record name
community.general.nios_a_record:
name: {new_name: a_new.ansible.com, old_name: a.ansible.com}
ipv4: 192.168.10.1
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Dynamically add a record to next available ip
community.general.nios_a_record:
name: a.ansible.com
ipv4: {nios_next_ip: 192.168.10.0/24}
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_A_RECORD
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def main():
''' Main entry point for module execution
'''
ib_spec = dict(
name=dict(required=True, ib_req=True),
view=dict(default='default', aliases=['dns_view'], ib_req=True),
ipv4addr=dict(aliases=['ipv4'], ib_req=True),
ttl=dict(type='int'),
extattrs=dict(type='dict'),
comment=dict(),
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
wapi = WapiModule(module)
result = wapi.run(NIOS_A_RECORD, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,166 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_aaaa_record
author: "Blair Rampling (@brampling)"
short_description: Configure Infoblox NIOS AAAA records
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_aaaa_record
removed_in: 5.0.0
description:
- Adds and/or removes instances of AAAA record objects from
Infoblox NIOS servers. This module manages NIOS C(record:aaaa) objects
using the Infoblox WAPI interface over REST.
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
name:
description:
- Specifies the fully qualified hostname to add or remove from
the system
required: true
type: str
view:
description:
- Sets the DNS view to associate this AAAA record with. The DNS
view must already be configured on the system
default: default
aliases:
- dns_view
type: str
ipv6addr:
description:
- Configures the IPv6 address for this AAAA record.
aliases:
- ipv6
type: str
ttl:
description:
- Configures the TTL to be associated with this AAAA record
type: int
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Configure an AAAA record
community.general.nios_aaaa_record:
name: aaaa.ansible.com
ipv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Add a comment to an existing AAAA record
community.general.nios_aaaa_record:
name: aaaa.ansible.com
ipv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
comment: this is a test comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove an AAAA record from the system
community.general.nios_aaaa_record:
name: aaaa.ansible.com
ipv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Update an AAAA record name
community.general.nios_aaaa_record:
name: {new_name: aaaa_new.ansible.com, old_name: aaaa.ansible.com}
ipv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_AAAA_RECORD
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def main():
''' Main entry point for module execution
'''
ib_spec = dict(
name=dict(required=True, ib_req=True),
view=dict(default='default', aliases=['dns_view'], ib_req=True),
ipv6addr=dict(aliases=['ipv6'], ib_req=True),
ttl=dict(type='int'),
extattrs=dict(type='dict'),
comment=dict(),
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
wapi = WapiModule(module)
result = wapi.run(NIOS_AAAA_RECORD, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,155 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_cname_record
author: "Blair Rampling (@brampling)"
short_description: Configure Infoblox NIOS CNAME records
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_cname_record
removed_in: 5.0.0
description:
- Adds and/or removes instances of CNAME record objects from
Infoblox NIOS servers. This module manages NIOS C(record:cname) objects
using the Infoblox WAPI interface over REST.
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
name:
description:
- Specifies the fully qualified hostname to add or remove from
the system
required: true
type: str
view:
description:
- Sets the DNS view to associate this CNAME record with. The DNS
view must already be configured on the system
default: default
aliases:
- dns_view
type: str
canonical:
description:
- Configures the canonical name for this CNAME record.
aliases:
- cname
type: str
ttl:
description:
- Configures the TTL to be associated with this CNAME record
type: int
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Configure a CNAME record
community.general.nios_cname_record:
name: cname.ansible.com
canonical: realhost.ansible.com
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Add a comment to an existing CNAME record
community.general.nios_cname_record:
name: cname.ansible.com
canonical: realhost.ansible.com
comment: this is a test comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove a CNAME record from the system
community.general.nios_cname_record:
name: cname.ansible.com
canonical: realhost.ansible.com
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_CNAME_RECORD
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def main():
''' Main entry point for module execution
'''
ib_spec = dict(
name=dict(required=True, ib_req=True),
view=dict(default='default', aliases=['dns_view'], ib_req=True),
canonical=dict(aliases=['cname'], ib_req=True),
ttl=dict(type='int'),
extattrs=dict(type='dict'),
comment=dict(),
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
wapi = WapiModule(module)
result = wapi.run(NIOS_CNAME_RECORD, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,150 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_dns_view
author: "Peter Sprygada (@privateip)"
short_description: Configure Infoblox NIOS DNS views
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_dns_view
removed_in: 5.0.0
description:
- Adds and/or removes instances of DNS view objects from
Infoblox NIOS servers. This module manages NIOS C(view) objects
using the Infoblox WAPI interface over REST.
- Updates instances of DNS view object from Infoblox NIOS servers.
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
name:
description:
- Specifies the fully qualified hostname to add or remove from
the system. User can also update the hostname as it is possible
to pass a dict containing I(new_name), I(old_name). See examples.
required: true
aliases:
- view
type: str
network_view:
description:
- Specifies the name of the network view to assign the configured
DNS view to. The network view must already be configured on the
target system.
default: default
type: str
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
required: false
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
required: false
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
required: false
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Configure a new dns view instance
community.general.nios_dns_view:
name: ansible-dns
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Update the comment for dns view
community.general.nios_dns_view:
name: ansible-dns
comment: this is an example comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove the dns view instance
community.general.nios_dns_view:
name: ansible-dns
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Update the dns view instance
community.general.nios_dns_view:
name: {new_name: ansible-dns-new, old_name: ansible-dns}
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_DNS_VIEW
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def main():
''' Main entry point for module execution
'''
ib_spec = dict(
name=dict(required=True, aliases=['view'], ib_req=True),
network_view=dict(default='default', ib_req=True),
extattrs=dict(type='dict'),
comment=dict()
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
wapi = WapiModule(module)
result = wapi.run(NIOS_DNS_VIEW, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,301 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_fixed_address
author: "Sumit Jaiswal (@sjaiswal)"
short_description: Configure Infoblox NIOS DHCP Fixed Address
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_fixed_address
removed_in: 5.0.0
description:
- A fixed address is a specific IP address that a DHCP server
always assigns when a lease request comes from a particular
MAC address of the client.
- Supports both IPV4 and IPV6 internet protocols
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
name:
description:
- Specifies the hostname with which fixed DHCP ip-address is stored
for respective mac.
required: true
type: str
ipaddr:
description:
- IPV4/V6 address of the fixed address.
required: true
type: str
mac:
description:
- The MAC address of the interface.
required: true
type: str
network:
description:
- Specifies the network range in which ipaddr exists.
required: true
type: str
network_view:
description:
- Configures the name of the network view to associate with this
configured instance.
required: false
default: default
type: str
options:
description:
- Configures the set of DHCP options to be included as part of
the configured network instance. This argument accepts a list
of values (see suboptions). When configuring suboptions at
least one of C(name) or C(num) must be specified.
type: list
elements: dict
suboptions:
name:
description:
- The name of the DHCP option to configure
type: str
num:
description:
- The number of the DHCP option to configure
type: int
value:
description:
- The value of the DHCP option specified by C(name)
required: true
type: str
use_option:
description:
- Only applies to a subset of options (see NIOS API documentation)
type: bool
default: 'yes'
vendor_class:
description:
- The name of the space this DHCP option is associated to
default: DHCP
type: str
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Configure ipv4 dhcp fixed address
community.general.nios_fixed_address:
name: ipv4_fixed
ipaddr: 192.168.10.1
mac: 08:6d:41:e8:fd:e8
network: 192.168.10.0/24
network_view: default
comment: this is a test comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Configure a ipv6 dhcp fixed address
community.general.nios_fixed_address:
name: ipv6_fixed
ipaddr: fe80::1/10
mac: 08:6d:41:e8:fd:e8
network: fe80::/64
network_view: default
comment: this is a test comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Set dhcp options for a ipv4 fixed address
community.general.nios_fixed_address:
name: ipv4_fixed
ipaddr: 192.168.10.1
mac: 08:6d:41:e8:fd:e8
network: 192.168.10.0/24
network_view: default
comment: this is a test comment
options:
- name: domain-name
value: ansible.com
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove a ipv4 dhcp fixed address
community.general.nios_fixed_address:
name: ipv4_fixed
ipaddr: 192.168.10.1
mac: 08:6d:41:e8:fd:e8
network: 192.168.10.0/24
network_view: default
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
import socket
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six import iteritems
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_IPV4_FIXED_ADDRESS, NIOS_IPV6_FIXED_ADDRESS
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def validate_ip_address(address):
try:
socket.inet_aton(address)
except socket.error:
return False
return address.count(".") == 3
def validate_ip_v6_address(address):
try:
socket.inet_pton(socket.AF_INET6, address)
except socket.error:
return False
return True
def options(module):
''' Transforms the module argument into a valid WAPI struct
This function will transform the options argument into a structure that
is a valid WAPI structure in the format of:
{
name: <value>,
num: <value>,
value: <value>,
use_option: <value>,
vendor_class: <value>
}
It will remove any options that are set to None since WAPI will error on
that condition. The use_option field only applies
to special options that are displayed separately from other options and
have a use flag. This function removes the use_option flag from all
other options. It will also verify that either `name` or `num` is
set in the structure but does not validate the values are equal.
The remainder of the value validation is performed by WAPI
'''
special_options = ['routers', 'router-templates', 'domain-name-servers',
'domain-name', 'broadcast-address', 'broadcast-address-offset',
'dhcp-lease-time', 'dhcp6.name-servers']
options = list()
for item in module.params['options']:
opt = dict([(k, v) for k, v in iteritems(item) if v is not None])
if 'name' not in opt and 'num' not in opt:
module.fail_json(msg='one of `name` or `num` is required for option value')
if opt['name'] not in special_options:
del opt['use_option']
options.append(opt)
return options
def validate_ip_addr_type(ip, arg_spec, module):
'''This function will check if the argument ip is type v4/v6 and return appropriate infoblox network type
'''
check_ip = ip.split('/')
if validate_ip_address(check_ip[0]) and 'ipaddr' in arg_spec:
arg_spec['ipv4addr'] = arg_spec.pop('ipaddr')
module.params['ipv4addr'] = module.params.pop('ipaddr')
return NIOS_IPV4_FIXED_ADDRESS, arg_spec, module
elif validate_ip_v6_address(check_ip[0]) and 'ipaddr' in arg_spec:
arg_spec['ipv6addr'] = arg_spec.pop('ipaddr')
module.params['ipv6addr'] = module.params.pop('ipaddr')
return NIOS_IPV6_FIXED_ADDRESS, arg_spec, module
def main():
''' Main entry point for module execution
'''
option_spec = dict(
# one of name or num is required; enforced by the function options()
name=dict(),
num=dict(type='int'),
value=dict(required=True),
use_option=dict(type='bool', default=True),
vendor_class=dict(default='DHCP')
)
ib_spec = dict(
name=dict(required=True),
ipaddr=dict(required=True, ib_req=True),
mac=dict(required=True, ib_req=True),
network=dict(required=True),
network_view=dict(default='default'),
options=dict(type='list', elements='dict', options=option_spec, transform=options),
extattrs=dict(type='dict'),
comment=dict()
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
# to get the argument ipaddr
obj_filter = dict([(k, module.params[k]) for k, v in iteritems(ib_spec) if v.get('ib_req')])
# to modify argument based on ipaddr type i.e. IPV4/IPV6
fixed_address_ip_type, ib_spec, module = validate_ip_addr_type(obj_filter['ipaddr'], ib_spec, module)
wapi = WapiModule(module)
result = wapi.run(fixed_address_ip_type, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,361 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_host_record
author: "Peter Sprygada (@privateip)"
short_description: Configure Infoblox NIOS host records
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_host_record
removed_in: 5.0.0
description:
- Adds and/or removes instances of host record objects from
Infoblox NIOS servers. This module manages NIOS C(record:host) objects
using the Infoblox WAPI interface over REST.
- Updates instances of host record object from Infoblox NIOS servers.
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
name:
description:
- Specifies the fully qualified hostname to add or remove from
the system. User can also update the hostname as it is possible
to pass a dict containing I(new_name), I(old_name). See examples.
required: true
type: str
view:
description:
- Sets the DNS view to associate this host record with. The DNS
view must already be configured on the system
default: default
aliases:
- dns_view
type: str
configure_for_dns:
description:
- Sets the DNS to particular parent. If user needs to bypass DNS
user can make the value to false.
type: bool
required: false
default: true
aliases:
- dns
ipv4addrs:
description:
- Configures the IPv4 addresses for this host record. This argument
accepts a list of values (see suboptions)
aliases:
- ipv4
type: list
elements: dict
suboptions:
ipv4addr:
description:
- Configures the IPv4 address for the host record. Users can dynamically
allocate ipv4 address to host record by passing dictionary containing,
I(nios_next_ip) and I(CIDR network range). If user wants to add or
remove the ipv4 address from existing record, I(add/remove)
params need to be used. See examples
required: true
aliases:
- address
type: str
configure_for_dhcp:
description:
- Configure the host_record over DHCP instead of DNS, if user
changes it to true, user need to mention MAC address to configure
required: false
aliases:
- dhcp
type: bool
mac:
description:
- Configures the hardware MAC address for the host record. If user makes
DHCP to true, user need to mention MAC address.
required: false
type: str
add:
description:
- If user wants to add the ipv4 address to an existing host record.
Note that with I(add) user will have to keep the I(state) as I(present),
as new IP address is allocated to existing host record. See examples.
type: bool
required: false
version_added: '0.2.0'
remove:
description:
- If user wants to remove the ipv4 address from an existing host record.
Note that with I(remove) user will have to change the I(state) to I(absent),
as IP address is de-allocated from an existing host record. See examples.
type: bool
required: false
version_added: '0.2.0'
ipv6addrs:
description:
- Configures the IPv6 addresses for the host record. This argument
accepts a list of values (see options)
aliases:
- ipv6
type: list
elements: dict
suboptions:
ipv6addr:
description:
- Configures the IPv6 address for the host record
required: true
aliases:
- address
type: str
configure_for_dhcp:
description:
- Configure the host_record over DHCP instead of DNS, if user
changes it to true, user need to mention MAC address to configure
required: false
type: bool
mac:
description:
- Configures the hardware MAC address for the host record. If user makes
DHCP to true, user need to mention MAC address.
required: false
type: str
aliases:
description:
- Configures an optional list of additional aliases to add to the host
record. These are equivalent to CNAMEs but held within a host
record. Must be in list format.
type: list
elements: str
ttl:
description:
- Configures the TTL to be associated with this host record
type: int
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Configure an ipv4 host record
community.general.nios_host_record:
name: host.ansible.com
ipv4:
- address: 192.168.10.1
aliases:
- cname.ansible.com
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Add a comment to an existing host record
community.general.nios_host_record:
name: host.ansible.com
ipv4:
- address: 192.168.10.1
comment: this is a test comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove a host record from the system
community.general.nios_host_record:
name: host.ansible.com
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Update an ipv4 host record
community.general.nios_host_record:
name: {new_name: host-new.ansible.com, old_name: host.ansible.com}
ipv4:
- address: 192.168.10.1
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Create an ipv4 host record bypassing DNS
community.general.nios_host_record:
name: new_host
ipv4:
- address: 192.168.10.1
dns: false
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Create an ipv4 host record over DHCP
community.general.nios_host_record:
name: host.ansible.com
ipv4:
- address: 192.168.10.1
dhcp: true
mac: 00-80-C8-E3-4C-BD
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Dynamically add host record to next available ip
community.general.nios_host_record:
name: host.ansible.com
ipv4:
- address: {nios_next_ip: 192.168.10.0/24}
comment: this is a test comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Add ip to host record
community.general.nios_host_record:
name: host.ansible.com
ipv4:
- address: 192.168.10.2
add: true
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove ip to host record
community.general.nios_host_record:
name: host.ansible.com
ipv4:
- address: 192.168.10.1
remove: true
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six import iteritems
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_HOST_RECORD
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def ipaddr(module, key, filtered_keys=None):
''' Transforms the input value into a struct supported by WAPI
This function will transform the input from the playbook into a struct
that is valid for WAPI in the form of:
{
ipv4addr: <value>,
mac: <value>
}
This function does not validate the values are properly formatted or in
the acceptable range, that is left to WAPI.
'''
filtered_keys = filtered_keys or list()
objects = list()
for item in module.params[key]:
objects.append(dict([(k, v) for k, v in iteritems(item) if v is not None and k not in filtered_keys]))
return objects
def ipv4addrs(module):
return ipaddr(module, 'ipv4addrs', filtered_keys=['address', 'dhcp'])
def ipv6addrs(module):
return ipaddr(module, 'ipv6addrs', filtered_keys=['address', 'dhcp'])
def main():
''' Main entry point for module execution
'''
ipv4addr_spec = dict(
ipv4addr=dict(required=True, aliases=['address']),
configure_for_dhcp=dict(type='bool', required=False, aliases=['dhcp']),
mac=dict(required=False),
add=dict(type='bool', required=False),
remove=dict(type='bool', required=False)
)
ipv6addr_spec = dict(
ipv6addr=dict(required=True, aliases=['address']),
configure_for_dhcp=dict(type='bool', required=False),
mac=dict(required=False)
)
ib_spec = dict(
name=dict(required=True, ib_req=True),
view=dict(default='default', aliases=['dns_view'], ib_req=True),
ipv4addrs=dict(type='list', aliases=['ipv4'], elements='dict', options=ipv4addr_spec, transform=ipv4addrs),
ipv6addrs=dict(type='list', aliases=['ipv6'], elements='dict', options=ipv6addr_spec, transform=ipv6addrs),
configure_for_dns=dict(type='bool', default=True, required=False, aliases=['dns'], ib_req=True),
aliases=dict(type='list', elements='str'),
ttl=dict(type='int'),
extattrs=dict(type='dict'),
comment=dict(),
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
wapi = WapiModule(module)
result = wapi.run(NIOS_HOST_RECORD, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,574 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_member
author: "Krishna Vasudevan (@krisvasudevan)"
short_description: Configure Infoblox NIOS members
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_member
removed_in: 5.0.0
description:
- Adds and/or removes Infoblox NIOS servers. This module manages NIOS C(member) objects using the Infoblox WAPI interface over REST.
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
host_name:
description:
- Specifies the host name of the member to either add or remove from
the NIOS instance.
required: true
aliases:
- name
type: str
vip_setting:
description:
- Configures the network settings for the grid member.
type: list
elements: dict
suboptions:
address:
description:
- The IPv4 Address of the Grid Member
type: str
subnet_mask:
description:
- The subnet mask for the Grid Member
type: str
gateway:
description:
- The default gateway for the Grid Member
type: str
ipv6_setting:
description:
- Configures the IPv6 settings for the grid member.
type: list
elements: dict
suboptions:
virtual_ip:
description:
- The IPv6 Address of the Grid Member
type: str
cidr_prefix:
description:
- The IPv6 CIDR prefix for the Grid Member
type: int
gateway:
description:
- The gateway address for the Grid Member
type: str
config_addr_type:
description:
- Address configuration type (IPV4/IPV6/BOTH)
default: IPV4
type: str
comment:
description:
- A descriptive comment of the Grid member.
type: str
extattrs:
description:
- Extensible attributes associated with the object.
type: dict
enable_ha:
description:
- If set to True, the member has two physical nodes (HA pair).
type: bool
default: false
router_id:
description:
- Virtual router identifier. Provide this ID if "ha_enabled" is set to "true". This is a unique VRID number (from 1 to 255) for the local subnet.
type: int
lan2_enabled:
description:
- When set to "true", the LAN2 port is enabled as an independent port or as a port for failover purposes.
type: bool
default: false
lan2_port_setting:
description:
- Settings for the Grid member LAN2 port if 'lan2_enabled' is set to "true".
type: list
elements: dict
suboptions:
enabled:
description:
- If set to True, then it has its own IP settings.
type: bool
network_setting:
description:
- If the 'enable' field is set to True, this defines IPv4 network settings for LAN2.
type: list
elements: dict
suboptions:
address:
description:
- The IPv4 Address of LAN2
type: str
subnet_mask:
description:
- The subnet mask of LAN2
type: str
gateway:
description:
- The default gateway of LAN2
type: str
v6_network_setting:
description:
- If the 'enable' field is set to True, this defines IPv6 network settings for LAN2.
type: list
elements: dict
suboptions:
virtual_ip:
description:
- The IPv6 Address of LAN2
type: str
cidr_prefix:
description:
- The IPv6 CIDR prefix of LAN2
type: int
gateway:
description:
- The gateway address of LAN2
type: str
platform:
description:
- Configures the Hardware Platform.
default: INFOBLOX
type: str
node_info:
description:
- Configures the node information list with detailed status report on the operations of the Grid Member.
type: list
elements: dict
suboptions:
lan2_physical_setting:
description:
- Physical port settings for the LAN2 interface.
type: list
elements: dict
suboptions:
auto_port_setting_enabled:
description:
- Enable or disalbe the auto port setting.
type: bool
duplex:
description:
- The port duplex; if speed is 1000, duplex must be FULL.
type: str
speed:
description:
- The port speed; if speed is 1000, duplex is FULL.
type: str
lan_ha_port_setting:
description:
- LAN/HA port settings for the node.
type: list
elements: dict
suboptions:
ha_ip_address:
description:
- HA IP address.
type: str
ha_port_setting:
description:
- Physical port settings for the HA interface.
type: list
elements: dict
suboptions:
auto_port_setting_enabled:
description:
- Enable or disalbe the auto port setting.
type: bool
duplex:
description:
- The port duplex; if speed is 1000, duplex must be FULL.
type: str
speed:
description:
- The port speed; if speed is 1000, duplex is FULL.
type: str
lan_port_setting:
description:
- Physical port settings for the LAN interface.
type: list
elements: dict
suboptions:
auto_port_setting_enabled:
description:
- Enable or disalbe the auto port setting.
type: bool
duplex:
description:
- The port duplex; if speed is 1000, duplex must be FULL.
type: str
speed:
description:
- The port speed; if speed is 1000, duplex is FULL.
type: str
mgmt_ipv6addr:
description:
- Public IPv6 address for the LAN1 interface.
type: str
mgmt_lan:
description:
- Public IPv4 address for the LAN1 interface.
type: str
mgmt_network_setting:
description:
- Network settings for the MGMT port of the node.
type: list
elements: dict
suboptions:
address:
description:
- The IPv4 Address of MGMT
type: str
subnet_mask:
description:
- The subnet mask of MGMT
type: str
gateway:
description:
- The default gateway of MGMT
type: str
v6_mgmt_network_setting:
description:
- The network settings for the IPv6 MGMT port of the node.
type: list
elements: dict
suboptions:
virtual_ip:
description:
- The IPv6 Address of MGMT
type: str
cidr_prefix:
description:
- The IPv6 CIDR prefix of MGMT
type: int
gateway:
description:
- The gateway address of MGMT
type: str
mgmt_port_setting:
description:
- Settings for the member MGMT port.
type: list
elements: dict
suboptions:
enabled:
description:
- Determines if MGMT port settings should be enabled.
type: bool
security_access_enabled:
description:
- Determines if security access on the MGMT port is enabled or not.
type: bool
vpn_enabled:
description:
- Determines if VPN on the MGMT port is enabled or not.
type: bool
upgrade_group:
description:
- The name of the upgrade group to which this Grid member belongs.
default: Default
type: str
use_syslog_proxy_setting:
description:
- Use flag for external_syslog_server_enable , syslog_servers, syslog_proxy_setting, syslog_size
type: bool
external_syslog_server_enable:
description:
- Determines if external syslog servers should be enabled
type: bool
syslog_servers:
description:
- The list of external syslog servers.
type: list
elements: dict
suboptions:
address:
description:
- The server address.
type: str
category_list:
description:
- The list of all syslog logging categories.
type: list
elements: str
connection_type:
description:
- The connection type for communicating with this server.(STCP/TCP?UDP)
default: UDP
type: str
local_interface:
description:
- The local interface through which the appliance sends syslog messages to the syslog server.(ANY/LAN/MGMT)
default: ANY
type: str
message_node_id:
description:
- Identify the node in the syslog message. (HOSTNAME/IP_HOSTNAME/LAN/MGMT)
default: LAN
type: str
message_source:
description:
- The source of syslog messages to be sent to the external syslog server.
default: ANY
type: str
only_category_list:
description:
- The list of selected syslog logging categories. The appliance forwards syslog messages that belong to the selected categories.
type: bool
port:
description:
- The port this server listens on.
default: 514
type: int
severity:
description:
- The severity filter. The appliance sends log messages of the specified severity and above to the external syslog server.
default: DEBUG
type: str
pre_provisioning:
description:
- Pre-provisioning information.
type: list
elements: dict
suboptions:
hardware_info:
description:
- An array of structures that describe the hardware being pre-provisioned.
type: list
elements: dict
suboptions:
hwmodel:
description:
- Hardware model
type: str
hwtype:
description:
- Hardware type.
type: str
licenses:
description:
- An array of license types.
type: list
elements: str
create_token:
description:
- Flag for initiating a create token request for pre-provisioned members.
type: bool
default: False
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Add a member to the grid with IPv4 address
community.general.nios_member:
host_name: member01.localdomain
vip_setting:
- address: 192.168.1.100
subnet_mask: 255.255.255.0
gateway: 192.168.1.1
config_addr_type: IPV4
platform: VNIOS
comment: "Created by Ansible"
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Add a HA member to the grid
community.general.nios_member:
host_name: memberha.localdomain
vip_setting:
- address: 192.168.1.100
subnet_mask: 255.255.255.0
gateway: 192.168.1.1
config_addr_type: IPV4
platform: VNIOS
enable_ha: true
router_id: 150
node_info:
- lan_ha_port_setting:
- ha_ip_address: 192.168.1.70
mgmt_lan: 192.168.1.80
- lan_ha_port_setting:
- ha_ip_address: 192.168.1.71
mgmt_lan: 192.168.1.81
comment: "Created by Ansible"
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Update the member with pre-provisioning details specified
community.general.nios_member:
name: member01.localdomain
pre_provisioning:
- hardware_info:
- hwmodel: IB-VM-820
hwtype: IB-VNIOS
licenses:
- dns
- dhcp
- enterprise
- vnios
comment: "Updated by Ansible"
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove the member
community.general.nios_member:
name: member01.localdomain
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_MEMBER
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def main():
''' Main entry point for module execution
'''
ipv4_spec = dict(
address=dict(),
subnet_mask=dict(),
gateway=dict(),
)
ipv6_spec = dict(
virtual_ip=dict(),
cidr_prefix=dict(type='int'),
gateway=dict(),
)
port_spec = dict(
auto_port_setting_enabled=dict(type='bool'),
duplex=dict(),
speed=dict(),
)
lan2_port_spec = dict(
enabled=dict(type='bool'),
network_setting=dict(type='list', elements='dict', options=ipv4_spec),
v6_network_setting=dict(type='list', elements='dict', options=ipv6_spec),
)
ha_port_spec = dict(
ha_ip_address=dict(),
ha_port_setting=dict(type='list', elements='dict', options=port_spec),
lan_port_setting=dict(type='list', elements='dict', options=port_spec),
mgmt_lan=dict(),
mgmt_ipv6addr=dict(),
)
node_spec = dict(
lan2_physical_setting=dict(type='list', elements='dict', options=port_spec),
lan_ha_port_setting=dict(type='list', elements='dict', options=ha_port_spec),
mgmt_network_setting=dict(type='list', elements='dict', options=ipv4_spec),
v6_mgmt_network_setting=dict(type='list', elements='dict', options=ipv6_spec),
)
mgmt_port_spec = dict(
enabled=dict(type='bool'),
security_access_enabled=dict(type='bool'),
vpn_enabled=dict(type='bool'),
)
syslog_spec = dict(
address=dict(),
category_list=dict(type='list', elements='str'),
connection_type=dict(default='UDP'),
local_interface=dict(default='ANY'),
message_node_id=dict(default='LAN'),
message_source=dict(default='ANY'),
only_category_list=dict(type='bool'),
port=dict(type='int', default=514),
severity=dict(default='DEBUG'),
)
hw_spec = dict(
hwmodel=dict(),
hwtype=dict(),
)
pre_prov_spec = dict(
hardware_info=dict(type='list', elements='dict', options=hw_spec),
licenses=dict(type='list', elements='str'),
)
ib_spec = dict(
host_name=dict(required=True, aliases=['name'], ib_req=True),
vip_setting=dict(type='list', elements='dict', options=ipv4_spec),
ipv6_setting=dict(type='list', elements='dict', options=ipv6_spec),
config_addr_type=dict(default='IPV4'),
comment=dict(),
enable_ha=dict(type='bool', default=False),
router_id=dict(type='int'),
lan2_enabled=dict(type='bool', default=False),
lan2_port_setting=dict(type='list', elements='dict', options=lan2_port_spec),
platform=dict(default='INFOBLOX'),
node_info=dict(type='list', elements='dict', options=node_spec),
mgmt_port_setting=dict(type='list', elements='dict', options=mgmt_port_spec),
upgrade_group=dict(default='Default'),
use_syslog_proxy_setting=dict(type='bool'),
external_syslog_server_enable=dict(type='bool'),
syslog_servers=dict(type='list', elements='dict', options=syslog_spec),
pre_provisioning=dict(type='list', elements='dict', options=pre_prov_spec),
extattrs=dict(type='dict'),
create_token=dict(type='bool', default=False),
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
wapi = WapiModule(module)
result = wapi.run(NIOS_MEMBER, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,163 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_mx_record
author: "Blair Rampling (@brampling)"
short_description: Configure Infoblox NIOS MX records
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_mx_record
removed_in: 5.0.0
description:
- Adds and/or removes instances of MX record objects from
Infoblox NIOS servers. This module manages NIOS C(record:mx) objects
using the Infoblox WAPI interface over REST.
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
name:
description:
- Specifies the fully qualified hostname to add or remove from
the system
required: true
type: str
view:
description:
- Sets the DNS view to associate this a record with. The DNS
view must already be configured on the system
default: default
aliases:
- dns_view
type: str
mail_exchanger:
description:
- Configures the mail exchanger FQDN for this MX record.
aliases:
- mx
type: str
preference:
description:
- Configures the preference (0-65535) for this MX record.
type: int
ttl:
description:
- Configures the TTL to be associated with this host record
type: int
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Configure an MX record
community.general.nios_mx_record:
name: ansible.com
mx: mailhost.ansible.com
preference: 0
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Add a comment to an existing MX record
community.general.nios_mx_record:
name: ansible.com
mx: mailhost.ansible.com
preference: 0
comment: this is a test comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove an MX record from the system
community.general.nios_mx_record:
name: ansible.com
mx: mailhost.ansible.com
preference: 0
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_MX_RECORD
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def main():
''' Main entry point for module execution
'''
ib_spec = dict(
name=dict(required=True, ib_req=True),
view=dict(default='default', aliases=['dns_view'], ib_req=True),
mail_exchanger=dict(aliases=['mx'], ib_req=True),
preference=dict(type='int', ib_req=True),
ttl=dict(type='int'),
extattrs=dict(type='dict'),
comment=dict(),
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
wapi = WapiModule(module)
result = wapi.run(NIOS_MX_RECORD, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,200 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_naptr_record
author: "Blair Rampling (@brampling)"
short_description: Configure Infoblox NIOS NAPTR records
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_naptr_record
removed_in: 5.0.0
description:
- Adds and/or removes instances of NAPTR record objects from
Infoblox NIOS servers. This module manages NIOS C(record:naptr) objects
using the Infoblox WAPI interface over REST.
requirements:
- infoblox_client
extends_documentation_fragment:
- community.general.nios
options:
name:
description:
- Specifies the fully qualified hostname to add or remove from
the system
required: true
type: str
view:
description:
- Sets the DNS view to associate this a record with. The DNS
view must already be configured on the system
default: default
aliases:
- dns_view
type: str
order:
description:
- Configures the order (0-65535) for this NAPTR record. This parameter
specifies the order in which the NAPTR rules are applied when
multiple rules are present.
type: int
preference:
description:
- Configures the preference (0-65535) for this NAPTR record. The
preference field determines the order NAPTR records are processed
when multiple records with the same order parameter are present.
type: int
replacement:
description:
- Configures the replacement field for this NAPTR record.
For nonterminal NAPTR records, this field specifies the
next domain name to look up.
type: str
services:
description:
- Configures the services field (128 characters maximum) for this
NAPTR record. The services field contains protocol and service
identifiers, such as "http+E2U" or "SIPS+D2T".
required: false
type: str
flags:
description:
- Configures the flags field for this NAPTR record. These control the
interpretation of the fields for an NAPTR record object. Supported
values for the flags field are "U", "S", "P" and "A".
required: false
type: str
regexp:
description:
- Configures the regexp field for this NAPTR record. This is the
regular expression-based rewriting rule of the NAPTR record. This
should be a POSIX compliant regular expression, including the
substitution rule and flags. Refer to RFC 2915 for the field syntax
details.
required: false
type: str
ttl:
description:
- Configures the TTL to be associated with this NAPTR record
type: int
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Configure a NAPTR record
community.general.nios_naptr_record:
name: '*.subscriber-100.ansiblezone.com'
order: 1000
preference: 10
replacement: replacement1.network.ansiblezone.com
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Add a comment to an existing NAPTR record
community.general.nios_naptr_record:
name: '*.subscriber-100.ansiblezone.com'
order: 1000
preference: 10
replacement: replacement1.network.ansiblezone.com
comment: this is a test comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove a NAPTR record from the system
community.general.nios_naptr_record:
name: '*.subscriber-100.ansiblezone.com'
order: 1000
preference: 10
replacement: replacement1.network.ansiblezone.com
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def main():
''' Main entry point for module execution
'''
ib_spec = dict(
name=dict(required=True, ib_req=True),
view=dict(default='default', aliases=['dns_view'], ib_req=True),
order=dict(type='int', ib_req=True),
preference=dict(type='int', ib_req=True),
replacement=dict(ib_req=True),
services=dict(),
flags=dict(),
regexp=dict(),
ttl=dict(type='int'),
extattrs=dict(type='dict'),
comment=dict(),
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
wapi = WapiModule(module)
result = wapi.run('record:naptr', ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,334 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_network
author: "Peter Sprygada (@privateip)"
short_description: Configure Infoblox NIOS network object
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_network
removed_in: 5.0.0
description:
- Adds and/or removes instances of network objects from
Infoblox NIOS servers. This module manages NIOS C(network) objects
using the Infoblox WAPI interface over REST.
- Supports both IPV4 and IPV6 internet protocols
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
network:
description:
- Specifies the network to add or remove from the system. The value
should use CIDR notation.
required: true
aliases:
- name
- cidr
type: str
network_view:
description:
- Configures the name of the network view to associate with this
configured instance.
default: default
type: str
options:
description:
- Configures the set of DHCP options to be included as part of
the configured network instance. This argument accepts a list
of values (see suboptions). When configuring suboptions at
least one of C(name) or C(num) must be specified.
type: list
elements: dict
suboptions:
name:
description:
- The name of the DHCP option to configure. The standard options are
C(router), C(router-templates), C(domain-name-servers), C(domain-name),
C(broadcast-address), C(broadcast-address-offset), C(dhcp-lease-time),
and C(dhcp6.name-servers).
type: str
num:
description:
- The number of the DHCP option to configure
type: int
value:
description:
- The value of the DHCP option specified by C(name)
required: true
type: str
use_option:
description:
- Only applies to a subset of options (see NIOS API documentation)
type: bool
default: 'yes'
vendor_class:
description:
- The name of the space this DHCP option is associated to
default: DHCP
type: str
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
type: str
container:
description:
- If set to true it'll create the network container to be added or removed
from the system.
type: bool
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Configure a network ipv4
community.general.nios_network:
network: 192.168.10.0/24
comment: this is a test comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Configure a network ipv6
community.general.nios_network:
network: fe80::/64
comment: this is a test comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Set dhcp options for a network ipv4
community.general.nios_network:
network: 192.168.10.0/24
comment: this is a test comment
options:
- name: domain-name
value: ansible.com
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove a network ipv4
community.general.nios_network:
network: 192.168.10.0/24
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Configure a ipv4 network container
community.general.nios_network:
network: 192.168.10.0/24
container: true
comment: test network container
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Configure a ipv6 network container
community.general.nios_network:
network: fe80::/64
container: true
comment: test network container
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove a ipv4 network container
community.general.nios_network:
networkr: 192.168.10.0/24
container: true
comment: test network container
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
import socket
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six import iteritems
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_IPV4_NETWORK, NIOS_IPV6_NETWORK
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_IPV4_NETWORK_CONTAINER, NIOS_IPV6_NETWORK_CONTAINER
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
# The following function validate_ip_address has been taken from
# https://github.com/ansible-collections/ansible.netcommon/blob/20124ecbb420daa0f5bb9cdaa865a952657aa0e7/plugins/module_utils/network/common/utils.py#L496
# The code there is licensed under BSD 2-clause.
# Copyright (c) 2016 Red Hat Inc.
def validate_ip_address(address):
try:
socket.inet_aton(address)
except socket.error:
return False
return address.count(".") == 3
# The following function validate_ip_v6_address has been taken from
# https://github.com/ansible-collections/ansible.netcommon/blob/20124ecbb420daa0f5bb9cdaa865a952657aa0e7/plugins/module_utils/network/common/utils.py#L504
# The code there is licensed under BSD 2-clause.
# Copyright (c) 2016 Red Hat Inc.
def validate_ip_v6_address(address):
try:
socket.inet_pton(socket.AF_INET6, address)
except socket.error:
return False
return True
def options(module):
''' Transforms the module argument into a valid WAPI struct
This function will transform the options argument into a structure that
is a valid WAPI structure in the format of:
{
name: <value>,
num: <value>,
value: <value>,
use_option: <value>,
vendor_class: <value>
}
It will remove any options that are set to None since WAPI will error on
that condition. It will also verify that either `name` or `num` is
set in the structure but does not validate the values are equal.
The remainder of the value validation is performed by WAPI
'''
options = list()
for item in module.params['options']:
opt = dict([(k, v) for k, v in iteritems(item) if v is not None])
if 'name' not in opt and 'num' not in opt:
module.fail_json(msg='one of `name` or `num` is required for option value')
options.append(opt)
return options
def check_ip_addr_type(obj_filter, ib_spec):
'''This function will check if the argument ip is type v4/v6 and return appropriate infoblox
network/networkcontainer type
'''
ip = obj_filter['network']
if 'container' in obj_filter and obj_filter['container']:
check_ip = ip.split('/')
del ib_spec['container'] # removing the container key from post arguments
del ib_spec['options'] # removing option argument as for network container it's not supported
if validate_ip_address(check_ip[0]):
return NIOS_IPV4_NETWORK_CONTAINER, ib_spec
elif validate_ip_v6_address(check_ip[0]):
return NIOS_IPV6_NETWORK_CONTAINER, ib_spec
else:
check_ip = ip.split('/')
del ib_spec['container'] # removing the container key from post arguments
if validate_ip_address(check_ip[0]):
return NIOS_IPV4_NETWORK, ib_spec
elif validate_ip_v6_address(check_ip[0]):
return NIOS_IPV6_NETWORK, ib_spec
def check_vendor_specific_dhcp_option(module, ib_spec):
'''This function will check if the argument dhcp option belongs to vendor-specific and if yes then will remove
use_options flag which is not supported with vendor-specific dhcp options.
'''
for key, value in iteritems(ib_spec):
if isinstance(module.params[key], list):
temp_dict = module.params[key][0]
if 'num' in temp_dict:
if temp_dict['num'] in (43, 124, 125):
del module.params[key][0]['use_option']
return ib_spec
def main():
''' Main entry point for module execution
'''
option_spec = dict(
# one of name or num is required; enforced by the function options()
name=dict(),
num=dict(type='int'),
value=dict(required=True),
use_option=dict(type='bool', default=True),
vendor_class=dict(default='DHCP')
)
ib_spec = dict(
network=dict(required=True, aliases=['name', 'cidr'], ib_req=True),
network_view=dict(default='default', ib_req=True),
options=dict(type='list', elements='dict', options=option_spec, transform=options),
extattrs=dict(type='dict'),
comment=dict(),
container=dict(type='bool', ib_req=True)
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
# to get the argument ipaddr
obj_filter = dict([(k, module.params[k]) for k, v in iteritems(ib_spec) if v.get('ib_req')])
network_type, ib_spec = check_ip_addr_type(obj_filter, ib_spec)
wapi = WapiModule(module)
# to check for vendor specific dhcp option
ib_spec = check_vendor_specific_dhcp_option(module, ib_spec)
result = wapi.run(network_type, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,138 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_network_view
author: "Peter Sprygada (@privateip)"
short_description: Configure Infoblox NIOS network views
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_network_view
removed_in: 5.0.0
description:
- Adds and/or removes instances of network view objects from
Infoblox NIOS servers. This module manages NIOS C(networkview) objects
using the Infoblox WAPI interface over REST.
- Updates instances of network view object from Infoblox NIOS servers.
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
name:
description:
- Specifies the fully qualified hostname to add or remove from
the system. User can also update the hostname as it is possible
to pass a dict containing I(new_name), I(old_name). See examples.
required: true
aliases:
- network_view
type: str
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Configure a new network view
community.general.nios_network_view:
name: ansible
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Update the comment for network view
community.general.nios_network_view:
name: ansible
comment: this is an example comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove the network view
community.general.nios_network_view:
name: ansible
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Update a existing network view
community.general.nios_network_view:
name: {new_name: ansible-new, old_name: ansible}
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_NETWORK_VIEW
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def main():
''' Main entry point for module execution
'''
ib_spec = dict(
name=dict(required=True, aliases=['network_view'], ib_req=True),
extattrs=dict(type='dict'),
comment=dict(),
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
wapi = WapiModule(module)
result = wapi.run(NIOS_NETWORK_VIEW, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,446 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_nsgroup
short_description: Configure InfoBlox DNS Nameserver Groups
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_nsgroup
removed_in: 5.0.0
extends_documentation_fragment:
- community.general.nios
author:
- Erich Birngruber (@ebirn)
- Sumit Jaiswal (@sjaiswal)
description:
- Adds and/or removes nameserver groups form Infoblox NIOS servers.
This module manages NIOS C(nsgroup) objects using the Infoblox. WAPI interface over REST.
requirements:
- infoblox_client
options:
name:
description:
- Specifies the name of the NIOS nameserver group to be managed.
required: true
type: str
grid_primary:
description:
- This host is to be used as primary server in this nameserver group. It must be a grid member.
This option is required when setting I(use_external_primaries) to C(false).
type: list
elements: dict
suboptions:
name:
description:
- Provide the name of the grid member to identify the host.
required: true
type: str
enable_preferred_primaries:
description:
- This flag represents whether the preferred_primaries field values of this member are used (see Infoblox WAPI docs).
default: false
type: bool
grid_replicate:
description:
- Use DNS zone transfers if set to C(True) or ID Grid Replication if set to C(False).
type: bool
default: false
lead:
description:
- This flag controls if the grid lead secondary nameserver performs zone transfers to non lead secondaries.
type: bool
default: false
stealth:
description:
- Configure the external nameserver as stealth server (without NS record) in the zones.
type: bool
default: false
preferred_primaries:
description:
- Provide a list of elements like in I(external_primaries) to set the precedence of preferred primary nameservers.
type: list
elements: dict
suboptions:
address:
description:
- Configures the IP address of the preferred primary nameserver.
required: true
type: str
name:
description:
- Set a label for the preferred primary nameserver.
required: true
type: str
stealth:
description:
- Configure the preferred primary nameserver as stealth server (without NS record) in the zones.
type: bool
default: false
tsig_key_name:
description:
- Sets a label for the I(tsig_key) value.
required: true
type: str
tsig_key_alg:
description:
- Provides the algorithm used for the I(tsig_key) in use.
choices: ['HMAC-MD5', 'HMAC-SHA256']
default: 'HMAC-MD5'
type: str
tsig_key:
description:
- Set a DNS TSIG key for the nameserver to secure zone transfers (AFXRs).
type: str
grid_secondaries:
description:
- Configures the list of grid member hosts that act as secondary nameservers.
This option is required when setting I(use_external_primaries) to C(true).
type: list
elements: dict
suboptions:
name:
description:
- Provide the name of the grid member to identify the host.
required: true
type: str
enable_preferred_primaries:
description:
- This flag represents whether the preferred_primaries field values of this member are used (see Infoblox WAPI docs).
default: false
type: bool
grid_replicate:
description:
- Use DNS zone transfers if set to C(True) or ID Grid Replication if set to C(False)
type: bool
default: false
lead:
description:
- This flag controls if the grid lead secondary nameserver performs zone transfers to non lead secondaries.
type: bool
default: false
stealth:
description:
- Configure the external nameserver as stealth server (without NS record) in the zones.
type: bool
default: false
preferred_primaries:
description:
- Provide a list of elements like in I(external_primaries) to set the precedence of preferred primary nameservers.
type: list
elements: dict
suboptions:
address:
description:
- Configures the IP address of the preferred primary nameserver.
required: true
type: str
name:
description:
- Set a label for the preferred primary nameserver.
required: true
type: str
stealth:
description:
- Configure the preferred primary nameserver as stealth server (without NS record) in the zones.
type: bool
default: false
tsig_key_name:
description:
- Sets a label for the I(tsig_key) value.
type: str
required: true
tsig_key_alg:
description:
- Provides the algorithm used for the I(tsig_key) in use.
choices: ['HMAC-MD5', 'HMAC-SHA256']
default: 'HMAC-MD5'
type: str
tsig_key:
description:
- Set a DNS TSIG key for the nameserver to secure zone transfers (AFXRs).
type: str
is_grid_default:
description:
- If set to C(True) this nsgroup will become the default nameserver group for new zones.
type: bool
required: false
default: false
use_external_primary:
description:
- This flag controls whether the group is using an external primary nameserver.
Note that modification of this field requires passing values for I(grid_secondaries) and I(external_primaries).
type: bool
required: false
default: false
external_primaries:
description:
- Configures a list of external nameservers (non-members of the grid).
This option is required when setting I(use_external_primaries) to C(true).
type: list
elements: dict
suboptions:
address:
description:
- Configures the IP address of the external nameserver
required: true
type: str
name:
description:
- Set a label for the external nameserver
required: true
type: str
stealth:
description:
- Configure the external nameserver as stealth server (without NS record) in the zones.
type: bool
default: false
tsig_key_name:
description:
- Sets a label for the I(tsig_key) value
type: str
required: true
tsig_key_alg:
description:
- Provides the algorithm used for the I(tsig_key) in use.
choices: ['HMAC-MD5', 'HMAC-SHA256']
default: 'HMAC-MD5'
type: str
tsig_key:
description:
- Set a DNS TSIG key for the nameserver to secure zone transfers (AFXRs).
type: str
required: false
external_secondaries:
description:
- Allows to provide a list of external secondary nameservers, that are not members of the grid.
type: list
elements: dict
suboptions:
address:
description:
- Configures the IP address of the external nameserver
required: true
type: str
name:
description:
- Set a label for the external nameserver
required: true
type: str
stealth:
description:
- Configure the external nameserver as stealth server (without NS record) in the zones.
type: bool
default: false
tsig_key_name:
description:
- Sets a label for the I(tsig_key) value
type: str
required: true
tsig_key_alg:
description:
- Provides the algorithm used for the I(tsig_key) in use.
choices: ['HMAC-MD5', 'HMAC-SHA256']
default: 'HMAC-MD5'
type: str
tsig_key:
description:
- Set a DNS TSIG key for the nameserver to secure zone transfers (AFXRs).
type: str
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
required: false
type: str
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
required: false
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
choices: [present, absent]
default: present
type: str
'''
EXAMPLES = '''
- name: Create simple infoblox nameserver group
community.general.nios_nsgroup:
name: my-simple-group
comment: "this is a simple nameserver group"
grid_primary:
- name: infoblox-test.example.com
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Create infoblox nameserver group with external primaries
community.general.nios_nsgroup:
name: my-example-group
use_external_primary: true
comment: "this is my example nameserver group"
external_primaries: "{{ ext_nameservers }}"
grid_secondaries:
- name: infoblox-test.example.com
lead: True
preferred_primaries: "{{ ext_nameservers }}"
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Delete infoblox nameserver group
community.general.nios_nsgroup:
name: my-simple-group
comment: "this is a simple nameserver group"
grid_primary:
- name: infoblox-test.example.com
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_NSGROUP
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
# from infoblox documentation
# Fields List
# Field Type Req R/O Base Search
# comment String N N Y : = ~
# extattrs Extattr N N N ext
# external_primaries [struct] N N N N/A
# external_secondaries [struct] N N N N/A
# grid_primary [struct] N N N N/A
# grid_secondaries [struct] N N N N/A
# is_grid_default Bool N N N N/A
# is_multimaster Bool N Y N N/A
# name String Y N Y : = ~
# use_external_primary Bool N N N N/A
def main():
'''entrypoint for module execution.'''
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent']),
)
# cleanup tsig fields
def clean_tsig(ext):
if 'tsig_key' in ext and not ext['tsig_key']:
del ext['tsig_key']
if 'tsig_key' not in ext and 'tsig_key_name' in ext and not ext['tsig_key_name']:
del ext['tsig_key_name']
if 'tsig_key' not in ext and 'tsig_key_alg' in ext:
del ext['tsig_key_alg']
def clean_grid_member(member):
if member['preferred_primaries']:
for ext in member['preferred_primaries']:
clean_tsig(ext)
if member['enable_preferred_primaries'] is False:
del member['enable_preferred_primaries']
del member['preferred_primaries']
if member['lead'] is False:
del member['lead']
if member['grid_replicate'] is False:
del member['grid_replicate']
def ext_primaries_transform(module):
if module.params['external_primaries']:
for ext in module.params['external_primaries']:
clean_tsig(ext)
return module.params['external_primaries']
def ext_secondaries_transform(module):
if module.params['external_secondaries']:
for ext in module.params['external_secondaries']:
clean_tsig(ext)
return module.params['external_secondaries']
def grid_primary_preferred_transform(module):
for member in module.params['grid_primary']:
clean_grid_member(member)
return module.params['grid_primary']
def grid_secondaries_preferred_primaries_transform(module):
for member in module.params['grid_secondaries']:
clean_grid_member(member)
return module.params['grid_secondaries']
extserver_spec = dict(
address=dict(required=True),
name=dict(required=True),
stealth=dict(type='bool', default=False),
tsig_key=dict(no_log=True),
tsig_key_alg=dict(choices=['HMAC-MD5', 'HMAC-SHA256'], default='HMAC-MD5'),
tsig_key_name=dict(required=True)
)
memberserver_spec = dict(
name=dict(required=True, ),
enable_preferred_primaries=dict(type='bool', default=False),
grid_replicate=dict(type='bool', default=False),
lead=dict(type='bool', default=False),
preferred_primaries=dict(type='list', elements='dict', options=extserver_spec, default=[]),
stealth=dict(type='bool', default=False),
)
ib_spec = dict(
name=dict(required=True, ib_req=True),
grid_primary=dict(type='list', elements='dict', options=memberserver_spec,
transform=grid_primary_preferred_transform),
grid_secondaries=dict(type='list', elements='dict', options=memberserver_spec,
transform=grid_secondaries_preferred_primaries_transform),
external_primaries=dict(type='list', elements='dict', options=extserver_spec, transform=ext_primaries_transform),
external_secondaries=dict(type='list', elements='dict', options=extserver_spec,
transform=ext_secondaries_transform),
is_grid_default=dict(type='bool', default=False),
use_external_primary=dict(type='bool', default=False),
extattrs=dict(),
comment=dict(),
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
wapi = WapiModule(module)
result = wapi.run(NIOS_NSGROUP, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,168 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_ptr_record
author: "Trebuchet Clement (@clementtrebuchet)"
short_description: Configure Infoblox NIOS PTR records
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_ptr_record
removed_in: 5.0.0
description:
- Adds and/or removes instances of PTR record objects from
Infoblox NIOS servers. This module manages NIOS C(record:ptr) objects
using the Infoblox WAPI interface over REST.
requirements:
- infoblox_client
extends_documentation_fragment:
- community.general.nios
options:
name:
description:
- The name of the DNS PTR record in FQDN format to add or remove from
the system.
The field is required only for an PTR object in Forward Mapping Zone.
required: false
type: str
view:
description:
- Sets the DNS view to associate this a record with. The DNS
view must already be configured on the system
required: false
aliases:
- dns_view
type: str
ipv4addr:
description:
- The IPv4 Address of the record. Mutually exclusive with the ipv6addr.
aliases:
- ipv4
type: str
ipv6addr:
description:
- The IPv6 Address of the record. Mutually exclusive with the ipv4addr.
aliases:
- ipv6
type: str
ptrdname:
description:
- The domain name of the DNS PTR record in FQDN format.
type: str
ttl:
description:
- Time To Live (TTL) value for the record.
A 32-bit unsigned integer that represents the duration, in seconds, that the record is valid (cached).
Zero indicates that the record should not be cached.
type: int
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance. Maximum 256 characters.
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Create a PTR Record
community.general.nios_ptr_record:
ipv4: 192.168.10.1
ptrdname: host.ansible.com
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Delete a PTR Record
community.general.nios_ptr_record:
ipv4: 192.168.10.1
ptrdname: host.ansible.com
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_PTR_RECORD
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def main():
# Module entry point
ib_spec = dict(
name=dict(required=False),
view=dict(aliases=['dns_view'], ib_req=True),
ipv4addr=dict(aliases=['ipv4'], ib_req=True),
ipv6addr=dict(aliases=['ipv6'], ib_req=True),
ptrdname=dict(ib_req=True),
ttl=dict(type='int'),
extattrs=dict(type='dict'),
comment=dict(),
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
mutually_exclusive = [('ipv4addr', 'ipv6addr')]
required_one_of = [
['ipv4addr', 'ipv6addr']
]
module = AnsibleModule(argument_spec=argument_spec,
mutually_exclusive=mutually_exclusive,
supports_check_mode=True,
required_one_of=required_one_of)
if module.params['ipv4addr']:
del ib_spec['ipv6addr']
elif module.params['ipv6addr']:
del ib_spec['ipv4addr']
wapi = WapiModule(module)
result = wapi.run(NIOS_PTR_RECORD, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,177 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_srv_record
author: "Blair Rampling (@brampling)"
short_description: Configure Infoblox NIOS SRV records
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_srv_record
removed_in: 5.0.0
description:
- Adds and/or removes instances of SRV record objects from
Infoblox NIOS servers. This module manages NIOS C(record:srv) objects
using the Infoblox WAPI interface over REST.
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
name:
description:
- Specifies the fully qualified hostname to add or remove from
the system
required: true
type: str
view:
description:
- Sets the DNS view to associate this a record with. The DNS
view must already be configured on the system
default: default
aliases:
- dns_view
type: str
port:
description:
- Configures the port (0-65535) of this SRV record.
type: int
priority:
description:
- Configures the priority (0-65535) for this SRV record.
type: int
target:
description:
- Configures the target FQDN for this SRV record.
type: str
weight:
description:
- Configures the weight (0-65535) for this SRV record.
type: int
ttl:
description:
- Configures the TTL to be associated with this host record
type: int
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Configure an SRV record
community.general.nios_srv_record:
name: _sip._tcp.service.ansible.com
port: 5080
priority: 10
target: service1.ansible.com
weight: 10
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Add a comment to an existing SRV record
community.general.nios_srv_record:
name: _sip._tcp.service.ansible.com
port: 5080
priority: 10
target: service1.ansible.com
weight: 10
comment: this is a test comment
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove an SRV record from the system
community.general.nios_srv_record:
name: _sip._tcp.service.ansible.com
port: 5080
priority: 10
target: service1.ansible.com
weight: 10
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_SRV_RECORD
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def main():
''' Main entry point for module execution
'''
ib_spec = dict(
name=dict(required=True, ib_req=True),
view=dict(default='default', aliases=['dns_view'], ib_req=True),
port=dict(type='int', ib_req=True),
priority=dict(type='int', ib_req=True),
target=dict(ib_req=True),
weight=dict(type='int', ib_req=True),
ttl=dict(type='int'),
extattrs=dict(type='dict'),
comment=dict(),
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
wapi = WapiModule(module)
result = wapi.run(NIOS_SRV_RECORD, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,140 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_txt_record
author: "Corey Wanless (@coreywan)"
short_description: Configure Infoblox NIOS txt records
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_txt_record
removed_in: 5.0.0
description:
- Adds and/or removes instances of txt record objects from
Infoblox NIOS servers. This module manages NIOS C(record:txt) objects
using the Infoblox WAPI interface over REST.
requirements:
- infoblox_client
extends_documentation_fragment:
- community.general.nios
options:
name:
description:
- Specifies the fully qualified hostname to add or remove from
the system
required: true
type: str
view:
description:
- Sets the DNS view to associate this tst record with. The DNS
view must already be configured on the system
default: default
aliases:
- dns_view
type: str
text:
description:
- Text associated with the record. It can contain up to 255 bytes
per substring, up to a total of 512 bytes. To enter leading,
trailing, or embedded spaces in the text, add quotes around the
text to preserve the spaces.
type: str
ttl:
description:
- Configures the TTL to be associated with this tst record
type: int
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Ensure a text Record Exists
community.general.nios_txt_record:
name: fqdn.txt.record.com
text: mytext
state: present
view: External
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
- name: Ensure a text Record does not exist
community.general.nios_txt_record:
name: fqdn.txt.record.com
text: mytext
state: absent
view: External
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def main():
''' Main entry point for module execution
'''
ib_spec = dict(
name=dict(required=True, ib_req=True),
view=dict(default='default', aliases=['dns_view'], ib_req=True),
text=dict(ib_req=True),
ttl=dict(type='int'),
extattrs=dict(type='dict'),
comment=dict(),
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
wapi = WapiModule(module)
result = wapi.run('record:txt', ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,241 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Red Hat, Inc.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: nios_zone
author: "Peter Sprygada (@privateip)"
short_description: Configure Infoblox NIOS DNS zones
deprecated:
why: Please install the infoblox.nios_modules collection and use the corresponding module from it.
alternative: infoblox.nios_modules.nios_zone
removed_in: 5.0.0
description:
- Adds and/or removes instances of DNS zone objects from
Infoblox NIOS servers. This module manages NIOS C(zone_auth) objects
using the Infoblox WAPI interface over REST.
requirements:
- infoblox-client
extends_documentation_fragment:
- community.general.nios
options:
fqdn:
description:
- Specifies the qualified domain name to either add or remove from
the NIOS instance based on the configured C(state) value.
required: true
aliases:
- name
type: str
view:
description:
- Configures the DNS view name for the configured resource. The
specified DNS zone must already exist on the running NIOS instance
prior to configuring zones.
default: default
aliases:
- dns_view
type: str
grid_primary:
description:
- Configures the grid primary servers for this zone.
type: list
elements: dict
suboptions:
name:
description:
- The name of the grid primary server
required: true
type: str
grid_secondaries:
description:
- Configures the grid secondary servers for this zone.
type: list
elements: dict
suboptions:
name:
description:
- The name of the grid secondary server
required: true
type: str
ns_group:
description:
- Configures the name server group for this zone. Name server group is
mutually exclusive with grid primary and grid secondaries.
type: str
restart_if_needed:
description:
- If set to true, causes the NIOS DNS service to restart and load the
new zone configuration
type: bool
zone_format:
description:
- Create an authorative Reverse-Mapping Zone which is an area of network
space for which one or more name servers-primary and secondary-have the
responsibility to respond to address-to-name queries. It supports
reverse-mapping zones for both IPv4 and IPv6 addresses.
default: FORWARD
type: str
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
instance of the object. This argument accepts a set of key / value
pairs for configuration.
type: dict
comment:
description:
- Configures a text string comment to be associated with the instance
of this object. The provided text string will be configured on the
object instance.
type: str
state:
description:
- Configures the intended state of the instance of the object on
the NIOS server. When this value is set to C(present), the object
is configured on the device and when this value is set to C(absent)
the value is removed (if necessary) from the device.
default: present
choices:
- present
- absent
type: str
'''
EXAMPLES = '''
- name: Configure a zone on the system using grid primary and secondaries
community.general.nios_zone:
name: ansible.com
grid_primary:
- name: gridprimary.grid.com
grid_secondaries:
- name: gridsecondary1.grid.com
- name: gridsecondary2.grid.com
restart_if_needed: true
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Configure a zone on the system using a name server group
community.general.nios_zone:
name: ansible.com
ns_group: examplensg
restart_if_needed: true
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Configure a reverse mapping zone on the system using IPV4 zone format
community.general.nios_zone:
name: 10.10.10.0/24
zone_format: IPV4
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Configure a reverse mapping zone on the system using IPV6 zone format
community.general.nios_zone:
name: 100::1/128
zone_format: IPV6
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Update the comment and ext attributes for an existing zone
community.general.nios_zone:
name: ansible.com
comment: this is an example comment
extattrs:
Site: west-dc
state: present
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove the dns zone
community.general.nios_zone:
name: ansible.com
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
- name: Remove the reverse mapping dns zone from the system with IPV4 zone format
community.general.nios_zone:
name: 10.10.10.0/24
zone_format: IPV4
state: absent
provider:
host: "{{ inventory_hostname_short }}"
username: admin
password: admin
connection: local
'''
RETURN = ''' # '''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiModule
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import NIOS_ZONE
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import normalize_ib_spec
def main():
''' Main entry point for module execution
'''
grid_spec = dict(
name=dict(required=True),
)
ib_spec = dict(
fqdn=dict(required=True, aliases=['name'], ib_req=True, update=False),
zone_format=dict(default='FORWARD', ib_req=False),
view=dict(default='default', aliases=['dns_view'], ib_req=True),
grid_primary=dict(type='list', elements='dict', options=grid_spec),
grid_secondaries=dict(type='list', elements='dict', options=grid_spec),
ns_group=dict(),
restart_if_needed=dict(type='bool'),
extattrs=dict(type='dict'),
comment=dict()
)
argument_spec = dict(
provider=dict(required=True),
state=dict(default='present', choices=['present', 'absent'])
)
argument_spec.update(normalize_ib_spec(ib_spec))
argument_spec.update(WapiModule.provider_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True,
mutually_exclusive=[
['ns_group', 'grid_primary'],
['ns_group', 'grid_secondaries']
])
wapi = WapiModule(module)
result = wapi.run(NIOS_ZONE, ib_spec)
module.exit_json(**result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_a_record.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_aaaa_record.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_cname_record.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_dns_view.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_fixed_address.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_host_record.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_member.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_mx_record.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_naptr_record.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_network.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_network_view.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_nsgroup.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_ptr_record.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_srv_record.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_txt_record.py

View File

@@ -0,0 +1 @@
./net_tools/nios/nios_zone.py

View File

@@ -33,6 +33,8 @@ options:
- Message content.
- The alias I(message) is deprecated and will be removed in community.general 4.0.0.
required: true
aliases:
- message
url:
type: str
description:
@@ -93,7 +95,9 @@ def main():
module = AnsibleModule(
argument_spec=dict(
channel_token=dict(type='str', required=True, no_log=True),
message_content=dict(type='str', required=True),
message_content=dict(type='str', required=True, aliases=['message'],
deprecated_aliases=[dict(name='message', version='4.0.0',
collection_name='community.general')]),
service=dict(type='str', default='ansible'),
url=dict(type='str', default=None),
icon_url=dict(type='str', default=None),

View File

@@ -22,6 +22,8 @@ description:
- Also, the user may try to use any other telegram bot API method, if you specify I(api_method) argument.
notes:
- You will require a telegram account and create telegram bot to use this module.
- The options I(msg), I(msg_format) and I(chat_id) have been deprecated and will be removed in community.general
4.0.0. Use the corresponding variables in I(api_args) instead. See the examples for how that works.
options:
token:
type: str
@@ -41,6 +43,22 @@ options:
- Any parameters for the method.
- For reference to default method, C(SendMessage), see U(https://core.telegram.org/bots/api#sendmessage).
version_added: 2.0.0
msg:
type: str
description:
- (Deprecated) What message you wish to send.
msg_format:
type: str
description:
- (Deprecated) Message format. Formatting options C(markdown), C(MarkdownV2), and C(html) described in
Telegram API docs (https://core.telegram.org/bots/api#formatting-options).
If option C(plain) set, message will not be formatted.
default: plain
choices: [ "plain", "markdown", "MarkdownV2", "html" ]
chat_id:
type: str
description:
- (Deprecated) Telegram group or user chat_id.
'''
@@ -65,6 +83,12 @@ EXAMPLES = """
from_chat_id: 111111
disable_notification: True
message_id: '{{ saved_msg_id }}'
- name: Send a message to chat in playbook (deprecated old style)
community.general.telegram:
token: '9999999:XXXXXXXXXXXXXXXXXXXXXXX'
chat_id: 000000
msg: Ansible task finished
"""
RETURN = """
@@ -95,6 +119,11 @@ def main():
token=dict(type='str', required=True, no_log=True),
api_args=dict(type='dict'),
api_method=dict(type="str", default="SendMessage"),
chat_id=dict(type='str', no_log=True, removed_in_version='4.0.0',
removed_from_collection='community.general'),
msg=dict(type='str', removed_in_version='4.0.0', removed_from_collection='community.general'),
msg_format=dict(type='str', choices=['plain', 'markdown', 'html', 'MarkdownV2'], default='plain',
removed_in_version='4.0.0', removed_from_collection='community.general'),
),
supports_check_mode=True
)
@@ -103,9 +132,9 @@ def main():
api_args = module.params.get('api_args') or {}
api_method = module.params.get('api_method')
# filling backward compatibility args
api_args['chat_id'] = api_args.get('chat_id')
api_args['parse_mode'] = api_args.get('parse_mode')
api_args['text'] = api_args.get('text')
api_args['chat_id'] = api_args.get('chat_id') or module.params.get('chat_id')
api_args['parse_mode'] = api_args.get('parse_mode') or module.params.get('msg_format')
api_args['text'] = api_args.get('text') or module.params.get('msg')
if api_args['parse_mode'] == 'plain':
del api_args['parse_mode']

View File

@@ -238,7 +238,7 @@ class AnsibleGalaxyInstall(CmdModuleHelper):
def _list_element(self, _type, path_re, elem_re):
params = ({'type': _type}, {'galaxy_cmd': 'list'}, 'dest')
elems = self.run_command(params=params,
publish_rc=False, publish_out=False, publish_err=False, publish_cmd=False,
publish_rc=False, publish_out=False, publish_err=False,
process_output=self._process_output_list,
check_rc=False)
elems_dict = {}

View File

@@ -53,6 +53,16 @@ options:
description:
- Version specification for the perl module. When I(mode) is C(new), C(cpanm) version operators are accepted.
type: str
system_lib:
description:
- Use this if you want to install modules to the system perl include path. You must be root or have "passwordless" sudo for this to work.
- This uses the cpanm commandline option C(--sudo), which has nothing to do with ansible privilege escalation.
- >
This option is not recommended for use and it will be deprecated in the future. If you need to escalate privileges
please consider using any of the multiple mechanisms available in Ansible.
type: bool
default: no
aliases: ['use_sudo']
executable:
description:
- Override the path to the cpanm executable.
@@ -150,6 +160,8 @@ class CPANMinus(CmdMixin, ModuleHelper):
mirror=dict(type='str'),
mirror_only=dict(type='bool', default=False),
installdeps=dict(type='bool', default=False),
system_lib=dict(type='bool', default=False, aliases=['use_sudo'],
removed_in_version="4.0.0", removed_from_collection="community.general"),
executable=dict(type='path'),
mode=dict(type='str', choices=['compatibility', 'new'], default='compatibility'),
name_check=dict(type='str')
@@ -164,6 +176,7 @@ class CPANMinus(CmdMixin, ModuleHelper):
mirror=dict(fmt=('--mirror', '{0}'),),
mirror_only=dict(fmt="--mirror-only", style=ArgFormat.BOOLEAN),
installdeps=dict(fmt="--installdeps", style=ArgFormat.BOOLEAN),
system_lib=dict(fmt="--sudo", style=ArgFormat.BOOLEAN),
)
check_rc = True
@@ -175,6 +188,8 @@ class CPANMinus(CmdMixin, ModuleHelper):
else:
if v.name and v.from_path:
raise ModuleHelperException("Parameters 'name' and 'from_path' are mutually exclusive when 'mode=new'")
if v.system_lib:
raise ModuleHelperException("Parameter 'system_lib' is invalid when 'mode=new'")
self.command = self.module.get_bin_path(v.executable if v.executable else self.command)
self.vars.set("binary", self.command)
@@ -215,7 +230,7 @@ class CPANMinus(CmdMixin, ModuleHelper):
return
pkg_spec = v[pkg_param]
self.changed = self.run_command(
params=['notest', 'locallib', 'mirror', 'mirror_only', 'installdeps', {'name': pkg_spec}],
params=['notest', 'locallib', 'mirror', 'mirror_only', 'installdeps', 'system_lib', {'name': pkg_spec}],
)
else:
installed = self._is_package_installed(v.name_check, v.locallib, v.version) if v.name_check else False

View File

@@ -197,7 +197,7 @@ class PipX(CmdStateModuleHelper):
return results
installed = self.run_command(params=[{'_list': True}], process_output=process_list,
publish_rc=False, publish_out=False, publish_err=False, publish_cmd=False)
publish_rc=False, publish_out=False, publish_err=False)
if self.vars.name is not None:
app_list = installed.get(self.vars.name)
@@ -215,6 +215,7 @@ class PipX(CmdStateModuleHelper):
facts = ansible_facts(self.module, gather_subset=['python'])
self.command = [facts['python']['executable'], '-m', 'pipx']
self.vars.set('will_change', False, output=False, change=True)
self.vars.set('application', self._retrieve_installed(), change=True, diff=True)
def __quit_module__(self):
@@ -222,7 +223,7 @@ class PipX(CmdStateModuleHelper):
def state_install(self):
if not self.vars.application or self.vars.force:
self.changed = True
self.vars.will_change = True
if not self.module.check_mode:
self.run_command(params=['state', 'index_url', 'install_deps', 'force', 'python',
{'name_source': [self.vars.name, self.vars.source]}])
@@ -234,7 +235,7 @@ class PipX(CmdStateModuleHelper):
raise ModuleHelperException(
"Trying to upgrade a non-existent application: {0}".format(self.vars.name))
if self.vars.force:
self.changed = True
self.vars.will_change = True
if not self.module.check_mode:
self.run_command(params=['state', 'index_url', 'install_deps', 'force', 'name'])
@@ -248,7 +249,7 @@ class PipX(CmdStateModuleHelper):
if not self.vars.application:
raise ModuleHelperException(
"Trying to reinstall a non-existent application: {0}".format(self.vars.name))
self.changed = True
self.vars.will_change = True
if not self.module.check_mode:
self.run_command(params=['state', 'name', 'python'])
@@ -257,7 +258,7 @@ class PipX(CmdStateModuleHelper):
raise ModuleHelperException(
"Trying to inject packages into a non-existent application: {0}".format(self.vars.name))
if self.vars.force:
self.changed = True
self.vars.will_change = True
if not self.module.check_mode:
self.run_command(params=['state', 'index_url', 'force', 'name', 'inject_packages'])
@@ -271,7 +272,7 @@ class PipX(CmdStateModuleHelper):
def state_upgrade_all(self):
if self.vars.force:
self.changed = True
self.vars.will_change = True
if not self.module.check_mode:
self.run_command(params=['state', 'include_injected', 'force'])

View File

@@ -1,347 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2021, Roberto Moreda <moreda@allenta.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r'''
---
module: dnf_versionlock
version_added: '4.0.0'
short_description: Locks package versions in C(dnf) based systems
description:
- Locks package versions using the C(versionlock) plugin in C(dnf) based
systems. This plugin takes a set of name and versions for packages and
excludes all other versions of those packages. This allows you to for example
protect packages from being updated by newer versions. The state of the
plugin that reflects locking of packages is the C(locklist).
options:
name:
description:
- Package name spec to add or exclude to or delete from the C(locklist)
using the format expected by the C(dnf repoquery) command.
- This parameter is mutually exclusive with I(state=clean).
type: list
required: false
elements: str
default: []
raw:
description:
- Do not resolve package name specs to NEVRAs to find specific version
to lock to. Instead the package name specs are used as they are. This
enables locking to not yet available versions of the package.
type: bool
default: false
state:
description:
- Whether to add (C(present) or C(excluded)) to or remove (C(absent) or
C(clean)) from the C(locklist).
- C(present) will add a package name spec to the C(locklist). If there is a
installed package that matches, then only that version will be added.
Otherwise, all available package versions will be added.
- C(excluded) will add a package name spec as excluded to the
C(locklist). It means that packages represented by the package name
spec will be excluded from transaction operations. All available
package versions will be added.
- C(absent) will delete entries in the C(locklist) that match the
package name spec.
- C(clean) will delete all entries in the C(locklist). This option is
mutually exclusive with C(name).
choices: [ 'absent', 'clean', 'excluded', 'present' ]
type: str
default: present
notes:
- The logics of the C(versionlock) plugin for corner cases could be
confusing, so please take in account that this module will do its best to
give a C(check_mode) prediction on what is going to happen. In case of
doubt, check the documentation of the plugin.
- Sometimes the module could predict changes in C(check_mode) that will not
be such because C(versionlock) concludes that there is already a entry in
C(locklist) that already matches.
- In an ideal world, the C(versionlock) plugin would have a dry-run option to
know for sure what is going to happen. So far we have to work with a best
guess as close as possible to the behaviour inferred from its code.
- For most of cases where you want to lock and unlock specific versions of a
package, this works fairly well.
- Supports C(check_mode).
requirements:
- dnf
- dnf-plugin-versionlock
author:
- Roberto Moreda (@moreda) <moreda@allenta.com>
'''
EXAMPLES = r'''
- name: Prevent installed nginx from being updated
community.general.dnf_versionlock:
name: nginx
state: present
- name: Prevent multiple packages from being updated
community.general.dnf_versionlock:
name:
- nginx
- haproxy
state: present
- name: Remove lock from nginx to be updated again
community.general.dnf_versionlock:
package: nginx
state: absent
- name: Exclude bind 32:9.11 from installs or updates
community.general.dnf_versionlock:
package: bind-32:9.11*
state: excluded
- name: Keep bash package in major version 4
community.general.dnf_versionlock:
name: bash-0:4.*
raw: true
state: present
- name: Delete all entries in the locklist of versionlock
community.general.dnf_versionlock:
state: clean
'''
RETURN = r'''
locklist_pre:
description: Locklist before module execution.
returned: success
type: list
elements: str
sample: [ 'bash-0:4.4.20-1.el8_4.*', '!bind-32:9.11.26-4.el8_4.*' ]
locklist_post:
description: Locklist after module execution.
returned: success and (not check mode or state is clean)
type: list
elements: str
sample: [ 'bash-0:4.4.20-1.el8_4.*' ]
specs_toadd:
description: Package name specs meant to be added by versionlock.
returned: success
type: list
elements: str
sample: [ 'bash' ]
specs_todelete:
description: Package name specs meant to be deleted by versionlock.
returned: success
type: list
elements: str
sample: [ 'bind' ]
'''
from ansible.module_utils.basic import AnsibleModule
import fnmatch
import os
import re
DNF_BIN = "/usr/bin/dnf"
VERSIONLOCK_CONF = "/etc/dnf/plugins/versionlock.conf"
# NEVRA regex.
NEVRA_RE = re.compile(r"^(?P<name>.+)-(?P<epoch>\d+):(?P<version>.+)-"
r"(?P<release>.+)\.(?P<arch>.+)$")
def do_versionlock(module, command, patterns=None, raw=False):
patterns = [] if not patterns else patterns
raw_parameter = ["--raw"] if raw else []
# Call dnf versionlock using a just one full NEVR package-name-spec each
# time because multiple package-name-spec and globs are not well supported.
#
# This is a workaround for two alleged bugs in the dnf versionlock plugin:
# * Multiple package-name-spec arguments don't lock correctly
# (https://bugzilla.redhat.com/show_bug.cgi?id=2013324).
# * Locking a version of a not installed package disallows locking other
# versions later (https://bugzilla.redhat.com/show_bug.cgi?id=2013332)
#
# NOTE: This is suboptimal in terms of performance if there are more than a
# few package-name-spec patterns to lock, because there is a command
# execution per each. This will improve by changing the strategy once the
# mentioned alleged bugs in the dnf versionlock plugin are fixed.
if patterns:
outs = []
for p in patterns:
rc, out, err = module.run_command(
[DNF_BIN, "-q", "versionlock", command] + raw_parameter + [p],
check_rc=True)
outs.append(out)
out = "\n".join(outs)
else:
rc, out, err = module.run_command(
[DNF_BIN, "-q", "versionlock", command], check_rc=True)
return out
# This is equivalent to the _match function of the versionlock plugin.
def match(entry, pattern):
entry = entry.lstrip('!')
if entry == pattern:
return True
m = NEVRA_RE.match(entry)
if not m:
return False
for name in (
'%s' % m["name"],
'%s.%s' % (m["name"], m["arch"]),
'%s-%s' % (m["name"], m["version"]),
'%s-%s-%s' % (m["name"], m["version"], m["release"]),
'%s-%s:%s' % (m["name"], m["epoch"], m["version"]),
'%s-%s-%s.%s' % (m["name"], m["version"], m["release"], m["arch"]),
'%s-%s:%s-%s' % (m["name"], m["epoch"], m["version"], m["release"]),
'%s:%s-%s-%s.%s' % (m["epoch"], m["name"], m["version"], m["release"],
m["arch"]),
'%s-%s:%s-%s.%s' % (m["name"], m["epoch"], m["version"], m["release"],
m["arch"])
):
if fnmatch.fnmatch(name, pattern):
return True
return False
def get_packages(module, patterns, only_installed=False):
packages_available_map_name_evrs = {}
rc, out, err = module.run_command(
[DNF_BIN, "-q", "repoquery"] +
(["--installed"] if only_installed else []) +
patterns,
check_rc=True)
for p in out.split():
# Extract the NEVRA pattern.
m = NEVRA_RE.match(p)
if not m:
module.fail_json(
msg="failed to parse nevra for %s" % p,
rc=rc, out=out, err=err)
evr = "%s:%s-%s" % (m["epoch"],
m["version"],
m["release"])
packages_available_map_name_evrs.setdefault(m["name"], set())
packages_available_map_name_evrs[m["name"]].add(evr)
return packages_available_map_name_evrs
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(type="list", elements="str", default=[]),
raw=dict(type="bool", default=False),
state=dict(type="str", default="present",
choices=["present", "absent", "excluded", "clean"]),
),
supports_check_mode=True,
)
patterns = module.params["name"]
raw = module.params["raw"]
state = module.params["state"]
changed = False
msg = ""
# Check module pre-requisites.
if not os.path.exists(DNF_BIN):
module.fail_json(msg="%s was not found" % DNF_BIN)
if not os.path.exists(VERSIONLOCK_CONF):
module.fail_json(msg="plugin versionlock is required")
# Check incompatible options.
if state == "clean" and patterns:
module.fail_json(msg="clean state is incompatible with a name list")
if state != "clean" and not patterns:
module.fail_json(msg="name list is required for %s state" % state)
locklist_pre = do_versionlock(module, "list").split()
specs_toadd = []
specs_todelete = []
if state in ["present", "excluded"]:
if raw:
# Add raw patterns as specs to add.
for p in patterns:
if ((p if state == "present" else "!" + p)
not in locklist_pre):
specs_toadd.append(p)
else:
# Get available packages that match the patterns.
packages_map_name_evrs = get_packages(
module,
patterns)
# Get installed packages that match the patterns.
packages_installed_map_name_evrs = get_packages(
module,
patterns,
only_installed=True)
# Obtain the list of package specs that require an entry in the
# locklist. This list is composed by:
# a) the non-installed packages list with all available
# versions
# b) the installed packages list
packages_map_name_evrs.update(packages_installed_map_name_evrs)
for name in packages_map_name_evrs:
for evr in packages_map_name_evrs[name]:
locklist_entry = "%s-%s.*" % (name, evr)
if (locklist_entry if state == "present"
else "!%s" % locklist_entry) not in locklist_pre:
specs_toadd.append(locklist_entry)
if specs_toadd and not module.check_mode:
cmd = "add" if state == "present" else "exclude"
msg = do_versionlock(module, cmd, patterns=specs_toadd, raw=raw)
elif state == "absent":
if raw:
# Add raw patterns as specs to delete.
for p in patterns:
if p in locklist_pre:
specs_todelete.append(p)
else:
# Get patterns that match the some line in the locklist.
for p in patterns:
for e in locklist_pre:
if match(e, p):
specs_todelete.append(p)
if specs_todelete and not module.check_mode:
msg = do_versionlock(
module, "delete", patterns=specs_todelete, raw=raw)
elif state == "clean":
specs_todelete = locklist_pre
if specs_todelete and not module.check_mode:
msg = do_versionlock(module, "clear")
if specs_toadd or specs_todelete:
changed = True
response = {
"changed": changed,
"msg": msg,
"locklist_pre": locklist_pre,
"specs_toadd": specs_toadd,
"specs_todelete": specs_todelete
}
if not module.check_mode:
response["locklist_post"] = do_versionlock(module, "list").split()
else:
if state == "clean":
response["locklist_post"] = []
module.exit_json(**response)
if __name__ == "__main__":
main()

View File

@@ -20,20 +20,19 @@ description:
options:
name:
description:
- Name of package(s) to install/remove.
- name of package to install/remove
aliases: [pkg]
required: true
type: list
elements: str
type: str
state:
description:
- State of the package.
- state of the package
choices: [ 'present', 'absent', 'installed', 'removed' ]
default: present
type: str
force:
description:
- The C(opkg --force) parameter used.
- opkg --force parameter used
choices:
- ""
- "depends"
@@ -49,10 +48,10 @@ options:
type: str
update_cache:
description:
- Update the package DB first.
- update the package db first
- Alias C(update-cache) has been deprecated and will be removed in community.general 5.0.0.
aliases: ['update-cache']
default: false
default: "no"
type: bool
requirements:
- opkg
@@ -77,9 +76,7 @@ EXAMPLES = '''
- name: Remove foo and bar
community.general.opkg:
name:
- foo
- bar
name: foo,bar
state: absent
- name: Install foo using overwrite option forcibly
@@ -173,7 +170,7 @@ def install_packages(module, opkg_path, packages):
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(aliases=["pkg"], required=True, type="list", elements="str"),
name=dict(aliases=["pkg"], required=True),
state=dict(default="present", choices=["present", "installed", "absent", "removed"]),
force=dict(default="", choices=["", "depends", "maintainer", "reinstall", "overwrite", "downgrade", "space", "postinstall", "remove",
"checksum", "removal-of-dependent-packages"]),
@@ -190,7 +187,7 @@ def main():
if p["update_cache"]:
update_package_db(module, opkg_path)
pkgs = p["name"]
pkgs = p["name"].split(",")
if p["state"] in ["present", "installed"]:
install_packages(module, opkg_path, pkgs)

View File

@@ -189,43 +189,38 @@ def get_name(module, pacman_output):
module.fail_json(msg="get_name: fail to retrieve package name from pacman output")
def query_package(module, pacman_path, name, state):
def query_package(module, pacman_path, name, state="present"):
"""Query the package status in both the local system and the repository. Returns a boolean to indicate if the package is installed, a second
boolean to indicate if the package is up-to-date and a third boolean to indicate whether online information were available
"""
lcmd = "%s --query %s" % (pacman_path, name)
lrc, lstdout, lstderr = module.run_command(lcmd, check_rc=False)
if lrc != 0:
# package is not installed locally
return False, False, False
else:
# a non-zero exit code doesn't always mean the package is installed
# for example, if the package name queried is "provided" by another package
installed_name = get_name(module, lstdout)
if installed_name != name:
if state == "present":
lcmd = "%s --query %s" % (pacman_path, name)
lrc, lstdout, lstderr = module.run_command(lcmd, check_rc=False)
if lrc != 0:
# package is not installed locally
return False, False, False
else:
# a non-zero exit code doesn't always mean the package is installed
# for example, if the package name queried is "provided" by another package
installed_name = get_name(module, lstdout)
if installed_name != name:
return False, False, False
# no need to check the repository if state is present or absent
# return False for package version check, because we didn't check it
if state == 'present' or state == 'absent':
return True, False, False
# get the version installed locally (if any)
lversion = get_version(lstdout)
# get the version installed locally (if any)
lversion = get_version(lstdout)
rcmd = "%s --sync --print-format \"%%n %%v\" %s" % (pacman_path, name)
rrc, rstdout, rstderr = module.run_command(rcmd, check_rc=False)
# get the version in the repository
rversion = get_version(rstdout)
rcmd = "%s --sync --print-format \"%%n %%v\" %s" % (pacman_path, name)
rrc, rstdout, rstderr = module.run_command(rcmd, check_rc=False)
# get the version in the repository
rversion = get_version(rstdout)
if rrc == 0:
# Return True to indicate that the package is installed locally, and the result of the version number comparison
# to determine if the package is up-to-date.
return True, (lversion == rversion), False
if rrc == 0:
# Return True to indicate that the package is installed locally, and the result of the version number comparison
# to determine if the package is up-to-date.
return True, (lversion == rversion), False
# package is installed but cannot fetch remote Version. Last True stands for the error
return True, True, True
return True, True, True
def update_package_db(module, pacman_path):
@@ -296,7 +291,7 @@ def remove_packages(module, pacman_path, packages):
# Using a for loop in case of error, we can report the package that failed
for package in packages:
# Query the package first, to see if we even need to remove
installed, updated, unknown = query_package(module, pacman_path, package, 'absent')
installed, updated, unknown = query_package(module, pacman_path, package)
if not installed:
continue
@@ -335,7 +330,7 @@ def install_packages(module, pacman_path, state, packages, package_files):
to_install_files = []
for i, package in enumerate(packages):
# if the package is installed and state == present or state == latest and is up-to-date then skip
installed, updated, latestError = query_package(module, pacman_path, package, state)
installed, updated, latestError = query_package(module, pacman_path, package)
if latestError and state == 'latest':
package_err.append(package)
@@ -404,7 +399,7 @@ def check_packages(module, pacman_path, packages, state):
}
for package in packages:
installed, updated, unknown = query_package(module, pacman_path, package, state)
installed, updated, unknown = query_package(module, pacman_path, package)
if ((state in ["present", "latest"] and not installed) or
(state == "absent" and installed) or
(state == "latest" and not updated)):

View File

@@ -50,14 +50,13 @@ options:
default: no
annotation:
description:
- A list of keyvalue-pairs of the form
- A comma-separated list of keyvalue-pairs of the form
C(<+/-/:><key>[=<value>]). A C(+) denotes adding an annotation, a
C(-) denotes removing an annotation, and C(:) denotes modifying an
annotation.
If setting or modifying annotations, a value must be provided.
required: false
type: list
elements: str
type: str
pkgsite:
description:
- For pkgng versions before 1.1.4, specify packagesite to use
@@ -114,16 +113,12 @@ EXAMPLES = '''
- name: Annotate package foo and bar
community.general.pkgng:
name:
- foo
- bar
name: foo,bar
annotation: '+test1=baz,-test2,:test3=foobar'
- name: Remove packages foo and bar
community.general.pkgng:
name:
- foo
- bar
name: foo,bar
state: absent
# "latest" support added in 2.7
@@ -144,9 +139,9 @@ import re
from ansible.module_utils.basic import AnsibleModule
def query_package(module, run_pkgng, name):
def query_package(module, pkgng_path, name, dir_arg):
rc, out, err = run_pkgng('info', '-g', '-e', name)
rc, out, err = module.run_command("%s %s info -g -e %s" % (pkgng_path, dir_arg, name))
if rc == 0:
return True
@@ -154,12 +149,15 @@ def query_package(module, run_pkgng, name):
return False
def query_update(module, run_pkgng, name):
def query_update(module, pkgng_path, name, dir_arg, old_pkgng, pkgsite):
# Check to see if a package upgrade is available.
# rc = 0, no updates available or package not installed
# rc = 1, updates available
rc, out, err = run_pkgng('upgrade', '-g', '-n', name)
if old_pkgng:
rc, out, err = module.run_command("%s %s upgrade -g -n %s" % (pkgsite, pkgng_path, name))
else:
rc, out, err = module.run_command("%s %s upgrade %s -g -n %s" % (pkgng_path, dir_arg, pkgsite, name))
if rc == 1:
return True
@@ -169,7 +167,7 @@ def query_update(module, run_pkgng, name):
def pkgng_older_than(module, pkgng_path, compare_version):
rc, out, err = module.run_command([pkgng_path, '-v'])
rc, out, err = module.run_command("%s -v" % pkgng_path)
version = [int(x) for x in re.split(r'[\._]', out)]
i = 0
@@ -184,39 +182,40 @@ def pkgng_older_than(module, pkgng_path, compare_version):
return not new_pkgng
def upgrade_packages(module, run_pkgng):
def upgrade_packages(module, pkgng_path, dir_arg):
# Run a 'pkg upgrade', updating all packages.
upgraded_c = 0
pkgng_args = ['upgrade']
pkgng_args.append('-n' if module.check_mode else '-y')
rc, out, err = run_pkgng(*pkgng_args)
cmd = "%s %s upgrade -y" % (pkgng_path, dir_arg)
if module.check_mode:
cmd += " -n"
rc, out, err = module.run_command(cmd)
matches = re.findall('^Number of packages to be (?:upgraded|reinstalled): ([0-9]+)', out, re.MULTILINE)
for match in matches:
upgraded_c += int(match)
match = re.search('^Number of packages to be upgraded: ([0-9]+)', out, re.MULTILINE)
if match:
upgraded_c = int(match.group(1))
if upgraded_c > 0:
return (True, "updated %s package(s)" % upgraded_c, out, err)
return (False, "no packages need upgrades", out, err)
def remove_packages(module, run_pkgng, packages):
def remove_packages(module, pkgng_path, packages, dir_arg):
remove_c = 0
stdout = ""
stderr = ""
# Using a for loop in case of error, we can report the package that failed
for package in packages:
# Query the package first, to see if we even need to remove
if not query_package(module, run_pkgng, package):
if not query_package(module, pkgng_path, package, dir_arg):
continue
if not module.check_mode:
rc, out, err = run_pkgng('delete', '-y', package)
rc, out, err = module.run_command("%s %s delete -y %s" % (pkgng_path, dir_arg, package))
stdout += out
stderr += err
if not module.check_mode and query_package(module, run_pkgng, package):
if not module.check_mode and query_package(module, pkgng_path, package, dir_arg):
module.fail_json(msg="failed to remove %s: %s" % (package, out), stdout=stdout, stderr=stderr)
remove_c += 1
@@ -227,27 +226,48 @@ def remove_packages(module, run_pkgng, packages):
return (False, "package(s) already absent", stdout, stderr)
def install_packages(module, run_pkgng, packages, cached, state):
def install_packages(module, pkgng_path, packages, cached, pkgsite, dir_arg, state, ignoreosver):
action_queue = defaultdict(list)
action_count = defaultdict(int)
stdout = ""
stderr = ""
# as of pkg-1.1.4, PACKAGESITE is deprecated in favor of repository definitions
# in /usr/local/etc/pkg/repos
old_pkgng = pkgng_older_than(module, pkgng_path, [1, 1, 4])
if pkgsite != "":
if old_pkgng:
pkgsite = "PACKAGESITE=%s" % (pkgsite)
else:
pkgsite = "-r %s" % (pkgsite)
# This environment variable skips mid-install prompts,
# setting them to their default values.
batch_var = 'env BATCH=yes'
if ignoreosver:
# Ignore FreeBSD OS version check,
# useful on -STABLE and -CURRENT branches.
batch_var = batch_var + ' IGNORE_OSVERSION=yes'
if not module.check_mode and not cached:
rc, out, err = run_pkgng('update')
if old_pkgng:
rc, out, err = module.run_command("%s %s update" % (pkgsite, pkgng_path))
else:
rc, out, err = module.run_command("%s %s %s update" % (batch_var, pkgng_path, dir_arg))
stdout += out
stderr += err
if rc != 0:
module.fail_json(msg="Could not update catalogue [%d]: %s %s" % (rc, out, err), stdout=stdout, stderr=stderr)
for package in packages:
already_installed = query_package(module, run_pkgng, package)
already_installed = query_package(module, pkgng_path, package, dir_arg)
if already_installed and state == "present":
continue
if (
already_installed and state == "latest"
and not query_update(module, run_pkgng, package)
and not query_update(module, pkgng_path, package, dir_arg, old_pkgng, pkgsite)
):
continue
@@ -256,32 +276,29 @@ def install_packages(module, run_pkgng, packages, cached, state):
else:
action_queue["install"].append(package)
# install/upgrade all named packages with one pkg command
for (action, package_list) in action_queue.items():
if module.check_mode:
# Do nothing, but count up how many actions
# would be performed so that the changed/msg
# is correct.
action_count[action] += len(package_list)
continue
pkgng_args = [action, '-g', '-U', '-y'] + package_list
rc, out, err = run_pkgng(*pkgng_args)
stdout += out
stderr += err
# individually verify packages are in requested state
for package in package_list:
verified = False
if action == 'install':
verified = query_package(module, run_pkgng, package)
elif action == 'upgrade':
verified = not query_update(module, run_pkgng, package)
if verified:
action_count[action] += 1
if not module.check_mode:
# install/upgrade all named packages with one pkg command
for (action, package_list) in action_queue.items():
packages = ' '.join(package_list)
if old_pkgng:
rc, out, err = module.run_command("%s %s %s %s -g -U -y %s" % (batch_var, pkgsite, pkgng_path, action, packages))
else:
module.fail_json(msg="failed to %s %s" % (action, package), stdout=stdout, stderr=stderr)
rc, out, err = module.run_command("%s %s %s %s %s -g -U -y %s" % (batch_var, pkgng_path, dir_arg, action, pkgsite, packages))
stdout += out
stderr += err
# individually verify packages are in requested state
for package in package_list:
verified = False
if action == 'install':
verified = query_package(module, pkgng_path, package, dir_arg)
elif action == 'upgrade':
verified = not query_update(module, pkgng_path, package, dir_arg, old_pkgng, pkgsite)
if verified:
action_count[action] += 1
else:
module.fail_json(msg="failed to %s %s" % (action, package), stdout=stdout, stderr=stderr)
if sum(action_count.values()) > 0:
past_tense = {'install': 'installed', 'upgrade': 'upgraded'}
@@ -294,28 +311,28 @@ def install_packages(module, run_pkgng, packages, cached, state):
return (False, "package(s) already %s" % (state), stdout, stderr)
def annotation_query(module, run_pkgng, package, tag):
rc, out, err = run_pkgng('info', '-g', '-A', package)
def annotation_query(module, pkgng_path, package, tag, dir_arg):
rc, out, err = module.run_command("%s %s info -g -A %s" % (pkgng_path, dir_arg, package))
match = re.search(r'^\s*(?P<tag>%s)\s*:\s*(?P<value>\w+)' % tag, out, flags=re.MULTILINE)
if match:
return match.group('value')
return False
def annotation_add(module, run_pkgng, package, tag, value):
_value = annotation_query(module, run_pkgng, package, tag)
def annotation_add(module, pkgng_path, package, tag, value, dir_arg):
_value = annotation_query(module, pkgng_path, package, tag, dir_arg)
if not _value:
# Annotation does not exist, add it.
if not module.check_mode:
rc, out, err = run_pkgng('annotate', '-y', '-A', package, tag, data=value, binary_data=True)
if rc != 0:
module.fail_json(msg="could not annotate %s: %s"
% (package, out), stderr=err)
rc, out, err = module.run_command('%s %s annotate -y -A %s %s "%s"'
% (pkgng_path, dir_arg, package, tag, value))
if rc != 0:
module.fail_json(msg="could not annotate %s: %s"
% (package, out), stderr=err)
return True
elif _value != value:
# Annotation exists, but value differs
module.fail_json(
msg="failed to annotate %s, because %s is already set to %s, but should be set to %s"
mgs="failed to annotate %s, because %s is already set to %s, but should be set to %s"
% (package, tag, _value, value))
return False
else:
@@ -323,21 +340,21 @@ def annotation_add(module, run_pkgng, package, tag, value):
return False
def annotation_delete(module, run_pkgng, package, tag, value):
_value = annotation_query(module, run_pkgng, package, tag)
def annotation_delete(module, pkgng_path, package, tag, value, dir_arg):
_value = annotation_query(module, pkgng_path, package, tag, dir_arg)
if _value:
if not module.check_mode:
rc, out, err = run_pkgng('annotate', '-y', '-D', package, tag)
if rc != 0:
module.fail_json(msg="could not delete annotation to %s: %s"
% (package, out), stderr=err)
rc, out, err = module.run_command('%s %s annotate -y -D %s %s'
% (pkgng_path, dir_arg, package, tag))
if rc != 0:
module.fail_json(msg="could not delete annotation to %s: %s"
% (package, out), stderr=err)
return True
return False
def annotation_modify(module, run_pkgng, package, tag, value):
_value = annotation_query(module, run_pkgng, package, tag)
if not _value:
def annotation_modify(module, pkgng_path, package, tag, value, dir_arg):
_value = annotation_query(module, pkgng_path, package, tag, dir_arg)
if not value:
# No such tag
module.fail_json(msg="could not change annotation to %s: tag %s does not exist"
% (package, tag))
@@ -345,27 +362,20 @@ def annotation_modify(module, run_pkgng, package, tag, value):
# No change in value
return False
else:
if not module.check_mode:
rc, out, err = run_pkgng('annotate', '-y', '-M', package, tag, data=value, binary_data=True)
# pkg sometimes exits with rc == 1, even though the modification succeeded
# Check the output for a success message
if (
rc != 0
and re.search(r'^%s-[^:]+: Modified annotation tagged: %s' % (package, tag), out, flags=re.MULTILINE) is None
):
module.fail_json(msg="failed to annotate %s, could not change annotation %s to %s: %s"
% (package, tag, value, out), stderr=err)
rc, out, err = module.run_command('%s %s annotate -y -M %s %s "%s"'
% (pkgng_path, dir_arg, package, tag, value))
if rc != 0:
module.fail_json(msg="could not change annotation annotation to %s: %s"
% (package, out), stderr=err)
return True
def annotate_packages(module, run_pkgng, packages, annotations):
def annotate_packages(module, pkgng_path, packages, annotation, dir_arg):
annotate_c = 0
if len(annotations) == 1:
# Split on commas with optional trailing whitespace,
# to support the old style of multiple annotations
# on a single line, rather than YAML list syntax
annotations = re.split(r'\s*,\s*', annotations[0])
annotations = map(lambda _annotation:
re.match(r'(?P<operation>[\+-:])(?P<tag>\w+)(=(?P<value>\w+))?',
_annotation).groupdict(),
re.split(r',', annotation))
operation = {
'+': annotation_add,
@@ -374,21 +384,8 @@ def annotate_packages(module, run_pkgng, packages, annotations):
}
for package in packages:
for annotation_string in annotations:
# Note to future maintainers: A dash (-) in a regex character class ([-+:] below)
# must appear as the first character in the class, or it will be interpreted
# as a range of characters.
annotation = \
re.match(r'(?P<operation>[-+:])(?P<tag>[^=]+)(=(?P<value>.+))?', annotation_string)
if annotation is None:
module.fail_json(
msg="failed to annotate %s, invalid annotate string: %s"
% (package, annotation_string)
)
annotation = annotation.groupdict()
if operation[annotation['operation']](module, run_pkgng, package, annotation['tag'], annotation['value']):
for _annotation in annotations:
if operation[_annotation['operation']](module, pkgng_path, package, _annotation['tag'], _annotation['value']):
annotate_c += 1
if annotate_c > 0:
@@ -396,10 +393,10 @@ def annotate_packages(module, run_pkgng, packages, annotations):
return (False, "changed no annotations")
def autoremove_packages(module, run_pkgng):
def autoremove_packages(module, pkgng_path, dir_arg):
stdout = ""
stderr = ""
rc, out, err = run_pkgng('autoremove', '-n')
rc, out, err = module.run_command("%s %s autoremove -n" % (pkgng_path, dir_arg))
autoremove_c = 0
@@ -411,7 +408,7 @@ def autoremove_packages(module, run_pkgng):
return (False, "no package(s) to autoremove", stdout, stderr)
if not module.check_mode:
rc, out, err = run_pkgng('autoremove', '-y')
rc, out, err = module.run_command("%s %s autoremove -y" % (pkgng_path, dir_arg))
stdout += out
stderr += err
@@ -425,11 +422,11 @@ def main():
name=dict(aliases=["pkg"], required=True, type='list', elements='str'),
cached=dict(default=False, type='bool'),
ignore_osver=dict(default=False, required=False, type='bool'),
annotation=dict(required=False, type='list', elements='str'),
pkgsite=dict(required=False),
rootdir=dict(required=False, type='path'),
chroot=dict(required=False, type='path'),
jail=dict(required=False, type='str'),
annotation=dict(default="", required=False),
pkgsite=dict(default="", required=False),
rootdir=dict(default="", required=False, type='path'),
chroot=dict(default="", required=False, type='path'),
jail=dict(default="", required=False, type='str'),
autoremove=dict(default=False, type='bool')),
supports_check_mode=True,
mutually_exclusive=[["rootdir", "chroot", "jail"]])
@@ -444,90 +441,61 @@ def main():
msgs = []
stdout = ""
stderr = ""
dir_arg = None
dir_arg = ""
if p["rootdir"] is not None:
rootdir_not_supported = pkgng_older_than(module, pkgng_path, [1, 5, 0])
if rootdir_not_supported:
if p["rootdir"] != "":
old_pkgng = pkgng_older_than(module, pkgng_path, [1, 5, 0])
if old_pkgng:
module.fail_json(msg="To use option 'rootdir' pkg version must be 1.5 or greater")
else:
dir_arg = "--rootdir=%s" % (p["rootdir"])
dir_arg = "--rootdir %s" % (p["rootdir"])
if p["ignore_osver"]:
ignore_osver_not_supported = pkgng_older_than(module, pkgng_path, [1, 11, 0])
if ignore_osver_not_supported:
old_pkgng = pkgng_older_than(module, pkgng_path, [1, 11, 0])
if old_pkgng:
module.fail_json(msg="To use option 'ignore_osver' pkg version must be 1.11 or greater")
if p["chroot"] is not None:
dir_arg = '--chroot=%s' % (p["chroot"])
if p["chroot"] != "":
dir_arg = '--chroot %s' % (p["chroot"])
if p["jail"] is not None:
dir_arg = '--jail=%s' % (p["jail"])
# as of pkg-1.1.4, PACKAGESITE is deprecated in favor of repository definitions
# in /usr/local/etc/pkg/repos
repo_flag_not_supported = pkgng_older_than(module, pkgng_path, [1, 1, 4])
def run_pkgng(action, *args, **kwargs):
cmd = [pkgng_path, dir_arg, action]
pkgng_env = {'BATCH': 'yes'}
if p["ignore_osver"]:
pkgng_env['IGNORE_OSVERSION'] = 'yes'
if p['pkgsite'] is not None and action in ('update', 'install', 'upgrade',):
if repo_flag_not_supported:
pkgng_env['PACKAGESITE'] = p['pkgsite']
else:
cmd.append('--repository=%s' % (p['pkgsite'],))
# If environ_update is specified to be "passed through"
# to module.run_command, then merge its values into pkgng_env
pkgng_env.update(kwargs.pop('environ_update', dict()))
return module.run_command(cmd + list(args), environ_update=pkgng_env, **kwargs)
if p["jail"] != "":
dir_arg = '--jail %s' % (p["jail"])
if pkgs == ['*'] and p["state"] == 'latest':
# Operate on all installed packages. Only state: latest makes sense here.
_changed, _msg, _stdout, _stderr = upgrade_packages(module, run_pkgng)
_changed, _msg, _stdout, _stderr = upgrade_packages(module, pkgng_path, dir_arg)
changed = changed or _changed
stdout += _stdout
stderr += _stderr
msgs.append(_msg)
# Operate on named packages
if len(pkgs) == 1:
# The documentation used to show multiple packages specified in one line
# with comma or space delimiters. That doesn't result in a YAML list, and
# wrong actions (install vs upgrade) can be reported if those
# comma- or space-delimited strings make it to the pkg command line.
pkgs = re.split(r'[,\s]', pkgs[0])
named_packages = [pkg for pkg in pkgs if pkg != '*']
if p["state"] in ("present", "latest") and named_packages:
_changed, _msg, _out, _err = install_packages(module, run_pkgng, named_packages,
p["cached"], p["state"])
_changed, _msg, _out, _err = install_packages(module, pkgng_path, named_packages,
p["cached"], p["pkgsite"], dir_arg,
p["state"], p["ignore_osver"])
stdout += _out
stderr += _err
changed = changed or _changed
msgs.append(_msg)
elif p["state"] == "absent" and named_packages:
_changed, _msg, _out, _err = remove_packages(module, run_pkgng, named_packages)
_changed, _msg, _out, _err = remove_packages(module, pkgng_path, named_packages, dir_arg)
stdout += _out
stderr += _err
changed = changed or _changed
msgs.append(_msg)
if p["autoremove"]:
_changed, _msg, _stdout, _stderr = autoremove_packages(module, run_pkgng)
_changed, _msg, _stdout, _stderr = autoremove_packages(module, pkgng_path, dir_arg)
changed = changed or _changed
stdout += _stdout
stderr += _stderr
msgs.append(_msg)
if p["annotation"] is not None:
_changed, _msg = annotate_packages(module, run_pkgng, pkgs, p["annotation"])
if p["annotation"]:
_changed, _msg = annotate_packages(module, pkgng_path, pkgs, p["annotation"], dir_arg)
changed = changed or _changed
msgs.append(_msg)

View File

@@ -50,9 +50,6 @@ options:
author:
- Victor Carceler (@vcarceler) <vcarceler@iespuigcastellar.xeill.net>
- Stanislas Lange (@angristan) <angristan@pm.me>
seealso:
- module: community.general.snap_alias
'''
EXAMPLES = '''

View File

@@ -1,179 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright: (c) 2021, Alexei Znamensky (russoz) <russoz@gmail.com>
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: snap_alias
short_description: Manages snap aliases
version_added: 4.0.0
description:
- "Manages snaps aliases."
options:
state:
description:
- Desired state of the alias.
type: str
choices: [ absent, present ]
default: present
name:
description:
- Name of the snap.
type: str
alias:
description:
- Aliases to be created or removed.
type: list
elements: str
aliases: [aliases]
author:
- Alexei Znamensky (@russoz) <russoz@gmail.com>
seealso:
- module: community.general.snap
'''
EXAMPLES = '''
# Install "foo" and "bar" snap
- name: Create snap alias
community.general.snap_alias:
name: hello-world
alias: hw
- name: Create multiple aliases
community.general.snap_alias:
name: hello-world
aliases:
- hw
- hw2
- hw3
state: present # optional
- name: Remove one specific aliases
community.general.snap_alias:
name: hw
state: absent
- name: Remove all aliases for snap
community.general.snap_alias:
name: hello-world
state: absent
'''
RETURN = '''
snap_aliases:
description: The snap aliases after execution. If called in check mode, then the list represents the state before execution.
type: list
elements: str
returned: always
'''
import re
from ansible_collections.community.general.plugins.module_utils.module_helper import (
CmdStateModuleHelper
)
_state_map = dict(
present='alias',
absent='unalias',
info='aliases',
)
class SnapAlias(CmdStateModuleHelper):
_RE_ALIAS_LIST = re.compile(r"^(?P<snap>[\w-]+)\s+(?P<alias>[\w-]+)\s+.*$")
module = dict(
argument_spec={
'state': dict(type='str', choices=['absent', 'present'], default='present'),
'name': dict(type='str'),
'alias': dict(type='list', elements='str', aliases=['aliases']),
},
required_if=[
('state', 'present', ['name', 'alias']),
('state', 'absent', ['name', 'alias'], True),
],
supports_check_mode=True,
)
command = "snap"
command_args_formats = dict(
_alias=dict(fmt=lambda v: [v]),
state=dict(fmt=lambda v: [_state_map[v]]),
)
check_rc = False
def _aliases(self):
n = self.vars.name
return {n: self._get_aliases_for(n)} if n else self._get_aliases()
def __init_module__(self):
self.vars.set("snap_aliases", self._aliases(), change=True, diff=True)
def __quit_module__(self):
self.vars.snap_aliases = self._aliases()
def _get_aliases(self):
def process_get_aliases(rc, out, err):
if err:
return {}
aliases = [self._RE_ALIAS_LIST.match(a.strip()) for a in out.splitlines()[1:]]
snap_alias_list = [(entry.group("snap"), entry.group("alias")) for entry in aliases]
results = {}
for snap, alias in snap_alias_list:
results[snap] = results.get(snap, []) + [alias]
return results
return self.run_command(params=[{'state': 'info'}, 'name'], check_rc=True,
publish_rc=False, publish_out=False, publish_err=False, publish_cmd=False,
process_output=process_get_aliases)
def _get_aliases_for(self, name):
return self._get_aliases().get(name, [])
def _has_alias(self, name=None, alias=None):
if name:
if name not in self.vars.snap_aliases:
return False
if alias is None:
return bool(self.vars.snap_aliases[name])
return alias in self.vars.snap_aliases[name]
return any(alias in aliases for aliases in self.vars.snap_aliases.values())
def state_present(self):
for alias in self.vars.alias:
if not self._has_alias(self.vars.name, alias):
self.changed = True
if not self.module.check_mode:
self.run_command(params=['state', 'name', {'_alias': alias}])
def state_absent(self):
if not self.vars.alias:
if self._has_alias(self.vars.name):
self.changed = True
if not self.module.check_mode:
self.run_command(params=['state', 'name'])
else:
for alias in self.vars.alias:
if self._has_alias(self.vars.name, alias):
self.changed = True
if not self.module.check_mode:
self.run_command(params=['state', {'_alias': alias}])
def main():
SnapAlias.execute()
if __name__ == '__main__':
main()

View File

@@ -1 +0,0 @@
./database/misc/redis_data_incr.py

View File

@@ -1 +0,0 @@
packaging/os/snap_alias.py

View File

@@ -15,21 +15,27 @@ description:
- Manages Bitbucket repository access keys (also called deploy keys).
author:
- Evgeniy Krysanov (@catcombo)
extends_documentation_fragment:
- community.general.bitbucket
options:
client_id:
description:
- The OAuth consumer key.
- If not set the environment variable C(BITBUCKET_CLIENT_ID) will be used.
type: str
client_secret:
description:
- The OAuth consumer secret.
- If not set the environment variable C(BITBUCKET_CLIENT_SECRET) will be used.
type: str
repository:
description:
- The repository name.
type: str
required: true
workspace:
username:
description:
- The repository owner.
- Alias I(username) has been deprecated and will become an alias of I(user) in community.general 6.0.0.
type: str
required: true
aliases: [ username ]
key:
description:
- The SSH public key.
@@ -46,7 +52,8 @@ options:
required: true
choices: [ absent, present ]
notes:
- Bitbucket OAuth consumer or App password should have permissions to read and administrate account repositories.
- Bitbucket OAuth consumer key and secret can be obtained from Bitbucket profile -> Settings -> Access Management -> OAuth.
- Bitbucket OAuth consumer should have permissions to read and administrate account repositories.
- Check mode is supported.
'''
@@ -54,7 +61,7 @@ EXAMPLES = r'''
- name: Create access key
community.general.bitbucket_access_key:
repository: 'bitbucket-repo'
workspace: bitbucket_workspace
username: bitbucket_username
key: '{{lookup("file", "bitbucket.pub") }}'
label: 'Bitbucket'
state: present
@@ -62,7 +69,7 @@ EXAMPLES = r'''
- name: Delete access key
community.general.bitbucket_access_key:
repository: bitbucket-repo
workspace: bitbucket_workspace
username: bitbucket_username
label: Bitbucket
state: absent
'''
@@ -75,13 +82,13 @@ from ansible_collections.community.general.plugins.module_utils.source_control.b
error_messages = {
'required_key': '`key` is required when the `state` is `present`',
'required_permission': 'OAuth consumer `client_id` should have permissions to read and administrate the repository',
'invalid_workspace_or_repo': 'Invalid `repository` or `workspace`',
'invalid_username_or_repo': 'Invalid `repository` or `username`',
'invalid_key': 'Invalid SSH key or key is already in use',
}
BITBUCKET_API_ENDPOINTS = {
'deploy-key-list': '%s/2.0/repositories/{workspace}/{repo_slug}/deploy-keys/' % BitbucketHelper.BITBUCKET_API_URL,
'deploy-key-detail': '%s/2.0/repositories/{workspace}/{repo_slug}/deploy-keys/{key_id}' % BitbucketHelper.BITBUCKET_API_URL,
'deploy-key-list': '%s/2.0/repositories/{username}/{repo_slug}/deploy-keys/' % BitbucketHelper.BITBUCKET_API_URL,
'deploy-key-detail': '%s/2.0/repositories/{username}/{repo_slug}/deploy-keys/{key_id}' % BitbucketHelper.BITBUCKET_API_URL,
}
@@ -131,7 +138,7 @@ def get_existing_deploy_key(module, bitbucket):
"""
content = {
'next': BITBUCKET_API_ENDPOINTS['deploy-key-list'].format(
workspace=module.params['workspace'],
username=module.params['username'],
repo_slug=module.params['repository'],
)
}
@@ -144,7 +151,7 @@ def get_existing_deploy_key(module, bitbucket):
)
if info['status'] == 404:
module.fail_json(msg=error_messages['invalid_workspace_or_repo'])
module.fail_json(msg=error_messages['invalid_username_or_repo'])
if info['status'] == 403:
module.fail_json(msg=error_messages['required_permission'])
@@ -163,7 +170,7 @@ def get_existing_deploy_key(module, bitbucket):
def create_deploy_key(module, bitbucket):
info, content = bitbucket.request(
api_url=BITBUCKET_API_ENDPOINTS['deploy-key-list'].format(
workspace=module.params['workspace'],
username=module.params['username'],
repo_slug=module.params['repository'],
),
method='POST',
@@ -174,7 +181,7 @@ def create_deploy_key(module, bitbucket):
)
if info['status'] == 404:
module.fail_json(msg=error_messages['invalid_workspace_or_repo'])
module.fail_json(msg=error_messages['invalid_username_or_repo'])
if info['status'] == 403:
module.fail_json(msg=error_messages['required_permission'])
@@ -192,7 +199,7 @@ def create_deploy_key(module, bitbucket):
def delete_deploy_key(module, bitbucket, key_id):
info, content = bitbucket.request(
api_url=BITBUCKET_API_ENDPOINTS['deploy-key-detail'].format(
workspace=module.params['workspace'],
username=module.params['username'],
repo_slug=module.params['repository'],
key_id=key_id,
),
@@ -200,7 +207,7 @@ def delete_deploy_key(module, bitbucket, key_id):
)
if info['status'] == 404:
module.fail_json(msg=error_messages['invalid_workspace_or_repo'])
module.fail_json(msg=error_messages['invalid_username_or_repo'])
if info['status'] == 403:
module.fail_json(msg=error_messages['required_permission'])
@@ -216,10 +223,7 @@ def main():
argument_spec = BitbucketHelper.bitbucket_argument_spec()
argument_spec.update(
repository=dict(type='str', required=True),
workspace=dict(
type='str', aliases=['username'], required=True,
deprecated_aliases=[dict(name='username', version='6.0.0', collection_name='community.general')],
),
username=dict(type='str', required=True),
key=dict(type='str', no_log=False),
label=dict(type='str', required=True),
state=dict(type='str', choices=['present', 'absent'], required=True),
@@ -227,8 +231,6 @@ def main():
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
required_one_of=BitbucketHelper.bitbucket_required_one_of(),
required_together=BitbucketHelper.bitbucket_required_together(),
)
bitbucket = BitbucketHelper(module)

View File

@@ -15,21 +15,27 @@ description:
- Manages Bitbucket pipeline SSH key pair.
author:
- Evgeniy Krysanov (@catcombo)
extends_documentation_fragment:
- community.general.bitbucket
options:
client_id:
description:
- OAuth consumer key.
- If not set the environment variable C(BITBUCKET_CLIENT_ID) will be used.
type: str
client_secret:
description:
- OAuth consumer secret.
- If not set the environment variable C(BITBUCKET_CLIENT_SECRET) will be used.
type: str
repository:
description:
- The repository name.
type: str
required: true
workspace:
username:
description:
- The repository owner.
- Alias I(username) has been deprecated and will become an alias of I(user) in community.general 6.0.0.
type: str
required: true
aliases: [ username ]
public_key:
description:
- The public key.
@@ -45,6 +51,7 @@ options:
required: true
choices: [ absent, present ]
notes:
- Bitbucket OAuth consumer key and secret can be obtained from Bitbucket profile -> Settings -> Access Management -> OAuth.
- Check mode is supported.
'''
@@ -52,7 +59,7 @@ EXAMPLES = r'''
- name: Create or update SSH key pair
community.general.bitbucket_pipeline_key_pair:
repository: 'bitbucket-repo'
workspace: bitbucket_workspace
username: bitbucket_username
public_key: '{{lookup("file", "bitbucket.pub") }}'
private_key: '{{lookup("file", "bitbucket") }}'
state: present
@@ -60,7 +67,7 @@ EXAMPLES = r'''
- name: Remove SSH key pair
community.general.bitbucket_pipeline_key_pair:
repository: bitbucket-repo
workspace: bitbucket_workspace
username: bitbucket_username
state: absent
'''
@@ -75,7 +82,7 @@ error_messages = {
}
BITBUCKET_API_ENDPOINTS = {
'ssh-key-pair': '%s/2.0/repositories/{workspace}/{repo_slug}/pipelines_config/ssh/key_pair' % BitbucketHelper.BITBUCKET_API_URL,
'ssh-key-pair': '%s/2.0/repositories/{username}/{repo_slug}/pipelines_config/ssh/key_pair' % BitbucketHelper.BITBUCKET_API_URL,
}
@@ -97,7 +104,7 @@ def get_existing_ssh_key_pair(module, bitbucket):
}
"""
api_url = BITBUCKET_API_ENDPOINTS['ssh-key-pair'].format(
workspace=module.params['workspace'],
username=module.params['username'],
repo_slug=module.params['repository'],
)
@@ -116,7 +123,7 @@ def get_existing_ssh_key_pair(module, bitbucket):
def update_ssh_key_pair(module, bitbucket):
info, content = bitbucket.request(
api_url=BITBUCKET_API_ENDPOINTS['ssh-key-pair'].format(
workspace=module.params['workspace'],
username=module.params['username'],
repo_slug=module.params['repository'],
),
method='PUT',
@@ -136,7 +143,7 @@ def update_ssh_key_pair(module, bitbucket):
def delete_ssh_key_pair(module, bitbucket):
info, content = bitbucket.request(
api_url=BITBUCKET_API_ENDPOINTS['ssh-key-pair'].format(
workspace=module.params['workspace'],
username=module.params['username'],
repo_slug=module.params['repository'],
),
method='DELETE',
@@ -153,10 +160,7 @@ def main():
argument_spec = BitbucketHelper.bitbucket_argument_spec()
argument_spec.update(
repository=dict(type='str', required=True),
workspace=dict(
type='str', aliases=['username'], required=True,
deprecated_aliases=[dict(name='username', version='6.0.0', collection_name='community.general')],
),
username=dict(type='str', required=True),
public_key=dict(type='str'),
private_key=dict(type='str', no_log=True),
state=dict(type='str', choices=['present', 'absent'], required=True),
@@ -164,8 +168,6 @@ def main():
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
required_one_of=BitbucketHelper.bitbucket_required_one_of(),
required_together=BitbucketHelper.bitbucket_required_together(),
)
bitbucket = BitbucketHelper(module)

Some files were not shown because too many files have changed in this diff Show More