From e9327a04641b35159815d9260bcb4d66e0c4d4e8 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 7 Nov 2022 21:45:57 +0100 Subject: [PATCH 001/134] Update links in README. --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 94d5b506ba..77888bdb7b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ SPDX-License-Identifier: GPL-3.0-or-later # Community General Collection -[![Build Status](https://dev.azure.com/ansible/community.general/_apis/build/status/CI?branchName=main)](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-6)](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. @@ -72,13 +72,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/main/CONTRIBUTING.md)! +You don't know how to start? Refer to our [contribution guide](https://github.com/ansible-collections/community.general/blob/stable-6/CONTRIBUTING.md)! -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. +The current maintainers are listed in the [commit-rights.md](https://github.com/ansible-collections/community.general/blob/stable-6/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/main/CONTRIBUTING.md). +Also for some notes specific to this collection see [our CONTRIBUTING documentation](https://github.com/ansible-collections/community.general/blob/stable-6/CONTRIBUTING.md). ### Running tests @@ -88,7 +88,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/main/commit-rights.md). +* [Committer guidelines](https://github.com/ansible-collections/community.general/blob/stable-6/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: @@ -116,7 +116,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/main/CHANGELOG.rst). +See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-6/CHANGELOG.rst). ## Roadmap @@ -135,8 +135,8 @@ See [this issue](https://github.com/ansible-collections/community.general/issues This collection is primarily licensed and distributed as a whole under the GNU General Public License v3.0 or later. -See [LICENSES/GPL-3.0-or-later.txt](https://github.com/ansible-collections/community.general/blob/main/COPYING) for the full text. +See [LICENSES/GPL-3.0-or-later.txt](https://github.com/ansible-collections/community.general/blob/stable-6/COPYING) for the full text. -Parts of the collection are licensed under the [BSD 2-Clause license](https://github.com/ansible-collections/community.general/blob/main/LICENSES/BSD-2-Clause.txt), the [MIT license](https://github.com/ansible-collections/community.general/blob/main/LICENSES/MIT.txt), and the [PSF 2.0 license](https://github.com/ansible-collections/community.general/blob/main/LICENSES/PSF-2.0.txt). +Parts of the collection are licensed under the [BSD 2-Clause license](https://github.com/ansible-collections/community.general/blob/stable-6/LICENSES/BSD-2-Clause.txt), the [MIT license](https://github.com/ansible-collections/community.general/blob/stable-6/LICENSES/MIT.txt), and the [PSF 2.0 license](https://github.com/ansible-collections/community.general/blob/stable-6/LICENSES/PSF-2.0.txt). All files have a machine readable `SDPX-License-Identifier:` comment denoting its respective license(s) or an equivalent entry in an accompanying `.license` file. Only changelog fragments (which will not be part of a release) are covered by a blanket statement in `.reuse/dep5`. This conforms to the [REUSE specification](https://reuse.software/spec/). From cd26aec2f3e80d07f4d6124e126b12de82afbd05 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 7 Nov 2022 21:46:12 +0100 Subject: [PATCH 002/134] Add missing new modules and plugins to 6.0.0-a1 release changelog. --- CHANGELOG.rst | 27 +++++++++++++++++++ changelogs/changelog.yaml | 55 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3b83faa551..faf91518bf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -229,8 +229,35 @@ Bugfixes - xfconf - fix setting of boolean values (https://github.com/ansible-collections/community.general/issues/4999, https://github.com/ansible-collections/community.general/pull/5007). - zfs - fix wrong quoting of properties (https://github.com/ansible-collections/community.general/issues/4707, https://github.com/ansible-collections/community.general/pull/4726). +New Plugins +----------- + +Filter +~~~~~~ + +- counter - Counts hashable elements in a sequence + +Lookup +~~~~~~ + +- bitwarden - Retrieve secrets from Bitwarden + New Modules ----------- +- gconftool2_info - Retrieve GConf configurations +- iso_customize - Add/remove/change files in ISO file +- keycloak_user_rolemapping - Allows administration of Keycloak user_rolemapping with the Keycloak API +- keyring - Set or delete a passphrase using the Operating System's native keyring +- keyring_info - Get a passphrase using the Operating System's native keyring +- manageiq_policies_info - Listing of resource policy_profiles in ManageIQ +- manageiq_tags_info - Retrieve resource tags in ManageIQ +- pipx_info - Rretrieves information about applications installed with pipx +- proxmox_disk - Management of a disk of a Qemu(KVM) VM in a Proxmox VE cluster. +- scaleway_compute_private_network - Scaleway compute - private network management +- scaleway_container_registry - Scaleway Container registry management module +- scaleway_container_registry_info - Scaleway Container registry info module - scaleway_function_namespace - Scaleway Function namespace management - scaleway_function_namespace_info - Retrieve information on Scaleway Function namespace +- wdc_redfish_command - Manages WDC UltraStar Data102 Out-Of-Band controllers using Redfish APIs +- wdc_redfish_info - Manages WDC UltraStar Data102 Out-Of-Band controllers using Redfish APIs diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index b5612b7ccc..d1db00d3ad 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -514,4 +514,59 @@ releases: - description: Retrieve information on Scaleway Function namespace name: scaleway_function_namespace_info namespace: '' + - description: Retrieve GConf configurations + name: gconftool2_info + namespace: '' + - description: Set or delete a passphrase using the Operating System's native + keyring + name: keyring + namespace: '' + - description: Get a passphrase using the Operating System's native keyring + name: keyring_info + namespace: '' + - description: Scaleway compute - private network management + name: scaleway_compute_private_network + namespace: '' + - description: Manages WDC UltraStar Data102 Out-Of-Band controllers using Redfish + APIs + name: wdc_redfish_command + namespace: '' + - description: Manages WDC UltraStar Data102 Out-Of-Band controllers using Redfish + APIs + name: wdc_redfish_info + namespace: '' + - description: Rretrieves information about applications installed with pipx + name: pipx_info + namespace: '' + - description: Allows administration of Keycloak user_rolemapping with the Keycloak + API + name: keycloak_user_rolemapping + namespace: '' + - description: Management of a disk of a Qemu(KVM) VM in a Proxmox VE cluster. + name: proxmox_disk + namespace: '' + - description: Add/remove/change files in ISO file + name: iso_customize + namespace: '' + - description: Listing of resource policy_profiles in ManageIQ + name: manageiq_policies_info + namespace: '' + - description: Retrieve resource tags in ManageIQ + name: manageiq_tags_info + namespace: '' + - description: Scaleway Container registry management module + name: scaleway_container_registry + namespace: '' + - description: Scaleway Container registry info module + name: scaleway_container_registry_info + namespace: '' + plugins: + filter: + - description: Counts hashable elements in a sequence + name: counter + namespace: null + lookup: + - description: Retrieve secrets from Bitwarden + name: bitwarden + namespace: null release_date: '2022-11-02' From 9a676bb88ffe2bd9992c7c32581f251a9aba46bf Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 7 Nov 2022 21:48:17 +0100 Subject: [PATCH 003/134] Add missing changelog fragment for #5497. --- changelogs/fragments/5497-scaleway-filtering.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/5497-scaleway-filtering.yml diff --git a/changelogs/fragments/5497-scaleway-filtering.yml b/changelogs/fragments/5497-scaleway-filtering.yml new file mode 100644 index 0000000000..4fa125f312 --- /dev/null +++ b/changelogs/fragments/5497-scaleway-filtering.yml @@ -0,0 +1,2 @@ +breaking_changes: + - "scaleway_container_registry_info - no longer replace ``secret_environment_variables`` in the output by ``SENSITIVE_VALUE`` (https://github.com/ansible-collections/community.general/pull/5497)." From 42b245eabfa5774816ea962a0bd558831f101c23 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 7 Nov 2022 21:49:22 +0100 Subject: [PATCH 004/134] Release 6.0.0. --- CHANGELOG.rst | 22 +++- changelogs/changelog.yaml | 119 +++++++++++++----- changelogs/fragments/4728-onepassword-v2.yml | 2 - .../fragments/5435-escape-ldap-param.yml | 2 - .../5450-allow-for-xordered-dns.yaml | 2 - .../5468-iso-create-not-add-folders.yml | 2 - .../5475-snap-option-value-whitespace.yml | 2 - ...5477-ansible-galaxy-install-cmd-runner.yml | 2 - .../fragments/5483-hponcfg-cmd-runner.yml | 2 - .../fragments/5484-mksysb-cmd-runner.yml | 2 - .../fragments/5485-cpanm-cmd-runner.yml | 2 - .../fragments/5497-scaleway-filtering.yml | 2 - changelogs/fragments/6.0.0.yml | 3 - 13 files changed, 107 insertions(+), 57 deletions(-) delete mode 100644 changelogs/fragments/4728-onepassword-v2.yml delete mode 100644 changelogs/fragments/5435-escape-ldap-param.yml delete mode 100644 changelogs/fragments/5450-allow-for-xordered-dns.yaml delete mode 100644 changelogs/fragments/5468-iso-create-not-add-folders.yml delete mode 100644 changelogs/fragments/5475-snap-option-value-whitespace.yml delete mode 100644 changelogs/fragments/5477-ansible-galaxy-install-cmd-runner.yml delete mode 100644 changelogs/fragments/5483-hponcfg-cmd-runner.yml delete mode 100644 changelogs/fragments/5484-mksysb-cmd-runner.yml delete mode 100644 changelogs/fragments/5485-cpanm-cmd-runner.yml delete mode 100644 changelogs/fragments/5497-scaleway-filtering.yml delete mode 100644 changelogs/fragments/6.0.0.yml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index faf91518bf..b9b6680e96 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,13 +6,13 @@ Community General Release Notes This changelog describes changes after version 5.0.0. -v6.0.0-a1 -========= +v6.0.0 +====== Release Summary --------------- -This is a pre-release for the upcoming 6.0.0 major release. The main objective of this pre-release is to make it possible to test the large stuctural changes by flattening the directory structure. See the corresponding entry in the changelog for details. +New major release of community.general with lots of bugfixes, new features, some removed deprecated features, and some other breaking changes. Please check the coresponding sections of the changelog for more details. Major Changes ------------- @@ -33,6 +33,7 @@ Minor Changes - alternatives - add ``state=absent`` to be able to remove an alternative (https://github.com/ansible-collections/community.general/pull/4654). - alternatives - add ``subcommands`` parameter (https://github.com/ansible-collections/community.general/pull/4654). - ansible_galaxy_install - minor refactoring using latest ``ModuleHelper`` updates (https://github.com/ansible-collections/community.general/pull/4752). +- ansible_galaxy_install - refactored module to use ``CmdRunner`` to execute ``ansible-galaxy`` (https://github.com/ansible-collections/community.general/pull/5477). - apk - add ``world`` parameter for supporting a custom world file (https://github.com/ansible-collections/community.general/pull/4976). - bitwarden lookup plugin - add option ``search`` to search for other attributes than name (https://github.com/ansible-collections/community.general/pull/5297). - cartesian lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440). @@ -41,6 +42,7 @@ Minor Changes - consul - adds ``ttl`` parameter for session (https://github.com/ansible-collections/community.general/pull/4996). - consul - minor refactoring (https://github.com/ansible-collections/community.general/pull/5367). - consul_session - adds ``token`` parameter for session (https://github.com/ansible-collections/community.general/pull/5193). +- cpanm - refactored module to use ``CmdRunner`` to execute ``cpanm`` (https://github.com/ansible-collections/community.general/pull/5485). - cpanm - using ``do_raise()`` to raise exceptions in ``ModuleHelper`` derived modules (https://github.com/ansible-collections/community.general/pull/4674). - credstash lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440). - dependent lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440). @@ -65,9 +67,11 @@ Minor Changes - gitlab_user - minor refactor when checking for installed dependency (https://github.com/ansible-collections/community.general/pull/5259). - hiera lookup plugin - start using Ansible's configuration manager to parse options. The Hiera executable and config file can now also be passed as lookup parameters (https://github.com/ansible-collections/community.general/pull/5440). - homebrew, homebrew_tap - added Homebrew on Linux path to defaults (https://github.com/ansible-collections/community.general/pull/5241). +- hponcfg - refactored module to use ``CmdRunner`` to execute ``hponcfg`` (https://github.com/ansible-collections/community.general/pull/5483). - keycloak_* modules - add ``http_agent`` parameter with default value ``Ansible`` (https://github.com/ansible-collections/community.general/issues/5023). - keyring lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440). - lastpass - use config manager for handling plugin options (https://github.com/ansible-collections/community.general/pull/5022). +- ldap_attrs - allow for DNs to have ``{x}`` prefix on first RDN (https://github.com/ansible-collections/community.general/issues/977, https://github.com/ansible-collections/community.general/pull/5450). - linode inventory plugin - simplify option handling (https://github.com/ansible-collections/community.general/pull/5438). - listen_ports_facts - add new ``include_non_listening`` option which adds ``-a`` option to ``netstat`` and ``ss``. This shows both listening and non-listening (for TCP this means established connections) sockets, and returns ``state`` and ``foreign_address`` (https://github.com/ansible-collections/community.general/issues/4762, https://github.com/ansible-collections/community.general/pull/4953). - lmdb_kv lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440). @@ -76,6 +80,7 @@ Minor Changes - machinectl become plugin - combine the success command when building the become command to be consistent with other become plugins (https://github.com/ansible-collections/community.general/pull/5287). - manifold lookup plugin - start using Ansible's configuration manager to parse options (https://github.com/ansible-collections/community.general/pull/5440). - maven_artifact - add a new ``unredirected_headers`` option that can be used with ansible-core 2.12 and above. The default value is to not use ``Authorization`` and ``Cookie`` headers on redirects for security reasons. With ansible-core 2.11, all headers are still passed on for redirects (https://github.com/ansible-collections/community.general/pull/4812). +- mksysb - refactored module to use ``CmdRunner`` to execute ``mksysb`` (https://github.com/ansible-collections/community.general/pull/5484). - mksysb - using ``do_raise()`` to raise exceptions in ``ModuleHelper`` derived modules (https://github.com/ansible-collections/community.general/pull/4674). - nagios - minor refactoring on parameter validation for different actions (https://github.com/ansible-collections/community.general/pull/5239). - netcup_dnsapi - add ``timeout`` parameter (https://github.com/ansible-collections/community.general/pull/5301). @@ -83,6 +88,7 @@ Minor Changes - nmcli - add bond option ``xmit_hash_policy`` to bond options (https://github.com/ansible-collections/community.general/issues/5148). - nmcli - adds ``vpn`` type and parameter for supporting VPN with service type L2TP and PPTP (https://github.com/ansible-collections/community.general/pull/4746). - nmcli - honor IP options for VPNs (https://github.com/ansible-collections/community.general/pull/5228). +- onepassword - support version 2 of the OnePassword CLI (https://github.com/ansible-collections/community.general/pull/4728) - opentelemetry callback plugin - allow configuring opentelementry callback via config file (https://github.com/ansible-collections/community.general/pull/4916). - opentelemetry callback plugin - send logs. This can be disabled by setting ``disable_logs=false`` (https://github.com/ansible-collections/community.general/pull/4175). - pacman - added parameters ``reason`` and ``reason_for`` to set/change the install reason of packages (https://github.com/ansible-collections/community.general/pull/4956). @@ -125,6 +131,7 @@ Breaking Changes / Porting Guide -------------------------------- - newrelic_deployment - ``revision`` is required for v2 API (https://github.com/ansible-collections/community.general/pull/5341). +- scaleway_container_registry_info - no longer replace ``secret_environment_variables`` in the output by ``SENSITIVE_VALUE`` (https://github.com/ansible-collections/community.general/pull/5497). Deprecated Features ------------------- @@ -179,8 +186,10 @@ Bugfixes - filesystem - improve error messages when output cannot be parsed by including newlines in escaped form (https://github.com/ansible-collections/community.general/pull/4700). - funcd connection plugin - fix signature of ``exec_command`` (https://github.com/ansible-collections/community.general/pull/5111). - ini_file - minor refactor fixing a python lint error (https://github.com/ansible-collections/community.general/pull/5307). +- iso_create - the module somtimes failed to add folders for Joliet and UDF formats (https://github.com/ansible-collections/community.general/issues/5275). - keycloak_realm - fix default groups and roles (https://github.com/ansible-collections/community.general/issues/4241). - keyring_info - fix the result from the keyring library never getting returned (https://github.com/ansible-collections/community.general/pull/4964). +- ldap_attrs - fix bug which caused a ``Bad search filter`` error. The error was occuring when the ldap attribute value contained special characters such as ``(`` or ``*`` (https://github.com/ansible-collections/community.general/issues/5434, https://github.com/ansible-collections/community.general/pull/5435). - ldap_attrs - fix ordering issue by ignoring the ``{x}`` prefix on attribute values (https://github.com/ansible-collections/community.general/issues/977, https://github.com/ansible-collections/community.general/pull/5385). - listen_ports_facts - removed leftover ``EnvironmentError`` . The ``else`` clause had a wrong indentation. The check is now handled in the ``split_pid_name`` function (https://github.com/ansible-collections/community.general/pull/5202). - locale_gen - fix support for Ubuntu (https://github.com/ansible-collections/community.general/issues/5281). @@ -220,6 +229,7 @@ Bugfixes - redis* modules - fix call to ``module.fail_json`` when failing because of missing Python libraries (https://github.com/ansible-collections/community.general/pull/4733). - slack - fix incorrect channel prefix ``#`` caused by incomplete pattern detection by adding ``G0`` and ``GF`` as channel ID patterns (https://github.com/ansible-collections/community.general/pull/5019). - slack - fix message update for channels which start with ``CP``. When ``message-id`` was passed it failed for channels which started with ``CP`` because the ``#`` symbol was added before the ``channel_id`` (https://github.com/ansible-collections/community.general/pull/5249). +- snap - allow values in the ``options`` parameter to contain whitespaces (https://github.com/ansible-collections/community.general/pull/5475). - sudoers - ensure sudoers config files are created with the permissions requested by sudoers (0440) (https://github.com/ansible-collections/community.general/pull/4814). - sudoers - fix incorrect handling of ``state: absent`` (https://github.com/ansible-collections/community.general/issues/4852). - tss lookup plugin - adding support for updated Delinea library (https://github.com/DelineaXPM/python-tss-sdk/issues/9, https://github.com/ansible-collections/community.general/pull/5151). @@ -255,8 +265,14 @@ New Modules - pipx_info - Rretrieves information about applications installed with pipx - proxmox_disk - Management of a disk of a Qemu(KVM) VM in a Proxmox VE cluster. - scaleway_compute_private_network - Scaleway compute - private network management +- scaleway_container - Scaleway Container management +- scaleway_container_info - Retrieve information on Scaleway Container +- scaleway_container_namespace - Scaleway Container namespace management +- scaleway_container_namespace_info - Retrieve information on Scaleway Container namespace - scaleway_container_registry - Scaleway Container registry management module - scaleway_container_registry_info - Scaleway Container registry info module +- scaleway_function - Scaleway Function management +- scaleway_function_info - Retrieve information on Scaleway Function - scaleway_function_namespace - Scaleway Function namespace management - scaleway_function_namespace_info - Retrieve information on Scaleway Function namespace - wdc_redfish_command - Manages WDC UltraStar Data102 Out-Of-Band controllers using Redfish APIs diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index d1db00d3ad..21eac0c266 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -1,5 +1,62 @@ ancestor: 5.0.0 releases: + 6.0.0: + changes: + breaking_changes: + - scaleway_container_registry_info - no longer replace ``secret_environment_variables`` + in the output by ``SENSITIVE_VALUE`` (https://github.com/ansible-collections/community.general/pull/5497). + bugfixes: + - iso_create - the module somtimes failed to add folders for Joliet and UDF + formats (https://github.com/ansible-collections/community.general/issues/5275). + - ldap_attrs - fix bug which caused a ``Bad search filter`` error. The error + was occuring when the ldap attribute value contained special characters such + as ``(`` or ``*`` (https://github.com/ansible-collections/community.general/issues/5434, + https://github.com/ansible-collections/community.general/pull/5435). + - snap - allow values in the ``options`` parameter to contain whitespaces (https://github.com/ansible-collections/community.general/pull/5475). + minor_changes: + - ansible_galaxy_install - refactored module to use ``CmdRunner`` to execute + ``ansible-galaxy`` (https://github.com/ansible-collections/community.general/pull/5477). + - cpanm - refactored module to use ``CmdRunner`` to execute ``cpanm`` (https://github.com/ansible-collections/community.general/pull/5485). + - hponcfg - refactored module to use ``CmdRunner`` to execute ``hponcfg`` (https://github.com/ansible-collections/community.general/pull/5483). + - ldap_attrs - allow for DNs to have ``{x}`` prefix on first RDN (https://github.com/ansible-collections/community.general/issues/977, + https://github.com/ansible-collections/community.general/pull/5450). + - mksysb - refactored module to use ``CmdRunner`` to execute ``mksysb`` (https://github.com/ansible-collections/community.general/pull/5484). + - onepassword - support version 2 of the OnePassword CLI (https://github.com/ansible-collections/community.general/pull/4728) + release_summary: New major release of community.general with lots of bugfixes, + new features, some removed deprecated features, and some other breaking changes. + Please check the coresponding sections of the changelog for more details. + fragments: + - 4728-onepassword-v2.yml + - 5435-escape-ldap-param.yml + - 5450-allow-for-xordered-dns.yaml + - 5468-iso-create-not-add-folders.yml + - 5475-snap-option-value-whitespace.yml + - 5477-ansible-galaxy-install-cmd-runner.yml + - 5483-hponcfg-cmd-runner.yml + - 5484-mksysb-cmd-runner.yml + - 5485-cpanm-cmd-runner.yml + - 5497-scaleway-filtering.yml + - 6.0.0.yml + modules: + - description: Scaleway Container management + name: scaleway_container + namespace: '' + - description: Retrieve information on Scaleway Container + name: scaleway_container_info + namespace: '' + - description: Scaleway Container namespace management + name: scaleway_container_namespace + namespace: '' + - description: Retrieve information on Scaleway Container namespace + name: scaleway_container_namespace_info + namespace: '' + - description: Scaleway Function management + name: scaleway_function + namespace: '' + - description: Retrieve information on Scaleway Function + name: scaleway_function_info + namespace: '' + release_date: '2022-11-07' 6.0.0-a1: changes: breaking_changes: @@ -508,15 +565,16 @@ releases: - simplified-bsd-license.yml - unflatmap.yml modules: - - description: Scaleway Function namespace management - name: scaleway_function_namespace - namespace: '' - - description: Retrieve information on Scaleway Function namespace - name: scaleway_function_namespace_info - namespace: '' - description: Retrieve GConf configurations name: gconftool2_info namespace: '' + - description: Add/remove/change files in ISO file + name: iso_customize + namespace: '' + - description: Allows administration of Keycloak user_rolemapping with the Keycloak + API + name: keycloak_user_rolemapping + namespace: '' - description: Set or delete a passphrase using the Operating System's native keyring name: keyring @@ -524,9 +582,33 @@ releases: - description: Get a passphrase using the Operating System's native keyring name: keyring_info namespace: '' + - description: Listing of resource policy_profiles in ManageIQ + name: manageiq_policies_info + namespace: '' + - description: Retrieve resource tags in ManageIQ + name: manageiq_tags_info + namespace: '' + - description: Rretrieves information about applications installed with pipx + name: pipx_info + namespace: '' + - description: Management of a disk of a Qemu(KVM) VM in a Proxmox VE cluster. + name: proxmox_disk + namespace: '' - description: Scaleway compute - private network management name: scaleway_compute_private_network namespace: '' + - description: Scaleway Container registry management module + name: scaleway_container_registry + namespace: '' + - description: Scaleway Container registry info module + name: scaleway_container_registry_info + namespace: '' + - description: Scaleway Function namespace management + name: scaleway_function_namespace + namespace: '' + - description: Retrieve information on Scaleway Function namespace + name: scaleway_function_namespace_info + namespace: '' - description: Manages WDC UltraStar Data102 Out-Of-Band controllers using Redfish APIs name: wdc_redfish_command @@ -535,31 +617,6 @@ releases: APIs name: wdc_redfish_info namespace: '' - - description: Rretrieves information about applications installed with pipx - name: pipx_info - namespace: '' - - description: Allows administration of Keycloak user_rolemapping with the Keycloak - API - name: keycloak_user_rolemapping - namespace: '' - - description: Management of a disk of a Qemu(KVM) VM in a Proxmox VE cluster. - name: proxmox_disk - namespace: '' - - description: Add/remove/change files in ISO file - name: iso_customize - namespace: '' - - description: Listing of resource policy_profiles in ManageIQ - name: manageiq_policies_info - namespace: '' - - description: Retrieve resource tags in ManageIQ - name: manageiq_tags_info - namespace: '' - - description: Scaleway Container registry management module - name: scaleway_container_registry - namespace: '' - - description: Scaleway Container registry info module - name: scaleway_container_registry_info - namespace: '' plugins: filter: - description: Counts hashable elements in a sequence diff --git a/changelogs/fragments/4728-onepassword-v2.yml b/changelogs/fragments/4728-onepassword-v2.yml deleted file mode 100644 index fbec3aa60d..0000000000 --- a/changelogs/fragments/4728-onepassword-v2.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - onepassword - support version 2 of the OnePassword CLI (https://github.com/ansible-collections/community.general/pull/4728) diff --git a/changelogs/fragments/5435-escape-ldap-param.yml b/changelogs/fragments/5435-escape-ldap-param.yml deleted file mode 100644 index 3f22f61759..0000000000 --- a/changelogs/fragments/5435-escape-ldap-param.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - ldap_attrs - fix bug which caused a ``Bad search filter`` error. The error was occuring when the ldap attribute value contained special characters such as ``(`` or ``*`` (https://github.com/ansible-collections/community.general/issues/5434, https://github.com/ansible-collections/community.general/pull/5435). diff --git a/changelogs/fragments/5450-allow-for-xordered-dns.yaml b/changelogs/fragments/5450-allow-for-xordered-dns.yaml deleted file mode 100644 index 1bb1d9c761..0000000000 --- a/changelogs/fragments/5450-allow-for-xordered-dns.yaml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - ldap_attrs - allow for DNs to have ``{x}`` prefix on first RDN (https://github.com/ansible-collections/community.general/issues/977, https://github.com/ansible-collections/community.general/pull/5450). diff --git a/changelogs/fragments/5468-iso-create-not-add-folders.yml b/changelogs/fragments/5468-iso-create-not-add-folders.yml deleted file mode 100644 index 5bbe48f579..0000000000 --- a/changelogs/fragments/5468-iso-create-not-add-folders.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - iso_create - the module somtimes failed to add folders for Joliet and UDF formats (https://github.com/ansible-collections/community.general/issues/5275). diff --git a/changelogs/fragments/5475-snap-option-value-whitespace.yml b/changelogs/fragments/5475-snap-option-value-whitespace.yml deleted file mode 100644 index c41c70da38..0000000000 --- a/changelogs/fragments/5475-snap-option-value-whitespace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - snap - allow values in the ``options`` parameter to contain whitespaces (https://github.com/ansible-collections/community.general/pull/5475). diff --git a/changelogs/fragments/5477-ansible-galaxy-install-cmd-runner.yml b/changelogs/fragments/5477-ansible-galaxy-install-cmd-runner.yml deleted file mode 100644 index f480456953..0000000000 --- a/changelogs/fragments/5477-ansible-galaxy-install-cmd-runner.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - ansible_galaxy_install - refactored module to use ``CmdRunner`` to execute ``ansible-galaxy`` (https://github.com/ansible-collections/community.general/pull/5477). diff --git a/changelogs/fragments/5483-hponcfg-cmd-runner.yml b/changelogs/fragments/5483-hponcfg-cmd-runner.yml deleted file mode 100644 index 9d6c0eb8a9..0000000000 --- a/changelogs/fragments/5483-hponcfg-cmd-runner.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - hponcfg - refactored module to use ``CmdRunner`` to execute ``hponcfg`` (https://github.com/ansible-collections/community.general/pull/5483). diff --git a/changelogs/fragments/5484-mksysb-cmd-runner.yml b/changelogs/fragments/5484-mksysb-cmd-runner.yml deleted file mode 100644 index 89f4d0dac8..0000000000 --- a/changelogs/fragments/5484-mksysb-cmd-runner.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - mksysb - refactored module to use ``CmdRunner`` to execute ``mksysb`` (https://github.com/ansible-collections/community.general/pull/5484). diff --git a/changelogs/fragments/5485-cpanm-cmd-runner.yml b/changelogs/fragments/5485-cpanm-cmd-runner.yml deleted file mode 100644 index 508f261762..0000000000 --- a/changelogs/fragments/5485-cpanm-cmd-runner.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - cpanm - refactored module to use ``CmdRunner`` to execute ``cpanm`` (https://github.com/ansible-collections/community.general/pull/5485). diff --git a/changelogs/fragments/5497-scaleway-filtering.yml b/changelogs/fragments/5497-scaleway-filtering.yml deleted file mode 100644 index 4fa125f312..0000000000 --- a/changelogs/fragments/5497-scaleway-filtering.yml +++ /dev/null @@ -1,2 +0,0 @@ -breaking_changes: - - "scaleway_container_registry_info - no longer replace ``secret_environment_variables`` in the output by ``SENSITIVE_VALUE`` (https://github.com/ansible-collections/community.general/pull/5497)." diff --git a/changelogs/fragments/6.0.0.yml b/changelogs/fragments/6.0.0.yml deleted file mode 100644 index 347d16861c..0000000000 --- a/changelogs/fragments/6.0.0.yml +++ /dev/null @@ -1,3 +0,0 @@ -release_summary: >- - New major release of community.general with lots of bugfixes, new features, some removed deprecated features, and some other breaking changes. - Please check the coresponding sections of the changelog for more details. From a411ff5ea8e910911f42fee5f22f47c365c5f041 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 7 Nov 2022 21:51:24 +0100 Subject: [PATCH 005/134] Add stable-6 to nightlies. (cherry picked from commit df9c5d1d356da2612650cbf0adf65f9871c3b4fe) --- .azure-pipelines/azure-pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index 52eaf65069..c39a855dd0 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -29,6 +29,7 @@ schedules: always: true branches: include: + - stable-6 - stable-5 - cron: 0 11 * * 0 displayName: Weekly (old stable branches) From 6065dd0f1825e3c6611373f321a1a4e71bdd901d Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 7 Nov 2022 21:52:46 +0100 Subject: [PATCH 006/134] Do not run docs PR workflow in stable branches. --- .github/workflows/docs-pr.yml | 93 ----------------------------------- 1 file changed, 93 deletions(-) delete mode 100644 .github/workflows/docs-pr.yml diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml deleted file mode 100644 index 04a50dc201..0000000000 --- a/.github/workflows/docs-pr.yml +++ /dev/null @@ -1,93 +0,0 @@ ---- -# Copyright (c) Ansible Project -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -name: Collection Docs -concurrency: - group: docs-${{ github.head_ref }} - cancel-in-progress: true -on: - pull_request_target: - types: [opened, synchronize, reopened, closed] - paths-ignore: - - '.azure-pipelines/**' - - 'changelogs/**' - - 'meta/**' - - 'tests/**' - -jobs: - build-docs: - permissions: - contents: read - name: Build Ansible Docs - uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-pr.yml@main - with: - init-fail-on-error: true - provide-link-targets: | - ansible_collections.ansible.builtin.dict2items_filter - ansible_collections.ansible.builtin.items_lookup - ansible_collections.ansible.builtin.path_join_filter - ansible_collections.community.kubevirt.kubevirt_cdi_upload_module - ansible_collections.community.kubevirt.kubevirt_inventory - ansible_collections.community.kubevirt.kubevirt_preset_module - ansible_collections.community.kubevirt.kubevirt_pvc_module - ansible_collections.community.kubevirt.kubevirt_rs_module - ansible_collections.community.kubevirt.kubevirt_template_module - ansible_collections.community.kubevirt.kubevirt_vm_module - ansible_collections.infoblox.nios_modules.nios_a_record_module - ansible_collections.infoblox.nios_modules.nios_aaaa_record_module - ansible_collections.infoblox.nios_modules.nios_cname_record_module - ansible_collections.infoblox.nios_modules.nios_dns_view_module - ansible_collections.infoblox.nios_modules.nios_fixed_address_module - ansible_collections.infoblox.nios_modules.nios_host_record_module - ansible_collections.infoblox.nios_modules.nios_lookup_lookup - ansible_collections.infoblox.nios_modules.nios_member_module - ansible_collections.infoblox.nios_modules.nios_mx_record_module - ansible_collections.infoblox.nios_modules.nios_naptr_record_module - ansible_collections.infoblox.nios_modules.nios_network_module - ansible_collections.infoblox.nios_modules.nios_network_view_module - ansible_collections.infoblox.nios_modules.nios_next_ip_lookup - ansible_collections.infoblox.nios_modules.nios_next_network_lookup - ansible_collections.infoblox.nios_modules.nios_nsgroup_module - ansible_collections.infoblox.nios_modules.nios_ptr_record_module - ansible_collections.infoblox.nios_modules.nios_srv_record_module - ansible_collections.infoblox.nios_modules.nios_txt_record_module - ansible_collections.infoblox.nios_modules.nios_zone_module - - comment: - permissions: - pull-requests: write - runs-on: ubuntu-latest - needs: build-docs - name: PR comments - steps: - - name: PR comment - uses: ansible-community/github-docs-build/actions/ansible-docs-build-comment@main - with: - body-includes: '## Docs Build' - reactions: heart - action: ${{ needs.build-docs.outputs.changed != 'true' && 'remove' || '' }} - on-closed-body: | - ## Docs Build πŸ“ - - This PR is closed and any previously published docsite has been unpublished. - on-merged-body: | - ## Docs Build πŸ“ - - Thank you for contribution!✨ - - This PR has been merged and your docs changes will be incorporated when they are next published. - body: | - ## Docs Build πŸ“ - - Thank you for contribution!✨ - - The docsite for **this PR** is available for download as an artifact from this run: - ${{ needs.build-docs.outputs.artifact-url }} - - File changes: - - ${{ needs.build-docs.outputs.diff-files-rendered }} - - ${{ needs.build-docs.outputs.diff-rendered }} From fad4c2d956456da20d17b602b718e0cd5608308d Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 7 Nov 2022 21:53:15 +0100 Subject: [PATCH 007/134] Next expected release is 6.0.1. --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 0a3fe09b6e..0fee26c05d 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -5,7 +5,7 @@ namespace: community name: general -version: 6.0.0 +version: 6.0.1 readme: README.md authors: - Ansible (https://github.com/ansible) From 8fba9ca75172c8311e76b95ec4b50513b74d0395 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 8 Nov 2022 14:19:54 +0100 Subject: [PATCH 008/134] minor docs update (#5501) (#5505) (cherry picked from commit 858eaac50089490e782b9a25754d21524eb7638c) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- plugins/modules/xfconf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/modules/xfconf.py b/plugins/modules/xfconf.py index aaf80d4db2..c231a47484 100644 --- a/plugins/modules/xfconf.py +++ b/plugins/modules/xfconf.py @@ -16,9 +16,9 @@ author: short_description: Edit XFCE4 Configurations description: - This module allows for the manipulation of Xfce 4 Configuration with the help of - xfconf-query. Please see the xfconf-query(1) man pages for more details. + xfconf-query. Please see the xfconf-query(1) man page for more details. seealso: - - name: C(xfconf-query) man page + - name: xfconf-query(1) man page description: Manual page of the C(xfconf-query) tool at the XFCE documentation site. link: 'https://docs.xfce.org/xfce/xfconf/xfconf-query' @@ -70,7 +70,7 @@ options: default: "present" force_array: description: - - Force array even if only one element + - Force array even if only one element. type: bool default: false aliases: ['array'] From 081b4068a0850c867af48d356700385d7eceb9f4 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 8 Nov 2022 20:32:20 +0100 Subject: [PATCH 009/134] Clarification to use underscores instead of dashes in parser name (#5500) (#5509) * Clarification to use underscores instead of dashes in parser name * Update plugins/filter/jc.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 27827cbea4e752cd73afa85ac09ce91ea7ab8af9) Co-authored-by: Kelly Brazil --- plugins/filter/jc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/filter/jc.py b/plugins/filter/jc.py index 879647a04d..6708f573d3 100644 --- a/plugins/filter/jc.py +++ b/plugins/filter/jc.py @@ -26,6 +26,7 @@ DOCUMENTATION = ''' description: - The correct parser for the input data. - For example C(ifconfig). + - "Note: use underscores instead of dashes (if any) in the parser module name." - See U(https://github.com/kellyjonbrazil/jc#parsers) for the latest list of parsers. type: string required: true From c6d0419460b14acc33b66d41e7950bf88d33286d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 07:11:59 +0100 Subject: [PATCH 010/134] one_vm: fix for 'NoneType' object has no attribute 'split' in get_vm_labels_and_attributes_dict (#5489) (#5513) * Fix for 'NoneType' object has no attribute 'split' * Added changelog to fix * Update changelogs/fragments/5489-nonetype-in-get-vm-by-label.yml Co-authored-by: Felix Fontein * Fix line ending in changelog Co-authored-by: Felix Fontein (cherry picked from commit 621fb6a619fce1d45a72dc2b46bdbc3fb64d86d5) Co-authored-by: wh1t3 r4bb1t <16529603+d34d5p4rr0w@users.noreply.github.com> --- changelogs/fragments/5489-nonetype-in-get-vm-by-label.yml | 2 ++ plugins/modules/one_vm.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5489-nonetype-in-get-vm-by-label.yml diff --git a/changelogs/fragments/5489-nonetype-in-get-vm-by-label.yml b/changelogs/fragments/5489-nonetype-in-get-vm-by-label.yml new file mode 100644 index 0000000000..8b0d92ec40 --- /dev/null +++ b/changelogs/fragments/5489-nonetype-in-get-vm-by-label.yml @@ -0,0 +1,2 @@ +bugfixes: + - one_vm - avoid splitting labels that are ``None`` (https://github.com/ansible-collections/community.general/pull/5489). \ No newline at end of file diff --git a/plugins/modules/one_vm.py b/plugins/modules/one_vm.py index 6bfc793603..7122907d38 100644 --- a/plugins/modules/one_vm.py +++ b/plugins/modules/one_vm.py @@ -970,7 +970,7 @@ def get_vm_labels_and_attributes_dict(client, vm_id): if key != 'LABELS': attrs_dict[key] = value else: - if key is not None: + if key is not None and value is not None: labels_list = value.split(',') return labels_list, attrs_dict From e96bfd07b4757c66e98339fc37005f8ccfe3ddf4 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 07:32:56 +0100 Subject: [PATCH 011/134] Actually sort the fixtures (#5510) (#5517) * Actually sort the fixtures I removed my more complicated fix but failed to actually put the sorted() call back in. * Sort by class name (cherry picked from commit eae33c20f6eb8e7616064b8ffee17165c5656b56) Co-authored-by: Sam Doran --- tests/unit/plugins/lookup/onepassword/test_onepassword.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/plugins/lookup/onepassword/test_onepassword.py b/tests/unit/plugins/lookup/onepassword/test_onepassword.py index 9e943dbfa0..e9f8f42c96 100644 --- a/tests/unit/plugins/lookup/onepassword/test_onepassword.py +++ b/tests/unit/plugins/lookup/onepassword/test_onepassword.py @@ -5,6 +5,7 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +import operator import itertools import json import pytest @@ -158,7 +159,7 @@ def test_op_get_field(mocker, op_fixture, output, expected, request): ("cli_class", "vault", "queries", "kwargs", "output", "expected"), ( (_cli_class, item["vault_name"], item["queries"], item.get("kwargs", {}), item["output"], item["expected"]) - for _cli_class in MOCK_ENTRIES + for _cli_class in sorted(MOCK_ENTRIES, key=operator.attrgetter("__name__")) for item in MOCK_ENTRIES[_cli_class] ) ) From 72d44768132cc3df33fe69acaf0a0cc6f7d02a86 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 07:38:27 +0100 Subject: [PATCH 012/134] onepassword_raw - Add missing parameter to doc string (#5511) (#5518) * onepassword_raw - Add missing parameter to doc string * Remove redundant mention of default value * Update changelogs/fragments/5506-onepassword_raw-missing-param.yml Co-authored-by: Felix Fontein (cherry picked from commit c604cc5ba901574697b99bd31236d99e0e6cd1a3) Co-authored-by: Sam Doran --- changelogs/fragments/5506-onepassword_raw-missing-param.yml | 2 ++ plugins/lookup/onepassword.py | 2 +- plugins/lookup/onepassword_raw.py | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5506-onepassword_raw-missing-param.yml diff --git a/changelogs/fragments/5506-onepassword_raw-missing-param.yml b/changelogs/fragments/5506-onepassword_raw-missing-param.yml new file mode 100644 index 0000000000..f10ff28d28 --- /dev/null +++ b/changelogs/fragments/5506-onepassword_raw-missing-param.yml @@ -0,0 +1,2 @@ +bugfixes: + - onepassword_raw - add missing parameter to plugin documentation (https://github.com/ansible-collections/community.general/issues/5506). diff --git a/plugins/lookup/onepassword.py b/plugins/lookup/onepassword.py index bbd11d6645..5e9549c2b7 100644 --- a/plugins/lookup/onepassword.py +++ b/plugins/lookup/onepassword.py @@ -32,7 +32,7 @@ DOCUMENTATION = ''' section: description: Item section containing the field to retrieve (case-insensitive). If absent will return first match from any section. domain: - description: Domain of 1Password. Default is U(1password.com). + description: Domain of 1Password. version_added: 3.2.0 default: '1password.com' type: str diff --git a/plugins/lookup/onepassword_raw.py b/plugins/lookup/onepassword_raw.py index c7b9332953..9b87a3f619 100644 --- a/plugins/lookup/onepassword_raw.py +++ b/plugins/lookup/onepassword_raw.py @@ -30,6 +30,11 @@ DOCUMENTATION = ''' description: Item section containing the field to retrieve (case-insensitive). If absent will return first match from any section. subdomain: description: The 1Password subdomain to authenticate against. + domain: + description: Domain of 1Password. + version_added: 6.0.0 + default: '1password.com' + type: str username: description: The username used to sign in. secret_key: From e9ec26ff1b0edd2c9d3173200430beb365176b65 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 07:38:36 +0100 Subject: [PATCH 013/134] Short descriptions (batch1) - massive fix on Capitalization and trailing period (#5503) (#5516) * short_description fix batch 1 * Update plugins/modules/ali_instance.py Co-authored-by: Felix Fontein * Update plugins/modules/apt_rpm.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 97b584e2617bcd7437ffc184acccb2e12be45206) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- plugins/modules/ali_instance.py | 2 +- plugins/modules/ali_instance_info.py | 2 +- plugins/modules/apache2_module.py | 2 +- plugins/modules/apt_rpm.py | 2 +- plugins/modules/beadm.py | 2 +- plugins/modules/circonus_annotation.py | 2 +- plugins/modules/clc_aa_policy.py | 2 +- plugins/modules/clc_alert_policy.py | 2 +- plugins/modules/clc_blueprint_package.py | 2 +- plugins/modules/clc_loadbalancer.py | 2 +- plugins/modules/clc_modify_server.py | 2 +- plugins/modules/clc_publicip.py | 2 +- plugins/modules/clc_server.py | 2 +- plugins/modules/clc_server_snapshot.py | 2 +- plugins/modules/cloud_init_data_facts.py | 2 +- plugins/modules/consul.py | 2 +- plugins/modules/cpanm.py | 2 +- plugins/modules/deploy_helper.py | 2 +- plugins/modules/dimensiondata_vlan.py | 2 +- plugins/modules/dnsmadeeasy.py | 2 +- plugins/modules/github_deploy_key.py | 2 +- plugins/modules/github_issue.py | 2 +- plugins/modules/github_key.py | 2 +- plugins/modules/gitlab_deploy_key.py | 2 +- plugins/modules/gitlab_hook.py | 2 +- plugins/modules/gitlab_runner.py | 2 +- plugins/modules/gunicorn.py | 2 +- plugins/modules/hipchat.py | 2 +- plugins/modules/homebrew_tap.py | 2 +- plugins/modules/htpasswd.py | 2 +- plugins/modules/ibm_sa_host.py | 2 +- plugins/modules/ibm_sa_host_ports.py | 2 +- plugins/modules/ibm_sa_pool.py | 2 +- plugins/modules/ibm_sa_vol.py | 2 +- plugins/modules/ibm_sa_vol_map.py | 2 +- plugins/modules/ipa_subca.py | 2 +- plugins/modules/jira.py | 2 +- plugins/modules/ldap_entry.py | 2 +- plugins/modules/ldap_passwd.py | 2 +- plugins/modules/librato_annotation.py | 2 +- plugins/modules/linode_v4.py | 2 +- plugins/modules/listen_ports_facts.py | 2 +- plugins/modules/lldp.py | 2 +- plugins/modules/logentries_msg.py | 2 +- plugins/modules/manageiq_group.py | 2 +- plugins/modules/manageiq_policies.py | 2 +- plugins/modules/manageiq_provider.py | 2 +- plugins/modules/manageiq_tags.py | 2 +- plugins/modules/manageiq_tenant.py | 2 +- plugins/modules/manageiq_user.py | 2 +- 50 files changed, 50 insertions(+), 50 deletions(-) diff --git a/plugins/modules/ali_instance.py b/plugins/modules/ali_instance.py index 4acec0a109..96a042f5ca 100644 --- a/plugins/modules/ali_instance.py +++ b/plugins/modules/ali_instance.py @@ -27,7 +27,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: ali_instance -short_description: Create, Start, Stop, Restart or Terminate an Instance in ECS. Add or Remove Instance to/from a Security Group. +short_description: Create, Start, Stop, Restart or Terminate an Instance in ECS; Add or Remove Instance to/from a Security Group description: - Create, start, stop, restart, modify or terminate ecs instances. - Add or remove ecs instances to/from security group. diff --git a/plugins/modules/ali_instance_info.py b/plugins/modules/ali_instance_info.py index ea7bcc8d4a..f489f96372 100644 --- a/plugins/modules/ali_instance_info.py +++ b/plugins/modules/ali_instance_info.py @@ -27,7 +27,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: ali_instance_info -short_description: Gather information on instances of Alibaba Cloud ECS. +short_description: Gather information on instances of Alibaba Cloud ECS description: - This module fetches data from the Open API in Alicloud. The module must be called from within the ECS instance itself. diff --git a/plugins/modules/apache2_module.py b/plugins/modules/apache2_module.py index 65d2f689bf..a58c0f0c54 100644 --- a/plugins/modules/apache2_module.py +++ b/plugins/modules/apache2_module.py @@ -16,7 +16,7 @@ author: - Christian Berendt (@berendt) - Ralf Hertel (@n0trax) - Robin Roth (@robinro) -short_description: Enables/disables a module of the Apache2 webserver. +short_description: Enables/disables a module of the Apache2 webserver description: - Enables or disables a specified module of the Apache2 webserver. options: diff --git a/plugins/modules/apt_rpm.py b/plugins/modules/apt_rpm.py index 2b6bf3e8a2..d949a61e68 100644 --- a/plugins/modules/apt_rpm.py +++ b/plugins/modules/apt_rpm.py @@ -14,7 +14,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: apt_rpm -short_description: apt_rpm package manager +short_description: APT-RPM package manager description: - Manages packages with I(apt-rpm). Both low-level (I(rpm)) and high-level (I(apt-get)) package manager binaries required. options: diff --git a/plugins/modules/beadm.py b/plugins/modules/beadm.py index 8cb43c6cbb..7a84997089 100644 --- a/plugins/modules/beadm.py +++ b/plugins/modules/beadm.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: beadm -short_description: Manage ZFS boot environments on FreeBSD/Solaris/illumos systems. +short_description: Manage ZFS boot environments on FreeBSD/Solaris/illumos systems description: - Create, delete or activate ZFS boot environments. - Mount and unmount ZFS boot environments. diff --git a/plugins/modules/circonus_annotation.py b/plugins/modules/circonus_annotation.py index 6248fd2f55..661c854e6d 100644 --- a/plugins/modules/circonus_annotation.py +++ b/plugins/modules/circonus_annotation.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: circonus_annotation -short_description: create an annotation in circonus +short_description: Create an annotation in circonus description: - Create an annotation event with a given category, title and description. Optionally start, end or durations can be provided author: "Nick Harring (@NickatEpic)" diff --git a/plugins/modules/clc_aa_policy.py b/plugins/modules/clc_aa_policy.py index d5d56b2a65..d1fba2429a 100644 --- a/plugins/modules/clc_aa_policy.py +++ b/plugins/modules/clc_aa_policy.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: clc_aa_policy -short_description: Create or Delete Anti Affinity Policies at CenturyLink Cloud. +short_description: Create or Delete Anti Affinity Policies at CenturyLink Cloud description: - An Ansible module to Create or Delete Anti Affinity Policies at CenturyLink Cloud. options: diff --git a/plugins/modules/clc_alert_policy.py b/plugins/modules/clc_alert_policy.py index c7f02c2ffa..1d733013d2 100644 --- a/plugins/modules/clc_alert_policy.py +++ b/plugins/modules/clc_alert_policy.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: clc_alert_policy -short_description: Create or Delete Alert Policies at CenturyLink Cloud. +short_description: Create or Delete Alert Policies at CenturyLink Cloud description: - An Ansible module to Create or Delete Alert Policies at CenturyLink Cloud. options: diff --git a/plugins/modules/clc_blueprint_package.py b/plugins/modules/clc_blueprint_package.py index 0dc29b0ce0..cb23df852b 100644 --- a/plugins/modules/clc_blueprint_package.py +++ b/plugins/modules/clc_blueprint_package.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: clc_blueprint_package -short_description: deploys a blue print package on a set of servers in CenturyLink Cloud. +short_description: Deploys a blue print package on a set of servers in CenturyLink Cloud description: - An Ansible module to deploy blue print package on a set of servers in CenturyLink Cloud. options: diff --git a/plugins/modules/clc_loadbalancer.py b/plugins/modules/clc_loadbalancer.py index d13c2d76ce..ab6d866fb6 100644 --- a/plugins/modules/clc_loadbalancer.py +++ b/plugins/modules/clc_loadbalancer.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: clc_loadbalancer -short_description: Create, Delete shared loadbalancers in CenturyLink Cloud. +short_description: Create, Delete shared loadbalancers in CenturyLink Cloud description: - An Ansible module to Create, Delete shared loadbalancers in CenturyLink Cloud. options: diff --git a/plugins/modules/clc_modify_server.py b/plugins/modules/clc_modify_server.py index ff0611e3f8..786cdf2ae4 100644 --- a/plugins/modules/clc_modify_server.py +++ b/plugins/modules/clc_modify_server.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: clc_modify_server -short_description: modify servers in CenturyLink Cloud. +short_description: Modify servers in CenturyLink Cloud description: - An Ansible module to modify servers in CenturyLink Cloud. options: diff --git a/plugins/modules/clc_publicip.py b/plugins/modules/clc_publicip.py index 98d392adf9..5111b3cf19 100644 --- a/plugins/modules/clc_publicip.py +++ b/plugins/modules/clc_publicip.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: clc_publicip -short_description: Add and Delete public ips on servers in CenturyLink Cloud. +short_description: Add and Delete public ips on servers in CenturyLink Cloud description: - An Ansible module to add or delete public ip addresses on an existing server or servers in CenturyLink Cloud. options: diff --git a/plugins/modules/clc_server.py b/plugins/modules/clc_server.py index 062c5ea411..d8e4f16217 100644 --- a/plugins/modules/clc_server.py +++ b/plugins/modules/clc_server.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: clc_server -short_description: Create, Delete, Start and Stop servers in CenturyLink Cloud. +short_description: Create, Delete, Start and Stop servers in CenturyLink Cloud description: - An Ansible module to Create, Delete, Start and Stop servers in CenturyLink Cloud. options: diff --git a/plugins/modules/clc_server_snapshot.py b/plugins/modules/clc_server_snapshot.py index 44f52ece64..096abfe29b 100644 --- a/plugins/modules/clc_server_snapshot.py +++ b/plugins/modules/clc_server_snapshot.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: clc_server_snapshot -short_description: Create, Delete and Restore server snapshots in CenturyLink Cloud. +short_description: Create, Delete and Restore server snapshots in CenturyLink Cloud description: - An Ansible module to Create, Delete and Restore server snapshots in CenturyLink Cloud. options: diff --git a/plugins/modules/cloud_init_data_facts.py b/plugins/modules/cloud_init_data_facts.py index df2f77148e..d8209cc61a 100644 --- a/plugins/modules/cloud_init_data_facts.py +++ b/plugins/modules/cloud_init_data_facts.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: cloud_init_data_facts -short_description: Retrieve facts of cloud-init. +short_description: Retrieve facts of cloud-init description: - Gathers facts by reading the status.json and result.json of cloud-init. author: RenΓ© Moser (@resmo) diff --git a/plugins/modules/consul.py b/plugins/modules/consul.py index 0d75bde2eb..a7cefc9865 100644 --- a/plugins/modules/consul.py +++ b/plugins/modules/consul.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: consul -short_description: "Add, modify & delete services within a consul cluster." +short_description: "Add, modify & delete services within a consul cluster" description: - Registers services and checks for an agent with a consul cluster. A service is some process running on the agent node that should be advertised by diff --git a/plugins/modules/cpanm.py b/plugins/modules/cpanm.py index 7ac8429bda..98f37d573e 100644 --- a/plugins/modules/cpanm.py +++ b/plugins/modules/cpanm.py @@ -13,7 +13,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: cpanm -short_description: Manages Perl library dependencies. +short_description: Manages Perl library dependencies description: - Manage Perl library dependencies using cpanminus. options: diff --git a/plugins/modules/deploy_helper.py b/plugins/modules/deploy_helper.py index 3d3fe08f28..afa63cba19 100644 --- a/plugins/modules/deploy_helper.py +++ b/plugins/modules/deploy_helper.py @@ -15,7 +15,7 @@ DOCUMENTATION = ''' --- module: deploy_helper author: "Ramon de la Fuente (@ramondelafuente)" -short_description: Manages some of the steps common in deploying projects. +short_description: Manages some of the steps common in deploying projects description: - The Deploy Helper manages some of the steps common in deploying software. It creates a folder structure, manages a symlink for the current release diff --git a/plugins/modules/dimensiondata_vlan.py b/plugins/modules/dimensiondata_vlan.py index ca25374dcb..86db5e5057 100644 --- a/plugins/modules/dimensiondata_vlan.py +++ b/plugins/modules/dimensiondata_vlan.py @@ -13,7 +13,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: dimensiondata_vlan -short_description: Manage a VLAN in a Cloud Control network domain. +short_description: Manage a VLAN in a Cloud Control network domain extends_documentation_fragment: - community.general.dimensiondata - community.general.dimensiondata_wait diff --git a/plugins/modules/dnsmadeeasy.py b/plugins/modules/dnsmadeeasy.py index cb27a5a68a..b775f24ab0 100644 --- a/plugins/modules/dnsmadeeasy.py +++ b/plugins/modules/dnsmadeeasy.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: dnsmadeeasy -short_description: Interface with dnsmadeeasy.com (a DNS hosting service). +short_description: Interface with dnsmadeeasy.com (a DNS hosting service) description: - > Manages DNS records via the v2 REST API of the DNS Made Easy service. It handles records only; there is no manipulation of domains or diff --git a/plugins/modules/github_deploy_key.py b/plugins/modules/github_deploy_key.py index 97e7a1ac7f..bd32438b0a 100644 --- a/plugins/modules/github_deploy_key.py +++ b/plugins/modules/github_deploy_key.py @@ -13,7 +13,7 @@ DOCUMENTATION = ''' --- module: github_deploy_key author: "Ali (@bincyber)" -short_description: Manages deploy keys for GitHub repositories. +short_description: Manages deploy keys for GitHub repositories description: - "Adds or removes deploy keys for GitHub repositories. Supports authentication using username and password, username and password and 2-factor authentication code (OTP), OAuth2 token, or personal access token. Admin diff --git a/plugins/modules/github_issue.py b/plugins/modules/github_issue.py index 4f8f2363cc..d49837499a 100644 --- a/plugins/modules/github_issue.py +++ b/plugins/modules/github_issue.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: github_issue -short_description: View GitHub issue. +short_description: View GitHub issue description: - View GitHub issue for a given repository and organization. options: diff --git a/plugins/modules/github_key.py b/plugins/modules/github_key.py index 5dfd694275..3c7ee7bd7b 100644 --- a/plugins/modules/github_key.py +++ b/plugins/modules/github_key.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: github_key -short_description: Manage GitHub access keys. +short_description: Manage GitHub access keys description: - Creates, removes, or updates GitHub access keys. options: diff --git a/plugins/modules/gitlab_deploy_key.py b/plugins/modules/gitlab_deploy_key.py index 1b77801ec4..3ed2b2d7a5 100644 --- a/plugins/modules/gitlab_deploy_key.py +++ b/plugins/modules/gitlab_deploy_key.py @@ -13,7 +13,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: gitlab_deploy_key -short_description: Manages GitLab project deploy keys. +short_description: Manages GitLab project deploy keys description: - Adds, updates and removes project deploy keys author: diff --git a/plugins/modules/gitlab_hook.py b/plugins/modules/gitlab_hook.py index c10cb45324..70864207ed 100644 --- a/plugins/modules/gitlab_hook.py +++ b/plugins/modules/gitlab_hook.py @@ -14,7 +14,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: gitlab_hook -short_description: Manages GitLab project hooks. +short_description: Manages GitLab project hooks description: - Adds, updates and removes project hook author: diff --git a/plugins/modules/gitlab_runner.py b/plugins/modules/gitlab_runner.py index 67d998f12f..1094df9424 100644 --- a/plugins/modules/gitlab_runner.py +++ b/plugins/modules/gitlab_runner.py @@ -13,7 +13,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: gitlab_runner -short_description: Create, modify and delete GitLab Runners. +short_description: Create, modify and delete GitLab Runners description: - Register, update and delete runners with the GitLab API. - All operations are performed using the GitLab API v4. diff --git a/plugins/modules/gunicorn.py b/plugins/modules/gunicorn.py index 9ed903dfd5..ff88cead7c 100644 --- a/plugins/modules/gunicorn.py +++ b/plugins/modules/gunicorn.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: gunicorn -short_description: Run gunicorn with various settings. +short_description: Run gunicorn with various settings description: - Starts gunicorn with the parameters specified. Common settings for gunicorn configuration are supported. For additional configuration use a config file diff --git a/plugins/modules/hipchat.py b/plugins/modules/hipchat.py index 1871bd23ae..a5aa150f32 100644 --- a/plugins/modules/hipchat.py +++ b/plugins/modules/hipchat.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: hipchat -short_description: Send a message to Hipchat. +short_description: Send a message to Hipchat description: - Send a message to a Hipchat room, with options to control the formatting. options: diff --git a/plugins/modules/homebrew_tap.py b/plugins/modules/homebrew_tap.py index 0cc5b23ce8..7099773b21 100644 --- a/plugins/modules/homebrew_tap.py +++ b/plugins/modules/homebrew_tap.py @@ -19,7 +19,7 @@ module: homebrew_tap author: - "Indrajit Raychaudhuri (@indrajitr)" - "Daniel Jaouen (@danieljaouen)" -short_description: Tap a Homebrew repository. +short_description: Tap a Homebrew repository description: - Tap external Homebrew repositories. options: diff --git a/plugins/modules/htpasswd.py b/plugins/modules/htpasswd.py index 4f05d21b0d..f24eaa0087 100644 --- a/plugins/modules/htpasswd.py +++ b/plugins/modules/htpasswd.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: htpasswd -short_description: manage user files for basic authentication +short_description: Manage user files for basic authentication description: - Add and remove username/password entries in a password file using htpasswd. - This is used by web servers such as Apache and Nginx for basic authentication. diff --git a/plugins/modules/ibm_sa_host.py b/plugins/modules/ibm_sa_host.py index 2902a02028..961e1bba19 100644 --- a/plugins/modules/ibm_sa_host.py +++ b/plugins/modules/ibm_sa_host.py @@ -13,7 +13,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: ibm_sa_host -short_description: Adds hosts to or removes them from IBM Spectrum Accelerate Family storage systems. +short_description: Adds hosts to or removes them from IBM Spectrum Accelerate Family storage systems description: - "This module adds hosts to or removes them from IBM Spectrum Accelerate Family storage systems." diff --git a/plugins/modules/ibm_sa_host_ports.py b/plugins/modules/ibm_sa_host_ports.py index 147c434344..fc543053a7 100644 --- a/plugins/modules/ibm_sa_host_ports.py +++ b/plugins/modules/ibm_sa_host_ports.py @@ -13,7 +13,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: ibm_sa_host_ports -short_description: Add host ports on IBM Spectrum Accelerate Family storage systems. +short_description: Add host ports on IBM Spectrum Accelerate Family storage systems description: - "This module adds ports to or removes them from the hosts diff --git a/plugins/modules/ibm_sa_pool.py b/plugins/modules/ibm_sa_pool.py index 6393a70686..998f3f74be 100644 --- a/plugins/modules/ibm_sa_pool.py +++ b/plugins/modules/ibm_sa_pool.py @@ -13,7 +13,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: ibm_sa_pool -short_description: Handles pools on IBM Spectrum Accelerate Family storage systems. +short_description: Handles pools on IBM Spectrum Accelerate Family storage systems description: - "This module creates or deletes pools to be used on IBM Spectrum Accelerate Family storage systems" diff --git a/plugins/modules/ibm_sa_vol.py b/plugins/modules/ibm_sa_vol.py index 6e28fcfd05..115ac9169f 100644 --- a/plugins/modules/ibm_sa_vol.py +++ b/plugins/modules/ibm_sa_vol.py @@ -13,7 +13,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: ibm_sa_vol -short_description: Handle volumes on IBM Spectrum Accelerate Family storage systems. +short_description: Handle volumes on IBM Spectrum Accelerate Family storage systems description: - "This module creates or deletes volumes to be used on IBM Spectrum Accelerate Family storage systems." diff --git a/plugins/modules/ibm_sa_vol_map.py b/plugins/modules/ibm_sa_vol_map.py index 72de7d8c07..f493a2d979 100644 --- a/plugins/modules/ibm_sa_vol_map.py +++ b/plugins/modules/ibm_sa_vol_map.py @@ -13,7 +13,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: ibm_sa_vol_map -short_description: Handles volume mapping on IBM Spectrum Accelerate Family storage systems. +short_description: Handles volume mapping on IBM Spectrum Accelerate Family storage systems description: - "This module maps volumes to or unmaps them from the hosts on diff --git a/plugins/modules/ipa_subca.py b/plugins/modules/ipa_subca.py index ef9f74ed87..b470be6aef 100644 --- a/plugins/modules/ipa_subca.py +++ b/plugins/modules/ipa_subca.py @@ -11,7 +11,7 @@ DOCUMENTATION = r''' --- module: ipa_subca author: Abhijeet Kasurde (@Akasurde) -short_description: Manage FreeIPA Lightweight Sub Certificate Authorities. +short_description: Manage FreeIPA Lightweight Sub Certificate Authorities description: - Add, modify, enable, disable and delete an IPA Lightweight Sub Certificate Authorities using IPA API. options: diff --git a/plugins/modules/jira.py b/plugins/modules/jira.py index 3b006a55bb..5e0a55119c 100644 --- a/plugins/modules/jira.py +++ b/plugins/modules/jira.py @@ -16,7 +16,7 @@ __metaclass__ = type DOCUMENTATION = r""" module: jira -short_description: create and modify issues in a JIRA instance +short_description: Create and modify issues in a JIRA instance description: - Create and modify issues in a JIRA instance. diff --git a/plugins/modules/ldap_entry.py b/plugins/modules/ldap_entry.py index d15b31f6d3..8cacbc42c1 100644 --- a/plugins/modules/ldap_entry.py +++ b/plugins/modules/ldap_entry.py @@ -14,7 +14,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: ldap_entry -short_description: Add or remove LDAP entries. +short_description: Add or remove LDAP entries description: - Add or remove LDAP entries. This module only asserts the existence or non-existence of an LDAP entry, not its attributes. To assert the diff --git a/plugins/modules/ldap_passwd.py b/plugins/modules/ldap_passwd.py index 5ffd5e12ca..029b5df252 100644 --- a/plugins/modules/ldap_passwd.py +++ b/plugins/modules/ldap_passwd.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: ldap_passwd -short_description: Set passwords in LDAP. +short_description: Set passwords in LDAP description: - Set a password for an LDAP entry. This module only asserts that a given password is valid for a given entry. To assert the diff --git a/plugins/modules/librato_annotation.py b/plugins/modules/librato_annotation.py index 4ca2e7204a..70e17cfef4 100644 --- a/plugins/modules/librato_annotation.py +++ b/plugins/modules/librato_annotation.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: librato_annotation -short_description: create an annotation in librato +short_description: Create an annotation in librato description: - Create an annotation event on the given annotation stream :name. If the annotation stream does not exist, it will be created automatically author: "Seth Edwards (@Sedward)" diff --git a/plugins/modules/linode_v4.py b/plugins/modules/linode_v4.py index 6ef8786af8..3613fc7b50 100644 --- a/plugins/modules/linode_v4.py +++ b/plugins/modules/linode_v4.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: linode_v4 -short_description: Manage instances on the Linode cloud. +short_description: Manage instances on the Linode cloud description: Manage instances on the Linode cloud. requirements: - python >= 2.7 diff --git a/plugins/modules/listen_ports_facts.py b/plugins/modules/listen_ports_facts.py index eb1ba09237..bc630e1d2e 100644 --- a/plugins/modules/listen_ports_facts.py +++ b/plugins/modules/listen_ports_facts.py @@ -18,7 +18,7 @@ description: - This module currently supports Linux only. requirements: - netstat or ss -short_description: Gather facts on processes listening on TCP and UDP ports. +short_description: Gather facts on processes listening on TCP and UDP ports notes: - | C(ss) returns all processes for each listen address and port. diff --git a/plugins/modules/lldp.py b/plugins/modules/lldp.py index 9a74f37f37..3a050ae29e 100644 --- a/plugins/modules/lldp.py +++ b/plugins/modules/lldp.py @@ -13,7 +13,7 @@ DOCUMENTATION = ''' --- module: lldp requirements: [ lldpctl ] -short_description: get details reported by lldp +short_description: Get details reported by lldp description: - Reads data out of lldpctl options: {} diff --git a/plugins/modules/logentries_msg.py b/plugins/modules/logentries_msg.py index b1b77e1d62..723273165f 100644 --- a/plugins/modules/logentries_msg.py +++ b/plugins/modules/logentries_msg.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: logentries_msg -short_description: Send a message to logentries. +short_description: Send a message to logentries description: - Send a message to logentries requirements: diff --git a/plugins/modules/manageiq_group.py b/plugins/modules/manageiq_group.py index 509de77e21..5772c19a7e 100644 --- a/plugins/modules/manageiq_group.py +++ b/plugins/modules/manageiq_group.py @@ -12,7 +12,7 @@ DOCUMENTATION = ''' module: manageiq_group -short_description: Management of groups in ManageIQ. +short_description: Management of groups in ManageIQ extends_documentation_fragment: - community.general.manageiq diff --git a/plugins/modules/manageiq_policies.py b/plugins/modules/manageiq_policies.py index ae36094768..c5b2d88287 100644 --- a/plugins/modules/manageiq_policies.py +++ b/plugins/modules/manageiq_policies.py @@ -13,7 +13,7 @@ DOCUMENTATION = ''' module: manageiq_policies -short_description: Management of resource policy_profiles in ManageIQ. +short_description: Management of resource policy_profiles in ManageIQ extends_documentation_fragment: - community.general.manageiq diff --git a/plugins/modules/manageiq_provider.py b/plugins/modules/manageiq_provider.py index 951e9bb07c..5eb6d779ac 100644 --- a/plugins/modules/manageiq_provider.py +++ b/plugins/modules/manageiq_provider.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: manageiq_provider -short_description: Management of provider in ManageIQ. +short_description: Management of provider in ManageIQ extends_documentation_fragment: - community.general.manageiq diff --git a/plugins/modules/manageiq_tags.py b/plugins/modules/manageiq_tags.py index 209fb5ea9d..9d051a5aa1 100644 --- a/plugins/modules/manageiq_tags.py +++ b/plugins/modules/manageiq_tags.py @@ -13,7 +13,7 @@ DOCUMENTATION = ''' module: manageiq_tags -short_description: Management of resource tags in ManageIQ. +short_description: Management of resource tags in ManageIQ extends_documentation_fragment: - community.general.manageiq diff --git a/plugins/modules/manageiq_tenant.py b/plugins/modules/manageiq_tenant.py index 0f4473092b..f3700d2492 100644 --- a/plugins/modules/manageiq_tenant.py +++ b/plugins/modules/manageiq_tenant.py @@ -12,7 +12,7 @@ DOCUMENTATION = ''' module: manageiq_tenant -short_description: Management of tenants in ManageIQ. +short_description: Management of tenants in ManageIQ extends_documentation_fragment: - community.general.manageiq diff --git a/plugins/modules/manageiq_user.py b/plugins/modules/manageiq_user.py index b9b69182cb..9910e092e0 100644 --- a/plugins/modules/manageiq_user.py +++ b/plugins/modules/manageiq_user.py @@ -12,7 +12,7 @@ DOCUMENTATION = ''' module: manageiq_user -short_description: Management of users in ManageIQ. +short_description: Management of users in ManageIQ extends_documentation_fragment: - community.general.manageiq From 4948b521a315d5a68653c6e949dfd890f660ec8b Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 14:11:41 +0100 Subject: [PATCH 014/134] short_description fix batch 2 (#5520) (#5523) (cherry picked from commit f683d6a05dd57deb4347755cf26064fd65bf8efc) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- plugins/modules/consul.py | 2 +- plugins/modules/etcd3.py | 2 +- plugins/modules/gitlab_protected_branch.py | 4 ++-- plugins/modules/heroku_collaborator.py | 2 +- plugins/modules/ipinfoio_facts.py | 2 +- plugins/modules/launchd.py | 2 +- plugins/modules/memset_memstore_info.py | 2 +- plugins/modules/memset_server_info.py | 2 +- plugins/modules/memset_zone.py | 2 +- plugins/modules/memset_zone_domain.py | 2 +- plugins/modules/memset_zone_record.py | 2 +- plugins/modules/mksysb.py | 2 +- plugins/modules/mssql_db.py | 2 +- plugins/modules/nagios.py | 2 +- plugins/modules/netcup_dns.py | 2 +- plugins/modules/nginx_status_info.py | 2 +- plugins/modules/nosh.py | 2 +- plugins/modules/nsupdate.py | 2 +- plugins/modules/omapi_host.py | 2 +- plugins/modules/oneandone_firewall_policy.py | 2 +- plugins/modules/oneandone_load_balancer.py | 2 +- plugins/modules/oneandone_monitoring_policy.py | 2 +- plugins/modules/oneandone_private_network.py | 2 +- plugins/modules/oneandone_public_ip.py | 2 +- plugins/modules/oneandone_server.py | 2 +- plugins/modules/oneview_fc_network.py | 2 +- plugins/modules/online_server_info.py | 2 +- plugins/modules/online_user_info.py | 2 +- plugins/modules/opendj_backendprop.py | 2 +- plugins/modules/openwrt_init.py | 2 +- plugins/modules/packet_device.py | 2 +- plugins/modules/packet_ip_subnet.py | 2 +- plugins/modules/packet_project.py | 2 +- plugins/modules/packet_sshkey.py | 2 +- plugins/modules/packet_volume.py | 2 +- plugins/modules/packet_volume_attachment.py | 2 +- plugins/modules/pids.py | 2 +- plugins/modules/pip_package_info.py | 2 +- plugins/modules/pkgin.py | 2 +- plugins/modules/profitbricks.py | 2 +- plugins/modules/profitbricks_datacenter.py | 2 +- plugins/modules/profitbricks_nic.py | 2 +- plugins/modules/profitbricks_volume.py | 2 +- plugins/modules/profitbricks_volume_attachments.py | 2 +- plugins/modules/proxmox.py | 2 +- plugins/modules/proxmox_disk.py | 2 +- plugins/modules/proxmox_kvm.py | 2 +- plugins/modules/proxmox_nic.py | 2 +- plugins/modules/proxmox_template.py | 2 +- plugins/modules/pubnub_blocks.py | 2 +- 50 files changed, 51 insertions(+), 51 deletions(-) diff --git a/plugins/modules/consul.py b/plugins/modules/consul.py index a7cefc9865..aabc1bd4b7 100644 --- a/plugins/modules/consul.py +++ b/plugins/modules/consul.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: consul -short_description: "Add, modify & delete services within a consul cluster" +short_description: Add, modify & delete services within a consul cluster description: - Registers services and checks for an agent with a consul cluster. A service is some process running on the agent node that should be advertised by diff --git a/plugins/modules/etcd3.py b/plugins/modules/etcd3.py index e67227cc19..2a89c71968 100644 --- a/plugins/modules/etcd3.py +++ b/plugins/modules/etcd3.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: etcd3 -short_description: "Set or delete key value pairs from an etcd3 cluster" +short_description: Set or delete key value pairs from an etcd3 cluster requirements: - etcd3 description: diff --git a/plugins/modules/gitlab_protected_branch.py b/plugins/modules/gitlab_protected_branch.py index bddf175f0f..335e1445a2 100644 --- a/plugins/modules/gitlab_protected_branch.py +++ b/plugins/modules/gitlab_protected_branch.py @@ -9,7 +9,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: gitlab_protected_branch -short_description: (un)Marking existing branches for protection +short_description: Manage protection of existing branches version_added: 3.4.0 description: - (un)Marking existing branches for protection. @@ -25,7 +25,7 @@ extends_documentation_fragment: options: state: description: - - Create or delete proteced branch. + - Create or delete protected branch. default: present type: str choices: ["present", "absent"] diff --git a/plugins/modules/heroku_collaborator.py b/plugins/modules/heroku_collaborator.py index e29439ca2f..d76b2b6507 100644 --- a/plugins/modules/heroku_collaborator.py +++ b/plugins/modules/heroku_collaborator.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: heroku_collaborator -short_description: "Add or delete app collaborators on Heroku" +short_description: Add or delete app collaborators on Heroku description: - Manages collaborators for Heroku apps. - If set to C(present) and heroku user is already collaborator, then do nothing. diff --git a/plugins/modules/ipinfoio_facts.py b/plugins/modules/ipinfoio_facts.py index 676e88d84d..f29b3cbf4c 100644 --- a/plugins/modules/ipinfoio_facts.py +++ b/plugins/modules/ipinfoio_facts.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: ipinfoio_facts -short_description: "Retrieve IP geolocation facts of a host's IP address" +short_description: Retrieve IP geolocation facts of a host's IP address description: - "Gather IP geolocation facts of a host's IP address using ipinfo.io API" author: "Aleksei Kostiuk (@akostyuk)" diff --git a/plugins/modules/launchd.py b/plugins/modules/launchd.py index 6e14e4c10c..250bbffb9e 100644 --- a/plugins/modules/launchd.py +++ b/plugins/modules/launchd.py @@ -13,7 +13,7 @@ DOCUMENTATION = r''' module: launchd author: - Martin Migasiewicz (@martinm82) -short_description: Manage macOS services +short_description: Manage macOS services version_added: 1.0.0 description: - Manage launchd services on target macOS hosts. diff --git a/plugins/modules/memset_memstore_info.py b/plugins/modules/memset_memstore_info.py index 4de803f991..8ce3d5b05a 100644 --- a/plugins/modules/memset_memstore_info.py +++ b/plugins/modules/memset_memstore_info.py @@ -12,7 +12,7 @@ DOCUMENTATION = ''' --- module: memset_memstore_info author: "Simon Weald (@glitchcrab)" -short_description: Retrieve Memstore product usage information. +short_description: Retrieve Memstore product usage information notes: - An API key generated via the Memset customer control panel is needed with the following minimum scope - I(memstore.usage). diff --git a/plugins/modules/memset_server_info.py b/plugins/modules/memset_server_info.py index 44aa0d8442..0c78f2bd1d 100644 --- a/plugins/modules/memset_server_info.py +++ b/plugins/modules/memset_server_info.py @@ -12,7 +12,7 @@ DOCUMENTATION = ''' --- module: memset_server_info author: "Simon Weald (@glitchcrab)" -short_description: Retrieve server information. +short_description: Retrieve server information notes: - An API key generated via the Memset customer control panel is needed with the following minimum scope - I(server.info). diff --git a/plugins/modules/memset_zone.py b/plugins/modules/memset_zone.py index 9731e3a943..02b5fd28f0 100644 --- a/plugins/modules/memset_zone.py +++ b/plugins/modules/memset_zone.py @@ -12,7 +12,7 @@ DOCUMENTATION = ''' --- module: memset_zone author: "Simon Weald (@glitchcrab)" -short_description: Creates and deletes Memset DNS zones. +short_description: Creates and deletes Memset DNS zones notes: - Zones can be thought of as a logical group of domains, all of which share the same DNS records (i.e. they point to the same IP). An API key generated via the diff --git a/plugins/modules/memset_zone_domain.py b/plugins/modules/memset_zone_domain.py index 995c7bc8d3..1e18a984b6 100644 --- a/plugins/modules/memset_zone_domain.py +++ b/plugins/modules/memset_zone_domain.py @@ -12,7 +12,7 @@ DOCUMENTATION = ''' --- module: memset_zone_domain author: "Simon Weald (@glitchcrab)" -short_description: Create and delete domains in Memset DNS zones. +short_description: Create and delete domains in Memset DNS zones notes: - Zone domains can be thought of as a collection of domains, all of which share the same DNS records (i.e. they point to the same IP). An API key generated via the diff --git a/plugins/modules/memset_zone_record.py b/plugins/modules/memset_zone_record.py index c114532f90..925a034c56 100644 --- a/plugins/modules/memset_zone_record.py +++ b/plugins/modules/memset_zone_record.py @@ -12,7 +12,7 @@ DOCUMENTATION = ''' --- module: memset_zone_record author: "Simon Weald (@glitchcrab)" -short_description: Create and delete records in Memset DNS zones. +short_description: Create and delete records in Memset DNS zones notes: - Zones can be thought of as a logical group of domains, all of which share the same DNS records (i.e. they point to the same IP). An API key generated via the diff --git a/plugins/modules/mksysb.py b/plugins/modules/mksysb.py index a466bd9df6..15b6ad9442 100644 --- a/plugins/modules/mksysb.py +++ b/plugins/modules/mksysb.py @@ -14,7 +14,7 @@ DOCUMENTATION = ''' --- author: Kairo Araujo (@kairoaraujo) module: mksysb -short_description: Generates AIX mksysb rootvg backups. +short_description: Generates AIX mksysb rootvg backups description: - This module manages a basic AIX mksysb (image) of rootvg. options: diff --git a/plugins/modules/mssql_db.py b/plugins/modules/mssql_db.py index a7d16b2710..58a8c4dea9 100644 --- a/plugins/modules/mssql_db.py +++ b/plugins/modules/mssql_db.py @@ -13,7 +13,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: mssql_db -short_description: Add or remove MSSQL databases from a remote host. +short_description: Add or remove MSSQL databases from a remote host description: - Add or remove MSSQL databases from a remote host. options: diff --git a/plugins/modules/nagios.py b/plugins/modules/nagios.py index 4fb2a9ff45..ec526a3959 100644 --- a/plugins/modules/nagios.py +++ b/plugins/modules/nagios.py @@ -17,7 +17,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: nagios -short_description: Perform common tasks in Nagios related to downtime and notifications. +short_description: Perform common tasks in Nagios related to downtime and notifications description: - "The C(nagios) module has two basic functions: scheduling downtime and toggling alerts for services or hosts." - The C(nagios) module is not idempotent. diff --git a/plugins/modules/netcup_dns.py b/plugins/modules/netcup_dns.py index 5d082c2980..4c3c015ebd 100644 --- a/plugins/modules/netcup_dns.py +++ b/plugins/modules/netcup_dns.py @@ -13,7 +13,7 @@ DOCUMENTATION = ''' --- module: netcup_dns notes: [] -short_description: manage Netcup DNS records +short_description: Manage Netcup DNS records description: - "Manages DNS records via the Netcup API, see the docs U(https://ccp.netcup.net/run/webservice/servers/endpoint.php)." options: diff --git a/plugins/modules/nginx_status_info.py b/plugins/modules/nginx_status_info.py index 1e1bb10495..6bbea078b0 100644 --- a/plugins/modules/nginx_status_info.py +++ b/plugins/modules/nginx_status_info.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: nginx_status_info -short_description: Retrieve information on nginx status. +short_description: Retrieve information on nginx status description: - Gathers information from nginx from an URL having C(stub_status) enabled. author: "RenΓ© Moser (@resmo)" diff --git a/plugins/modules/nosh.py b/plugins/modules/nosh.py index 756f5fed42..432990a4d2 100644 --- a/plugins/modules/nosh.py +++ b/plugins/modules/nosh.py @@ -14,7 +14,7 @@ DOCUMENTATION = ''' module: nosh author: - "Thomas Caravia (@tacatac)" -short_description: Manage services with nosh +short_description: Manage services with nosh description: - Control running and enabled state for system-wide or user services. - BSD and Linux systems are supported. diff --git a/plugins/modules/nsupdate.py b/plugins/modules/nsupdate.py index 43b951fe61..2be4863b68 100644 --- a/plugins/modules/nsupdate.py +++ b/plugins/modules/nsupdate.py @@ -18,7 +18,7 @@ DOCUMENTATION = ''' --- module: nsupdate -short_description: Manage DNS records. +short_description: Manage DNS records description: - Create, update and remove DNS records using DDNS updates requirements: diff --git a/plugins/modules/omapi_host.py b/plugins/modules/omapi_host.py index 7d1897ca55..4e3a6247d6 100644 --- a/plugins/modules/omapi_host.py +++ b/plugins/modules/omapi_host.py @@ -13,7 +13,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: omapi_host -short_description: Setup OMAPI hosts. +short_description: Setup OMAPI hosts description: Manage OMAPI hosts into compatible DHCPd servers requirements: - pypureomapi diff --git a/plugins/modules/oneandone_firewall_policy.py b/plugins/modules/oneandone_firewall_policy.py index 23203e8d05..5cceffa812 100644 --- a/plugins/modules/oneandone_firewall_policy.py +++ b/plugins/modules/oneandone_firewall_policy.py @@ -10,7 +10,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: oneandone_firewall_policy -short_description: Configure 1&1 firewall policy. +short_description: Configure 1&1 firewall policy description: - Create, remove, reconfigure, update firewall policies. This module has a dependency on 1and1 >= 1.0 diff --git a/plugins/modules/oneandone_load_balancer.py b/plugins/modules/oneandone_load_balancer.py index 04aefde63a..432fc456b1 100644 --- a/plugins/modules/oneandone_load_balancer.py +++ b/plugins/modules/oneandone_load_balancer.py @@ -10,7 +10,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: oneandone_load_balancer -short_description: Configure 1&1 load balancer. +short_description: Configure 1&1 load balancer description: - Create, remove, update load balancers. This module has a dependency on 1and1 >= 1.0 diff --git a/plugins/modules/oneandone_monitoring_policy.py b/plugins/modules/oneandone_monitoring_policy.py index 46c68e86e0..04e9c67570 100644 --- a/plugins/modules/oneandone_monitoring_policy.py +++ b/plugins/modules/oneandone_monitoring_policy.py @@ -10,7 +10,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: oneandone_monitoring_policy -short_description: Configure 1&1 monitoring policy. +short_description: Configure 1&1 monitoring policy description: - Create, remove, update monitoring policies (and add/remove ports, processes, and servers). diff --git a/plugins/modules/oneandone_private_network.py b/plugins/modules/oneandone_private_network.py index a6db23310a..4a912a0f35 100644 --- a/plugins/modules/oneandone_private_network.py +++ b/plugins/modules/oneandone_private_network.py @@ -10,7 +10,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: oneandone_private_network -short_description: Configure 1&1 private networking. +short_description: Configure 1&1 private networking description: - Create, remove, reconfigure, update a private network. This module has a dependency on 1and1 >= 1.0 diff --git a/plugins/modules/oneandone_public_ip.py b/plugins/modules/oneandone_public_ip.py index a5970735ce..31ed082c74 100644 --- a/plugins/modules/oneandone_public_ip.py +++ b/plugins/modules/oneandone_public_ip.py @@ -10,7 +10,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: oneandone_public_ip -short_description: Configure 1&1 public IPs. +short_description: Configure 1&1 public IPs description: - Create, update, and remove public IPs. This module has a dependency on 1and1 >= 1.0 diff --git a/plugins/modules/oneandone_server.py b/plugins/modules/oneandone_server.py index 22b4b9dd69..e0f1b0eb03 100644 --- a/plugins/modules/oneandone_server.py +++ b/plugins/modules/oneandone_server.py @@ -10,7 +10,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: oneandone_server -short_description: Create, destroy, start, stop, and reboot a 1&1 Host server. +short_description: Create, destroy, start, stop, and reboot a 1&1 Host server description: - Create, destroy, update, start, stop, and reboot a 1&1 Host server. When the server is created it can optionally wait for it to be 'running' before returning. diff --git a/plugins/modules/oneview_fc_network.py b/plugins/modules/oneview_fc_network.py index e4b1a17339..2898447c0b 100644 --- a/plugins/modules/oneview_fc_network.py +++ b/plugins/modules/oneview_fc_network.py @@ -10,7 +10,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: oneview_fc_network -short_description: Manage OneView Fibre Channel Network resources. +short_description: Manage OneView Fibre Channel Network resources description: - Provides an interface to manage Fibre Channel Network resources. Can create, update, and delete. requirements: diff --git a/plugins/modules/online_server_info.py b/plugins/modules/online_server_info.py index 533e0453f9..f6d03cb275 100644 --- a/plugins/modules/online_server_info.py +++ b/plugins/modules/online_server_info.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: online_server_info -short_description: Gather information about Online servers. +short_description: Gather information about Online servers description: - Gather information about the servers. - U(https://www.online.net/en/dedicated-server) diff --git a/plugins/modules/online_user_info.py b/plugins/modules/online_user_info.py index 17cbc7d662..1d91418caf 100644 --- a/plugins/modules/online_user_info.py +++ b/plugins/modules/online_user_info.py @@ -9,7 +9,7 @@ __metaclass__ = type DOCUMENTATION = r''' module: online_user_info -short_description: Gather information about Online user. +short_description: Gather information about Online user description: - Gather information about the user. author: diff --git a/plugins/modules/opendj_backendprop.py b/plugins/modules/opendj_backendprop.py index dfdf6a903a..7e620c4305 100644 --- a/plugins/modules/opendj_backendprop.py +++ b/plugins/modules/opendj_backendprop.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: opendj_backendprop -short_description: Will update the backend configuration of OpenDJ via the dsconfig set-backend-prop command. +short_description: Will update the backend configuration of OpenDJ via the dsconfig set-backend-prop command description: - This module will update settings for OpenDJ with the command set-backend-prop. - It will check first via de get-backend-prop if configuration needs to be applied. diff --git a/plugins/modules/openwrt_init.py b/plugins/modules/openwrt_init.py index be7031791e..978a6bec35 100644 --- a/plugins/modules/openwrt_init.py +++ b/plugins/modules/openwrt_init.py @@ -12,7 +12,7 @@ DOCUMENTATION = ''' module: openwrt_init author: - "Andrew Gaffney (@agaffney)" -short_description: Manage services on OpenWrt. +short_description: Manage services on OpenWrt description: - Controls OpenWrt services on remote hosts. options: diff --git a/plugins/modules/packet_device.py b/plugins/modules/packet_device.py index 6b78406a6e..500a400273 100644 --- a/plugins/modules/packet_device.py +++ b/plugins/modules/packet_device.py @@ -14,7 +14,7 @@ DOCUMENTATION = ''' --- module: packet_device -short_description: Manage a bare metal server in the Packet Host. +short_description: Manage a bare metal server in the Packet Host description: - Manage a bare metal server in the Packet Host (a "device" in the API terms). diff --git a/plugins/modules/packet_ip_subnet.py b/plugins/modules/packet_ip_subnet.py index 79f93a6413..63790e1c6a 100644 --- a/plugins/modules/packet_ip_subnet.py +++ b/plugins/modules/packet_ip_subnet.py @@ -14,7 +14,7 @@ DOCUMENTATION = ''' --- module: packet_ip_subnet -short_description: Assign IP subnet to a bare metal server. +short_description: Assign IP subnet to a bare metal server description: - Assign or unassign IPv4 or IPv6 subnets to or from a device in the Packet host. diff --git a/plugins/modules/packet_project.py b/plugins/modules/packet_project.py index 18b6f73f99..9a82c2ec72 100644 --- a/plugins/modules/packet_project.py +++ b/plugins/modules/packet_project.py @@ -14,7 +14,7 @@ DOCUMENTATION = ''' --- module: packet_project -short_description: Create/delete a project in Packet host. +short_description: Create/delete a project in Packet host description: - Create/delete a project in Packet host. diff --git a/plugins/modules/packet_sshkey.py b/plugins/modules/packet_sshkey.py index d39e419747..87beb01aa8 100644 --- a/plugins/modules/packet_sshkey.py +++ b/plugins/modules/packet_sshkey.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: packet_sshkey -short_description: Create/delete an SSH key in Packet host. +short_description: Create/delete an SSH key in Packet host description: - Create/delete an SSH key in Packet host. - API is documented at U(https://www.packet.net/help/api/#page:ssh-keys,header:ssh-keys-ssh-keys-post). diff --git a/plugins/modules/packet_volume.py b/plugins/modules/packet_volume.py index f0508c5891..b06e57b56c 100644 --- a/plugins/modules/packet_volume.py +++ b/plugins/modules/packet_volume.py @@ -13,7 +13,7 @@ DOCUMENTATION = ''' --- module: packet_volume -short_description: Create/delete a volume in Packet host. +short_description: Create/delete a volume in Packet host description: - Create/delete a volume in Packet host. diff --git a/plugins/modules/packet_volume_attachment.py b/plugins/modules/packet_volume_attachment.py index 4f55d60cfa..74b42ab479 100644 --- a/plugins/modules/packet_volume_attachment.py +++ b/plugins/modules/packet_volume_attachment.py @@ -14,7 +14,7 @@ DOCUMENTATION = ''' --- module: packet_volume_attachment -short_description: Attach/detach a volume to a device in the Packet host. +short_description: Attach/detach a volume to a device in the Packet host description: - Attach/detach a volume to a device in the Packet host. diff --git a/plugins/modules/pids.py b/plugins/modules/pids.py index 072a2bb7a4..eaaf7f9437 100644 --- a/plugins/modules/pids.py +++ b/plugins/modules/pids.py @@ -10,7 +10,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: pids description: "Retrieves a list of PIDs of given process name in Ansible controller/controlled machines.Returns an empty list if no process in that name exists." -short_description: "Retrieves process IDs list if the process is running otherwise return empty list" +short_description: Retrieves process IDs list if the process is running otherwise return empty list author: - Saranya Sridharan (@saranyasridharan) requirements: diff --git a/plugins/modules/pip_package_info.py b/plugins/modules/pip_package_info.py index c89e47014e..2cde7218d4 100644 --- a/plugins/modules/pip_package_info.py +++ b/plugins/modules/pip_package_info.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: pip_package_info -short_description: pip package information +short_description: Pip package information description: - Return information about installed pip packages extends_documentation_fragment: diff --git a/plugins/modules/pkgin.py b/plugins/modules/pkgin.py index 477460e0e3..0da06e0502 100644 --- a/plugins/modules/pkgin.py +++ b/plugins/modules/pkgin.py @@ -19,7 +19,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: pkgin -short_description: Package manager for SmartOS, NetBSD, et al. +short_description: Package manager for SmartOS, NetBSD, et al description: - "The standard package manager for SmartOS, but also usable on NetBSD or any OS that uses C(pkgsrc). (Home: U(http://pkgin.net/))" diff --git a/plugins/modules/profitbricks.py b/plugins/modules/profitbricks.py index cb41491464..6b0134cb99 100644 --- a/plugins/modules/profitbricks.py +++ b/plugins/modules/profitbricks.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: profitbricks -short_description: Create, destroy, start, stop, and reboot a ProfitBricks virtual machine. +short_description: Create, destroy, start, stop, and reboot a ProfitBricks virtual machine description: - Create, destroy, update, start, stop, and reboot a ProfitBricks virtual machine. When the virtual machine is created it can optionally wait for it to be 'running' before returning. This module has a dependency on profitbricks >= 1.0.0 diff --git a/plugins/modules/profitbricks_datacenter.py b/plugins/modules/profitbricks_datacenter.py index cc3184320d..a11d12bfd9 100644 --- a/plugins/modules/profitbricks_datacenter.py +++ b/plugins/modules/profitbricks_datacenter.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: profitbricks_datacenter -short_description: Create or destroy a ProfitBricks Virtual Datacenter. +short_description: Create or destroy a ProfitBricks Virtual Datacenter description: - This is a simple module that supports creating or removing vDCs. A vDC is required before you can create servers. This module has a dependency on profitbricks >= 1.0.0 diff --git a/plugins/modules/profitbricks_nic.py b/plugins/modules/profitbricks_nic.py index facb146b60..c6239f5ef5 100644 --- a/plugins/modules/profitbricks_nic.py +++ b/plugins/modules/profitbricks_nic.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: profitbricks_nic -short_description: Create or Remove a NIC. +short_description: Create or Remove a NIC description: - This module allows you to create or restore a volume snapshot. This module has a dependency on profitbricks >= 1.0.0 options: diff --git a/plugins/modules/profitbricks_volume.py b/plugins/modules/profitbricks_volume.py index 2d449fd92a..1d21897715 100644 --- a/plugins/modules/profitbricks_volume.py +++ b/plugins/modules/profitbricks_volume.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: profitbricks_volume -short_description: Create or destroy a volume. +short_description: Create or destroy a volume description: - Allows you to create or remove a volume from a ProfitBricks datacenter. This module has a dependency on profitbricks >= 1.0.0 options: diff --git a/plugins/modules/profitbricks_volume_attachments.py b/plugins/modules/profitbricks_volume_attachments.py index 5637aca67f..49b418362b 100644 --- a/plugins/modules/profitbricks_volume_attachments.py +++ b/plugins/modules/profitbricks_volume_attachments.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: profitbricks_volume_attachments -short_description: Attach or detach a volume. +short_description: Attach or detach a volume description: - Allows you to attach or detach a volume from a ProfitBricks server. This module has a dependency on profitbricks >= 1.0.0 options: diff --git a/plugins/modules/proxmox.py b/plugins/modules/proxmox.py index 5a89ee7796..89706655f2 100644 --- a/plugins/modules/proxmox.py +++ b/plugins/modules/proxmox.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: proxmox -short_description: management of instances in Proxmox VE cluster +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) diff --git a/plugins/modules/proxmox_disk.py b/plugins/modules/proxmox_disk.py index 182a0d25f2..7a39d38d05 100644 --- a/plugins/modules/proxmox_disk.py +++ b/plugins/modules/proxmox_disk.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: proxmox_disk -short_description: Management of a disk of a Qemu(KVM) VM in a Proxmox VE cluster. +short_description: Management of a disk of a Qemu(KVM) VM in a Proxmox VE cluster version_added: 5.7.0 description: - Allows you to perform some supported operations on a disk in Qemu(KVM) Virtual Machines in a Proxmox VE cluster. diff --git a/plugins/modules/proxmox_kvm.py b/plugins/modules/proxmox_kvm.py index 92aaf6a904..25e252bee9 100644 --- a/plugins/modules/proxmox_kvm.py +++ b/plugins/modules/proxmox_kvm.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: proxmox_kvm -short_description: Management of Qemu(KVM) Virtual Machines in Proxmox VE cluster. +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). diff --git a/plugins/modules/proxmox_nic.py b/plugins/modules/proxmox_nic.py index 49f7f91bcd..bcc56de57e 100644 --- a/plugins/modules/proxmox_nic.py +++ b/plugins/modules/proxmox_nic.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: proxmox_nic -short_description: Management of a NIC of a Qemu(KVM) VM in a Proxmox VE cluster. +short_description: Management of a NIC of a Qemu(KVM) VM in a Proxmox VE cluster version_added: 3.1.0 description: - Allows you to create/update/delete a NIC on Qemu(KVM) Virtual Machines in a Proxmox VE cluster. diff --git a/plugins/modules/proxmox_template.py b/plugins/modules/proxmox_template.py index 24a6c87d31..a09af2f2a3 100644 --- a/plugins/modules/proxmox_template.py +++ b/plugins/modules/proxmox_template.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: proxmox_template -short_description: management of OS templates in Proxmox VE cluster +short_description: Management of OS templates in Proxmox VE cluster description: - allows you to upload/delete templates in Proxmox VE cluster options: diff --git a/plugins/modules/pubnub_blocks.py b/plugins/modules/pubnub_blocks.py index 9942c57134..28b17b5431 100644 --- a/plugins/modules/pubnub_blocks.py +++ b/plugins/modules/pubnub_blocks.py @@ -17,7 +17,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: pubnub_blocks -short_description: PubNub blocks management module. +short_description: PubNub blocks management module description: - "This module allows Ansible to interface with the PubNub BLOCKS infrastructure by providing the following operations: create / remove, From 076ebb4b2d7e6ed9a034a93e54116ce5a0813cb9 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 18:44:48 +0100 Subject: [PATCH 015/134] Ignore mpdehaan in BOTMETA. (#5524) (#5525) (cherry picked from commit 0e9cd5e6b6ae33b0d0781c0d81413b0bb52d2dbb) Co-authored-by: Felix Fontein --- .github/BOTMETA.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index dfacfbecfb..c56720cb0d 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -822,7 +822,8 @@ files: maintainers: marc-sensenich $modules/ohai.py: labels: ohai - maintainers: $team_ansible_core mpdehaan + maintainers: $team_ansible_core + ignore: mpdehaan $modules/omapi_host.py: maintainers: amasolov nerzhul $modules/one_: @@ -1072,7 +1073,8 @@ files: $modules/sapcar_extract.py: maintainers: RainerLeber $modules/say.py: - maintainers: $team_ansible_core mpdehaan + maintainers: $team_ansible_core + ignore: mpdehaan $modules/scaleway_: maintainers: $team_scaleway $modules/scaleway_compute_private_network.py: From 246abffce5643845771ba5a46e350cc0062d9dd8 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Wed, 9 Nov 2022 21:17:15 +0100 Subject: [PATCH 016/134] Prepare 6.0.1 release. --- changelogs/fragments/6.0.1.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/fragments/6.0.1.yml diff --git a/changelogs/fragments/6.0.1.yml b/changelogs/fragments/6.0.1.yml new file mode 100644 index 0000000000..9fe28c711a --- /dev/null +++ b/changelogs/fragments/6.0.1.yml @@ -0,0 +1 @@ +release_summary: Bugfix release for Ansible 7.0.0. From 618e567377cdd41b3a3bc6c3d65597bae15a0ccb Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 9 Nov 2022 21:18:39 +0100 Subject: [PATCH 017/134] Short descriptions (batch3) - massive fix on Capitalization and trailing period (#5521) (#5529) * short_description fix batch 3 * Update plugins/modules/telegram.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 6b20572ea17da272be87d74e3abf52153a3b33f1) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- plugins/modules/pulp_repo.py | 2 +- plugins/modules/rax.py | 2 +- plugins/modules/rax_cdb.py | 2 +- plugins/modules/rax_cdb_database.py | 2 +- plugins/modules/rax_cdb_user.py | 2 +- plugins/modules/rax_clb.py | 2 +- plugins/modules/rax_clb_nodes.py | 2 +- plugins/modules/rax_clb_ssl.py | 2 +- plugins/modules/rax_mon_alarm.py | 2 +- plugins/modules/rax_mon_notification.py | 2 +- plugins/modules/rax_network.py | 2 +- plugins/modules/rax_queue.py | 2 +- plugins/modules/rundeck_acl_policy.py | 2 +- plugins/modules/rundeck_project.py | 2 +- plugins/modules/say.py | 2 +- plugins/modules/scaleway_image_info.py | 2 +- plugins/modules/scaleway_ip_info.py | 2 +- plugins/modules/scaleway_organization_info.py | 2 +- plugins/modules/scaleway_security_group_info.py | 2 +- plugins/modules/scaleway_server_info.py | 2 +- plugins/modules/scaleway_snapshot_info.py | 2 +- plugins/modules/scaleway_volume_info.py | 2 +- plugins/modules/sl_vm.py | 2 +- plugins/modules/smartos_image_info.py | 2 +- plugins/modules/spectrum_device.py | 2 +- plugins/modules/spectrum_model_attrs.py | 2 +- plugins/modules/svc.py | 2 +- plugins/modules/swupd.py | 2 +- plugins/modules/telegram.py | 2 +- plugins/modules/twilio.py | 2 +- plugins/modules/utm_aaa_group.py | 2 +- plugins/modules/utm_aaa_group_info.py | 2 +- plugins/modules/utm_ca_host_key_cert.py | 2 +- plugins/modules/utm_dns_host.py | 2 +- plugins/modules/utm_proxy_auth_profile.py | 2 +- plugins/modules/utm_proxy_frontend.py | 2 +- plugins/modules/utm_proxy_frontend_info.py | 2 +- plugins/modules/utm_proxy_location.py | 2 +- plugins/modules/utm_proxy_location_info.py | 2 +- plugins/modules/vertica_configuration.py | 2 +- plugins/modules/vertica_info.py | 2 +- plugins/modules/vertica_role.py | 2 +- plugins/modules/vertica_schema.py | 2 +- plugins/modules/vertica_user.py | 2 +- plugins/modules/vmadm.py | 2 +- plugins/modules/xenserver_facts.py | 2 +- plugins/modules/zfs_facts.py | 2 +- plugins/modules/zpool_facts.py | 2 +- 48 files changed, 48 insertions(+), 48 deletions(-) diff --git a/plugins/modules/pulp_repo.py b/plugins/modules/pulp_repo.py index 030d2fd9af..9e100ba93e 100644 --- a/plugins/modules/pulp_repo.py +++ b/plugins/modules/pulp_repo.py @@ -14,7 +14,7 @@ DOCUMENTATION = ''' --- module: pulp_repo author: "Joe Adams (@sysadmind)" -short_description: Add or remove Pulp repos from a remote host. +short_description: Add or remove Pulp repos from a remote host description: - Add or remove Pulp repos from a remote host. - Note, this is for Pulp 2 only. diff --git a/plugins/modules/rax.py b/plugins/modules/rax.py index b35384173a..fa929f7971 100644 --- a/plugins/modules/rax.py +++ b/plugins/modules/rax.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: rax -short_description: create / delete an instance in Rackspace Public Cloud +short_description: Create / delete an instance in Rackspace Public Cloud description: - creates / deletes a Rackspace Public Cloud instance and optionally waits for it to be 'running'. diff --git a/plugins/modules/rax_cdb.py b/plugins/modules/rax_cdb.py index 6703a8dd4b..3fb6194d9d 100644 --- a/plugins/modules/rax_cdb.py +++ b/plugins/modules/rax_cdb.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: rax_cdb -short_description: create/delete or resize a Rackspace Cloud Databases instance +short_description: Create/delete or resize a Rackspace Cloud Databases instance description: - creates / deletes or resize a Rackspace Cloud Databases instance and optionally waits for it to be 'running'. The name option needs to be diff --git a/plugins/modules/rax_cdb_database.py b/plugins/modules/rax_cdb_database.py index 5b5ebc6e29..6e0e8411c2 100644 --- a/plugins/modules/rax_cdb_database.py +++ b/plugins/modules/rax_cdb_database.py @@ -10,7 +10,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: rax_cdb_database -short_description: 'create / delete a database in the Cloud Databases' +short_description: Create / delete a database in the Cloud Databases description: - create / delete a database in the Cloud Databases. options: diff --git a/plugins/modules/rax_cdb_user.py b/plugins/modules/rax_cdb_user.py index ccc3e677a5..63cb00b608 100644 --- a/plugins/modules/rax_cdb_user.py +++ b/plugins/modules/rax_cdb_user.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: rax_cdb_user -short_description: create / delete a Rackspace Cloud Database +short_description: Create / delete a Rackspace Cloud Database description: - create / delete a database in the Cloud Databases. options: diff --git a/plugins/modules/rax_clb.py b/plugins/modules/rax_clb.py index 7d45c865f0..8355a42921 100644 --- a/plugins/modules/rax_clb.py +++ b/plugins/modules/rax_clb.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: rax_clb -short_description: create / delete a load balancer in Rackspace Public Cloud +short_description: Create / delete a load balancer in Rackspace Public Cloud description: - creates / deletes a Rackspace Public Cloud load balancer. options: diff --git a/plugins/modules/rax_clb_nodes.py b/plugins/modules/rax_clb_nodes.py index 04341f7ceb..e6d050de46 100644 --- a/plugins/modules/rax_clb_nodes.py +++ b/plugins/modules/rax_clb_nodes.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: rax_clb_nodes -short_description: add, modify and remove nodes from a Rackspace Cloud Load Balancer +short_description: Add, modify and remove nodes from a Rackspace Cloud Load Balancer description: - Adds, modifies and removes nodes from a Rackspace Cloud Load Balancer options: diff --git a/plugins/modules/rax_clb_ssl.py b/plugins/modules/rax_clb_ssl.py index db192368b4..85110d3390 100644 --- a/plugins/modules/rax_clb_ssl.py +++ b/plugins/modules/rax_clb_ssl.py @@ -10,7 +10,7 @@ __metaclass__ = type DOCUMENTATION = ''' module: rax_clb_ssl -short_description: Manage SSL termination for a Rackspace Cloud Load Balancer. +short_description: Manage SSL termination for a Rackspace Cloud Load Balancer description: - Set up, reconfigure, or remove SSL termination for an existing load balancer. options: diff --git a/plugins/modules/rax_mon_alarm.py b/plugins/modules/rax_mon_alarm.py index dd971f7243..d167420341 100644 --- a/plugins/modules/rax_mon_alarm.py +++ b/plugins/modules/rax_mon_alarm.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: rax_mon_alarm -short_description: Create or delete a Rackspace Cloud Monitoring alarm. +short_description: Create or delete a Rackspace Cloud Monitoring alarm description: - Create or delete a Rackspace Cloud Monitoring alarm that associates an existing rax_mon_entity, rax_mon_check, and rax_mon_notification_plan with diff --git a/plugins/modules/rax_mon_notification.py b/plugins/modules/rax_mon_notification.py index c26b0315db..73bfd1a78f 100644 --- a/plugins/modules/rax_mon_notification.py +++ b/plugins/modules/rax_mon_notification.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: rax_mon_notification -short_description: Create or delete a Rackspace Cloud Monitoring notification. +short_description: Create or delete a Rackspace Cloud Monitoring notification description: - Create or delete a Rackspace Cloud Monitoring notification that specifies a channel that can be used to communicate alarms, such as email, webhooks, or diff --git a/plugins/modules/rax_network.py b/plugins/modules/rax_network.py index 02de3ce011..edb7773b72 100644 --- a/plugins/modules/rax_network.py +++ b/plugins/modules/rax_network.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: rax_network -short_description: create / delete an isolated network in Rackspace Public Cloud +short_description: Create / delete an isolated network in Rackspace Public Cloud description: - creates / deletes a Rackspace Public Cloud isolated network. options: diff --git a/plugins/modules/rax_queue.py b/plugins/modules/rax_queue.py index 366c1c77e3..e053f3266d 100644 --- a/plugins/modules/rax_queue.py +++ b/plugins/modules/rax_queue.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: rax_queue -short_description: create / delete a queue in Rackspace Public Cloud +short_description: Create / delete a queue in Rackspace Public Cloud description: - creates / deletes a Rackspace Public Cloud queue. options: diff --git a/plugins/modules/rundeck_acl_policy.py b/plugins/modules/rundeck_acl_policy.py index 6168cb5b64..4830c44784 100644 --- a/plugins/modules/rundeck_acl_policy.py +++ b/plugins/modules/rundeck_acl_policy.py @@ -15,7 +15,7 @@ DOCUMENTATION = ''' --- module: rundeck_acl_policy -short_description: Manage Rundeck ACL policies. +short_description: Manage Rundeck ACL policies description: - Create, update and remove Rundeck ACL policies through HTTP API. author: "Loic Blot (@nerzhul)" diff --git a/plugins/modules/rundeck_project.py b/plugins/modules/rundeck_project.py index 88f4a78100..2039a00a02 100644 --- a/plugins/modules/rundeck_project.py +++ b/plugins/modules/rundeck_project.py @@ -17,7 +17,7 @@ DOCUMENTATION = ''' --- module: rundeck_project -short_description: Manage Rundeck projects. +short_description: Manage Rundeck projects description: - Create and remove Rundeck projects through HTTP API. author: "Loic Blot (@nerzhul)" diff --git a/plugins/modules/say.py b/plugins/modules/say.py index fe36b02d15..04b5027cae 100644 --- a/plugins/modules/say.py +++ b/plugins/modules/say.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: say -short_description: Makes a computer to speak. +short_description: Makes a computer to speak description: - makes a computer speak! Amuse your friends, annoy your coworkers! notes: diff --git a/plugins/modules/scaleway_image_info.py b/plugins/modules/scaleway_image_info.py index ee0134a52a..56ca689c38 100644 --- a/plugins/modules/scaleway_image_info.py +++ b/plugins/modules/scaleway_image_info.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: scaleway_image_info -short_description: Gather information about the Scaleway images available. +short_description: Gather information about the Scaleway images available description: - Gather information about the Scaleway images available. author: diff --git a/plugins/modules/scaleway_ip_info.py b/plugins/modules/scaleway_ip_info.py index d8725894e6..1fd4be5898 100644 --- a/plugins/modules/scaleway_ip_info.py +++ b/plugins/modules/scaleway_ip_info.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: scaleway_ip_info -short_description: Gather information about the Scaleway ips available. +short_description: Gather information about the Scaleway ips available description: - Gather information about the Scaleway ips available. author: diff --git a/plugins/modules/scaleway_organization_info.py b/plugins/modules/scaleway_organization_info.py index aca8a0c43f..6e1f8df388 100644 --- a/plugins/modules/scaleway_organization_info.py +++ b/plugins/modules/scaleway_organization_info.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: scaleway_organization_info -short_description: Gather information about the Scaleway organizations available. +short_description: Gather information about the Scaleway organizations available description: - Gather information about the Scaleway organizations available. author: diff --git a/plugins/modules/scaleway_security_group_info.py b/plugins/modules/scaleway_security_group_info.py index 7fd96fd067..fb28e87740 100644 --- a/plugins/modules/scaleway_security_group_info.py +++ b/plugins/modules/scaleway_security_group_info.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: scaleway_security_group_info -short_description: Gather information about the Scaleway security groups available. +short_description: Gather information about the Scaleway security groups available description: - Gather information about the Scaleway security groups available. author: diff --git a/plugins/modules/scaleway_server_info.py b/plugins/modules/scaleway_server_info.py index 7a31882ef7..01e9410da8 100644 --- a/plugins/modules/scaleway_server_info.py +++ b/plugins/modules/scaleway_server_info.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: scaleway_server_info -short_description: Gather information about the Scaleway servers available. +short_description: Gather information about the Scaleway servers available description: - Gather information about the Scaleway servers available. author: diff --git a/plugins/modules/scaleway_snapshot_info.py b/plugins/modules/scaleway_snapshot_info.py index 47cd14cee8..687f43c85b 100644 --- a/plugins/modules/scaleway_snapshot_info.py +++ b/plugins/modules/scaleway_snapshot_info.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: scaleway_snapshot_info -short_description: Gather information about the Scaleway snapshots available. +short_description: Gather information about the Scaleway snapshots available description: - Gather information about the Scaleway snapshot available. author: diff --git a/plugins/modules/scaleway_volume_info.py b/plugins/modules/scaleway_volume_info.py index 369fadbe64..471845c43e 100644 --- a/plugins/modules/scaleway_volume_info.py +++ b/plugins/modules/scaleway_volume_info.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: scaleway_volume_info -short_description: Gather information about the Scaleway volumes available. +short_description: Gather information about the Scaleway volumes available description: - Gather information about the Scaleway volumes available. author: diff --git a/plugins/modules/sl_vm.py b/plugins/modules/sl_vm.py index 56b3ccdd39..ca925c345f 100644 --- a/plugins/modules/sl_vm.py +++ b/plugins/modules/sl_vm.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: sl_vm -short_description: create or cancel a virtual instance in SoftLayer +short_description: Create or cancel a virtual instance in SoftLayer description: - Creates or cancels SoftLayer instances. - When created, optionally waits for it to be 'running'. diff --git a/plugins/modules/smartos_image_info.py b/plugins/modules/smartos_image_info.py index 0b5117fc45..37267d115a 100644 --- a/plugins/modules/smartos_image_info.py +++ b/plugins/modules/smartos_image_info.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: smartos_image_info -short_description: Get SmartOS image details. +short_description: Get SmartOS image details description: - Retrieve information about all installed images on SmartOS. - This module was called C(smartos_image_facts) before Ansible 2.9, returning C(ansible_facts). diff --git a/plugins/modules/spectrum_device.py b/plugins/modules/spectrum_device.py index c2bab55016..40093aa3a9 100644 --- a/plugins/modules/spectrum_device.py +++ b/plugins/modules/spectrum_device.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: spectrum_device -short_description: Creates/deletes devices in CA Spectrum. +short_description: Creates/deletes devices in CA Spectrum description: - This module allows you to create and delete devices in CA Spectrum U(https://www.ca.com/us/products/ca-spectrum.html). - Tested on CA Spectrum 9.4.2, 10.1.1 and 10.2.1 diff --git a/plugins/modules/spectrum_model_attrs.py b/plugins/modules/spectrum_model_attrs.py index 5a92802f5f..de771b0ad3 100644 --- a/plugins/modules/spectrum_model_attrs.py +++ b/plugins/modules/spectrum_model_attrs.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = r''' --- module: spectrum_model_attrs -short_description: Enforce a model's attributes in CA Spectrum. +short_description: Enforce a model's attributes in CA Spectrum description: - This module can be used to enforce a model's attributes in CA Spectrum. version_added: 2.5.0 diff --git a/plugins/modules/svc.py b/plugins/modules/svc.py index 2800c9d2bf..4d92892ce3 100644 --- a/plugins/modules/svc.py +++ b/plugins/modules/svc.py @@ -13,7 +13,7 @@ DOCUMENTATION = ''' module: svc author: - Brian Coca (@bcoca) -short_description: Manage daemontools services +short_description: Manage daemontools services description: - Controls daemontools services on remote hosts using the svc utility. options: diff --git a/plugins/modules/swupd.py b/plugins/modules/swupd.py index 4567709f48..a47dd667ae 100644 --- a/plugins/modules/swupd.py +++ b/plugins/modules/swupd.py @@ -13,7 +13,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: swupd -short_description: Manages updates and bundles in ClearLinux systems. +short_description: Manages updates and bundles in ClearLinux systems description: - Manages updates and bundles with the swupd bundle manager, which is used by the Clear Linux Project for Intel Architecture. diff --git a/plugins/modules/telegram.py b/plugins/modules/telegram.py index 499af4ef1a..4e89825120 100644 --- a/plugins/modules/telegram.py +++ b/plugins/modules/telegram.py @@ -16,7 +16,7 @@ author: - "Artem Feofanov (@tyouxa)" - "Nikolai Lomov (@lomserman)" -short_description: module for sending notifications via telegram +short_description: Send notifications via telegram description: - Send notifications via telegram bot, to a verified group or user. diff --git a/plugins/modules/twilio.py b/plugins/modules/twilio.py index 1934820fe3..6d22563d1c 100644 --- a/plugins/modules/twilio.py +++ b/plugins/modules/twilio.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: twilio -short_description: Sends a text message to a mobile phone through Twilio. +short_description: Sends a text message to a mobile phone through Twilio description: - Sends a text message to a phone number through the Twilio messaging API. notes: diff --git a/plugins/modules/utm_aaa_group.py b/plugins/modules/utm_aaa_group.py index cff1834c93..3d5cbc2007 100644 --- a/plugins/modules/utm_aaa_group.py +++ b/plugins/modules/utm_aaa_group.py @@ -15,7 +15,7 @@ module: utm_aaa_group author: - Johannes Brunswicker (@MatrixCrawler) -short_description: Create, update or destroy an aaa group object in Sophos UTM. +short_description: Create, update or destroy an aaa group object in Sophos UTM description: - Create, update or destroy an aaa group object in Sophos UTM. diff --git a/plugins/modules/utm_aaa_group_info.py b/plugins/modules/utm_aaa_group_info.py index a01dad92ac..8798fda7f3 100644 --- a/plugins/modules/utm_aaa_group_info.py +++ b/plugins/modules/utm_aaa_group_info.py @@ -17,7 +17,7 @@ module: utm_aaa_group_info author: - Johannes Brunswicker (@MatrixCrawler) -short_description: get info for reverse_proxy frontend entry in Sophos UTM +short_description: Get info for reverse_proxy frontend entry in Sophos UTM description: - get info for a reverse_proxy frontend entry in SOPHOS UTM. diff --git a/plugins/modules/utm_ca_host_key_cert.py b/plugins/modules/utm_ca_host_key_cert.py index 693f25964a..318bc1fd31 100644 --- a/plugins/modules/utm_ca_host_key_cert.py +++ b/plugins/modules/utm_ca_host_key_cert.py @@ -16,7 +16,7 @@ module: utm_ca_host_key_cert author: - Stephan Schwarz (@stearz) -short_description: create, update or destroy ca host_key_cert entry in Sophos UTM +short_description: Create, update or destroy ca host_key_cert entry in Sophos UTM description: - Create, update or destroy a ca host_key_cert entry in SOPHOS UTM. diff --git a/plugins/modules/utm_dns_host.py b/plugins/modules/utm_dns_host.py index af91e2433b..3a1744651a 100644 --- a/plugins/modules/utm_dns_host.py +++ b/plugins/modules/utm_dns_host.py @@ -15,7 +15,7 @@ module: utm_dns_host author: - Johannes Brunswicker (@MatrixCrawler) -short_description: create, update or destroy dns entry in Sophos UTM +short_description: Create, update or destroy dns entry in Sophos UTM description: - Create, update or destroy a dns entry in SOPHOS UTM. diff --git a/plugins/modules/utm_proxy_auth_profile.py b/plugins/modules/utm_proxy_auth_profile.py index aab426cc03..0c53a92380 100644 --- a/plugins/modules/utm_proxy_auth_profile.py +++ b/plugins/modules/utm_proxy_auth_profile.py @@ -16,7 +16,7 @@ module: utm_proxy_auth_profile author: - Stephan Schwarz (@stearz) -short_description: create, update or destroy reverse_proxy auth_profile entry in Sophos UTM +short_description: Create, update or destroy reverse_proxy auth_profile entry in Sophos UTM description: - Create, update or destroy a reverse_proxy auth_profile entry in SOPHOS UTM. diff --git a/plugins/modules/utm_proxy_frontend.py b/plugins/modules/utm_proxy_frontend.py index 8f5a1e8686..127c7d4d43 100644 --- a/plugins/modules/utm_proxy_frontend.py +++ b/plugins/modules/utm_proxy_frontend.py @@ -16,7 +16,7 @@ module: utm_proxy_frontend author: - Johannes Brunswicker (@MatrixCrawler) -short_description: create, update or destroy reverse_proxy frontend entry in Sophos UTM +short_description: Create, update or destroy reverse_proxy frontend entry in Sophos UTM description: - Create, update or destroy a reverse_proxy frontend entry in Sophos UTM. diff --git a/plugins/modules/utm_proxy_frontend_info.py b/plugins/modules/utm_proxy_frontend_info.py index 0b8e124379..65faecfbc8 100644 --- a/plugins/modules/utm_proxy_frontend_info.py +++ b/plugins/modules/utm_proxy_frontend_info.py @@ -16,7 +16,7 @@ module: utm_proxy_frontend_info author: - Johannes Brunswicker (@MatrixCrawler) -short_description: create, update or destroy reverse_proxy frontend entry in Sophos UTM +short_description: Create, update or destroy reverse_proxy frontend entry in Sophos UTM description: - Create, update or destroy a reverse_proxy frontend entry in SOPHOS UTM. diff --git a/plugins/modules/utm_proxy_location.py b/plugins/modules/utm_proxy_location.py index c6ff1bd26b..0efeea5a27 100644 --- a/plugins/modules/utm_proxy_location.py +++ b/plugins/modules/utm_proxy_location.py @@ -16,7 +16,7 @@ module: utm_proxy_location author: - Johannes Brunswicker (@MatrixCrawler) -short_description: create, update or destroy reverse_proxy location entry in Sophos UTM +short_description: Create, update or destroy reverse_proxy location entry in Sophos UTM description: - Create, update or destroy a reverse_proxy location entry in SOPHOS UTM. diff --git a/plugins/modules/utm_proxy_location_info.py b/plugins/modules/utm_proxy_location_info.py index 0e7b165903..4b502df296 100644 --- a/plugins/modules/utm_proxy_location_info.py +++ b/plugins/modules/utm_proxy_location_info.py @@ -16,7 +16,7 @@ module: utm_proxy_location_info author: - Johannes Brunswicker (@MatrixCrawler) -short_description: create, update or destroy reverse_proxy location entry in Sophos UTM +short_description: Create, update or destroy reverse_proxy location entry in Sophos UTM description: - Create, update or destroy a reverse_proxy location entry in SOPHOS UTM. diff --git a/plugins/modules/vertica_configuration.py b/plugins/modules/vertica_configuration.py index f3ac067d0f..553630da39 100644 --- a/plugins/modules/vertica_configuration.py +++ b/plugins/modules/vertica_configuration.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: vertica_configuration -short_description: Updates Vertica configuration parameters. +short_description: Updates Vertica configuration parameters description: - Updates Vertica configuration parameters. options: diff --git a/plugins/modules/vertica_info.py b/plugins/modules/vertica_info.py index a51187de1d..3106be3b38 100644 --- a/plugins/modules/vertica_info.py +++ b/plugins/modules/vertica_info.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: vertica_info -short_description: Gathers Vertica database facts. +short_description: Gathers Vertica database facts description: - Gathers Vertica database information. - This module was called C(vertica_facts) before Ansible 2.9, returning C(ansible_facts). diff --git a/plugins/modules/vertica_role.py b/plugins/modules/vertica_role.py index e9f2ef34df..dde9919511 100644 --- a/plugins/modules/vertica_role.py +++ b/plugins/modules/vertica_role.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: vertica_role -short_description: Adds or removes Vertica database roles and assigns roles to them. +short_description: Adds or removes Vertica database roles and assigns roles to them description: - Adds or removes Vertica database role and, optionally, assign other roles. options: diff --git a/plugins/modules/vertica_schema.py b/plugins/modules/vertica_schema.py index b1bdf944b9..3c4071473a 100644 --- a/plugins/modules/vertica_schema.py +++ b/plugins/modules/vertica_schema.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: vertica_schema -short_description: Adds or removes Vertica database schema and roles. +short_description: Adds or removes Vertica database schema and roles description: - Adds or removes Vertica database schema and, optionally, roles with schema access privileges. diff --git a/plugins/modules/vertica_user.py b/plugins/modules/vertica_user.py index ff2f02d0cc..89f1cb92a3 100644 --- a/plugins/modules/vertica_user.py +++ b/plugins/modules/vertica_user.py @@ -11,7 +11,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: vertica_user -short_description: Adds or removes Vertica database users and assigns roles. +short_description: Adds or removes Vertica database users and assigns roles description: - Adds or removes Vertica database user and, optionally, assigns roles. - A user will not be removed until all the dependencies have been dropped. diff --git a/plugins/modules/vmadm.py b/plugins/modules/vmadm.py index 3bc016d679..6b4490ca57 100644 --- a/plugins/modules/vmadm.py +++ b/plugins/modules/vmadm.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: vmadm -short_description: Manage SmartOS virtual machines and zones. +short_description: Manage SmartOS virtual machines and zones description: - Manage SmartOS virtual machines through vmadm(1M). author: Jasper Lievisse Adriaanse (@jasperla) diff --git a/plugins/modules/xenserver_facts.py b/plugins/modules/xenserver_facts.py index 10ec3cd50f..59c457c7f7 100644 --- a/plugins/modules/xenserver_facts.py +++ b/plugins/modules/xenserver_facts.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: xenserver_facts -short_description: get facts reported on xenserver +short_description: Get facts reported on xenserver description: - Reads data out of XenAPI, can be used instead of multiple xe commands. author: diff --git a/plugins/modules/zfs_facts.py b/plugins/modules/zfs_facts.py index 734659a7ea..bb4530c473 100644 --- a/plugins/modules/zfs_facts.py +++ b/plugins/modules/zfs_facts.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: zfs_facts -short_description: Gather facts about ZFS datasets. +short_description: Gather facts about ZFS datasets description: - Gather facts from ZFS dataset properties. author: Adam Ε tevko (@xen0l) diff --git a/plugins/modules/zpool_facts.py b/plugins/modules/zpool_facts.py index ec5fdc4442..2477a920b0 100644 --- a/plugins/modules/zpool_facts.py +++ b/plugins/modules/zpool_facts.py @@ -12,7 +12,7 @@ __metaclass__ = type DOCUMENTATION = ''' --- module: zpool_facts -short_description: Gather facts about ZFS pools. +short_description: Gather facts about ZFS pools description: - Gather facts from ZFS pool properties. author: Adam Ε tevko (@xen0l) From fef6abc8c8c324551c20adbb3092de85450b4d94 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 13 Nov 2022 17:36:34 +0100 Subject: [PATCH 018/134] Fix a logical flaw when deleting a build in the jenkins_build module (#5514) (#5531) * Fix the logical flaw when deleting a build in the jenkins_build module. * Fix the logical flaw when deleting a Jenkins build in the jenkins_build module. * Adding changelogs. * Update tests/unit/plugins/modules/test_jenkins_build.py Co-authored-by: Felix Fontein * Attempt to mock the exception classes. * Remedy the CI issues when mocking the exception classes. * Assuming a way to mock the get_build_status function. * Near to the feasible approach. * Calls the correct class when unit testing. * Fix sending wrong arguments when unit testing. * Directly assign the argument value in the unit testing. * Fix errors calling different classes. Co-authored-by: Felix Fontein (cherry picked from commit 7610501c66a704214091aa0ba89065a53719f9cd) Co-authored-by: Tong He <68936428+unnecessary-username@users.noreply.github.com> --- ...gical-flaw-when-deleting-jenkins-build.yml | 2 + plugins/modules/jenkins_build.py | 10 +++- .../plugins/modules/test_jenkins_build.py | 48 +++++++++++++++++-- 3 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/5514-fix-logical-flaw-when-deleting-jenkins-build.yml diff --git a/changelogs/fragments/5514-fix-logical-flaw-when-deleting-jenkins-build.yml b/changelogs/fragments/5514-fix-logical-flaw-when-deleting-jenkins-build.yml new file mode 100644 index 0000000000..818ee95146 --- /dev/null +++ b/changelogs/fragments/5514-fix-logical-flaw-when-deleting-jenkins-build.yml @@ -0,0 +1,2 @@ +bugfixes: + - jenkins_build - fix the logical flaw when deleting a Jenkins build (https://github.com/ansible-collections/community.general/pull/5514). \ No newline at end of file diff --git a/plugins/modules/jenkins_build.py b/plugins/modules/jenkins_build.py index 09304ccfbc..b02027f229 100644 --- a/plugins/modules/jenkins_build.py +++ b/plugins/modules/jenkins_build.py @@ -183,7 +183,10 @@ class JenkinsBuild: try: response = self.server.get_build_info(self.name, self.build_number) return response - + except jenkins.JenkinsException as e: + response = {} + response["result"] = "ABSENT" + return response except Exception as e: self.module.fail_json(msg='Unable to fetch build information, %s' % to_native(e), exception=traceback.format_exc()) @@ -231,7 +234,10 @@ class JenkinsBuild: if self.state == "stopped" and build_status['result'] == "ABORTED": result['changed'] = True result['build_info'] = build_status - elif build_status['result'] == "SUCCESS": + elif self.state == "absent" and build_status['result'] == "ABSENT": + result['changed'] = True + result['build_info'] = build_status + elif self.state != "absent" and build_status['result'] == "SUCCESS": result['changed'] = True result['build_info'] = build_status else: diff --git a/tests/unit/plugins/modules/test_jenkins_build.py b/tests/unit/plugins/modules/test_jenkins_build.py index adee2fce99..44c6307ac9 100644 --- a/tests/unit/plugins/modules/test_jenkins_build.py +++ b/tests/unit/plugins/modules/test_jenkins_build.py @@ -43,6 +43,28 @@ def fail_json(*args, **kwargs): raise AnsibleFailJson(kwargs) +class jenkins: + class JenkinsException(Exception): + pass + + class NotFoundException(JenkinsException): + pass + + +class JenkinsBuildMock(): + def get_build_status(self): + try: + instance = JenkinsMock() + response = JenkinsMock.get_build_info(instance, 'host-delete', 1234) + return response + except jenkins.JenkinsException as e: + response = {} + response["result"] = "ABSENT" + return response + except Exception as e: + fail_json(msg='Unable to fetch build information, {0}'.format(e)) + + class JenkinsMock(): def get_job_info(self, name): @@ -51,6 +73,8 @@ class JenkinsMock(): } def get_build_info(self, name, build_number): + if name == "host-delete": + raise jenkins.JenkinsException("job {0} number {1} does not exist".format(name, build_number)) return { "building": True, "result": "SUCCESS" @@ -83,7 +107,7 @@ class JenkinsMockIdempotent(): return None def delete_build(self, name, build_number): - return None + raise jenkins.NotFoundException("job {0} number {1} does not exist".format(name, build_number)) def stop_build(self, name, build_number): return None @@ -167,13 +191,31 @@ class TestJenkinsBuild(unittest.TestCase): @patch('ansible_collections.community.general.plugins.modules.jenkins_build.test_dependencies') @patch('ansible_collections.community.general.plugins.modules.jenkins_build.JenkinsBuild.get_jenkins_connection') - def test_module_delete_build(self, jenkins_connection, test_deps): + @patch('ansible_collections.community.general.plugins.modules.jenkins_build.JenkinsBuild.get_build_status') + def test_module_delete_build(self, build_status, jenkins_connection, test_deps): test_deps.return_value = None jenkins_connection.return_value = JenkinsMock() + build_status.return_value = JenkinsBuildMock().get_build_status() with self.assertRaises(AnsibleExitJson): set_module_args({ - "name": "host-check", + "name": "host-delete", + "build_number": "1234", + "state": "absent", + "user": "abc", + "token": "xyz" + }) + jenkins_build.main() + + @patch('ansible_collections.community.general.plugins.modules.jenkins_build.test_dependencies') + @patch('ansible_collections.community.general.plugins.modules.jenkins_build.JenkinsBuild.get_jenkins_connection') + def test_module_delete_build_again(self, jenkins_connection, test_deps): + test_deps.return_value = None + jenkins_connection.return_value = JenkinsMockIdempotent() + + with self.assertRaises(AnsibleFailJson): + set_module_args({ + "name": "host-delete", "build_number": "1234", "state": "absent", "user": "abc", From 09ea44131659c691b7fab7d2714ce9da62cde846 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 13 Nov 2022 21:21:31 +0100 Subject: [PATCH 019/134] [PR #5493/27a4ffc2 backport][stable-6] Fix: Duplicate vmid in proxmox_disk module #5492 (#5537) * Fix: Duplicate vmid in proxmox_disk module #5492 (#5493) https://github.com/ansible-collections/community.general/issues/5492 (cherry picked from commit 27a4ffc2931e5ccdd3a2d4d09260351d1050c4f9) * Add changelog fragment. (cherry picked from commit 672385309ce68912201ed1bd34bf74bc0cd25112) Co-authored-by: Doc_Tiebeau Co-authored-by: Felix Fontein --- changelogs/fragments/5493-proxmox.yml | 2 ++ plugins/modules/proxmox_disk.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5493-proxmox.yml diff --git a/changelogs/fragments/5493-proxmox.yml b/changelogs/fragments/5493-proxmox.yml new file mode 100644 index 0000000000..a14b7767e6 --- /dev/null +++ b/changelogs/fragments/5493-proxmox.yml @@ -0,0 +1,2 @@ +bugfixes: + - "proxmox_disk - avoid duplicate ``vmid`` reference (https://github.com/ansible-collections/community.general/issues/5492, https://github.com/ansible-collections/community.general/pull/5493)." diff --git a/plugins/modules/proxmox_disk.py b/plugins/modules/proxmox_disk.py index 7a39d38d05..8f55e2d130 100644 --- a/plugins/modules/proxmox_disk.py +++ b/plugins/modules/proxmox_disk.py @@ -725,7 +725,7 @@ def main(): actual_size = disk_config['size'] if size == actual_size: module.exit_json(changed=False, vmid=vmid, msg="Disk %s is already %s size" % (disk, size)) - proxmox.proxmox_api.nodes(vm['node']).qemu(vmid).resize.set(vmid=vmid, disk=disk, size=size) + proxmox.proxmox_api.nodes(vm['node']).qemu(vmid).resize.set(disk=disk, size=size) module.exit_json(changed=True, vmid=vmid, msg="Disk %s resized in VM %s" % (disk, vmid)) except Exception as e: module.fail_json(msg="Failed to resize disk %s in VM %s with exception: %s" % (disk, vmid, str(e))) From 9c4487ebc52ddae16d7a49932b06ba096ae1cc8b Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 15 Nov 2022 08:38:34 +0100 Subject: [PATCH 020/134] dependent lookup: prevent deprecation warning with ansible-core 2.14 (#5543) (#5548) * Prevent deprecation warning. * Improve naming and add comment. (cherry picked from commit 60c8b9a67fe0788c770db69641ca6552beb2f522) Co-authored-by: Felix Fontein --- changelogs/fragments/5543-dependent-template.yml | 2 ++ plugins/lookup/dependent.py | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5543-dependent-template.yml diff --git a/changelogs/fragments/5543-dependent-template.yml b/changelogs/fragments/5543-dependent-template.yml new file mode 100644 index 0000000000..63e8f67d63 --- /dev/null +++ b/changelogs/fragments/5543-dependent-template.yml @@ -0,0 +1,2 @@ +bugfixes: + - "dependent lookup plugin - avoid warning on deprecated parameter for ``Templar.template()`` (https://github.com/ansible-collections/community.general/pull/5543)." diff --git a/plugins/lookup/dependent.py b/plugins/lookup/dependent.py index b44a9208af..54714344eb 100644 --- a/plugins/lookup/dependent.py +++ b/plugins/lookup/dependent.py @@ -125,8 +125,16 @@ from ansible.errors import AnsibleLookupError from ansible.module_utils.common._collections_compat import Mapping, Sequence from ansible.module_utils.six import string_types from ansible.plugins.lookup import LookupBase +from ansible.release import __version__ as ansible_version from ansible.template import Templar +from ansible_collections.community.general.plugins.module_utils.version import LooseVersion + + +# Whether Templar has a cache, which can be controlled by Templar.template()'s cache option. +# The cache was removed for ansible-core 2.14 (https://github.com/ansible/ansible/pull/78419) +_TEMPLAR_HAS_TEMPLATE_CACHE = LooseVersion(ansible_version) < LooseVersion('2.14.0') + class LookupModule(LookupBase): def __evaluate(self, expression, templar, variables): @@ -136,7 +144,10 @@ class LookupModule(LookupBase): ``variables`` are the variables to use. """ templar.available_variables = variables or {} - return templar.template("{0}{1}{2}".format("{{", expression, "}}"), cache=False) + expression = "{0}{1}{2}".format("{{", expression, "}}") + if _TEMPLAR_HAS_TEMPLATE_CACHE: + return templar.template(expression, cache=False) + return templar.template(expression) def __process(self, result, terms, index, current, templar, variables): """Fills ``result`` list with evaluated items. From a4be229f675b684122ec4bcd37e6ebbc6a61e512 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 15 Nov 2022 08:58:18 +0100 Subject: [PATCH 021/134] Release 6.0.1. --- CHANGELOG.rst | 17 +++++++++++++++++ changelogs/changelog.yaml | 19 +++++++++++++++++++ .../5489-nonetype-in-get-vm-by-label.yml | 2 -- changelogs/fragments/5493-proxmox.yml | 2 -- .../5506-onepassword_raw-missing-param.yml | 2 -- ...gical-flaw-when-deleting-jenkins-build.yml | 2 -- .../fragments/5543-dependent-template.yml | 2 -- changelogs/fragments/6.0.1.yml | 1 - 8 files changed, 36 insertions(+), 11 deletions(-) delete mode 100644 changelogs/fragments/5489-nonetype-in-get-vm-by-label.yml delete mode 100644 changelogs/fragments/5493-proxmox.yml delete mode 100644 changelogs/fragments/5506-onepassword_raw-missing-param.yml delete mode 100644 changelogs/fragments/5514-fix-logical-flaw-when-deleting-jenkins-build.yml delete mode 100644 changelogs/fragments/5543-dependent-template.yml delete mode 100644 changelogs/fragments/6.0.1.yml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b9b6680e96..320f2f3745 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,23 @@ Community General Release Notes This changelog describes changes after version 5.0.0. +v6.0.1 +====== + +Release Summary +--------------- + +Bugfix release for Ansible 7.0.0. + +Bugfixes +-------- + +- dependent lookup plugin - avoid warning on deprecated parameter for ``Templar.template()`` (https://github.com/ansible-collections/community.general/pull/5543). +- jenkins_build - fix the logical flaw when deleting a Jenkins build (https://github.com/ansible-collections/community.general/pull/5514). +- one_vm - avoid splitting labels that are ``None`` (https://github.com/ansible-collections/community.general/pull/5489). +- onepassword_raw - add missing parameter to plugin documentation (https://github.com/ansible-collections/community.general/issues/5506). +- proxmox_disk - avoid duplicate ``vmid`` reference (https://github.com/ansible-collections/community.general/issues/5492, https://github.com/ansible-collections/community.general/pull/5493). + v6.0.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 21eac0c266..029f7dc12b 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -627,3 +627,22 @@ releases: name: bitwarden namespace: null release_date: '2022-11-02' + 6.0.1: + changes: + bugfixes: + - dependent lookup plugin - avoid warning on deprecated parameter for ``Templar.template()`` + (https://github.com/ansible-collections/community.general/pull/5543). + - jenkins_build - fix the logical flaw when deleting a Jenkins build (https://github.com/ansible-collections/community.general/pull/5514). + - one_vm - avoid splitting labels that are ``None`` (https://github.com/ansible-collections/community.general/pull/5489). + - onepassword_raw - add missing parameter to plugin documentation (https://github.com/ansible-collections/community.general/issues/5506). + - proxmox_disk - avoid duplicate ``vmid`` reference (https://github.com/ansible-collections/community.general/issues/5492, + https://github.com/ansible-collections/community.general/pull/5493). + release_summary: Bugfix release for Ansible 7.0.0. + fragments: + - 5489-nonetype-in-get-vm-by-label.yml + - 5493-proxmox.yml + - 5506-onepassword_raw-missing-param.yml + - 5514-fix-logical-flaw-when-deleting-jenkins-build.yml + - 5543-dependent-template.yml + - 6.0.1.yml + release_date: '2022-11-15' diff --git a/changelogs/fragments/5489-nonetype-in-get-vm-by-label.yml b/changelogs/fragments/5489-nonetype-in-get-vm-by-label.yml deleted file mode 100644 index 8b0d92ec40..0000000000 --- a/changelogs/fragments/5489-nonetype-in-get-vm-by-label.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - one_vm - avoid splitting labels that are ``None`` (https://github.com/ansible-collections/community.general/pull/5489). \ No newline at end of file diff --git a/changelogs/fragments/5493-proxmox.yml b/changelogs/fragments/5493-proxmox.yml deleted file mode 100644 index a14b7767e6..0000000000 --- a/changelogs/fragments/5493-proxmox.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - "proxmox_disk - avoid duplicate ``vmid`` reference (https://github.com/ansible-collections/community.general/issues/5492, https://github.com/ansible-collections/community.general/pull/5493)." diff --git a/changelogs/fragments/5506-onepassword_raw-missing-param.yml b/changelogs/fragments/5506-onepassword_raw-missing-param.yml deleted file mode 100644 index f10ff28d28..0000000000 --- a/changelogs/fragments/5506-onepassword_raw-missing-param.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - onepassword_raw - add missing parameter to plugin documentation (https://github.com/ansible-collections/community.general/issues/5506). diff --git a/changelogs/fragments/5514-fix-logical-flaw-when-deleting-jenkins-build.yml b/changelogs/fragments/5514-fix-logical-flaw-when-deleting-jenkins-build.yml deleted file mode 100644 index 818ee95146..0000000000 --- a/changelogs/fragments/5514-fix-logical-flaw-when-deleting-jenkins-build.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - jenkins_build - fix the logical flaw when deleting a Jenkins build (https://github.com/ansible-collections/community.general/pull/5514). \ No newline at end of file diff --git a/changelogs/fragments/5543-dependent-template.yml b/changelogs/fragments/5543-dependent-template.yml deleted file mode 100644 index 63e8f67d63..0000000000 --- a/changelogs/fragments/5543-dependent-template.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - "dependent lookup plugin - avoid warning on deprecated parameter for ``Templar.template()`` (https://github.com/ansible-collections/community.general/pull/5543)." diff --git a/changelogs/fragments/6.0.1.yml b/changelogs/fragments/6.0.1.yml deleted file mode 100644 index 9fe28c711a..0000000000 --- a/changelogs/fragments/6.0.1.yml +++ /dev/null @@ -1 +0,0 @@ -release_summary: Bugfix release for Ansible 7.0.0. From 0bd085714f7388f7bb45291213bd8f35e1f0b1ac Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 15 Nov 2022 13:09:30 +0100 Subject: [PATCH 022/134] Next expected release is 6.1.0. --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 0fee26c05d..1c300da904 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -5,7 +5,7 @@ namespace: community name: general -version: 6.0.1 +version: 6.1.0 readme: README.md authors: - Ansible (https://github.com/ansible) From 41a23f093d398f1fde1411f7245939889cf01e39 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 16 Nov 2022 05:35:56 +0000 Subject: [PATCH 023/134] spotinst_aws_elasticgroup: sanity checks (#5553) (#5554) * spotinst_aws_elastigroup: add elements to parameter do_not_update * spotinst_aws_elastigroup: add docs for parameter token * add missing docs * add changelog fragment * Update plugins/modules/spotinst_aws_elastigroup.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 270dc133b3f4b030886d343f65694aa6bcd33457) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../5553-spotinst-aws-elasticgroup-sanity.yml | 2 ++ plugins/modules/spotinst_aws_elastigroup.py | 28 +++++++++++++++++-- tests/sanity/ignore-2.11.txt | 3 -- tests/sanity/ignore-2.12.txt | 3 -- tests/sanity/ignore-2.13.txt | 3 -- tests/sanity/ignore-2.14.txt | 3 -- tests/sanity/ignore-2.15.txt | 3 -- 7 files changed, 28 insertions(+), 17 deletions(-) create mode 100644 changelogs/fragments/5553-spotinst-aws-elasticgroup-sanity.yml diff --git a/changelogs/fragments/5553-spotinst-aws-elasticgroup-sanity.yml b/changelogs/fragments/5553-spotinst-aws-elasticgroup-sanity.yml new file mode 100644 index 0000000000..1213f5412a --- /dev/null +++ b/changelogs/fragments/5553-spotinst-aws-elasticgroup-sanity.yml @@ -0,0 +1,2 @@ +minor_changes: + - spotinst_aws_elastigroup - add ``elements`` attribute when missing in ``list`` parameters (https://github.com/ansible-collections/community.general/pull/5553). diff --git a/plugins/modules/spotinst_aws_elastigroup.py b/plugins/modules/spotinst_aws_elastigroup.py index df2b8d84db..481ba70cb9 100644 --- a/plugins/modules/spotinst_aws_elastigroup.py +++ b/plugins/modules/spotinst_aws_elastigroup.py @@ -35,6 +35,13 @@ options: By default this is retrieved from the credentials path. type: str + token: + description: + - A Personal API Access Token issued by Spotinst. + - >- + When not specified, the module will try to obtain it, in that order, from: environment variable C(SPOTINST_TOKEN), or from the credentials path. + type: str + availability_vs_cost: description: - The strategy orientation. @@ -507,8 +514,25 @@ options: description: - TODO document. type: list + elements: str default: [] + multai_token: + description: + - Token used for Multai configuration. + type: str + + multai_load_balancers: + description: + - Configuration parameters for Multai load balancers. + type: list + elements: dict + + elastic_beanstalk: + description: + - Placeholder parameter for future implementation of Elastic Beanstalk configurations. + type: dict + ''' EXAMPLES = ''' # Basic configuration YAML example @@ -1455,7 +1479,7 @@ def main(): block_device_mappings=dict(type='list', elements='dict'), chef=dict(type='dict'), credentials_path=dict(type='path', default="~/.spotinst/credentials"), - do_not_update=dict(default=[], type='list'), + do_not_update=dict(default=[], type='list', elements='str'), down_scaling_policies=dict(type='list', elements='dict'), draining_timeout=dict(type='int'), ebs_optimized=dict(type='bool'), @@ -1479,7 +1503,7 @@ def main(): mesosphere=dict(type='dict'), min_size=dict(type='int', required=True), monitoring=dict(type='str'), - multai_load_balancers=dict(type='list'), + multai_load_balancers=dict(type='list', elements='dict'), multai_token=dict(type='str', no_log=True), name=dict(type='str', required=True), network_interfaces=dict(type='list', elements='dict'), diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 603981df04..848247e944 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -29,9 +29,6 @@ plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expand plugins/modules/redhat_subscription.py validate-modules:return-syntax-error plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error -plugins/modules/spotinst_aws_elastigroup.py validate-modules:parameter-list-no-elements -plugins/modules/spotinst_aws_elastigroup.py validate-modules:parameter-type-not-in-doc -plugins/modules/spotinst_aws_elastigroup.py validate-modules:undocumented-parameter plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py validate-modules:parameter-list-no-elements diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index 778f25ae53..9f277b5367 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -24,9 +24,6 @@ plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expand plugins/modules/redhat_subscription.py validate-modules:return-syntax-error plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error -plugins/modules/spotinst_aws_elastigroup.py validate-modules:parameter-list-no-elements -plugins/modules/spotinst_aws_elastigroup.py validate-modules:parameter-type-not-in-doc -plugins/modules/spotinst_aws_elastigroup.py validate-modules:undocumented-parameter plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py validate-modules:parameter-list-no-elements diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index 778f25ae53..9f277b5367 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -24,9 +24,6 @@ plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expand plugins/modules/redhat_subscription.py validate-modules:return-syntax-error plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error -plugins/modules/spotinst_aws_elastigroup.py validate-modules:parameter-list-no-elements -plugins/modules/spotinst_aws_elastigroup.py validate-modules:parameter-type-not-in-doc -plugins/modules/spotinst_aws_elastigroup.py validate-modules:undocumented-parameter plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py validate-modules:parameter-list-no-elements diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 20f87d1af2..dd73e39327 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -25,9 +25,6 @@ plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expand plugins/modules/redhat_subscription.py validate-modules:return-syntax-error plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error -plugins/modules/spotinst_aws_elastigroup.py validate-modules:parameter-list-no-elements -plugins/modules/spotinst_aws_elastigroup.py validate-modules:parameter-type-not-in-doc -plugins/modules/spotinst_aws_elastigroup.py validate-modules:undocumented-parameter plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt' diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index 20f87d1af2..dd73e39327 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -25,9 +25,6 @@ plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expand plugins/modules/redhat_subscription.py validate-modules:return-syntax-error plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error -plugins/modules/spotinst_aws_elastigroup.py validate-modules:parameter-list-no-elements -plugins/modules/spotinst_aws_elastigroup.py validate-modules:parameter-type-not-in-doc -plugins/modules/spotinst_aws_elastigroup.py validate-modules:undocumented-parameter plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt' From 57a4195b0de5f99498b13e93498a133fb4a177f2 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 16 Nov 2022 06:57:38 +0100 Subject: [PATCH 024/134] redhat_subscription: fix sanity check (#5555) (#5560) * redhat_subscription: fix sanity check * removed ignore lines (cherry picked from commit 801e3d86ef4f71bd99a6ffc1696b3b8fe7b89223) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- plugins/modules/redhat_subscription.py | 2 +- tests/sanity/ignore-2.11.txt | 1 - tests/sanity/ignore-2.12.txt | 1 - tests/sanity/ignore-2.13.txt | 1 - tests/sanity/ignore-2.14.txt | 1 - tests/sanity/ignore-2.15.txt | 1 - 6 files changed, 1 insertion(+), 6 deletions(-) diff --git a/plugins/modules/redhat_subscription.py b/plugins/modules/redhat_subscription.py index 69aa550c5d..997d1e5153 100644 --- a/plugins/modules/redhat_subscription.py +++ b/plugins/modules/redhat_subscription.py @@ -264,7 +264,7 @@ RETURN = ''' subscribed_pool_ids: description: List of pool IDs to which system is now subscribed returned: success - type: complex + type: dict sample: { "8a85f9815ab905d3015ab928c7005de4": "1" } diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 848247e944..70293ac81a 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -26,7 +26,6 @@ plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values -plugins/modules/redhat_subscription.py validate-modules:return-syntax-error plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index 9f277b5367..aa16533b4d 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -21,7 +21,6 @@ plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values -plugins/modules/redhat_subscription.py validate-modules:return-syntax-error plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index 9f277b5367..aa16533b4d 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -21,7 +21,6 @@ plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values -plugins/modules/redhat_subscription.py validate-modules:return-syntax-error plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index dd73e39327..95ee9b4f17 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -22,7 +22,6 @@ plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values -plugins/modules/redhat_subscription.py validate-modules:return-syntax-error plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index dd73e39327..95ee9b4f17 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -22,7 +22,6 @@ plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values -plugins/modules/redhat_subscription.py validate-modules:return-syntax-error plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path From c681249364ca4fa9a7781258612c2ce4b12a1432 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 16 Nov 2022 06:58:30 +0100 Subject: [PATCH 025/134] cmd_runner module utils: fix case for as_fixed() format (#5538) (#5562) * cmd_runner module utils: fix case for as_fixed() format * add changelog fragment * simplified test_cmd_runner * fix handling empty default for `as_map()` * add changelog fragment * MissingArgumentValue is reraised in run() (cherry picked from commit e87ca10b61275a4c679f7e945116b8c11090504e) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../fragments/5538-cmd-runner-as-fixed.yml | 3 + plugins/module_utils/cmd_runner.py | 19 ++- .../plugins/module_utils/test_cmd_runner.py | 124 +++++++++--------- 3 files changed, 77 insertions(+), 69 deletions(-) create mode 100644 changelogs/fragments/5538-cmd-runner-as-fixed.yml diff --git a/changelogs/fragments/5538-cmd-runner-as-fixed.yml b/changelogs/fragments/5538-cmd-runner-as-fixed.yml new file mode 100644 index 0000000000..714564b09f --- /dev/null +++ b/changelogs/fragments/5538-cmd-runner-as-fixed.yml @@ -0,0 +1,3 @@ +bugfixes: + - cmd_runner module utils - formatting arguments ``cmd_runner_fmt.as_fixed()`` was expecting an non-existing argument (https://github.com/ansible-collections/community.general/pull/5538). + - cmd_runner module utils - fixed bug when handling default cases in ``cmd_runner_fmt.as_map()`` (https://github.com/ansible-collections/community.general/pull/5538). diff --git a/plugins/module_utils/cmd_runner.py b/plugins/module_utils/cmd_runner.py index 141a6be9b2..38daac6716 100644 --- a/plugins/module_utils/cmd_runner.py +++ b/plugins/module_utils/cmd_runner.py @@ -88,9 +88,10 @@ class FormatError(CmdRunnerException): class _ArgFormat(object): - def __init__(self, func, ignore_none=None): + def __init__(self, func, ignore_none=None, ignore_missing_value=False): self.func = func self.ignore_none = ignore_none + self.ignore_missing_value = ignore_missing_value def __call__(self, value, ctx_ignore_none): ignore_none = self.ignore_none if self.ignore_none is not None else ctx_ignore_none @@ -127,7 +128,7 @@ class _Format(object): @staticmethod def as_fixed(args): - return _ArgFormat(lambda value: _ensure_list(args), ignore_none=False) + return _ArgFormat(lambda value: _ensure_list(args), ignore_none=False, ignore_missing_value=True) @staticmethod def as_func(func, ignore_none=None): @@ -135,14 +136,15 @@ class _Format(object): @staticmethod def as_map(_map, default=None, ignore_none=None): + if default is None: + default = [] return _ArgFormat(lambda value: _ensure_list(_map.get(value, default)), ignore_none=ignore_none) @staticmethod def as_default_type(_type, arg="", ignore_none=None): fmt = _Format if _type == "dict": - return fmt.as_func(lambda d: ["--{0}={1}".format(*a) for a in iteritems(d)], - ignore_none=ignore_none) + return fmt.as_func(lambda d: ["--{0}={1}".format(*a) for a in iteritems(d)], ignore_none=ignore_none) if _type == "list": return fmt.as_func(lambda value: ["--{0}".format(x) for x in value], ignore_none=ignore_none) if _type == "bool": @@ -261,10 +263,13 @@ class _CmdRunnerContext(object): for arg_name in self.args_order: value = None try: - value = named_args[arg_name] + if arg_name in named_args: + value = named_args[arg_name] + elif not runner.arg_formats[arg_name].ignore_missing_value: + raise MissingArgumentValue(self.args_order, arg_name) self.cmd.extend(runner.arg_formats[arg_name](value, ctx_ignore_none=self.ignore_value_none)) - except KeyError: - raise MissingArgumentValue(self.args_order, arg_name) + except MissingArgumentValue: + raise except Exception as e: raise FormatError(arg_name, value, runner.arg_formats[arg_name], e) diff --git a/tests/unit/plugins/module_utils/test_cmd_runner.py b/tests/unit/plugins/module_utils/test_cmd_runner.py index 5fdc5fb5fc..f1c3e25a9b 100644 --- a/tests/unit/plugins/module_utils/test_cmd_runner.py +++ b/tests/unit/plugins/module_utils/test_cmd_runner.py @@ -240,6 +240,60 @@ TC_RUNNER = dict( ), ), ), + aa_bb_fixed=( + dict( + args_bundle=dict( + aa=dict(type="int", value=11, fmt_func=fmt.as_opt_eq_val, fmt_arg="--answer"), + bb=dict(fmt_func=fmt.as_fixed, fmt_arg=["fixed", "args"]), + ), + runner_init_args=dict(), + runner_ctx_args=dict(args_order=['aa', 'bb']), + ), + dict(runner_ctx_run_args=dict(), rc=0, out="", err=""), + dict( + run_info=dict( + cmd=['/mock/bin/testing', '--answer=11', 'fixed', 'args'], + environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'}, + args_order=('aa', 'bb'), + ), + ), + ), + aa_bb_map=( + dict( + args_bundle=dict( + aa=dict(type="int", value=11, fmt_func=fmt.as_opt_eq_val, fmt_arg="--answer"), + bb=dict(fmt_func=fmt.as_map, fmt_arg={"v1": 111, "v2": 222}), + ), + runner_init_args=dict(), + runner_ctx_args=dict(args_order=['aa', 'bb']), + ), + dict(runner_ctx_run_args=dict(bb="v2"), rc=0, out="", err=""), + dict( + run_info=dict( + cmd=['/mock/bin/testing', '--answer=11', '222'], + environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'}, + args_order=('aa', 'bb'), + ), + ), + ), + aa_bb_map_default=( + dict( + args_bundle=dict( + aa=dict(type="int", value=11, fmt_func=fmt.as_opt_eq_val, fmt_arg="--answer"), + bb=dict(fmt_func=fmt.as_map, fmt_arg={"v1": 111, "v2": 222}), + ), + runner_init_args=dict(), + runner_ctx_args=dict(args_order=['aa', 'bb']), + ), + dict(runner_ctx_run_args=dict(bb="v123456789"), rc=0, out="", err=""), + dict( + run_info=dict( + cmd=['/mock/bin/testing', '--answer=11'], + environ_update={'LANGUAGE': 'C', 'LC_ALL': 'C'}, + args_order=('aa', 'bb'), + ), + ), + ), ) TC_RUNNER_IDS = sorted(TC_RUNNER.keys()) @@ -301,70 +355,16 @@ def test_runner_context(runner_input, cmd_execution, expected): results = ctx.run(**cmd_execution['runner_ctx_run_args']) _assert_run(runner_input, cmd_execution, expected, ctx, results) + with pytest.raises(exc): + with runner(**runner_input['runner_ctx_args']) as ctx2: + results2 = ctx2.run(**cmd_execution['runner_ctx_run_args']) + _assert_run(runner_input, cmd_execution, expected, ctx2, results2) + else: with runner.context(**runner_input['runner_ctx_args']) as ctx: results = ctx.run(**cmd_execution['runner_ctx_run_args']) _assert_run(runner_input, cmd_execution, expected, ctx, results) - -@pytest.mark.parametrize('runner_input, cmd_execution, expected', - (TC_RUNNER[tc] for tc in TC_RUNNER_IDS), - ids=TC_RUNNER_IDS) -def test_runner_callable(runner_input, cmd_execution, expected): - arg_spec = {} - params = {} - arg_formats = {} - for k, v in runner_input['args_bundle'].items(): - try: - arg_spec[k] = {'type': v['type']} - except KeyError: - pass - try: - params[k] = v['value'] - except KeyError: - pass - try: - arg_formats[k] = v['fmt_func'](v['fmt_arg']) - except KeyError: - pass - - orig_results = tuple(cmd_execution[x] for x in ('rc', 'out', 'err')) - - print("arg_spec={0}\nparams={1}\narg_formats={2}\n".format( - arg_spec, - params, - arg_formats, - )) - - module = MagicMock() - type(module).argument_spec = PropertyMock(return_value=arg_spec) - type(module).params = PropertyMock(return_value=params) - module.get_bin_path.return_value = '/mock/bin/testing' - module.run_command.return_value = orig_results - - runner = CmdRunner( - module=module, - command="testing", - arg_formats=arg_formats, - **runner_input['runner_init_args'] - ) - - def _assert_run_info(actual, expected): - reduced = dict((k, actual[k]) for k in expected.keys()) - assert reduced == expected, "{0}".format(reduced) - - def _assert_run(runner_input, cmd_execution, expected, ctx, results): - _assert_run_info(ctx.run_info, expected['run_info']) - assert results == expected.get('results', orig_results) - - exc = expected.get("exc") - if exc: - with pytest.raises(exc): - with runner(**runner_input['runner_ctx_args']) as ctx: - results = ctx.run(**cmd_execution['runner_ctx_run_args']) - _assert_run(runner_input, cmd_execution, expected, ctx, results) - - else: - with runner(**runner_input['runner_ctx_args']) as ctx: - results = ctx.run(**cmd_execution['runner_ctx_run_args']) - _assert_run(runner_input, cmd_execution, expected, ctx, results) + with runner(**runner_input['runner_ctx_args']) as ctx2: + results2 = ctx2.run(**cmd_execution['runner_ctx_run_args']) + _assert_run(runner_input, cmd_execution, expected, ctx2, results2) From 4b04e3cc324141f986a16a69a83b9ac6c2d9b838 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 17 Nov 2022 07:29:49 +0100 Subject: [PATCH 026/134] scaleway_organization_info: sanity checks (#5571) (#5577) * scaleway_organization_info: fix sanity checks * remove lines from ignore files * Update plugins/modules/scaleway_organization_info.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 83ff4429e887c89edfb7f6c494d2a755fd75a3fd) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- plugins/modules/scaleway_organization_info.py | 3 ++- tests/sanity/ignore-2.11.txt | 1 - tests/sanity/ignore-2.12.txt | 1 - tests/sanity/ignore-2.13.txt | 1 - tests/sanity/ignore-2.14.txt | 1 - tests/sanity/ignore-2.15.txt | 1 - 6 files changed, 2 insertions(+), 6 deletions(-) diff --git a/plugins/modules/scaleway_organization_info.py b/plugins/modules/scaleway_organization_info.py index 6e1f8df388..717c47db19 100644 --- a/plugins/modules/scaleway_organization_info.py +++ b/plugins/modules/scaleway_organization_info.py @@ -44,7 +44,8 @@ RETURN = r''' scaleway_organization_info: description: Response from Scaleway API returned: success - type: complex + type: list + elements: dict sample: "scaleway_organization_info": [ { diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 70293ac81a..c33b0b10a2 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -27,7 +27,6 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice -plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py validate-modules:parameter-list-no-elements diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index aa16533b4d..709f8c4eb0 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -22,7 +22,6 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice -plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py validate-modules:parameter-list-no-elements diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index aa16533b4d..709f8c4eb0 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -22,7 +22,6 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice -plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py validate-modules:parameter-list-no-elements diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 95ee9b4f17..9998a5550d 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -23,7 +23,6 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice -plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt' diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index 95ee9b4f17..9998a5550d 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -23,7 +23,6 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice -plugins/modules/scaleway_organization_info.py validate-modules:return-syntax-error plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt' From d6d9f84b0a9817ed15217df8a7d5747432f6bbad Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 17 Nov 2022 07:30:00 +0100 Subject: [PATCH 027/134] chroot plugin fix inventory_hostname var for remote_addr (#5570) (#5573) * Add inventory_hostname under remote_addr.vars in chroot connection plugin required by ansible 2.13 * fix changelog fragment (cherry picked from commit 5e5af458fb431d742a22b1ba8642e30a75765667) Co-authored-by: Evan Jarrett --- .../5570-chroot-plugin-fix-default-inventory_hostname.yml | 2 ++ plugins/connection/chroot.py | 1 + 2 files changed, 3 insertions(+) create mode 100644 changelogs/fragments/5570-chroot-plugin-fix-default-inventory_hostname.yml diff --git a/changelogs/fragments/5570-chroot-plugin-fix-default-inventory_hostname.yml b/changelogs/fragments/5570-chroot-plugin-fix-default-inventory_hostname.yml new file mode 100644 index 0000000000..fc0c074f84 --- /dev/null +++ b/changelogs/fragments/5570-chroot-plugin-fix-default-inventory_hostname.yml @@ -0,0 +1,2 @@ +bugfixes: + - "chroot connection plugin - add ``inventory_hostname`` to vars under ``remote_addr``. This is needed for compatibility with ansible-core 2.13 (https://github.com/ansible-collections/community.general/pull/5570)." \ No newline at end of file diff --git a/plugins/connection/chroot.py b/plugins/connection/chroot.py index cbbf9612e9..ef6d5566d3 100644 --- a/plugins/connection/chroot.py +++ b/plugins/connection/chroot.py @@ -22,6 +22,7 @@ DOCUMENTATION = ''' - The path of the chroot you want to access. default: inventory_hostname vars: + - name: inventory_hostname - name: ansible_host executable: description: From 2435fb3f3063ac834e8e25929b360d65d81967e2 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 07:37:12 +0100 Subject: [PATCH 028/134] rax_scaling_group: fix sanity check (#5563) (#5569) * rax_scaling_group: fix sanity check * add changelog fragment * added missing call to expanduser() (cherry picked from commit 6a03108609cba48b88b57d2bf43eb238fc13f229) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../5563-rax-scaling-group-sanity.yml | 2 ++ plugins/module_utils/rax.py | 18 ++++++++++++++++ plugins/modules/rax_scaling_group.py | 21 ++++++------------- tests/sanity/ignore-2.11.txt | 1 - tests/sanity/ignore-2.12.txt | 1 - tests/sanity/ignore-2.13.txt | 1 - tests/sanity/ignore-2.14.txt | 1 - tests/sanity/ignore-2.15.txt | 1 - 8 files changed, 26 insertions(+), 20 deletions(-) create mode 100644 changelogs/fragments/5563-rax-scaling-group-sanity.yml diff --git a/changelogs/fragments/5563-rax-scaling-group-sanity.yml b/changelogs/fragments/5563-rax-scaling-group-sanity.yml new file mode 100644 index 0000000000..310257f293 --- /dev/null +++ b/changelogs/fragments/5563-rax-scaling-group-sanity.yml @@ -0,0 +1,2 @@ +minor_changes: + - rax_scaling_group - refactored out code to the ``rax`` module utils to clear the sanity check (https://github.com/ansible-collections/community.general/pull/5563). diff --git a/plugins/module_utils/rax.py b/plugins/module_utils/rax.py index 2372088033..6331c0d1be 100644 --- a/plugins/module_utils/rax.py +++ b/plugins/module_utils/rax.py @@ -314,3 +314,21 @@ def setup_rax_module(module, rax_module, region_required=True): (region, ','.join(rax_module.regions))) return rax_module + + +def rax_scaling_group_personality_file(module, files): + if not files: + return [] + + results = [] + for rpath, lpath in files.items(): + lpath = os.path.expanduser(lpath) + try: + with open(lpath, 'r') as f: + results.append({ + 'path': rpath, + 'contents': f.read(), + }) + except Exception as e: + module.fail_json(msg='Failed to load %s: %s' % (lpath, str(e))) + return results diff --git a/plugins/modules/rax_scaling_group.py b/plugins/modules/rax_scaling_group.py index ef31cbb031..ed974ef0f9 100644 --- a/plugins/modules/rax_scaling_group.py +++ b/plugins/modules/rax_scaling_group.py @@ -161,8 +161,11 @@ except ImportError: HAS_PYRAX = False from ansible.module_utils.basic import AnsibleModule -from ansible_collections.community.general.plugins.module_utils.rax import (rax_argument_spec, rax_find_image, rax_find_network, - rax_required_together, rax_to_dict, setup_rax_module) +from ansible_collections.community.general.plugins.module_utils.rax import ( + rax_argument_spec, rax_find_image, rax_find_network, + rax_required_together, rax_to_dict, setup_rax_module, + rax_scaling_group_personality_file, +) from ansible.module_utils.six import string_types @@ -223,19 +226,7 @@ def rax_asg(module, cooldown=300, disk_config=None, files=None, flavor=None, del nic['net-id'] # Handle the file contents - personality = [] - if files: - for rpath in files.keys(): - lpath = os.path.expanduser(files[rpath]) - try: - f = open(lpath, 'r') - personality.append({ - 'path': rpath, - 'contents': f.read() - }) - f.close() - except Exception as e: - module.fail_json(msg='Failed to load %s' % lpath) + personality = rax_scaling_group_personality_file(module, files) lbs = [] if loadbalancers: diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index c33b0b10a2..a736032da2 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -25,7 +25,6 @@ plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed -plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index 709f8c4eb0..d01077cc9c 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -20,7 +20,6 @@ plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed -plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index 709f8c4eb0..d01077cc9c 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -20,7 +20,6 @@ plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed -plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 9998a5550d..293e878680 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -21,7 +21,6 @@ plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed -plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index 9998a5550d..293e878680 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -21,7 +21,6 @@ plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed -plugins/modules/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements From b52a6f3611eb5bff023e1aca76e12c01e20786bd Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 07:37:27 +0100 Subject: [PATCH 029/134] gconftool2: refactored to use ModuleHelper + CmdRunner (#5545) (#5551) * gconftool2: refactored to use ModuleHelper + CmdRunner * add changelog fragment * removed old code commented out (cherry picked from commit 6c7e9116e1abba6c125e7f05cf7fd0e8042a1f43) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../fragments/5545-gconftool-cmd-runner.yml | 2 + plugins/module_utils/gconftool2.py | 23 ++- plugins/modules/gconftool2.py | 173 +++++------------- plugins/modules/gconftool2_info.py | 4 +- tests/sanity/ignore-2.11.txt | 2 +- tests/sanity/ignore-2.12.txt | 2 +- tests/sanity/ignore-2.13.txt | 2 +- tests/sanity/ignore-2.14.txt | 2 +- tests/sanity/ignore-2.15.txt | 2 +- tests/unit/plugins/modules/test_gconftool2.py | 116 ++++++++++++ 10 files changed, 186 insertions(+), 142 deletions(-) create mode 100644 changelogs/fragments/5545-gconftool-cmd-runner.yml create mode 100644 tests/unit/plugins/modules/test_gconftool2.py diff --git a/changelogs/fragments/5545-gconftool-cmd-runner.yml b/changelogs/fragments/5545-gconftool-cmd-runner.yml new file mode 100644 index 0000000000..a41d5c3657 --- /dev/null +++ b/changelogs/fragments/5545-gconftool-cmd-runner.yml @@ -0,0 +1,2 @@ +minor_changes: + - gconftool2 - refactor using ``ModuleHelper`` and ``CmdRunner`` (https://github.com/ansible-collections/community.general/pull/5545). diff --git a/plugins/module_utils/gconftool2.py b/plugins/module_utils/gconftool2.py index cd9de57695..e90c3fb2cb 100644 --- a/plugins/module_utils/gconftool2.py +++ b/plugins/module_utils/gconftool2.py @@ -6,7 +6,14 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt as fmt +from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt + + +_state_map = { + "present": "--set", + "absent": "--unset", + "get": "--get", +} def gconftool2_runner(module, **kwargs): @@ -14,14 +21,12 @@ def gconftool2_runner(module, **kwargs): module, command='gconftool-2', arg_formats=dict( - key=fmt.as_list(), - value_type=fmt.as_opt_val("--type"), - value=fmt.as_list(), - direct=fmt.as_bool("--direct"), - config_source=fmt.as_opt_val("--config-source"), - get=fmt.as_bool("--get"), - set_arg=fmt.as_bool("--set"), - unset=fmt.as_bool("--unset"), + state=cmd_runner_fmt.as_map(_state_map), + key=cmd_runner_fmt.as_list(), + value_type=cmd_runner_fmt.as_opt_val("--type"), + value=cmd_runner_fmt.as_list(), + direct=cmd_runner_fmt.as_bool("--direct"), + config_source=cmd_runner_fmt.as_opt_val("--config-source"), ), **kwargs ) diff --git a/plugins/modules/gconftool2.py b/plugins/modules/gconftool2.py index 931b43d76c..a3ac8bb8f1 100644 --- a/plugins/modules/gconftool2.py +++ b/plugins/modules/gconftool2.py @@ -83,75 +83,17 @@ RETURN = ''' ... ''' -from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.general.plugins.module_utils.module_helper import StateModuleHelper +from ansible_collections.community.general.plugins.module_utils.gconftool2 import gconftool2_runner -class GConf2Preference(object): - def __init__(self, ansible, key, value_type, value, - direct=False, config_source=""): - self.ansible = ansible - self.key = key - self.value_type = value_type - self.value = value - self.config_source = config_source - self.direct = direct - - def value_already_set(self): - return False - - def call(self, call_type, fail_onerr=True): - """ Helper function to perform gconftool-2 operations """ - config_source = [] - direct = [] - changed = False - out = '' - - # If the configuration source is different from the default, create - # the argument - if self.config_source is not None and len(self.config_source) > 0: - config_source = ["--config-source", self.config_source] - - # If direct is true, create the argument - if self.direct: - direct = ["--direct"] - - # Execute the call - cmd = ["gconftool-2"] - try: - # If the call is "get", then we don't need as many parameters and - # we can ignore some - if call_type == 'get': - self.ansible.deprecate( - msg="State 'get' is deprecated. Please use the module community.general.gconftool2_info instead", - version="8.0.0", collection_name="community.general" - ) - cmd.extend(["--get", self.key]) - # Otherwise, we will use all relevant parameters - elif call_type == 'set': - cmd.extend(direct) - cmd.extend(config_source) - cmd.extend(["--type", self.value_type, "--{3}".format(call_type), self.key, self.value]) - elif call_type == 'unset': - cmd.extend(["--unset", self.key]) - - # Start external command - rc, out, err = self.ansible.run_command(cmd) - - if err and fail_onerr: - self.ansible.fail_json(msg='gconftool-2 failed with ' - 'error: %s' % (str(err))) - else: - changed = True - - except OSError as exception: - self.ansible.fail_json(msg='gconftool-2 failed with exception: ' - '%s' % exception) - return changed, out.rstrip() - - -def main(): - # Setup the Ansible module - module = AnsibleModule( +class GConftool(StateModuleHelper): + change_params = 'value', + diff_params = 'value', + output_params = ('key', 'value_type') + facts_params = ('key', 'value_type') + facts_name = 'gconftool2' + module = dict( argument_spec=dict( key=dict(type='str', required=True, no_log=False), value_type=dict(type='str', choices=['bool', 'float', 'int', 'string']), @@ -160,75 +102,54 @@ def main(): direct=dict(type='bool', default=False), config_source=dict(type='str'), ), - supports_check_mode=True + required_if=[ + ('state', 'present', ['value', 'value_type']), + ('state', 'absent', ['value']), + ('direct', True, ['config_source']), + ], + supports_check_mode=True, ) - state_values = {"present": "set", "absent": "unset", "get": "get"} + def __init_module__(self): + self.runner = gconftool2_runner(self.module, check_rc=True) + if self.vars.state != "get": + if not self.vars.direct and self.vars.config_source is not None: + self.module.fail_json(msg='If the "config_source" is specified then "direct" must be "true"') - # Assign module values to dictionary values - key = module.params['key'] - value_type = module.params['value_type'] - if module.params['value'].lower() == "true": - value = "true" - elif module.params['value'] == "false": - value = "false" - else: - value = module.params['value'] + self.vars.set('previous_value', self._get(), fact=True) + self.vars.set('value_type', self.vars.value_type) + self.vars.set_meta('value', initial_value=self.vars.previous_value) + self.vars.set('playbook_value', self.vars.value, fact=True) - state = state_values[module.params['state']] - direct = module.params['direct'] - config_source = module.params['config_source'] + def _make_process(self, fail_on_err): + def process(rc, out, err): + if err and fail_on_err: + self.ansible.fail_json(msg='gconftool-2 failed with error: %s' % (str(err))) + self.vars.value = out.rstrip() + return self.vars.value + return process - # Initialize some variables for later - change = False - new_value = '' + def _get(self): + return self.runner("state key", output_process=self._make_process(False)).run(state="get") - if state != "get": - if value is None or value == "": - module.fail_json(msg='State %s requires "value" to be set' - % str(state)) - elif value_type is None or value_type == "": - module.fail_json(msg='State %s requires "value_type" to be set' - % str(state)) + def state_get(self): + self.deprecate( + msg="State 'get' is deprecated. Please use the module community.general.gconftool2_info instead", + version="8.0.0", collection_name="community.general" + ) - if direct and config_source is None: - module.fail_json(msg='If "direct" is "true" then the ' + - '"config_source" must be specified') - elif not direct and config_source is not None: - module.fail_json(msg='If the "config_source" is specified ' + - 'then "direct" must be "true"') + def state_absent(self): + with self.runner("state key", output_process=self._make_process(False)) as ctx: + ctx.run() + self.vars.set('new_value', None, fact=True) - # Create a gconf2 preference - gconf_pref = GConf2Preference(module, key, value_type, - value, direct, config_source) - # Now we get the current value, if not found don't fail - dummy, current_value = gconf_pref.call("get", fail_onerr=False) + def state_present(self): + with self.runner("direct config_source value_type state key value", output_process=self._make_process(True)) as ctx: + self.vars.set('new_value', ctx.run(), fact=True) - # Check if the current value equals the value we want to set. If not, make - # a change - if current_value != value: - # If check mode, we know a change would have occurred. - if module.check_mode: - # So we will set the change to True - change = True - # And set the new_value to the value that would have been set - new_value = value - # If not check mode make the change. - else: - change, new_value = gconf_pref.call(state) - # If the value we want to set is the same as the current_value, we will - # set the new_value to the current_value for reporting - else: - new_value = current_value - facts = dict(gconftool2={'changed': change, - 'key': key, - 'value_type': value_type, - 'new_value': new_value, - 'previous_value': current_value, - 'playbook_value': module.params['value']}) - - module.exit_json(changed=change, ansible_facts=facts) +def main(): + GConftool.execute() if __name__ == '__main__': diff --git a/plugins/modules/gconftool2_info.py b/plugins/modules/gconftool2_info.py index f9231104d4..282065b95e 100644 --- a/plugins/modules/gconftool2_info.py +++ b/plugins/modules/gconftool2_info.py @@ -65,8 +65,8 @@ class GConftoolInfo(ModuleHelper): self.runner = gconftool2_runner(self.module, check_rc=True) def __run__(self): - with self.runner.context(args_order=["get", "key"]) as ctx: - rc, out, err = ctx.run(get=True) + with self.runner.context(args_order=["state", "key"]) as ctx: + rc, out, err = ctx.run(state="get") self.vars.value = None if err and not out else out.rstrip() diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index a736032da2..40b96de649 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -7,7 +7,7 @@ plugins/modules/consul.py validate-modules:doc-missing-type plugins/modules/consul.py validate-modules:undocumented-parameter plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice -plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice +plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0 plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/jenkins_plugin.py use-argspec-type-path plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index d01077cc9c..6e27e3105a 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -2,7 +2,7 @@ plugins/modules/consul.py validate-modules:doc-missing-type plugins/modules/consul.py validate-modules:undocumented-parameter plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice -plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice +plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0 plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/jenkins_plugin.py use-argspec-type-path plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index d01077cc9c..6e27e3105a 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -2,7 +2,7 @@ plugins/modules/consul.py validate-modules:doc-missing-type plugins/modules/consul.py validate-modules:undocumented-parameter plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice -plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice +plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0 plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/jenkins_plugin.py use-argspec-type-path plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 293e878680..da21cc0225 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -2,7 +2,7 @@ plugins/modules/consul.py validate-modules:doc-missing-type plugins/modules/consul.py validate-modules:undocumented-parameter plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice -plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice +plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0 plugins/modules/homectl.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/jenkins_plugin.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index 293e878680..da21cc0225 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -2,7 +2,7 @@ plugins/modules/consul.py validate-modules:doc-missing-type plugins/modules/consul.py validate-modules:undocumented-parameter plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice -plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice +plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0 plugins/modules/homectl.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/jenkins_plugin.py use-argspec-type-path diff --git a/tests/unit/plugins/modules/test_gconftool2.py b/tests/unit/plugins/modules/test_gconftool2.py new file mode 100644 index 0000000000..f01f15ef82 --- /dev/null +++ b/tests/unit/plugins/modules/test_gconftool2.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Alexei Znamensky (russoz@gmail.com) +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json + +from ansible_collections.community.general.plugins.modules import gconftool2 + +import pytest + +TESTED_MODULE = gconftool2.__name__ + + +@pytest.fixture +def patch_gconftool2(mocker): + """ + Function used for mocking some parts of redhat_subscription module + """ + mocker.patch('ansible_collections.community.general.plugins.module_utils.mh.module_helper.AnsibleModule.get_bin_path', + return_value='/testbin/gconftool-2') + + +TEST_CASES = [ + [ + {'state': 'get', 'key': '/desktop/gnome/background/picture_filename'}, + { + 'id': 'test_simple_element_get', + 'run_command.calls': [ + ( + ['/testbin/gconftool-2', '--get', '/desktop/gnome/background/picture_filename'], + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, + (0, '100\n', '',), + ), + ], + 'new_value': '100', + } + ], + [ + {'state': 'get', 'key': '/desktop/gnome/background/picture_filename'}, + { + 'id': 'test_simple_element_get_not_found', + 'run_command.calls': [ + ( + ['/testbin/gconftool-2', '--get', '/desktop/gnome/background/picture_filename'], + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, + (0, '', "No value set for `/desktop/gnome/background/picture_filename'\n",), + ), + ], + 'new_value': None, + } + ], + [ + {'state': 'present', 'key': '/desktop/gnome/background/picture_filename', 'value': '200', 'value_type': 'int'}, + { + 'id': 'test_simple_element_set', + 'run_command.calls': [ + ( + ['/testbin/gconftool-2', '--get', '/desktop/gnome/background/picture_filename'], + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, + (0, '100\n', '',), + ), + ( + ['/testbin/gconftool-2', '--type', 'int', '--set', '/desktop/gnome/background/picture_filename', '200'], + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, + (0, '200\n', '',), + ), + ], + 'new_value': '200', + } + ], +] +TEST_CASES_IDS = [item[1]['id'] for item in TEST_CASES] + + +@pytest.mark.parametrize('patch_ansible_module, testcase', + TEST_CASES, + ids=TEST_CASES_IDS, + indirect=['patch_ansible_module']) +@pytest.mark.usefixtures('patch_ansible_module') +def test_gconftool2(mocker, capfd, patch_gconftool2, testcase): + """ + Run unit tests for test cases listen in TEST_CASES + """ + + # Mock function used for running commands first + call_results = [item[2] for item in testcase['run_command.calls']] + mock_run_command = mocker.patch( + 'ansible_collections.community.general.plugins.module_utils.mh.module_helper.AnsibleModule.run_command', + side_effect=call_results) + + # Try to run test case + with pytest.raises(SystemExit): + gconftool2.main() + + out, err = capfd.readouterr() + results = json.loads(out) + print("testcase =\n%s" % testcase) + print("results =\n%s" % results) + + for conditional_test_result in ('value',): + if conditional_test_result in testcase: + assert conditional_test_result in results, "'{0}' not found in {1}".format(conditional_test_result, results) + assert results[conditional_test_result] == testcase[conditional_test_result], \ + "'{0}': '{1}' != '{2}'".format(conditional_test_result, results[conditional_test_result], testcase[conditional_test_result]) + + assert mock_run_command.call_count == len(testcase['run_command.calls']) + if mock_run_command.call_count: + call_args_list = [(item[0][0], item[1]) for item in mock_run_command.call_args_list] + expected_call_args_list = [(item[0], item[1]) for item in testcase['run_command.calls']] + print("call args list =\n%s" % call_args_list) + print("expected args list =\n%s" % expected_call_args_list) + assert call_args_list == expected_call_args_list From 38b4e316aeb66f5cb9b965640de3b3905dd885c0 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 07:37:36 +0100 Subject: [PATCH 030/134] lxd_project: refactored os.path.expanduser() to module utils (#5549) (#5552) * lxd_project: refactored os.path.expanduser() to module utils * add changelog fragment (cherry picked from commit 9874462abb10a079cc45b88e778e33160a737253) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- changelogs/fragments/5549-lxd-project-sanity.yml | 2 ++ plugins/module_utils/lxd.py | 12 ++++++++++-- plugins/modules/lxd_project.py | 8 +++++--- tests/sanity/ignore-2.11.txt | 1 - tests/sanity/ignore-2.12.txt | 1 - tests/sanity/ignore-2.13.txt | 1 - tests/sanity/ignore-2.14.txt | 1 - tests/sanity/ignore-2.15.txt | 1 - 8 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 changelogs/fragments/5549-lxd-project-sanity.yml diff --git a/changelogs/fragments/5549-lxd-project-sanity.yml b/changelogs/fragments/5549-lxd-project-sanity.yml new file mode 100644 index 0000000000..0a5e328e1c --- /dev/null +++ b/changelogs/fragments/5549-lxd-project-sanity.yml @@ -0,0 +1,2 @@ +minor_changes: + - lxd_project - refactored code out to module utils to clear sanity check (https://github.com/ansible-collections/community.general/pull/5549). diff --git a/plugins/module_utils/lxd.py b/plugins/module_utils/lxd.py index bdf026313a..007de4d8db 100644 --- a/plugins/module_utils/lxd.py +++ b/plugins/module_utils/lxd.py @@ -8,8 +8,10 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +import os import socket import ssl +import json from ansible.module_utils.urls import generic_urlparse from ansible.module_utils.six.moves.urllib.parse import urlparse @@ -20,8 +22,6 @@ from ansible.module_utils.common.text.converters import to_text HTTPConnection = http_client.HTTPConnection HTTPSConnection = http_client.HTTPSConnection -import json - class UnixHTTPConnection(HTTPConnection): def __init__(self, path): @@ -124,3 +124,11 @@ class LXDClient(object): if err is None: err = resp_json.get('error', None) return err + + +def default_key_file(): + return os.path.expanduser('~/.config/lxc/client.key') + + +def default_cert_file(): + return os.path.expanduser('~/.config/lxc/client.crt') diff --git a/plugins/modules/lxd_project.py b/plugins/modules/lxd_project.py index f0aa4058e7..ad6019c2ec 100644 --- a/plugins/modules/lxd_project.py +++ b/plugins/modules/lxd_project.py @@ -178,7 +178,9 @@ actions: sample: ["create"] ''' -from ansible_collections.community.general.plugins.module_utils.lxd import LXDClient, LXDClientException +from ansible_collections.community.general.plugins.module_utils.lxd import ( + LXDClient, LXDClientException, default_key_file, default_cert_file +) from ansible.module_utils.basic import AnsibleModule import os @@ -211,10 +213,10 @@ class LXDProjectManagement(object): self.key_file = self.module.params.get('client_key') if self.key_file is None: - self.key_file = os.path.expanduser('~/.config/lxc/client.key') + self.key_file = default_key_file() self.cert_file = self.module.params.get('client_cert') if self.cert_file is None: - self.cert_file = os.path.expanduser('~/.config/lxc/client.crt') + self.cert_file = default_cert_file() self.debug = self.module._verbosity >= 4 try: diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 40b96de649..92d11fb437 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -11,7 +11,6 @@ plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/jenkins_plugin.py use-argspec-type-path plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen -plugins/modules/lxd_project.py use-argspec-type-path # expanduser() applied to constants plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:doc-missing-type # missing docs on suboptions diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index 6e27e3105a..1fdd39ec6e 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -6,7 +6,6 @@ plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/jenkins_plugin.py use-argspec-type-path plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen -plugins/modules/lxd_project.py use-argspec-type-path # expanduser() applied to constants plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:doc-missing-type # missing docs on suboptions diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index 6e27e3105a..1fdd39ec6e 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -6,7 +6,6 @@ plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/jenkins_plugin.py use-argspec-type-path plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen -plugins/modules/lxd_project.py use-argspec-type-path # expanduser() applied to constants plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:doc-missing-type # missing docs on suboptions diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index da21cc0225..7a7eaea341 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -7,7 +7,6 @@ plugins/modules/homectl.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/jenkins_plugin.py use-argspec-type-path plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen -plugins/modules/lxd_project.py use-argspec-type-path # expanduser() applied to constants plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:doc-missing-type # missing docs on suboptions diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index da21cc0225..7a7eaea341 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -7,7 +7,6 @@ plugins/modules/homectl.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/jenkins_plugin.py use-argspec-type-path plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen -plugins/modules/lxd_project.py use-argspec-type-path # expanduser() applied to constants plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:doc-missing-type # missing docs on suboptions From ffee01cd9ccf81c0d299f6dcb8660590385148a6 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 07:37:45 +0100 Subject: [PATCH 031/134] add dependency manager (#5535) (#5574) * add dependency manager * add plugins/module_utils/deps.py to BOTMETA * ditch usng OrderedDict to keep compatibility with Python 2.6 * Update plugins/module_utils/deps.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 0624951e177466912f4bda642b72dd2d9c54c1cd) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .github/BOTMETA.yml | 2 + plugins/module_utils/deps.py | 90 +++++++++++++++++++++++++++++++ plugins/modules/dnsimple_info.py | 16 ++---- plugins/modules/iso_customize.py | 19 +++---- plugins/modules/pagerduty_user.py | 27 ++-------- plugins/modules/pids.py | 15 +++--- plugins/modules/snmp_facts.py | 17 ++---- 7 files changed, 117 insertions(+), 69 deletions(-) create mode 100644 plugins/module_utils/deps.py diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index c56720cb0d..2fbbf64f65 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -265,6 +265,8 @@ files: maintainers: delineaKrehl tylerezimmerman $module_utils/: labels: module_utils + $module_utils/deps.py: + maintainers: russoz $module_utils/gconftool2.py: labels: gconftool2 maintainers: russoz diff --git a/plugins/module_utils/deps.py b/plugins/module_utils/deps.py new file mode 100644 index 0000000000..bfb94cbc09 --- /dev/null +++ b/plugins/module_utils/deps.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# (c) 2022, Alexei Znamensky +# Copyright (c) 2022, Ansible Project +# Simplified BSD License (see LICENSES/BSD-2-Clause.txt or https://opensource.org/licenses/BSD-2-Clause) +# SPDX-License-Identifier: BSD-2-Clause + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +import traceback +from contextlib import contextmanager + +from ansible.module_utils.common.text.converters import to_native +from ansible.module_utils.basic import missing_required_lib + + +_deps = dict() + + +class _Dependency(object): + _states = ["pending", "failure", "success"] + + def __init__(self, name, reason=None, url=None, msg=None): + self.name = name + self.reason = reason + self.url = url + self.msg = msg + + self.state = 0 + self.trace = None + self.exc = None + + def succeed(self): + self.state = 2 + + def fail(self, exc, trace): + self.state = 1 + self.exc = exc + self.trace = trace + + @property + def message(self): + if self.msg: + return to_native(self.msg) + else: + return missing_required_lib(self.name, reason=self.reason, url=self.url) + + @property + def failed(self): + return self.state == 1 + + def verify(self, module): + if self.failed: + module.fail_json(msg=self.message, exception=self.trace) + + def __str__(self): + return "".format(self.name, self._states[self.state]) + + +@contextmanager +def declare(name, *args, **kwargs): + dep = _Dependency(name, *args, **kwargs) + try: + yield dep + except Exception as e: + dep.fail(e, traceback.format_exc()) + else: + dep.succeed() + finally: + _deps[name] = dep + + +def validate(module, spec=None): + dep_names = sorted(_deps) + + if spec is not None: + if spec.startswith("-"): + spec_split = spec[1:].split(":") + for d in spec_split: + dep_names.remove(d) + else: + spec_split = spec[1:].split(":") + dep_names = [] + for d in spec_split: + _deps[d] # ensure it exists + dep_names.append(d) + + for dep in dep_names: + _deps[dep].verify(module) diff --git a/plugins/modules/dnsimple_info.py b/plugins/modules/dnsimple_info.py index 959bacbbe8..52fd53303f 100644 --- a/plugins/modules/dnsimple_info.py +++ b/plugins/modules/dnsimple_info.py @@ -230,18 +230,11 @@ dnsimple_record_info: type: str ''' -import traceback from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.basic import missing_required_lib +from ansible_collections.community.general.plugins.module_utils import deps -try: +with deps.declare("requests"): from requests import Request, Session -except ImportError: - HAS_REQUESTS = False - REQUESTS_IMPORT_ERROR = traceback.format_exc() -else: - HAS_REQUESTS = True - REQUESTS_IMPORT_ERROR = None def build_url(account, key, is_sandbox): @@ -310,10 +303,7 @@ def main(): params['api_key'], params['sandbox']) - if not HAS_REQUESTS: - module.exit_json( - msg=missing_required_lib('requests'), - exception=REQUESTS_IMPORT_ERROR) + deps.validate(module) # At minimum we need account and key if params['account_id'] and params['api_key']: diff --git a/plugins/modules/iso_customize.py b/plugins/modules/iso_customize.py index c3a2ae2651..4f902f47e4 100644 --- a/plugins/modules/iso_customize.py +++ b/plugins/modules/iso_customize.py @@ -97,19 +97,14 @@ dest_iso: ''' import os -import traceback -PYCDLIB_IMP_ERR = None -try: - import pycdlib - HAS_PYCDLIB = True -except ImportError: - PYCDLIB_IMP_ERR = traceback.format_exc() - HAS_PYCDLIB = False - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib +from ansible_collections.community.general.plugins.module_utils import deps +from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.common.text.converters import to_native +with deps.declare("pycdlib"): + import pycdlib + # The upper dir exist, we only add subdirectoy def iso_add_dir(module, opened_iso, iso_type, dir_path): @@ -306,9 +301,7 @@ def main(): required_one_of=[('delete_files', 'add_files'), ], supports_check_mode=True, ) - if not HAS_PYCDLIB: - module.fail_json( - missing_required_lib('pycdlib'), exception=PYCDLIB_IMP_ERR) + deps.validate(module) src_iso = module.params['src_iso'] if not os.path.exists(src_iso): diff --git a/plugins/modules/pagerduty_user.py b/plugins/modules/pagerduty_user.py index 4d8e32248f..e16fe59e76 100644 --- a/plugins/modules/pagerduty_user.py +++ b/plugins/modules/pagerduty_user.py @@ -80,25 +80,12 @@ EXAMPLES = r''' RETURN = r''' # ''' -from ansible.module_utils.basic import AnsibleModule, missing_required_lib -import traceback from os import path +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.general.plugins.module_utils import deps -try: - from pdpyras import APISession - HAS_PD_PY = True - PD_IMPORT_ERR = None -except ImportError: - HAS_PD_PY = False - PD_IMPORT_ERR = traceback.format_exc() - -try: - from pdpyras import PDClientError - HAS_PD_CLIENT_ERR = True - PD_CLIENT_ERR_IMPORT_ERR = None -except ImportError: - HAS_PD_CLIENT_ERR = False - PD_CLIENT_ERR_IMPORT_ERR = traceback.format_exc() +with deps.declare("pdpyras", url="https://github.com/PagerDuty/pdpyras"): + from pdpyras import APISession, PDClientError class PagerDutyUser(object): @@ -202,11 +189,7 @@ def main(): supports_check_mode=True, ) - if not HAS_PD_PY: - module.fail_json(msg=missing_required_lib('pdpyras', url='https://github.com/PagerDuty/pdpyras'), exception=PD_IMPORT_ERR) - - if not HAS_PD_CLIENT_ERR: - module.fail_json(msg=missing_required_lib('PDClientError', url='https://github.com/PagerDuty/pdpyras'), exception=PD_CLIENT_ERR_IMPORT_ERR) + deps.validate(module) access_token = module.params['access_token'] pd_user = module.params['pd_user'] diff --git a/plugins/modules/pids.py b/plugins/modules/pids.py index eaaf7f9437..2fe2a6b8ac 100644 --- a/plugins/modules/pids.py +++ b/plugins/modules/pids.py @@ -3,8 +3,8 @@ # Copyright (c) 2019, Saranya Sridharan # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # SPDX-License-Identifier: GPL-3.0-or-later -from __future__ import (absolute_import, division, print_function) +from __future__ import (absolute_import, division, print_function) __metaclass__ = type DOCUMENTATION = ''' @@ -60,18 +60,15 @@ import re from os.path import basename from ansible.module_utils import six -from ansible.module_utils.basic import AnsibleModule, missing_required_lib +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.general.plugins.module_utils import deps from ansible.module_utils.common.text.converters import to_native from ansible_collections.community.general.plugins.module_utils.version import LooseVersion -try: +with deps.declare("psutil"): import psutil - HAS_PSUTIL = True -except ImportError: - HAS_PSUTIL = False - class PSAdapterError(Exception): pass @@ -177,8 +174,8 @@ def compare_lower(a, b): class Pids(object): def __init__(self, module): - if not HAS_PSUTIL: - module.fail_json(msg=missing_required_lib('psutil')) + + deps.validate(module) self._ps = PSAdapter.from_package(psutil) diff --git a/plugins/modules/snmp_facts.py b/plugins/modules/snmp_facts.py index 71821faaa8..0242bc6dde 100644 --- a/plugins/modules/snmp_facts.py +++ b/plugins/modules/snmp_facts.py @@ -183,20 +183,14 @@ ansible_interfaces: ''' import binascii -import traceback from collections import defaultdict +from ansible_collections.community.general.plugins.module_utils import deps +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.common.text.converters import to_text -PYSNMP_IMP_ERR = None -try: +with deps.declare("pysnmp"): from pysnmp.entity.rfc3413.oneliner import cmdgen from pysnmp.proto.rfc1905 import EndOfMibView - HAS_PYSNMP = True -except Exception: - PYSNMP_IMP_ERR = traceback.format_exc() - HAS_PYSNMP = False - -from ansible.module_utils.basic import AnsibleModule, missing_required_lib -from ansible.module_utils.common.text.converters import to_text class DefineOid(object): @@ -299,8 +293,7 @@ def main(): m_args = module.params - if not HAS_PYSNMP: - module.fail_json(msg=missing_required_lib('pysnmp'), exception=PYSNMP_IMP_ERR) + deps.validate(module) cmdGen = cmdgen.CommandGenerator() transport_opts = dict((k, m_args[k]) for k in ('timeout', 'retries') if m_args[k] is not None) From 17447d2a8434c6ea3b5b65e06a19f607f0cb701b Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 07:37:52 +0100 Subject: [PATCH 032/134] jenkins_plugin: fix sanity checks (#5565) (#5575) * jenkins_plugin: fix sanity checks * update BOTMETA * add changelog fragment * fix copyright * Update plugins/module_utils/jenkins.py Co-authored-by: Felix Fontein * Update plugins/module_utils/jenkins.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 8ad43fd77484f85bedc114dbedaee04168d6c8ee) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .github/BOTMETA.yml | 3 + .../fragments/5565-jenkins-plugin-sanity.yml | 2 + plugins/module_utils/jenkins.py | 35 ++++++++ plugins/modules/jenkins_plugin.py | 85 +++++++------------ tests/sanity/ignore-2.11.txt | 1 - tests/sanity/ignore-2.12.txt | 1 - tests/sanity/ignore-2.13.txt | 1 - tests/sanity/ignore-2.14.txt | 1 - tests/sanity/ignore-2.15.txt | 1 - 9 files changed, 71 insertions(+), 59 deletions(-) create mode 100644 changelogs/fragments/5565-jenkins-plugin-sanity.yml create mode 100644 plugins/module_utils/jenkins.py diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 2fbbf64f65..6aacdc9cad 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -284,6 +284,9 @@ files: $module_utils/ipa.py: labels: ipa maintainers: $team_ipa + $module_utils/jenkins.py: + labels: jenkins + maintainers: russoz $module_utils/manageiq.py: labels: manageiq maintainers: $team_manageiq diff --git a/changelogs/fragments/5565-jenkins-plugin-sanity.yml b/changelogs/fragments/5565-jenkins-plugin-sanity.yml new file mode 100644 index 0000000000..ea72d90615 --- /dev/null +++ b/changelogs/fragments/5565-jenkins-plugin-sanity.yml @@ -0,0 +1,2 @@ +minor_changes: + - jenkins_plugin - refactor code to module util to fix sanity check (https://github.com/ansible-collections/community.general/pull/5565). diff --git a/plugins/module_utils/jenkins.py b/plugins/module_utils/jenkins.py new file mode 100644 index 0000000000..c742b364b7 --- /dev/null +++ b/plugins/module_utils/jenkins.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2022, Alexei Znamensky +# +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +import os +import time + + +def download_updates_file(updates_expiration): + updates_filename = 'jenkins-plugin-cache.json' + updates_dir = os.path.expanduser('~/.ansible/tmp') + updates_file = os.path.join(updates_dir, updates_filename) + download_updates = True + + # Make sure the destination directory exists + if not os.path.isdir(updates_dir): + os.makedirs(updates_dir, 0o700) + + # Check if we need to download new updates file + if os.path.isfile(updates_file): + # Get timestamp when the file was changed last time + ts_file = os.stat(updates_file).st_mtime + ts_now = time.time() + + if ts_now - ts_file < updates_expiration: + download_updates = False + + return updates_file, download_updates diff --git a/plugins/modules/jenkins_plugin.py b/plugins/modules/jenkins_plugin.py index 27261bf815..c4e1b7fb66 100644 --- a/plugins/modules/jenkins_plugin.py +++ b/plugins/modules/jenkins_plugin.py @@ -290,12 +290,6 @@ state: sample: "present" ''' -from ansible.module_utils.basic import AnsibleModule, to_bytes -from ansible.module_utils.six.moves import http_cookiejar as cookiejar -from ansible.module_utils.six.moves.urllib.parse import urlencode -from ansible.module_utils.urls import fetch_url, url_argument_spec -from ansible.module_utils.six import text_type, binary_type -from ansible.module_utils.common.text.converters import to_native import hashlib import io import json @@ -303,6 +297,15 @@ import os import tempfile import time +from ansible.module_utils.basic import AnsibleModule, to_bytes +from ansible.module_utils.six.moves import http_cookiejar as cookiejar +from ansible.module_utils.six.moves.urllib.parse import urlencode +from ansible.module_utils.urls import fetch_url, url_argument_spec +from ansible.module_utils.six import text_type, binary_type +from ansible.module_utils.common.text.converters import to_native + +from ansible_collections.community.general.plugins.module_utils.jenkins import download_updates_file + class FailedInstallingWithPluginManager(Exception): pass @@ -605,21 +608,12 @@ class JenkinsPlugin(object): return urls def _download_updates(self): - updates_filename = 'jenkins-plugin-cache.json' - updates_dir = os.path.expanduser('~/.ansible/tmp') - updates_file = "%s/%s" % (updates_dir, updates_filename) - download_updates = True - - # Check if we need to download new updates file - if os.path.isfile(updates_file): - # Get timestamp when the file was changed last time - ts_file = os.stat(updates_file).st_mtime - ts_now = time.time() - - if ts_now - ts_file < self.params['updates_expiration']: - download_updates = False - - updates_file_orig = updates_file + try: + updates_file, download_updates = download_updates_file(self.params['updates_expiration']) + except OSError as e: + self.module.fail_json( + msg="Cannot create temporal directory.", + details=to_native(e)) # Download the updates file if needed if download_updates: @@ -632,56 +626,39 @@ class JenkinsPlugin(object): msg_exception="Updates download failed.") # Write the updates file - update_fd, updates_file = tempfile.mkstemp() - os.write(update_fd, r.read()) + tmp_update_fd, tmp_updates_file = tempfile.mkstemp() + os.write(tmp_update_fd, r.read()) try: - os.close(update_fd) + os.close(tmp_update_fd) except IOError as e: self.module.fail_json( - msg="Cannot close the tmp updates file %s." % updates_file, + msg="Cannot close the tmp updates file %s." % tmp_updates_file, details=to_native(e)) # Open the updates file try: - f = io.open(updates_file, encoding='utf-8') + f = io.open(tmp_updates_file, encoding='utf-8') + + # Read only the second line + dummy = f.readline() + data = json.loads(f.readline()) except IOError as e: self.module.fail_json( msg="Cannot open temporal updates file.", details=to_native(e)) - - i = 0 - for line in f: - # Read only the second line - if i == 1: - try: - data = json.loads(line) - except Exception as e: - self.module.fail_json( - msg="Cannot load JSON data from the tmp updates file.", - details=to_native(e)) - - break - - i += 1 + except Exception as e: + self.module.fail_json( + msg="Cannot load JSON data from the tmp updates file.", + details=to_native(e)) # Move the updates file to the right place if we could read it if download_updates: - # Make sure the destination directory exists - if not os.path.isdir(updates_dir): - try: - os.makedirs(updates_dir, int('0700', 8)) - except OSError as e: - self.module.fail_json( - msg="Cannot create temporal directory.", - details=to_native(e)) - - self.module.atomic_move(updates_file, updates_file_orig) + self.module.atomic_move(tmp_updates_file, updates_file) # Check if we have the plugin data available - if 'plugins' not in data or self.params['name'] not in data['plugins']: - self.module.fail_json( - msg="Cannot find plugin data in the updates file.") + if not data.get('plugins', {}).get(self.params['name']): + self.module.fail_json(msg="Cannot find plugin data in the updates file.") return data['plugins'][self.params['name']] diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 92d11fb437..86d7f6a9e2 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -9,7 +9,6 @@ plugins/modules/consul.py validate-modules:undocumented-parameter plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0 plugins/modules/iptables_state.py validate-modules:undocumented-parameter -plugins/modules/jenkins_plugin.py use-argspec-type-path plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index 1fdd39ec6e..45772005a3 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -4,7 +4,6 @@ plugins/modules/consul.py validate-modules:undocumented-parameter plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0 plugins/modules/iptables_state.py validate-modules:undocumented-parameter -plugins/modules/jenkins_plugin.py use-argspec-type-path plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index 1fdd39ec6e..45772005a3 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -4,7 +4,6 @@ plugins/modules/consul.py validate-modules:undocumented-parameter plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0 plugins/modules/iptables_state.py validate-modules:undocumented-parameter -plugins/modules/jenkins_plugin.py use-argspec-type-path plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 7a7eaea341..49c2eb1bb2 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -5,7 +5,6 @@ plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choic plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0 plugins/modules/homectl.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/iptables_state.py validate-modules:undocumented-parameter -plugins/modules/jenkins_plugin.py use-argspec-type-path plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index 7a7eaea341..49c2eb1bb2 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -5,7 +5,6 @@ plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choic plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0 plugins/modules/homectl.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/iptables_state.py validate-modules:undocumented-parameter -plugins/modules/jenkins_plugin.py use-argspec-type-path plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions From 5ebd980e264936bc5b6cfdcb900897f9bc350215 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 07:37:59 +0100 Subject: [PATCH 033/134] Add additional flags to nmap.py (#5566) (#5576) * Adding extra flag options for NMAP scaning udp_scan, icmp_timestamp and dns_resolve * Update nmap.py * Update plugins/inventory/nmap.py Co-authored-by: Felix Fontein * Updates as per felixfontein suggestions * Updates as per felixfontein suggestions * Update plugins/inventory/nmap.py Co-authored-by: Felix Fontein * Update plugins/inventory/nmap.py Co-authored-by: Felix Fontein * Update nmap.py * Update changelogs/fragments/5566-additional-flags-nmap.yml Co-authored-by: Felix Fontein * Update changelogs/fragments/5566-additional-flags-nmap.yml Co-authored-by: Felix Fontein * Update 5566-additional-flags-nmap.yml * Update nmap.py Co-authored-by: Axis12 <3225945+axistwelve@users.noreply.github.com> Co-authored-by: Felix Fontein (cherry picked from commit 52c28494ca903642aa4278afb580321302d119c9) Co-authored-by: David Stuart --- .../fragments/5566-additional-flags-nmap.yml | 3 ++ plugins/inventory/nmap.py | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 changelogs/fragments/5566-additional-flags-nmap.yml diff --git a/changelogs/fragments/5566-additional-flags-nmap.yml b/changelogs/fragments/5566-additional-flags-nmap.yml new file mode 100644 index 0000000000..d42f3a4695 --- /dev/null +++ b/changelogs/fragments/5566-additional-flags-nmap.yml @@ -0,0 +1,3 @@ +minor_changes: + - nmap inventory plugin - add new options ``udp_scan``, ``icmp_timestamp``, and ``dns_resolve`` for different types of scans (https://github.com/ansible-collections/community.general/pull/5566). + diff --git a/plugins/inventory/nmap.py b/plugins/inventory/nmap.py index 01a5fa04ba..f0fa50e3b3 100644 --- a/plugins/inventory/nmap.py +++ b/plugins/inventory/nmap.py @@ -46,6 +46,25 @@ DOCUMENTATION = ''' description: use IPv6 type addresses type: boolean default: true + udp_scan: + description: + - Scan via UDP. + - Depending on your system you might need I(sudo=true) for this to work. + type: boolean + default: false + version_added: 6.1.0 + icmp_timestamp: + description: + - Scan via ICMP Timestamp (C(-PP)). + - Depending on your system you might need I(sudo=true) for this to work. + type: boolean + default: false + version_added: 6.1.0 + dns_resolve: + description: Whether to always (C(true)) or never (C(false)) do DNS resolution. + type: boolean + default: false + version_added: 6.1.0 notes: - At least one of ipv4 or ipv6 is required to be True, both can be True, but they cannot both be False. - 'TODO: add OS fingerprinting' @@ -166,6 +185,15 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): cmd.append('--exclude') cmd.append(','.join(self._options['exclude'])) + if self._options['dns_resolve']: + cmd.append('-n') + + if self._options['udp_scan']: + cmd.append('-sU') + + if self._options['icmp_timestamp']: + cmd.append('-PP') + cmd.append(self._options['address']) try: # execute From 8d83557e52dc2501606522dcdc578da428ec1c83 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 07:38:08 +0100 Subject: [PATCH 034/134] [GitLab] Add modules to manager project badges (#5534) (#5584) * [GitLab] Add modules to manager project badges Signed-off-by: Lunik * first review Signed-off-by: Lunik * Update plugins/modules/gitlab_project_badge.py Co-authored-by: Felix Fontein Signed-off-by: Lunik Co-authored-by: Felix Fontein (cherry picked from commit c7481c5c96536a6bb8a0c32639706bada10346bb) Co-authored-by: Guillaume MARTINEZ --- plugins/modules/gitlab_project_badge.py | 216 ++++++++++++++++++ .../targets/gitlab_project_badge/aliases | 6 + .../gitlab_project_badge/defaults/main.yml | 11 + .../gitlab_project_badge/tasks/main.yml | 214 +++++++++++++++++ 4 files changed, 447 insertions(+) create mode 100644 plugins/modules/gitlab_project_badge.py create mode 100644 tests/integration/targets/gitlab_project_badge/aliases create mode 100644 tests/integration/targets/gitlab_project_badge/defaults/main.yml create mode 100644 tests/integration/targets/gitlab_project_badge/tasks/main.yml diff --git a/plugins/modules/gitlab_project_badge.py b/plugins/modules/gitlab_project_badge.py new file mode 100644 index 0000000000..5b1a8d3f1c --- /dev/null +++ b/plugins/modules/gitlab_project_badge.py @@ -0,0 +1,216 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2022, Guillaume MARTINEZ (lunik@tiwabbit.fr) +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: gitlab_project_badge +short_description: Manage project badges on GitLab Server +version_added: 6.1.0 +description: + - This module allows to add and remove badges to/from a project. +author: Guillaume MARTINEZ (@Lunik) +requirements: + - C(owner) or C(maintainer) rights to project on the GitLab server +extends_documentation_fragment: + - community.general.auth_basic + - community.general.gitlab + - community.general.attributes + +attributes: + check_mode: + support: full + diff_mode: + support: none + +options: + project: + description: + - The name (or full path) of the GitLab project the badge is added to/removed from. + required: true + type: str + + state: + description: + - State of the badge in the project. + - On C(present), it adds a badge to a GitLab project. + - On C(absent), it removes a badge from a GitLab project. + choices: ['present', 'absent'] + default: 'present' + type: str + + link_url: + description: + - The URL associated with the badge. + required: true + type: str + + image_url: + description: + - The image URL of the badge. + - A badge is identified by this URL. + required: true + type: str +''' + +EXAMPLES = r''' +- name: Add a badge to a GitLab Project + community.general.gitlab_project_badge: + api_url: 'https://example.gitlab.com' + api_token: 'Your-Private-Token' + project: projectname + state: present + link_url: 'https://example.gitlab.com/%{project_path}' + image_url: 'https://example.gitlab.com/%{project_path}/badges/%{default_branch}/pipeline.svg' + +- name: Remove a badge from a GitLab Project + community.general.gitlab_project_badge: + api_url: 'https://example.gitlab.com' + api_token: 'Your-Private-Token' + project: projectname + state: absent + link_url: 'https://example.gitlab.com/%{project_path}' + image_url: 'https://example.gitlab.com/%{project_path}/badges/%{default_branch}/pipeline.svg' +''' + +RETURN = ''' +badge: + description: The badge information. + returned: when I(state=present) + type: dict + sample: + id: 1 + link_url: 'http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}' + image_url: 'https://shields.io/my/badge' + rendered_link_url: 'http://example.com/ci_status.svg?project=example-org/example-project&ref=master' + rendered_image_url: 'https://shields.io/my/badge' + kind: project +''' + +from ansible.module_utils.api import basic_auth_argument_spec +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.community.general.plugins.module_utils.gitlab import ( + auth_argument_spec, gitlab_authentication, find_project, ensure_gitlab_package +) + + +def present_strategy(module, gl, project, wished_badge): + changed = False + + existing_badge = None + for badge in project.badges.list(iterator=True): + if badge.image_url == wished_badge["image_url"]: + existing_badge = badge + break + + if not existing_badge: + changed = True + if module.check_mode: + return changed, {"status": "A project badge would be created."} + + badge = project.badges.create(wished_badge) + return changed, badge.attributes + + if existing_badge.link_url != wished_badge["link_url"]: + changed = True + existing_badge.link_url = wished_badge["link_url"] + + if changed: + if module.check_mode: + return changed, {"status": "Project badge attributes would be changed."} + + existing_badge.save() + + return changed, existing_badge.attributes + + +def absent_strategy(module, gl, project, wished_badge): + changed = False + + existing_badge = None + for badge in project.badges.list(iterator=True): + if badge.image_url == wished_badge["image_url"]: + existing_badge = badge + break + + if not existing_badge: + return changed, None + + changed = True + if module.check_mode: + return changed, {"status": "Project badge would be destroyed."} + + existing_badge.delete() + + return changed, None + + +state_strategy = { + "present": present_strategy, + "absent": absent_strategy +} + + +def core(module): + ensure_gitlab_package(module) + + gitlab_project = module.params['project'] + state = module.params['state'] + + gl = gitlab_authentication(module) + + project = find_project(gl, gitlab_project) + # project doesn't exist + if not project: + module.fail_json(msg="project '%s' not found." % gitlab_project) + + wished_badge = { + "link_url": module.params["link_url"], + "image_url": module.params["image_url"], + } + + changed, summary = state_strategy[state](module=module, gl=gl, project=project, wished_badge=wished_badge) + + module.exit_json(changed=changed, badge=summary) + + +def main(): + argument_spec = basic_auth_argument_spec() + argument_spec.update(auth_argument_spec()) + argument_spec.update(dict( + project=dict(type='str', required=True), + state=dict(type='str', default='present', choices=['present', 'absent']), + link_url=dict(type='str', required=True), + image_url=dict(type='str', required=True), + )) + + module = AnsibleModule( + argument_spec=argument_spec, + mutually_exclusive=[ + ['api_username', 'api_token'], + ['api_username', 'api_oauth_token'], + ['api_username', 'api_job_token'], + ['api_token', 'api_oauth_token'], + ['api_token', 'api_job_token'], + ], + required_together=[ + ['api_username', 'api_password'], + ], + required_one_of=[ + ['api_username', 'api_token', 'api_oauth_token', 'api_job_token'], + ], + supports_check_mode=True, + ) + + core(module) + + +if __name__ == '__main__': + main() diff --git a/tests/integration/targets/gitlab_project_badge/aliases b/tests/integration/targets/gitlab_project_badge/aliases new file mode 100644 index 0000000000..9f72f37111 --- /dev/null +++ b/tests/integration/targets/gitlab_project_badge/aliases @@ -0,0 +1,6 @@ +# Copyright (c) 2022, Guillaume MARTINEZ (lunik@tiwabbit.fr) +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +gitlab/ci +disabled diff --git a/tests/integration/targets/gitlab_project_badge/defaults/main.yml b/tests/integration/targets/gitlab_project_badge/defaults/main.yml new file mode 100644 index 0000000000..bf84a4751a --- /dev/null +++ b/tests/integration/targets/gitlab_project_badge/defaults/main.yml @@ -0,0 +1,11 @@ +--- +# Copyright (c) 2022, Guillaume MARTINEZ +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +gitlab_api_token: glpat-XXXXXXXXXXXXXXXXXXXX +gitlab_api_url: https://gitlab.com +gitlab_project_name: ansible_test_project +gitlab_badge_link_url: 'https://example.gitlab.com/%{project_path}' +updated_gitlab_badge_link_url: 'https://test.gitlab.com/%{project_path}' +gitlab_badge_image_url: 'https://example.gitlab.com/%{project_path}/badges/%{default_branch}/pipeline.svg' \ No newline at end of file diff --git a/tests/integration/targets/gitlab_project_badge/tasks/main.yml b/tests/integration/targets/gitlab_project_badge/tasks/main.yml new file mode 100644 index 0000000000..fa8a806efe --- /dev/null +++ b/tests/integration/targets/gitlab_project_badge/tasks/main.yml @@ -0,0 +1,214 @@ +--- +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +# Copyright (c) 2022, Guillaume MARTINEZ +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +- name: Install required libs + pip: + name: python-gitlab + state: present + +- name: Create {{ gitlab_project_name }} + gitlab_project: + api_url: "{{ gitlab_api_url }}" + validate_certs: False + api_token: "{{ gitlab_api_token }}" + name: "{{ gitlab_project_name }}" + initialize_with_readme: True + state: present + +- name: Create Badge (check) + check_mode: yes + gitlab_project_badge: + api_url: "{{ gitlab_api_url }}" + validate_certs: False + api_token: "{{ gitlab_api_token }}" + project: "{{ gitlab_project_name }}" + state: present + link_url: "{{ gitlab_badge_link_url }}" + image_url: "{{ gitlab_badge_image_url }}" + register: gitlab_badge_create_check_task + +- ansible.builtin.debug: + var: gitlab_badge_create_check_task + +- name: Check module call result + assert: + that: + - gitlab_badge_create_check_task.changed + - not gitlab_badge_create_check_task.failed + +- name: Create Badge + gitlab_project_badge: + api_url: "{{ gitlab_api_url }}" + validate_certs: False + api_token: "{{ gitlab_api_token }}" + project: "{{ gitlab_project_name }}" + state: present + link_url: "{{ gitlab_badge_link_url }}" + image_url: "{{ gitlab_badge_image_url }}" + register: gitlab_badge_create_task + +- ansible.builtin.debug: + var: gitlab_badge_create_task + +- name: Check module call result + assert: + that: + - gitlab_badge_create_task.changed + - not gitlab_badge_create_task.failed + +- name: Create Badge (confirmation) + gitlab_project_badge: + api_url: "{{ gitlab_api_url }}" + validate_certs: False + api_token: "{{ gitlab_api_token }}" + project: "{{ gitlab_project_name }}" + state: present + link_url: "{{ gitlab_badge_link_url }}" + image_url: "{{ gitlab_badge_image_url }}" + register: gitlab_badge_create_confirmation_task + +- ansible.builtin.debug: + var: gitlab_badge_create_confirmation_task + +- name: Check module call result + assert: + that: + - not gitlab_badge_create_confirmation_task.changed + - not gitlab_badge_create_confirmation_task.failed + +- name: Update Badge (check) + check_mode: yes + gitlab_project_badge: + api_url: "{{ gitlab_api_url }}" + validate_certs: False + api_token: "{{ gitlab_api_token }}" + project: "{{ gitlab_project_name }}" + state: present + link_url: "{{ updated_gitlab_badge_link_url }}" + image_url: "{{ gitlab_badge_image_url }}" + register: gitlab_badge_update_check_task + +- ansible.builtin.debug: + var: gitlab_badge_update_check_task + +- name: Check module call result + assert: + that: + - gitlab_badge_update_check_task.changed + - not gitlab_badge_update_check_task.failed + +- name: Update Badge + gitlab_project_badge: + api_url: "{{ gitlab_api_url }}" + validate_certs: False + api_token: "{{ gitlab_api_token }}" + project: "{{ gitlab_project_name }}" + state: present + link_url: "{{ updated_gitlab_badge_link_url }}" + image_url: "{{ gitlab_badge_image_url }}" + register: gitlab_badge_update_task + +- ansible.builtin.debug: + var: gitlab_badge_update_task + +- name: Check module call result + assert: + that: + - gitlab_badge_update_task.changed + - not gitlab_badge_update_task.failed + +- name: Update Badge (confirmation) + gitlab_project_badge: + api_url: "{{ gitlab_api_url }}" + validate_certs: False + api_token: "{{ gitlab_api_token }}" + project: "{{ gitlab_project_name }}" + state: present + link_url: "{{ updated_gitlab_badge_link_url }}" + image_url: "{{ gitlab_badge_image_url }}" + register: gitlab_badge_update_confirmation_task + +- ansible.builtin.debug: + var: gitlab_badge_update_confirmation_task + +- name: Check module call result + assert: + that: + - not gitlab_badge_update_confirmation_task.changed + - not gitlab_badge_update_confirmation_task.failed + +- name: Delete Badge (check) + check_mode: yes + gitlab_project_badge: + api_url: "{{ gitlab_api_url }}" + validate_certs: False + api_token: "{{ gitlab_api_token }}" + project: "{{ gitlab_project_name }}" + state: absent + link_url: "{{ updated_gitlab_badge_link_url }}" + image_url: "{{ gitlab_badge_image_url }}" + register: gitlab_badge_delete_check_task + +- ansible.builtin.debug: + var: gitlab_badge_delete_check_task + +- name: Check module call result + assert: + that: + - gitlab_badge_delete_check_task.changed + - not gitlab_badge_delete_check_task.failed + +- name: Delete Badge + gitlab_project_badge: + api_url: "{{ gitlab_api_url }}" + validate_certs: False + api_token: "{{ gitlab_api_token }}" + project: "{{ gitlab_project_name }}" + state: absent + link_url: "{{ updated_gitlab_badge_link_url }}" + image_url: "{{ gitlab_badge_image_url }}" + register: gitlab_badge_delete_task + +- ansible.builtin.debug: + var: gitlab_badge_delete_task + +- name: Check module call result + assert: + that: + - gitlab_badge_delete_task.changed + - not gitlab_badge_delete_task.failed + +- name: Delete Badge (confirmation) + gitlab_project_badge: + api_url: "{{ gitlab_api_url }}" + validate_certs: False + api_token: "{{ gitlab_api_token }}" + project: "{{ gitlab_project_name }}" + state: absent + link_url: "{{ updated_gitlab_badge_link_url }}" + image_url: "{{ gitlab_badge_image_url }}" + register: gitlab_badge_delete_confirmation_task + +- ansible.builtin.debug: + var: gitlab_badge_delete_confirmation_task + +- name: Check module call result + assert: + that: + - not gitlab_badge_delete_confirmation_task.changed + - not gitlab_badge_delete_confirmation_task.failed + +- name: Clean up {{ gitlab_project_name }} + gitlab_project: + api_url: "{{ gitlab_api_url }}" + validate_certs: False + api_token: "{{ gitlab_api_token }}" + name: "{{ gitlab_project_name }}" + state: absent From 6f4580ebd9ea303990adc8184605372aacf3aab6 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 08:03:19 +0100 Subject: [PATCH 035/134] Redfish: Expanded SimpleUpdate command to allow for users to monitor the progress of an update and perform follow-up operations (#5580) (#5590) * Redfish: Expanded SimpleUpdate command to allow for users to monitor the progress of an update and perform follow-up operations * Update changelogs/fragments/3910-redfish-add-operation-apply-time-to-simple-update.yml Co-authored-by: Felix Fontein * Update plugins/modules/redfish_command.py Co-authored-by: Felix Fontein * Update changelogs/fragments/4276-redfish-command-updates-for-full-simple-update-workflow.yml Co-authored-by: Felix Fontein * Updated based on feedback and CI results * Update plugins/modules/redfish_command.py Co-authored-by: Felix Fontein * Update plugins/modules/redfish_command.py Co-authored-by: Felix Fontein * Update plugins/modules/redfish_info.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 5c1c8152ec1c392e11fe1242dbbb24fe8ea3fdb8) Co-authored-by: Mike Raineri --- ...-operation-apply-time-to-simple-update.yml | 2 + ...pdates-for-full-simple-update-workflow.yml | 4 + plugins/module_utils/redfish_utils.py | 136 +++++++++++++++++- plugins/modules/redfish_command.py | 58 +++++++- plugins/modules/redfish_info.py | 26 +++- 5 files changed, 218 insertions(+), 8 deletions(-) create mode 100644 changelogs/fragments/3910-redfish-add-operation-apply-time-to-simple-update.yml create mode 100644 changelogs/fragments/4276-redfish-command-updates-for-full-simple-update-workflow.yml diff --git a/changelogs/fragments/3910-redfish-add-operation-apply-time-to-simple-update.yml b/changelogs/fragments/3910-redfish-add-operation-apply-time-to-simple-update.yml new file mode 100644 index 0000000000..d52438ca45 --- /dev/null +++ b/changelogs/fragments/3910-redfish-add-operation-apply-time-to-simple-update.yml @@ -0,0 +1,2 @@ +minor_changes: + - redfish_command - add ``update_apply_time`` to ``SimpleUpdate`` command (https://github.com/ansible-collections/community.general/issues/3910). diff --git a/changelogs/fragments/4276-redfish-command-updates-for-full-simple-update-workflow.yml b/changelogs/fragments/4276-redfish-command-updates-for-full-simple-update-workflow.yml new file mode 100644 index 0000000000..2f5da1467b --- /dev/null +++ b/changelogs/fragments/4276-redfish-command-updates-for-full-simple-update-workflow.yml @@ -0,0 +1,4 @@ +minor_changes: + - redfish_command - add ``update_status`` to output of ``SimpleUpdate`` command to allow a user monitor the update in progress (https://github.com/ansible-collections/community.general/issues/4276). + - redfish_info - add ``GetUpdateStatus`` command to check the progress of a previous update request (https://github.com/ansible-collections/community.general/issues/4276). + - redfish_command - add ``PerformRequestedOperations`` command to perform any operations necessary to continue the update flow (https://github.com/ansible-collections/community.general/issues/4276). diff --git a/plugins/module_utils/redfish_utils.py b/plugins/module_utils/redfish_utils.py index 3bd3d73676..a86baa1066 100644 --- a/plugins/module_utils/redfish_utils.py +++ b/plugins/module_utils/redfish_utils.py @@ -143,7 +143,7 @@ class RedfishUtils(object): except Exception as e: return {'ret': False, 'msg': "Failed GET request to '%s': '%s'" % (uri, to_text(e))} - return {'ret': True, 'data': data, 'headers': headers} + return {'ret': True, 'data': data, 'headers': headers, 'resp': resp} def post_request(self, uri, pyld): req_headers = dict(POST_HEADERS) @@ -155,6 +155,11 @@ class RedfishUtils(object): force_basic_auth=basic_auth, validate_certs=False, follow_redirects='all', use_proxy=True, timeout=self.timeout) + try: + data = json.loads(to_native(resp.read())) + except Exception as e: + # No response data; this is okay in many cases + data = None headers = dict((k.lower(), v) for (k, v) in resp.info().items()) except HTTPError as e: msg = self._get_extended_message(e) @@ -169,7 +174,7 @@ class RedfishUtils(object): except Exception as e: return {'ret': False, 'msg': "Failed POST request to '%s': '%s'" % (uri, to_text(e))} - return {'ret': True, 'headers': headers, 'resp': resp} + return {'ret': True, 'data': data, 'headers': headers, 'resp': resp} def patch_request(self, uri, pyld, check_pyld=False): req_headers = dict(PATCH_HEADERS) @@ -1384,11 +1389,82 @@ class RedfishUtils(object): else: return self._software_inventory(self.software_uri) + def _operation_results(self, response, data, handle=None): + """ + Builds the results for an operation from task, job, or action response. + + :param response: HTTP response object + :param data: HTTP response data + :param handle: The task or job handle that was last used + :return: dict containing operation results + """ + + operation_results = {'status': None, 'messages': [], 'handle': None, 'ret': True, + 'resets_requested': []} + + if response.status == 204: + # No content; successful, but nothing to return + # Use the Redfish "Completed" enum from TaskState for the operation status + operation_results['status'] = 'Completed' + else: + # Parse the response body for details + + # Determine the next handle, if any + operation_results['handle'] = handle + if response.status == 202: + # Task generated; get the task monitor URI + operation_results['handle'] = response.getheader('Location', handle) + + # Pull out the status and messages based on the body format + if data is not None: + response_type = data.get('@odata.type', '') + if response_type.startswith('#Task.') or response_type.startswith('#Job.'): + # Task and Job have similar enough structures to treat the same + operation_results['status'] = data.get('TaskState', data.get('JobState')) + operation_results['messages'] = data.get('Messages', []) + else: + # Error response body, which is a bit of a misnomer since it's used in successful action responses + operation_results['status'] = 'Completed' + if response.status >= 400: + operation_results['status'] = 'Exception' + operation_results['messages'] = data.get('error', {}).get('@Message.ExtendedInfo', []) + else: + # No response body (or malformed); build based on status code + operation_results['status'] = 'Completed' + if response.status == 202: + operation_results['status'] = 'New' + elif response.status >= 400: + operation_results['status'] = 'Exception' + + # Clear out the handle if the operation is complete + if operation_results['status'] in ['Completed', 'Cancelled', 'Exception', 'Killed']: + operation_results['handle'] = None + + # Scan the messages to see if next steps are needed + for message in operation_results['messages']: + message_id = message['MessageId'] + + if message_id.startswith('Update.1.') and message_id.endswith('.OperationTransitionedToJob'): + # Operation rerouted to a job; update the status and handle + operation_results['status'] = 'New' + operation_results['handle'] = message['MessageArgs'][0] + operation_results['resets_requested'] = [] + # No need to process other messages in this case + break + + if message_id.startswith('Base.1.') and message_id.endswith('.ResetRequired'): + # A reset to some device is needed to continue the update + reset = {'uri': message['MessageArgs'][0], 'type': message['MessageArgs'][1]} + operation_results['resets_requested'].append(reset) + + return operation_results + def simple_update(self, update_opts): image_uri = update_opts.get('update_image_uri') protocol = update_opts.get('update_protocol') targets = update_opts.get('update_targets') creds = update_opts.get('update_creds') + apply_time = update_opts.get('update_apply_time') if not image_uri: return {'ret': False, 'msg': @@ -1439,11 +1515,65 @@ class RedfishUtils(object): payload["Username"] = creds.get('username') if creds.get('password'): payload["Password"] = creds.get('password') + if apply_time: + payload["@Redfish.OperationApplyTime"] = apply_time response = self.post_request(self.root_uri + update_uri, payload) if response['ret'] is False: return response return {'ret': True, 'changed': True, - 'msg': "SimpleUpdate requested"} + 'msg': "SimpleUpdate requested", + 'update_status': self._operation_results(response['resp'], response['data'])} + + def get_update_status(self, update_handle): + """ + Gets the status of an update operation. + + :param handle: The task or job handle tracking the update + :return: dict containing the response of the update status + """ + + if not update_handle: + return {'ret': False, 'msg': 'Must provide a handle tracking the update.'} + + # Get the task or job tracking the update + response = self.get_request(self.root_uri + update_handle) + if response['ret'] is False: + return response + + # Inspect the response to build the update status + return self._operation_results(response['resp'], response['data'], update_handle) + + def perform_requested_update_operations(self, update_handle): + """ + Performs requested operations to allow the update to continue. + + :param handle: The task or job handle tracking the update + :return: dict containing the result of the operations + """ + + # Get the current update status + update_status = self.get_update_status(update_handle) + if update_status['ret'] is False: + return update_status + + changed = False + + # Perform any requested updates + for reset in update_status['resets_requested']: + resp = self.post_request(self.root_uri + reset['uri'], {'ResetType': reset['type']}) + if resp['ret'] is False: + # Override the 'changed' indicator since other resets may have + # been successful + resp['changed'] = changed + return resp + changed = True + + msg = 'No operations required for the update' + if changed: + # Will need to consider finetuning this message if the scope of the + # requested operations grow over time + msg = 'One or more components reset to continue the update' + return {'ret': True, 'changed': changed, 'msg': msg} def get_bios_attributes(self, systems_uri): result = {} diff --git a/plugins/modules/redfish_command.py b/plugins/modules/redfish_command.py index 43443cf38e..9d5640996a 100644 --- a/plugins/modules/redfish_command.py +++ b/plugins/modules/redfish_command.py @@ -161,6 +161,24 @@ options: description: - Password for retrieving the update image. type: str + update_apply_time: + required: false + description: + - Time when to apply the update. + type: str + choices: + - Immediate + - OnReset + - AtMaintenanceWindowStart + - InMaintenanceWindowOnReset + - OnStartUpdateRequest + version_added: '6.1.0' + update_handle: + required: false + description: + - Handle to check the status of an update in progress. + type: str + version_added: '6.1.0' virtual_media: required: false description: @@ -508,6 +526,15 @@ EXAMPLES = ''' username: operator password: supersecretpwd + - name: Perform requested operations to continue the update + community.general.redfish_command: + category: Update + command: PerformRequestedOperations + baseuri: "{{ baseuri }}" + username: "{{ username }}" + password: "{{ password }}" + update_handle: /redfish/v1/TaskService/TaskMonitors/735 + - name: Insert Virtual Media community.general.redfish_command: category: Systems @@ -610,6 +637,20 @@ msg: returned: always type: str sample: "Action was successful" +return_values: + description: Dictionary containing command-specific response data from the action. + returned: on success + type: dict + version_added: 6.1.0 + sample: { + "update_status": { + "handle": "/redfish/v1/TaskService/TaskMonitors/735", + "messages": [], + "resets_requested": [], + "ret": true, + "status": "New" + } + } ''' from ansible.module_utils.basic import AnsibleModule @@ -630,12 +671,13 @@ CATEGORY_COMMANDS_ALL = { "Manager": ["GracefulRestart", "ClearLogs", "VirtualMediaInsert", "VirtualMediaEject", "PowerOn", "PowerForceOff", "PowerForceRestart", "PowerGracefulRestart", "PowerGracefulShutdown", "PowerReboot"], - "Update": ["SimpleUpdate"] + "Update": ["SimpleUpdate", "PerformRequestedOperations"], } def main(): result = {} + return_values = {} module = AnsibleModule( argument_spec=dict( category=dict(required=True), @@ -667,6 +709,9 @@ def main(): password=dict(no_log=True) ) ), + update_apply_time=dict(choices=['Immediate', 'OnReset', 'AtMaintenanceWindowStart', + 'InMaintenanceWindowOnReset', 'OnStartUpdateRequest']), + update_handle=dict(), virtual_media=dict( type='dict', options=dict( @@ -721,7 +766,9 @@ def main(): 'update_image_uri': module.params['update_image_uri'], 'update_protocol': module.params['update_protocol'], 'update_targets': module.params['update_targets'], - 'update_creds': module.params['update_creds'] + 'update_creds': module.params['update_creds'], + 'update_apply_time': module.params['update_apply_time'], + 'update_handle': module.params['update_handle'], } # Boot override options @@ -859,6 +906,10 @@ def main(): for command in command_list: if command == "SimpleUpdate": result = rf_utils.simple_update(update_opts) + if 'update_status' in result: + return_values['update_status'] = result['update_status'] + elif command == "PerformRequestedOperations": + result = rf_utils.perform_requested_update_operations(update_opts['update_handle']) # Return data back or fail with proper message if result['ret'] is True: @@ -866,7 +917,8 @@ def main(): changed = result.get('changed', True) session = result.get('session', dict()) module.exit_json(changed=changed, session=session, - msg='Action was successful') + msg='Action was successful', + return_values=return_values) else: module.fail_json(msg=to_native(result['msg'])) diff --git a/plugins/modules/redfish_info.py b/plugins/modules/redfish_info.py index fd81695368..e6df4813ad 100644 --- a/plugins/modules/redfish_info.py +++ b/plugins/modules/redfish_info.py @@ -58,6 +58,12 @@ options: - Timeout in seconds for HTTP requests to OOB controller. default: 10 type: int + update_handle: + required: false + description: + - Handle to check the status of an update in progress. + type: str + version_added: '6.1.0' author: "Jose Delarosa (@jose-delarosa)" ''' @@ -247,6 +253,15 @@ EXAMPLES = ''' username: "{{ username }}" password: "{{ password }}" + - name: Get the status of an update operation + community.general.redfish_info: + category: Update + command: GetUpdateStatus + baseuri: "{{ baseuri }}" + username: "{{ username }}" + password: "{{ password }}" + update_handle: /redfish/v1/TaskService/TaskMonitors/735 + - name: Get Manager Services community.general.redfish_info: category: Manager @@ -324,7 +339,8 @@ CATEGORY_COMMANDS_ALL = { "GetChassisThermals", "GetChassisInventory", "GetHealthReport"], "Accounts": ["ListUsers"], "Sessions": ["GetSessions"], - "Update": ["GetFirmwareInventory", "GetFirmwareUpdateCapabilities", "GetSoftwareInventory"], + "Update": ["GetFirmwareInventory", "GetFirmwareUpdateCapabilities", "GetSoftwareInventory", + "GetUpdateStatus"], "Manager": ["GetManagerNicInventory", "GetVirtualMedia", "GetLogs", "GetNetworkProtocols", "GetHealthReport", "GetHostInterfaces", "GetManagerInventory"], } @@ -350,7 +366,8 @@ def main(): username=dict(), password=dict(no_log=True), auth_token=dict(no_log=True), - timeout=dict(type='int', default=10) + timeout=dict(type='int', default=10), + update_handle=dict(), ), required_together=[ ('username', 'password'), @@ -372,6 +389,9 @@ def main(): # timeout timeout = module.params['timeout'] + # update handle + update_handle = module.params['update_handle'] + # Build root URI root_uri = "https://" + module.params['baseuri'] rf_utils = RedfishUtils(creds, root_uri, timeout, module) @@ -482,6 +502,8 @@ def main(): result["software"] = rf_utils.get_software_inventory() elif command == "GetFirmwareUpdateCapabilities": result["firmware_update_capabilities"] = rf_utils.get_firmware_update_capabilities() + elif command == "GetUpdateStatus": + result["update_status"] = rf_utils.get_update_status(update_handle) elif category == "Sessions": # execute only if we find SessionService resources From 3a456a645df1132b904883d10f0c8354779ba456 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 18:58:37 +0100 Subject: [PATCH 036/134] udm_user: sanity (#5559) (#5593) * fix parameter email * fix parameter groups * fix parameters home_telephone_number, mail_alternative_address, mobile_telephone_number, pager_telephonenumber * fix parameter phone * fix parameter samba_privileges * fix parameter samba_user_workstations * fix parameter secretary * fix parameter serviceprovider * remove lines from ignore files * add changelog fragment (cherry picked from commit 79929830c401b5f127d95be71e4b81edf0f61986) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- changelogs/fragments/5559-udm-user-sanity.yml | 2 ++ plugins/modules/udm_user.py | 32 ++++++++++++++++--- tests/sanity/ignore-2.11.txt | 1 - tests/sanity/ignore-2.12.txt | 1 - tests/sanity/ignore-2.13.txt | 1 - tests/sanity/ignore-2.14.txt | 1 - tests/sanity/ignore-2.15.txt | 1 - 7 files changed, 29 insertions(+), 10 deletions(-) create mode 100644 changelogs/fragments/5559-udm-user-sanity.yml diff --git a/changelogs/fragments/5559-udm-user-sanity.yml b/changelogs/fragments/5559-udm-user-sanity.yml new file mode 100644 index 0000000000..1501591f81 --- /dev/null +++ b/changelogs/fragments/5559-udm-user-sanity.yml @@ -0,0 +1,2 @@ +minor_changes: + - udm_user - add ``elements`` attribute when missing in ``list`` parameters (https://github.com/ansible-collections/community.general/pull/5559). diff --git a/plugins/modules/udm_user.py b/plugins/modules/udm_user.py index d5b26fbb28..96bbdfbc10 100644 --- a/plugins/modules/udm_user.py +++ b/plugins/modules/udm_user.py @@ -78,6 +78,7 @@ options: description: - A list of e-mail addresses. type: list + elements: str employee_number: description: - Employee number @@ -99,6 +100,7 @@ options: LDAP filter for each group as $GROUP: C((&(objectClass=posixGroup)(cn=$GROUP)))." type: list + elements: str home_share: description: - "Home NFS share. Must be a LDAP DN, e.g. @@ -116,6 +118,7 @@ options: - List of private telephone numbers. aliases: [ homeTelephoneNumber ] type: list + elements: str homedrive: description: - Windows home drive, e.g. C("H:"). @@ -126,6 +129,7 @@ options: - List of alternative e-mail addresses. aliases: [ mailAlternativeAddress ] type: list + elements: str mail_home_server: description: - FQDN of mail server @@ -142,6 +146,7 @@ options: - Mobile phone number aliases: [ mobileTelephoneNumber ] type: list + elements: str organisation: description: - Organisation @@ -165,10 +170,12 @@ options: - List of pager telephone numbers. aliases: [ pagerTelephonenumber ] type: list + elements: str phone: description: - List of telephone numbers. type: list + elements: str default: [] postcode: description: @@ -201,12 +208,14 @@ options: join." aliases: [ sambaPrivileges ] type: list + elements: str default: [] samba_user_workstations: description: - Allow the authentication only on this Microsoft Windows host. aliases: [ sambaUserWorkstations ] type: list + elements: str default: [] sambahome: description: @@ -221,11 +230,13 @@ options: description: - A list of superiors as LDAP DNs. type: list + elements: str serviceprovider: default: [''] description: - Enable user for the following service providers. type: list + elements: str shell: default: '/bin/bash' description: @@ -333,7 +344,8 @@ def main(): display_name=dict(type='str', aliases=['displayName']), email=dict(default=[''], - type='list'), + type='list', + elements='str'), employee_number=dict(type='str', aliases=['employeeNumber']), employee_type=dict(type='str', @@ -341,18 +353,21 @@ def main(): firstname=dict(type='str'), gecos=dict(type='str'), groups=dict(default=[], - type='list'), + type='list', + elements='str'), home_share=dict(type='str', aliases=['homeShare']), home_share_path=dict(type='str', aliases=['homeSharePath']), home_telephone_number=dict(default=[], type='list', + elements='str', aliases=['homeTelephoneNumber']), homedrive=dict(type='str'), lastname=dict(type='str'), mail_alternative_address=dict(default=[], type='list', + elements='str', aliases=['mailAlternativeAddress']), mail_home_server=dict(type='str', aliases=['mailHomeServer']), @@ -360,6 +375,7 @@ def main(): aliases=['mailPrimaryAddress']), mobile_telephone_number=dict(default=[], type='list', + elements='str', aliases=['mobileTelephoneNumber']), organisation=dict(type='str', aliases=['organization']), @@ -371,11 +387,13 @@ def main(): aliases=['override_pw_length']), pager_telephonenumber=dict(default=[], type='list', + elements='str', aliases=['pagerTelephonenumber']), password=dict(type='str', no_log=True), phone=dict(default=[], - type='list'), + type='list', + elements='str'), postcode=dict(type='str'), primary_group=dict(type='str', aliases=['primaryGroup']), @@ -387,16 +405,20 @@ def main(): aliases=['roomNumber']), samba_privileges=dict(default=[], type='list', + elements='str', aliases=['sambaPrivileges']), samba_user_workstations=dict(default=[], type='list', + elements='str', aliases=['sambaUserWorkstations']), sambahome=dict(type='str'), scriptpath=dict(type='str'), secretary=dict(default=[], - type='list'), + type='list', + elements='str'), serviceprovider=dict(default=[''], - type='list'), + type='list', + elements='str'), shell=dict(default='/bin/bash', type='str'), street=dict(type='str'), diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 86d7f6a9e2..1b89dae547 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -26,7 +26,6 @@ plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements -plugins/modules/udm_user.py validate-modules:parameter-list-no-elements plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path tests/integration/targets/django_manage/files/base_test/simple_project/p1/manage.py compile-2.6 # django generated code diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index 45772005a3..29e8927103 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -21,6 +21,5 @@ plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements -plugins/modules/udm_user.py validate-modules:parameter-list-no-elements plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index 45772005a3..29e8927103 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -21,6 +21,5 @@ plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements -plugins/modules/udm_user.py validate-modules:parameter-list-no-elements plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 49c2eb1bb2..9c667f3d7b 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -23,6 +23,5 @@ plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt' -plugins/modules/udm_user.py validate-modules:parameter-list-no-elements plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index 49c2eb1bb2..9c667f3d7b 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -23,6 +23,5 @@ plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt' -plugins/modules/udm_user.py validate-modules:parameter-list-no-elements plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path From 4b7554445b2a7d13e9f2e675959755bdb57ad69c Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 20:34:31 +0100 Subject: [PATCH 037/134] Temporarily disable copr tests. (#5594) (#5598) (cherry picked from commit 11e1423f60e6cdad13de0da1707e57688ebe82e8) Co-authored-by: Felix Fontein --- tests/integration/targets/copr/aliases | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/integration/targets/copr/aliases b/tests/integration/targets/copr/aliases index ed3c1af00d..c9fc0e0a2f 100644 --- a/tests/integration/targets/copr/aliases +++ b/tests/integration/targets/copr/aliases @@ -7,3 +7,5 @@ needs/root skip/macos skip/osx skip/freebsd + +disabled # FIXME tests are currently failing From 352e91a389c32b1a311d9101d6c8d3b8024d9b58 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 26 Nov 2022 18:49:40 +0100 Subject: [PATCH 038/134] redhat_subscription: improve wording wrt Satellite (#5581) (#5608) Do not mention an explicit version of Satellite for an environment to use; future versions of Satellite will support that, and older versions are long EOL. Also mention Katello next to Red Hat Satellite. (cherry picked from commit 911769d2f3478e67daad411a1b87f1803bbbe143) Co-authored-by: Pino Toscano --- plugins/modules/redhat_subscription.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/plugins/modules/redhat_subscription.py b/plugins/modules/redhat_subscription.py index 997d1e5153..aaf39d6d3f 100644 --- a/plugins/modules/redhat_subscription.py +++ b/plugins/modules/redhat_subscription.py @@ -34,15 +34,15 @@ options: type: str username: description: - - access.redhat.com or Sat6 username + - access.redhat.com or Red Hat Satellite or Katello username type: str password: description: - - access.redhat.com or Sat6 password + - access.redhat.com or Red Hat Satellite or Katello password type: str server_hostname: description: - - Specify an alternative Red Hat Subscription Management or Sat6 server + - Specify an alternative Red Hat Subscription Management or Red Hat Satellite or Katello server type: str server_insecure: description: @@ -50,12 +50,12 @@ options: type: str server_prefix: description: - - Specify the prefix when registering to the Red Hat Subscription Management or Sat6 server. + - Specify the prefix when registering to the Red Hat Subscription Management or Red Hat Satellite or Katello server. type: str version_added: 3.3.0 server_port: description: - - Specify the port when registering to the Red Hat Subscription Management or Sat6 server. + - Specify the port when registering to the Red Hat Subscription Management or Red Hat Satellite or Katello server. type: str version_added: 3.3.0 rhsm_baseurl: @@ -98,7 +98,7 @@ options: type: str environment: description: - - Register with a specific environment in the destination org. Used with Red Hat Satellite 6.x or Katello + - Register with a specific environment in the destination org. Used with Red Hat Satellite or Katello type: str pool: description: @@ -229,7 +229,7 @@ EXAMPLES = ''' org_id: 222333444 pool: '^Red Hat Enterprise Server$' -- name: Register as user credentials into given environment (against Red Hat Satellite 6.x), and auto-subscribe. +- name: Register as user credentials into given environment (against Red Hat Satellite or Katello), and auto-subscribe. community.general.redhat_subscription: state: present username: joe_user @@ -397,7 +397,9 @@ class Rhsm(RegistrationBase): rhsm_baseurl, server_insecure, server_hostname, server_proxy_hostname, server_proxy_port, server_proxy_user, server_proxy_password, release): ''' - Register the current system to the provided RHSM or Sat6 server + Register the current system to the provided RHSM or Red Hat Satellite + or Katello server + Raises: * Exception - if error occurs while running command ''' From d930c8d87759c663552c7929edfac2da07572cbe Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 26 Nov 2022 18:58:09 +0100 Subject: [PATCH 039/134] udm_share: fix sanity checks (#5557) (#5609) * udm_share: fix sanity checks * add changelog fragment (cherry picked from commit a3b748a15ed9250d67d812c8929fd1ec3cf7ae3b) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- changelogs/fragments/5557-udm-share-sanity.yml | 2 ++ plugins/modules/udm_share.py | 10 ++++++++++ tests/sanity/ignore-2.11.txt | 1 - tests/sanity/ignore-2.12.txt | 1 - tests/sanity/ignore-2.13.txt | 1 - tests/sanity/ignore-2.14.txt | 1 - tests/sanity/ignore-2.15.txt | 1 - 7 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/5557-udm-share-sanity.yml diff --git a/changelogs/fragments/5557-udm-share-sanity.yml b/changelogs/fragments/5557-udm-share-sanity.yml new file mode 100644 index 0000000000..12bd3d026e --- /dev/null +++ b/changelogs/fragments/5557-udm-share-sanity.yml @@ -0,0 +1,2 @@ +minor_changes: + - udm_share - added ``elements`` attribute to ``list`` type parameters (https://github.com/ansible-collections/community.general/pull/5557). diff --git a/plugins/modules/udm_share.py b/plugins/modules/udm_share.py index b1d7e13287..8120df1b00 100644 --- a/plugins/modules/udm_share.py +++ b/plugins/modules/udm_share.py @@ -125,6 +125,7 @@ options: description: - Option name in smb.conf and its value. type: list + elements: dict aliases: [ samba_custom_settings ] sambaDirectoryMode: default: '0755' @@ -200,12 +201,14 @@ options: description: - Allowed host/network. type: list + elements: str aliases: [ samba_hosts_allow ] sambaHostsDeny: default: [] description: - Denied host/network. type: list + elements: str aliases: [ samba_hosts_deny ] sambaInheritAcls: default: true @@ -314,11 +317,13 @@ options: description: - Only allow access for this host, IP address or network. type: list + elements: str nfsCustomSettings: default: [] description: - Option name in exports file. type: list + elements: str aliases: [ nfs_custom_settings ] ''' @@ -382,6 +387,7 @@ def main(): aliases=['samba_csc_policy'], default='manual'), sambaCustomSettings=dict(type='list', + elements='dict', aliases=['samba_custom_settings'], default=[]), sambaDirectoryMode=dict(type='str', @@ -418,9 +424,11 @@ def main(): aliases=['samba_hide_unreadable'], default=False), sambaHostsAllow=dict(type='list', + elements='str', aliases=['samba_hosts_allow'], default=[]), sambaHostsDeny=dict(type='list', + elements='str', aliases=['samba_hosts_deny'], default=[]), sambaInheritAcls=dict(type='bool', @@ -474,8 +482,10 @@ def main(): aliases=['samba_writeable'], default=True), nfs_hosts=dict(type='list', + elements='str', default=[]), nfsCustomSettings=dict(type='list', + elements='str', aliases=['nfs_custom_settings'], default=[]), state=dict(default='present', diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 1b89dae547..d12199993a 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -25,7 +25,6 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path -plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path tests/integration/targets/django_manage/files/base_test/simple_project/p1/manage.py compile-2.6 # django generated code diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index 29e8927103..d5dd72b549 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -20,6 +20,5 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path -plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index 29e8927103..d5dd72b549 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -20,6 +20,5 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path -plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 9c667f3d7b..b54479472b 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -21,7 +21,6 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path -plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index 9c667f3d7b..b54479472b 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -21,7 +21,6 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path -plugins/modules/udm_share.py validate-modules:parameter-list-no-elements plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path From a0d4ee4fc1576a04d249ecb60a9b782000839def Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 28 Nov 2022 21:08:22 +0100 Subject: [PATCH 040/134] contributing: Modify link anchor to changelog fragments docs (#5618) (#5621) The hmtl anchor linked now points to the parent section ("Creating changelog fragments"). Previously new contributors were linked to the subsection "Creating a changelog fragment", just to be immediately be guided by the second paragraph to jump to the previous section. Signed-off-by: Fabian P. Schmidt Signed-off-by: Fabian P. Schmidt (cherry picked from commit 3f80aa3c636f0ccd0f84dfca1954048699737f52) Co-authored-by: Fabian P. Schmidt --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4236778dc6..358daa5e91 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,7 +31,7 @@ Also, consider taking up a valuable, reviewed, but abandoned pull request which * Try committing your changes with an informative but short commit message. * Do not squash your commits and force-push to your branch if not needed. Reviews of your pull request are much easier with individual commits to comprehend the pull request history. All commits of your pull request branch will be squashed into one commit by GitHub upon merge. * Do not add merge commits to your PR. The bot will complain and you will have to rebase ([instructions for rebasing](https://docs.ansible.com/ansible/latest/dev_guide/developing_rebasing.html)) to remove them before your PR can be merged. To avoid that git automatically does merges during pulls, you can configure it to do rebases instead by running `git config pull.rebase true` inside the repository checkout. -* Make sure your PR includes a [changelog fragment](https://docs.ansible.com/ansible/devel/community/development_process.html#changelogs-how-to). (You must not include a fragment for new modules or new plugins, except for test and filter plugins. Also you shouldn't include one for docs-only changes. If you're not sure, simply don't include one, we'll tell you whether one is needed or not :) ) +* Make sure your PR includes a [changelog fragment](https://docs.ansible.com/ansible/devel/community/development_process.html#creating-changelog-fragments). (You must not include a fragment for new modules or new plugins, except for test and filter plugins. Also you shouldn't include one for docs-only changes. If you're not sure, simply don't include one, we'll tell you whether one is needed or not :) ) * Avoid reformatting unrelated parts of the codebase in your PR. These types of changes will likely be requested for reversion, create additional work for reviewers, and may cause approval to be delayed. You can also read [our Quick-start development guide](https://github.com/ansible/community-docs/blob/main/create_pr_quick_start_guide.rst). From ced1baad63af9a9311d54909a7ec326dbff565a1 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 29 Nov 2022 07:40:11 +0100 Subject: [PATCH 041/134] java_certs : Not enough info on error (#5550) (#5623) * java_certs : Not enough info on error Just bumped into an issue when the message was "Internal module failure, cannot extract public certificate from pkcs12, error: " Seems that the issue #2560 doesn't cover all cases. To make debugging easier, I propose to add error output on json return instead of only expose standard output. * java_certs - add missing fragment message * Word-smithing. Co-authored-by: Felix Fontein (cherry picked from commit 1ca775248f6e8df679ec57e710582f2b7131cc66) Co-authored-by: Naewis --- .../fragments/5550-java_certs-not-enough-info-on-error.yml | 2 ++ plugins/modules/java_cert.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5550-java_certs-not-enough-info-on-error.yml diff --git a/changelogs/fragments/5550-java_certs-not-enough-info-on-error.yml b/changelogs/fragments/5550-java_certs-not-enough-info-on-error.yml new file mode 100644 index 0000000000..c2b2be0418 --- /dev/null +++ b/changelogs/fragments/5550-java_certs-not-enough-info-on-error.yml @@ -0,0 +1,2 @@ +minor_changes: + - java_certs - add more detailed error output when extracting certificate from PKCS12 fails (https://github.com/ansible-collections/community.general/pull/5550). diff --git a/plugins/modules/java_cert.py b/plugins/modules/java_cert.py index 1d1327ed71..461f365a72 100644 --- a/plugins/modules/java_cert.py +++ b/plugins/modules/java_cert.py @@ -281,7 +281,8 @@ def _export_public_cert_from_pkcs12(module, executable, pkcs_file, alias, passwo (export_rc, export_stdout, export_err) = module.run_command(export_cmd, data=password, check_rc=False) if export_rc != 0: - module.fail_json(msg="Internal module failure, cannot extract public certificate from pkcs12, error: %s" % export_stdout, + module.fail_json(msg="Internal module failure, cannot extract public certificate from PKCS12, message: %s" % export_stdout, + stderr=export_err, rc=export_rc) with open(dest, 'w') as f: From ee7fdf5f8c7507243cb43349a55cb0b46f44dd71 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 29 Nov 2022 08:01:09 +0100 Subject: [PATCH 042/134] unixy Callback: Use Ansible's config manager (#5601) (#5625) * unixy Callback: Use Ansible's config manager In ansible-core 2.14 deprecated support was removed[1] for accessing options of the DefaultCallback via class attributes. Use the "new" config system instead. [1]: https://github.com/ansible/ansible/commit/dbdbfe845adac977a78c6484da1c5923754d83a2 Fixes #5600. Signed-off-by: Fabian P. Schmidt * Update changelog fragment. Signed-off-by: Fabian P. Schmidt Co-authored-by: Felix Fontein (cherry picked from commit 53da86c1a5efc8c8e397c73776fae8bd993854d7) Co-authored-by: Fabian P. Schmidt --- .../5601-unixy-callback-use-config-manager.yml | 2 ++ plugins/callback/unixy.py | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/5601-unixy-callback-use-config-manager.yml diff --git a/changelogs/fragments/5601-unixy-callback-use-config-manager.yml b/changelogs/fragments/5601-unixy-callback-use-config-manager.yml new file mode 100644 index 0000000000..f3d0362f8f --- /dev/null +++ b/changelogs/fragments/5601-unixy-callback-use-config-manager.yml @@ -0,0 +1,2 @@ +bugfixes: + - unixy callback plugin - fix plugin to work with ansible-core 2.14 by using Ansible's configuration manager for handling options (https://github.com/ansible-collections/community.general/issues/5600). diff --git a/plugins/callback/unixy.py b/plugins/callback/unixy.py index fa26be8238..55f46afd32 100644 --- a/plugins/callback/unixy.py +++ b/plugins/callback/unixy.py @@ -63,7 +63,7 @@ class CallbackModule(CallbackModule_default): def _preprocess_result(self, result): self.delegated_vars = result._result.get('_ansible_delegated_vars', None) - self._handle_exception(result._result, use_stderr=self.display_failed_stderr) + self._handle_exception(result._result, use_stderr=self.get_option('display_failed_stderr')) self._handle_warnings(result._result) def _process_result_output(self, result, msg): @@ -109,7 +109,7 @@ class CallbackModule(CallbackModule_default): self._display.display(msg) def v2_runner_on_skipped(self, result, ignore_errors=False): - if self.display_skipped_hosts: + if self.get_option('display_skipped_hosts'): self._preprocess_result(result) display_color = C.COLOR_SKIP msg = "skipped" @@ -128,7 +128,7 @@ class CallbackModule(CallbackModule_default): msg += " | item: %s" % (item_value,) task_result = self._process_result_output(result, msg) - self._display.display(" " + task_result, display_color, stderr=self.display_failed_stderr) + self._display.display(" " + task_result, display_color, stderr=self.get_option('display_failed_stderr')) def v2_runner_on_ok(self, result, msg="ok", display_color=C.COLOR_OK): self._preprocess_result(result) @@ -142,7 +142,7 @@ class CallbackModule(CallbackModule_default): display_color = C.COLOR_CHANGED task_result = self._process_result_output(result, msg) self._display.display(" " + task_result, display_color) - elif self.display_ok_hosts: + elif self.get('display_ok_hosts'): task_result = self._process_result_output(result, msg) self._display.display(" " + task_result, display_color) @@ -162,7 +162,7 @@ class CallbackModule(CallbackModule_default): display_color = C.COLOR_UNREACHABLE task_result = self._process_result_output(result, msg) - self._display.display(" " + task_result, display_color, stderr=self.display_failed_stderr) + self._display.display(" " + task_result, display_color, stderr=self.get_option('display_failed_stderr')) def v2_on_file_diff(self, result): if result._task.loop and 'results' in result._result: @@ -205,7 +205,7 @@ class CallbackModule(CallbackModule_default): colorize(u'ignored', t['ignored'], None)), log_only=True ) - if stats.custom and self.show_custom_stats: + if stats.custom and self.get_option('show_custom_stats'): self._display.banner("CUSTOM STATS: ") # per host # TODO: come up with 'pretty format' From 8079aea1ee4b4dedf4e051ae65df80afd4879567 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 29 Nov 2022 11:05:23 +0100 Subject: [PATCH 043/134] Announce removal of sap modules. (#5614) --- changelogs/fragments/sap-removal.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelogs/fragments/sap-removal.yml diff --git a/changelogs/fragments/sap-removal.yml b/changelogs/fragments/sap-removal.yml new file mode 100644 index 0000000000..603e0fb856 --- /dev/null +++ b/changelogs/fragments/sap-removal.yml @@ -0,0 +1,5 @@ +deprecated_features: + - "The ``sap`` modules ``sapcar_extract``, ``sap_task_list_execute``, and ``hana_query``, will be removed + from this collection in community.general 7.0.0 and replaced with redirects to ``community.sap_libs``. + If you want to continue using these modules, make sure to also install ``community.sap_libs`` (it is + part of the Ansible package) (https://github.com/ansible-collections/community.general/pull/5614)." From efedd0d6e2d3cd40fba92b3bee437166a6fb9029 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 29 Nov 2022 13:20:30 +0100 Subject: [PATCH 044/134] redhat_subscription: drop unneeded args to Rhsm.register() (#5583) (#5626) Stop passing all the "rhsm_", and "server_" module arguments to "Rhsm.register()", and thus as arguments for "subscription-manager register": - right before calling "Rhsm.register()", "Rhsm.configure()" is called to configure subscription-manager with all the "rhsm_", and "server_" arguments; hence, they are already configured - the passed argument to "--serverurl" is partially wrong: "Rhsm.register()" passes only the hostname, whereas the other bits (port and prefix) are supported too; this "works" because port and prefix were already configured previously, and the lax parsing that subscription-manager does allows for missing bits - the parsing done by subscription-manager for "--baseurl" strips out the URL scheme and always uses https: this means that specifying "rhsm_baseurl: http://server" as module parameter will be taken as "https://server" by subscription-manager; since "rhsm_baseurl" is already configured by "Rhsm.configure()", this issue is gone (cherry picked from commit 101c957631445dc3902eb71f74b0f52708cc8050) Co-authored-by: Pino Toscano --- ...hat_subscription-subscribe-parameters.yaml | 3 +++ plugins/modules/redhat_subscription.py | 24 ++----------------- .../modules/test_redhat_subscription.py | 5 ---- 3 files changed, 5 insertions(+), 27 deletions(-) create mode 100644 changelogs/fragments/5583-redhat_subscription-subscribe-parameters.yaml diff --git a/changelogs/fragments/5583-redhat_subscription-subscribe-parameters.yaml b/changelogs/fragments/5583-redhat_subscription-subscribe-parameters.yaml new file mode 100644 index 0000000000..bef3676c3b --- /dev/null +++ b/changelogs/fragments/5583-redhat_subscription-subscribe-parameters.yaml @@ -0,0 +1,3 @@ +bugfixes: + - redhat_subscription - do not pass arguments to ``subscription-manager register`` for things already configured; now a specified ``rhsm_baseurl`` is properly set for subscription-manager + (https://github.com/ansible-collections/community.general/pull/5583). diff --git a/plugins/modules/redhat_subscription.py b/plugins/modules/redhat_subscription.py index aaf39d6d3f..bb21578fa5 100644 --- a/plugins/modules/redhat_subscription.py +++ b/plugins/modules/redhat_subscription.py @@ -394,8 +394,7 @@ class Rhsm(RegistrationBase): def register(self, username, password, auto_attach, activationkey, org_id, consumer_type, consumer_name, consumer_id, force_register, environment, - rhsm_baseurl, server_insecure, server_hostname, server_proxy_hostname, - server_proxy_port, server_proxy_user, server_proxy_password, release): + release): ''' Register the current system to the provided RHSM or Red Hat Satellite or Katello server @@ -409,27 +408,9 @@ class Rhsm(RegistrationBase): if force_register: args.extend(['--force']) - if rhsm_baseurl: - args.extend(['--baseurl', rhsm_baseurl]) - - if server_insecure: - args.extend(['--insecure']) - - if server_hostname: - args.extend(['--serverurl', server_hostname]) - if org_id: args.extend(['--org', org_id]) - if server_proxy_hostname and server_proxy_port: - args.extend(['--proxy', server_proxy_hostname + ':' + server_proxy_port]) - - if server_proxy_user: - args.extend(['--proxyuser', server_proxy_user]) - - if server_proxy_password: - args.extend(['--proxypassword', server_proxy_password]) - if activationkey: args.extend(['--activationkey', activationkey]) else: @@ -924,8 +905,7 @@ def main(): rhsm.configure(**module.params) rhsm.register(username, password, auto_attach, activationkey, org_id, consumer_type, consumer_name, consumer_id, force_register, - environment, rhsm_baseurl, server_insecure, server_hostname, - server_proxy_hostname, server_proxy_port, server_proxy_user, server_proxy_password, release) + environment, release) if syspurpose and 'sync' in syspurpose and syspurpose['sync'] is True: rhsm.sync_syspurpose() if pool_ids: diff --git a/tests/unit/plugins/modules/test_redhat_subscription.py b/tests/unit/plugins/modules/test_redhat_subscription.py index bf65671419..f38f1ffe0d 100644 --- a/tests/unit/plugins/modules/test_redhat_subscription.py +++ b/tests/unit/plugins/modules/test_redhat_subscription.py @@ -92,7 +92,6 @@ TEST_CASES = [ ), ( ['/testbin/subscription-manager', 'register', - '--serverurl', 'satellite.company.com', '--username', 'admin', '--password', 'admin'], {'check_rc': True, 'expand_user_and_vars': False}, @@ -180,7 +179,6 @@ TEST_CASES = [ [ '/testbin/subscription-manager', 'register', - '--serverurl', 'satellite.company.com', '--org', 'admin', '--activationkey', 'some-activation-key' ], @@ -340,9 +338,6 @@ TEST_CASES = [ 'register', '--force', '--org', 'admin', - '--proxy', 'proxy.company.com:12345', - '--proxyuser', 'proxy_user', - '--proxypassword', 'secret_proxy_password', '--username', 'admin', '--password', 'admin' ], From e1e89f7735a56dc739f5a8d0cd0e7b845d4aca96 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 30 Nov 2022 22:30:49 +0100 Subject: [PATCH 045/134] redhat_subscription: don't discard vars with key (#5627) (#5633) Fixes #3486. From the man-pages of subscription-manager, none of the parameters used are tied to the activationkey except the two that remain in its else-clause. Note that type is not mentioned in the man-pages on 7.6 (at least), but is still present and available. Co-authored-by: Thor K. H (cherry picked from commit f7fa54eed9f82ea2d0287541d9bef31a8e3631d3) Co-authored-by: Pino Toscano --- ...t_subscription-subscribe-parameters-2.yaml | 3 +++ plugins/modules/redhat_subscription.py | 25 +++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) create mode 100644 changelogs/fragments/5627-redhat_subscription-subscribe-parameters-2.yaml diff --git a/changelogs/fragments/5627-redhat_subscription-subscribe-parameters-2.yaml b/changelogs/fragments/5627-redhat_subscription-subscribe-parameters-2.yaml new file mode 100644 index 0000000000..c76f6871d8 --- /dev/null +++ b/changelogs/fragments/5627-redhat_subscription-subscribe-parameters-2.yaml @@ -0,0 +1,3 @@ +bugfixes: + - redhat_subscription - do not ignore ``consumer_name`` and other variables if ``activationkey`` is specified + (https://github.com/ansible-collections/community.general/issues/3486, https://github.com/ansible-collections/community.general/pull/5627). diff --git a/plugins/modules/redhat_subscription.py b/plugins/modules/redhat_subscription.py index bb21578fa5..041c1a0097 100644 --- a/plugins/modules/redhat_subscription.py +++ b/plugins/modules/redhat_subscription.py @@ -411,23 +411,28 @@ class Rhsm(RegistrationBase): if org_id: args.extend(['--org', org_id]) + if auto_attach: + args.append('--auto-attach') + + if consumer_type: + args.extend(['--type', consumer_type]) + + if consumer_name: + args.extend(['--name', consumer_name]) + + if consumer_id: + args.extend(['--consumerid', consumer_id]) + + if environment: + args.extend(['--environment', environment]) + if activationkey: args.extend(['--activationkey', activationkey]) else: - if auto_attach: - args.append('--auto-attach') if username: args.extend(['--username', username]) if password: args.extend(['--password', password]) - if consumer_type: - args.extend(['--type', consumer_type]) - if consumer_name: - args.extend(['--name', consumer_name]) - if consumer_id: - args.extend(['--consumerid', consumer_id]) - if environment: - args.extend(['--environment', environment]) if release: args.extend(['--release', release]) From 2bc74f4f0497f0e87f3c011172bc54d9ddbc02a6 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 30 Nov 2022 22:55:52 +0100 Subject: [PATCH 046/134] vdo: Use yaml.safe_load() instead of yaml.load() (#5632) (#5637) * vdo: Use yaml.safe_load() instead of yaml.load() yaml.load() without specifying a Loader= is deprecated and unsafe. For details, see https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation * Update changelogs/fragments/5632-vdo-Use-yaml-safe-load-instead-of-yaml-load.yml Co-authored-by: Felix Fontein Co-authored-by: Lee Garrett Co-authored-by: Felix Fontein (cherry picked from commit 428e181440dc92378c7326d9d2bfadda052ce372) Co-authored-by: Lee Garrett --- .../5632-vdo-Use-yaml-safe-load-instead-of-yaml-load.yml | 2 ++ plugins/modules/vdo.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/5632-vdo-Use-yaml-safe-load-instead-of-yaml-load.yml diff --git a/changelogs/fragments/5632-vdo-Use-yaml-safe-load-instead-of-yaml-load.yml b/changelogs/fragments/5632-vdo-Use-yaml-safe-load-instead-of-yaml-load.yml new file mode 100644 index 0000000000..c2b0756eca --- /dev/null +++ b/changelogs/fragments/5632-vdo-Use-yaml-safe-load-instead-of-yaml-load.yml @@ -0,0 +1,2 @@ +bugfixes: + - vdo - now uses ``yaml.safe_load()`` to parse command output instead of the deprecated ``yaml.load()`` which is potentially unsafe. Using ``yaml.load()`` without explicitely setting a ``Loader=`` is also an error in pyYAML 6.0 (https://github.com/ansible-collections/community.general/pull/5632). diff --git a/plugins/modules/vdo.py b/plugins/modules/vdo.py index 21e8a96100..d2d4afe944 100644 --- a/plugins/modules/vdo.py +++ b/plugins/modules/vdo.py @@ -332,7 +332,7 @@ def inventory_vdos(module, vdocmd): if rc != 0: module.fail_json(msg="Inventorying VDOs failed: %s" % vdostatusout, rc=rc, err=err) - vdostatusyaml = yaml.load(vdostatusout) + vdostatusyaml = yaml.safe_load(vdostatusout) if vdostatusyaml is None: return vdolist @@ -548,7 +548,7 @@ def run_module(): # Modify the current parameters of a VDO that exists. if desiredvdo in vdolist and state == 'present': rc, vdostatusoutput, err = module.run_command([vdocmd, "status"]) - vdostatusyaml = yaml.load(vdostatusoutput) + vdostatusyaml = yaml.safe_load(vdostatusoutput) # An empty dictionary to contain dictionaries of VDO statistics processedvdos = {} From caaebb38e7c1ce054d71ef0af51d0eb7f3dbc3fd Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 30 Nov 2022 22:56:03 +0100 Subject: [PATCH 047/134] Fix for vmadm get_vm_uuid out of range (#5628) (#5635) * Fix for vmadm get_vm_uuid out of range * Fix for vmadm get_vm_uuid out of range * Update changelogs/fragments/5628-fix-vmadm-off-by-one.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit b8545d10e6dc0655995fe354b285871ce1f263b2) Co-authored-by: Carlos Neira --- changelogs/fragments/5628-fix-vmadm-off-by-one.yml | 2 ++ plugins/modules/vmadm.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5628-fix-vmadm-off-by-one.yml diff --git a/changelogs/fragments/5628-fix-vmadm-off-by-one.yml b/changelogs/fragments/5628-fix-vmadm-off-by-one.yml new file mode 100644 index 0000000000..bcb7bf63e6 --- /dev/null +++ b/changelogs/fragments/5628-fix-vmadm-off-by-one.yml @@ -0,0 +1,2 @@ +bugfixes: + - vmadm - fix for index out of range error in ``get_vm_uuid`` (https://github.com/ansible-collections/community.general/pull/5628). diff --git a/plugins/modules/vmadm.py b/plugins/modules/vmadm.py index 6b4490ca57..d6110726f4 100644 --- a/plugins/modules/vmadm.py +++ b/plugins/modules/vmadm.py @@ -438,7 +438,7 @@ def get_vm_prop(module, uuid, prop): def get_vm_uuid(module, alias): # Lookup the uuid that goes with the given alias. # Returns the uuid or '' if not found. - cmd = [module.vmadm, 'lookup', '-j', '-o', 'uuid', 'alias={1}'.format(alias)] + cmd = [module.vmadm, 'lookup', '-j', '-o', 'uuid', 'alias={0}'.format(alias)] (rc, stdout, stderr) = module.run_command(cmd) From 406fa121422d14a2c228655c892f530e3b598614 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 1 Dec 2022 22:48:44 +0100 Subject: [PATCH 048/134] [PR #5629/03039a56 backport][stable-6] Remove automatically adding # symbol to channel names (#5641) Remove automatically adding # symbol to channel names (#5629) * Add regex to match all channel ids * Add changelog fragment * Allow matching of channel ids with 9-11 characters * Fix file name * Update changelogs/fragments/5629-add-channel-prefix-regex.yml Co-authored-by: Felix Fontein * Remove channel auto prepend # * Update changelog fragment * Add prepend_hash option * Add version_added to prepend_hash doc string Co-authored-by: Felix Fontein * Add description of possible values for the prepend_hash option Co-authored-by: Felix Fontein * Remove old channel assign statement * Update changelogs/fragments/5629-add-prepend-hash-option-for-channel-id.yml Co-authored-by: Felix Fontein * Update changelog fragment tag Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 03039a56c0a409b574f79f456df72950d95362c6) Co-authored-by: William McBroom --- ...add-prepend-hash-option-for-channel-id.yml | 2 ++ plugins/modules/slack.py | 32 ++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/5629-add-prepend-hash-option-for-channel-id.yml diff --git a/changelogs/fragments/5629-add-prepend-hash-option-for-channel-id.yml b/changelogs/fragments/5629-add-prepend-hash-option-for-channel-id.yml new file mode 100644 index 0000000000..f38a6b4e13 --- /dev/null +++ b/changelogs/fragments/5629-add-prepend-hash-option-for-channel-id.yml @@ -0,0 +1,2 @@ +minor_changes: + - "slack - add option ``prepend_hash`` which allows to control whether a ``#`` is prepended to ``channel_id``. The current behavior (value ``auto``) is to prepend ``#`` unless some specific prefixes are found. That list of prefixes is incomplete, and there does not seem to exist a documented condition on when exactly ``#`` must not be prepended. We recommend to explicitly set ``prepend_hash=always`` or ``prepend_hash=never`` to avoid any ambiguity (https://github.com/ansible-collections/community.general/pull/5629)." \ No newline at end of file diff --git a/plugins/modules/slack.py b/plugins/modules/slack.py index 46602a5d16..2854277f60 100644 --- a/plugins/modules/slack.py +++ b/plugins/modules/slack.py @@ -129,6 +129,21 @@ options: type: list elements: dict version_added: 1.0.0 + prepend_hash: + type: str + description: + - Setting for automatically prepending a C(#) symbol on the passed in I(channel_id). + - The C(auto) method prepends a C(#) unless I(channel_id) starts with one of C(#), C(@), C(C0), C(GF), C(G0), C(CP). + These prefixes only cover a small set of the prefixes that should not have a C(#) prepended. + Since an exact condition which I(channel_id) values must not have the C(#) prefix is not known, + the value C(auto) for this option will be deprecated in the future. It is best to explicitly set + I(prepend_hash=always) or I(prepend_hash=never) to obtain the needed behavior. + choices: + - 'always' + - 'never' + - 'auto' + default: 'auto' + version_added: 6.1.0 """ EXAMPLES = """ @@ -289,7 +304,7 @@ def recursive_escape_quotes(obj, keys): def build_payload_for_slack(text, channel, thread_id, username, icon_url, icon_emoji, link_names, - parse, color, attachments, blocks, message_id): + parse, color, attachments, blocks, message_id, prepend_hash): payload = {} if color == "normal" and text is not None: payload = dict(text=escape_quotes(text)) @@ -297,10 +312,15 @@ def build_payload_for_slack(text, channel, thread_id, username, icon_url, icon_e # With a custom color we have to set the message as attachment, and explicitly turn markdown parsing on for it. payload = dict(attachments=[dict(text=escape_quotes(text), color=color, mrkdwn_in=["text"])]) if channel is not None: - if channel.startswith(('#', '@', 'C0', 'GF', 'G0', 'CP')): - payload['channel'] = channel - else: + if prepend_hash == 'auto': + if channel.startswith(('#', '@', 'C0', 'GF', 'G0', 'CP')): + payload['channel'] = channel + else: + payload['channel'] = '#' + channel + elif prepend_hash == 'always': payload['channel'] = '#' + channel + elif prepend_hash == 'never': + payload['channel'] = channel if thread_id is not None: payload['thread_ts'] = thread_id if username is not None: @@ -428,6 +448,7 @@ def main(): attachments=dict(type='list', elements='dict'), blocks=dict(type='list', elements='dict'), message_id=dict(type='str'), + prepend_hash=dict(type='str', default='auto', choices=['always', 'never', 'auto']), ), supports_check_mode=True, ) @@ -446,6 +467,7 @@ def main(): attachments = module.params['attachments'] blocks = module.params['blocks'] message_id = module.params['message_id'] + prepend_hash = module.params['prepend_hash'] color_choices = ['normal', 'good', 'warning', 'danger'] if color not in color_choices and not is_valid_hex_color(color): @@ -470,7 +492,7 @@ def main(): module.exit_json(changed=changed) payload = build_payload_for_slack(text, channel, thread_id, username, icon_url, icon_emoji, link_names, - parse, color, attachments, blocks, message_id) + parse, color, attachments, blocks, message_id, prepend_hash) slack_response = do_notify_slack(module, domain, token, payload) if 'ok' in slack_response: From 9abda18071ab3f0a2f048285064bae7573039316 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 1 Dec 2022 22:48:59 +0100 Subject: [PATCH 049/134] [PR #5639/da7cba4c backport][stable-6] Fix example in keycloak_realm documentation (#5643) Fix example in keycloak_realm documentation (#5639) (cherry picked from commit da7cba4c12dcdf04a41949f05ccf9d9d952da57d) Co-authored-by: Dorian Monnier --- plugins/modules/keycloak_realm.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/modules/keycloak_realm.py b/plugins/modules/keycloak_realm.py index f457d20cd3..73a17cf10b 100644 --- a/plugins/modules/keycloak_realm.py +++ b/plugins/modules/keycloak_realm.py @@ -519,6 +519,7 @@ EXAMPLES = ''' auth_username: USERNAME auth_password: PASSWORD id: realm + realm: realm state: present - name: Delete a Keycloak realm From 25d9ab8dcd865f6632bcee15713e9999cf3abcb7 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 2 Dec 2022 06:59:43 +0100 Subject: [PATCH 050/134] [PR #5640/fd436bdb backport][stable-6] fix typo disable_looups in inventory/proxmox (#5644) fix typo disable_looups in inventory/proxmox (#5640) * fix typo disable_looups in inventory/proxmox - resolve issue with lookups in proxmox inventory config * add changelog fragment * Update changelogs/fragments/5640-fix-typo-proxmox-inventory.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit fd436bdbc2917365580851a9a0cf940875633ea1) Co-authored-by: Torgny Bjers --- changelogs/fragments/5640-fix-typo-proxmox-inventory.yml | 2 ++ plugins/inventory/proxmox.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5640-fix-typo-proxmox-inventory.yml diff --git a/changelogs/fragments/5640-fix-typo-proxmox-inventory.yml b/changelogs/fragments/5640-fix-typo-proxmox-inventory.yml new file mode 100644 index 0000000000..d5b8de5aea --- /dev/null +++ b/changelogs/fragments/5640-fix-typo-proxmox-inventory.yml @@ -0,0 +1,2 @@ +bugfixes: + - "proxmox inventory plugin - fix bug while templating when using templates for the ``url``, ``user``, ``password``, ``token_id``, or ``token_secret`` options (https://github.com/ansible-collections/community.general/pull/5640)." diff --git a/plugins/inventory/proxmox.py b/plugins/inventory/proxmox.py index b24bcacf25..904579a494 100644 --- a/plugins/inventory/proxmox.py +++ b/plugins/inventory/proxmox.py @@ -615,7 +615,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): for o in ('url', 'user', 'password', 'token_id', 'token_secret'): v = self.get_option(o) if self.templar.is_template(v): - v = self.templar.template(v, disable_looups=False) + v = self.templar.template(v, disable_lookups=False) setattr(self, 'proxmox_%s' % o, v) # some more cleanup and validation From 2d616bf4d19822186633d7e85939555037cf2d29 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 3 Dec 2022 22:40:55 +0100 Subject: [PATCH 051/134] [PR #5638/23aacc78 backport][stable-6] Reenable and enhance `copr` integration tests (#5646) Reenable and enhance `copr` integration tests (#5638) * Enhance `copr` integration tests - Switch to a new test Copr repository. @copr/integration_tests was removed which caused the tests to fail. I created a new one under my account that I'll ensure stays around. - Add basic testing to ensure that repo files are created in the correct location and contain the correct baseurl and enabled status. - Also run tests on Enterprise Linux. - Test that packages from the Copr install. This has to be disabled on EOL Fedoras that Copr does not allow building new packages for. Resolves: https://github.com/ansible-collections/community.general/issues/5595 * copr tests: Fix ansible_python_interpreter on c8s * copr: Don't test on alt Pythons on cs8 * Revert "copr tests: Fix ansible_python_interpreter on c8s" This reverts commit 58e15a7ebf3a8b270a7ada1a3834ab8322ca006c. (cherry picked from commit 23aacc78e1dd4eb6a05fea4a243075fd6ed0e2ef) Co-authored-by: Maxwell G --- tests/integration/targets/copr/aliases | 2 - tests/integration/targets/copr/tasks/main.yml | 112 ++++++++++++++++-- tests/integration/targets/copr/vars/main.yml | 15 +++ 3 files changed, 117 insertions(+), 12 deletions(-) create mode 100644 tests/integration/targets/copr/vars/main.yml diff --git a/tests/integration/targets/copr/aliases b/tests/integration/targets/copr/aliases index c9fc0e0a2f..ed3c1af00d 100644 --- a/tests/integration/targets/copr/aliases +++ b/tests/integration/targets/copr/aliases @@ -7,5 +7,3 @@ needs/root skip/macos skip/osx skip/freebsd - -disabled # FIXME tests are currently failing diff --git a/tests/integration/targets/copr/tasks/main.yml b/tests/integration/targets/copr/tasks/main.yml index ac78255d48..917e44b7ec 100644 --- a/tests/integration/targets/copr/tasks/main.yml +++ b/tests/integration/targets/copr/tasks/main.yml @@ -3,14 +3,27 @@ # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # SPDX-License-Identifier: GPL-3.0-or-later -- when: ansible_distribution == 'Fedora' +- when: + # Fedora or RHEL >= 8 + # This module requires the dnf module which is not available on RHEL 7. + - > + ansible_distribution == 'Fedora' + or (ansible_os_family == 'RedHat' and ansible_distribution != 'Fedora' + and ansible_distribution_major_version | int >= 8) + # The copr module imports dnf which is only available for the system Python + # interpreter. + - > + not (ansible_distribution == 'CentOS' and + ansible_distribution_major_version | int == 8 and not + ansible_python_version.startswith('3.6')) block: + - debug: var=copr_chroot - name: enable copr project copr: host: copr.fedorainfracloud.org state: enabled - name: '@copr/integration_tests' - chroot: fedora-rawhide-x86_64 + name: '{{ copr_fullname }}' + chroot: "{{ copr_chroot }}" register: result - name: assert that the copr project was enabled @@ -24,8 +37,8 @@ check_mode: yes copr: state: enabled - name: '@copr/integration_tests' - chroot: fedora-rawhide-x86_64 + name: '{{ copr_fullname }}' + chroot: '{{ copr_chroot }}' register: result - name: assert that the copr project was enabled @@ -34,10 +47,53 @@ - result is not changed - result.msg == 'enabled' + - name: Ensure the repo is installed and enabled | slurp + register: result + ansible.builtin.slurp: + src: "{{ copr_repofile }}" + + - name: Ensure the repo is installed and enabled + vars: + content: "{{ result.content | b64decode }}" + _baseurl: "{{ 'https://download.copr.fedorainfracloud.org/results/gotmax23/community.general.copr_integration_tests' | regex_escape }}" + baseurl: "{{ content | regex_search('baseurl=' ~ _baseurl) }}" + block: + - ansible.builtin.debug: + var: content + - ansible.builtin.debug: + var: baseurl + - name: Ensure the repo is installed and enabled + ansible.builtin.assert: + that: + - "'enabled=1' in content" + - baseurl | length > 0 + + - name: Install test package from Copr + when: + # Copr does not build new packages for EOL Fedoras. + - > + not (ansible_distribution == 'Fedora' and + ansible_distribution_major_version | int < 35) + block: + - name: install test package from the copr + ansible.builtin.package: + update_cache: true + name: copr-module-integration-dummy-package + + - name: uninstall test package + register: result + ansible.builtin.package: + name: copr-module-integration-dummy-package + state: absent + + - name: check uninstall test package + ansible.builtin.assert: + that: result.changed | bool + - name: remove copr project copr: state: absent - name: '@copr/integration_tests' + name: '{{ copr_fullname }}' register: result - name: assert that the copr project was removed @@ -46,11 +102,20 @@ - 'result is changed' - result.msg == 'absent' + - name: Ensure the repo file was removed | stat + register: result + ansible.builtin.stat: + dest: "{{ copr_repofile }}" + + - name: Ensure the repo file was removed + ansible.builtin.assert: + that: not result.stat.exists | bool + - name: disable copr project copr: state: disabled - name: '@copr/integration_tests' - chroot: fedora-rawhide-x86_64 + name: '{{ copr_fullname }}' + chroot: '{{ copr_chroot }}' register: result - name: assert that the copr project was disabled @@ -59,10 +124,37 @@ - 'result is changed' - result.msg == 'disabled' + - name: Ensure the repo is installed but disabled | slurp + register: result + ansible.builtin.slurp: + src: "{{ copr_repofile }}" + + - name: Ensure the repo is installed but disabled + vars: + content: "{{ result.content | b64decode }}" + _baseurl: "{{ 'https://download.copr.fedorainfracloud.org/results/gotmax23/community.general.copr_integration_tests' | regex_escape }}" + baseurl: "{{ content | regex_search('baseurl=' ~ _baseurl) }}" + block: + - ansible.builtin.debug: + var: content + - ansible.builtin.debug: + var: baseurl + - name: Ensure the repo is installed but disabled + ansible.builtin.assert: + that: + - "'enabled=0' in content" + - baseurl | length > 0 + always: - name: clean up + ignore_errors: true copr: host: copr.fedorainfracloud.org state: absent - name: '@copr/integration_tests' - chroot: fedora-rawhide-x86_64 + name: '{{ copr_fullname }}' + chroot: '{{ copr_chroot }}' + + - name: cleanup test package + ansible.builtin.package: + name: copr-module-integration-dummy-package + state: absent diff --git a/tests/integration/targets/copr/vars/main.yml b/tests/integration/targets/copr/vars/main.yml new file mode 100644 index 0000000000..a37a44d478 --- /dev/null +++ b/tests/integration/targets/copr/vars/main.yml @@ -0,0 +1,15 @@ +# Copyright (c) 2022 Maxwell G +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or +# https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later +--- +copr_host: copr.fedorainfracloud.org +copr_namespace: gotmax23 +copr_name: community.general.copr_integration_tests +copr_fullname: '{{ copr_namespace }}/{{ copr_name }}' +copr_repofile: '/etc/yum.repos.d/_copr:{{ copr_host }}:{{ copr_namespace }}:{{ copr_name }}.repo' + +# TODO: Fix chroot autodetection so this isn't necessary +_copr_chroot_fedora: "fedora-rawhide-x86_64" +_copr_chroot_rhelish: "epel-{{ ansible_distribution_major_version }}-x86_64" +copr_chroot: "{{ _copr_chroot_fedora if ansible_distribution == 'Fedora' else _copr_chroot_rhelish }}" From cc28cde3a2b99ed32451bf6446ba60a34a817a62 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 4 Dec 2022 12:39:30 +0100 Subject: [PATCH 052/134] [PR #5647/be22ca06 backport][stable-6] cmd_runner: allow bool format to pass alternate (false) value (#5650) cmd_runner: allow bool format to pass alternate (false) value (#5647) * allow bool format to pass alternate (false) value * add changelog fragment (cherry picked from commit be22ca063354507fbafb6d55032be39636bbf036) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- changelogs/fragments/5647-cmd-runner-as-bool-false.yml | 2 ++ plugins/module_utils/cmd_runner.py | 9 +++++++-- tests/unit/plugins/module_utils/test_cmd_runner.py | 4 ++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/5647-cmd-runner-as-bool-false.yml diff --git a/changelogs/fragments/5647-cmd-runner-as-bool-false.yml b/changelogs/fragments/5647-cmd-runner-as-bool-false.yml new file mode 100644 index 0000000000..5dc447d235 --- /dev/null +++ b/changelogs/fragments/5647-cmd-runner-as-bool-false.yml @@ -0,0 +1,2 @@ +minor_changes: + - cmd_runner module utils - ``cmd_runner_fmt.as_bool()`` can now take an extra parameter to format when value is false (https://github.com/ansible-collections/community.general/pull/5647). diff --git a/plugins/module_utils/cmd_runner.py b/plugins/module_utils/cmd_runner.py index 38daac6716..21d61a6a5c 100644 --- a/plugins/module_utils/cmd_runner.py +++ b/plugins/module_utils/cmd_runner.py @@ -103,8 +103,13 @@ class _ArgFormat(object): class _Format(object): @staticmethod - def as_bool(args): - return _ArgFormat(lambda value: _ensure_list(args) if value else []) + def as_bool(args_true, args_false=None, ignore_none=None): + if args_false is not None: + if ignore_none is None: + ignore_none = False + else: + args_false = [] + return _ArgFormat(lambda value: _ensure_list(args_true) if value else _ensure_list(args_false), ignore_none=ignore_none) @staticmethod def as_bool_not(args): diff --git a/tests/unit/plugins/module_utils/test_cmd_runner.py b/tests/unit/plugins/module_utils/test_cmd_runner.py index f1c3e25a9b..7cec215a76 100644 --- a/tests/unit/plugins/module_utils/test_cmd_runner.py +++ b/tests/unit/plugins/module_utils/test_cmd_runner.py @@ -18,6 +18,10 @@ TC_FORMATS = dict( simple_boolean__true=(fmt.as_bool, ("--superflag",), True, ["--superflag"]), simple_boolean__false=(fmt.as_bool, ("--superflag",), False, []), simple_boolean__none=(fmt.as_bool, ("--superflag",), None, []), + simple_boolean_both__true=(fmt.as_bool, ("--superflag", "--falseflag"), True, ["--superflag"]), + simple_boolean_both__false=(fmt.as_bool, ("--superflag", "--falseflag"), False, ["--falseflag"]), + simple_boolean_both__none=(fmt.as_bool, ("--superflag", "--falseflag"), None, ["--falseflag"]), + simple_boolean_both__none_ig=(fmt.as_bool, ("--superflag", "--falseflag", True), None, []), simple_boolean_not__true=(fmt.as_bool_not, ("--superflag",), True, []), simple_boolean_not__false=(fmt.as_bool_not, ("--superflag",), False, ["--superflag"]), simple_boolean_not__none=(fmt.as_bool_not, ("--superflag",), None, ["--superflag"]), From 2b0e335752cb02d9166e89e3f869ec8d13dc2ddb Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 4 Dec 2022 12:57:24 +0100 Subject: [PATCH 053/134] [PR #5602/632fc07e backport][stable-6] Updated tags delimiter (#5652) Updated tags delimiter (#5602) * Updated tags delimiter Starting from Proxmox 7.3 tags are delimited by semicolon. For backward compatibility it needs to be splitted by both commas and semicolons. * Added missing space * Add changelog fragment. Co-authored-by: Felix Fontein (cherry picked from commit 632fc07e65778cf236a8da35bf4204bddcd052b0) Co-authored-by: domelek <40233039+domelek@users.noreply.github.com> --- changelogs/fragments/5602-proxmox-tags.yml | 2 ++ plugins/inventory/proxmox.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5602-proxmox-tags.yml diff --git a/changelogs/fragments/5602-proxmox-tags.yml b/changelogs/fragments/5602-proxmox-tags.yml new file mode 100644 index 0000000000..32498f0366 --- /dev/null +++ b/changelogs/fragments/5602-proxmox-tags.yml @@ -0,0 +1,2 @@ +bugfixes: + - "proxmox inventory plugin - handle tags delimited by semicolon instead of comma, which happens from Proxmox 7.3 on (https://github.com/ansible-collections/community.general/pull/5602)." diff --git a/plugins/inventory/proxmox.py b/plugins/inventory/proxmox.py index 904579a494..e33f7ed77d 100644 --- a/plugins/inventory/proxmox.py +++ b/plugins/inventory/proxmox.py @@ -408,7 +408,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): stripped_value = value.strip() if stripped_value: parsed_key = key + "_parsed" - properties[parsed_key] = [tag.strip() for tag in stripped_value.split(",")] + properties[parsed_key] = [tag.strip() for tag in stripped_value.replace(',', ';').split(";")] # The first field in the agent string tells you whether the agent is enabled # the rest of the comma separated string is extra config for the agent. From 51d704bfe39c18ff1a019fe691aa26ec6ff823cc Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 4 Dec 2022 13:10:32 +0100 Subject: [PATCH 054/134] [PR #5605/fb2833d3 backport][stable-6] feat(ssh_config): host_key_algorithms option (#5653) feat(ssh_config): host_key_algorithms option (#5605) * feat(ssh_config): host_key_algorithms option * chore: add changelog fragment * chore(ssh_config): add version info to option and update fragment (cherry picked from commit fb2833d34d5e8b389ed017084d87ea6b079d4d9b) Co-authored-by: Arek Kalandyk <36413794+koralowiec@users.noreply.github.com> --- .../5605-ssh-config-add-host-key-algorithms.yaml | 2 ++ plugins/modules/ssh_config.py | 7 +++++++ .../targets/ssh_config/tasks/options.yml | 13 +++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 changelogs/fragments/5605-ssh-config-add-host-key-algorithms.yaml diff --git a/changelogs/fragments/5605-ssh-config-add-host-key-algorithms.yaml b/changelogs/fragments/5605-ssh-config-add-host-key-algorithms.yaml new file mode 100644 index 0000000000..1535d9b13d --- /dev/null +++ b/changelogs/fragments/5605-ssh-config-add-host-key-algorithms.yaml @@ -0,0 +1,2 @@ +minor_changes: + - ssh_config - add ``host_key_algorithms`` option (https://github.com/ansible-collections/community.general/pull/5605). diff --git a/plugins/modules/ssh_config.py b/plugins/modules/ssh_config.py index 00a0525d6c..cb028ac8e5 100644 --- a/plugins/modules/ssh_config.py +++ b/plugins/modules/ssh_config.py @@ -88,6 +88,11 @@ options: - If I(user) and this option are not specified, C(/etc/ssh/ssh_config) is used. - Mutually exclusive with I(user). type: path + host_key_algorithms: + description: + - Sets the C(HostKeyAlgorithms) option. + type: str + version_added: 6.1.0 requirements: - StormSSH notes: @@ -207,6 +212,7 @@ class SSHConfig(): strict_host_key_checking=self.params.get('strict_host_key_checking'), user_known_hosts_file=self.params.get('user_known_hosts_file'), proxycommand=self.params.get('proxycommand'), + host_key_algorithms=self.params.get('host_key_algorithms'), ) # Convert True / False to 'yes' / 'no' for usage in ssh_config @@ -297,6 +303,7 @@ def main(): group=dict(default=None, type='str'), host=dict(type='str', required=True), hostname=dict(type='str'), + host_key_algorithms=dict(type='str', no_log=False), identity_file=dict(type='path'), port=dict(type='str'), proxycommand=dict(type='str', default=None), diff --git a/tests/integration/targets/ssh_config/tasks/options.yml b/tests/integration/targets/ssh_config/tasks/options.yml index 04586873ad..65ce691cf8 100644 --- a/tests/integration/targets/ssh_config/tasks/options.yml +++ b/tests/integration/targets/ssh_config/tasks/options.yml @@ -15,6 +15,7 @@ host: "options.example.com" proxycommand: "ssh jumphost.example.com -W %h:%p" forward_agent: true + host_key_algorithms: "+ssh-rsa" state: present register: options_add check_mode: yes @@ -43,6 +44,7 @@ host: "options.example.com" proxycommand: "ssh jumphost.example.com -W %h:%p" forward_agent: true + host_key_algorithms: "+ssh-rsa" state: present register: options_add @@ -60,6 +62,7 @@ host: "options.example.com" proxycommand: "ssh jumphost.example.com -W %h:%p" forward_agent: true + host_key_algorithms: "+ssh-rsa" state: present register: options_add_again @@ -81,6 +84,7 @@ that: - "'proxycommand ssh jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode" - "'forwardagent yes' in slurp_ssh_config['content'] | b64decode" + - "'hostkeyalgorithms +ssh-rsa' in slurp_ssh_config['content'] | b64decode" - name: Options - Update host community.general.ssh_config: @@ -88,6 +92,7 @@ host: "options.example.com" proxycommand: "ssh new-jumphost.example.com -W %h:%p" forward_agent: no + host_key_algorithms: "+ssh-ed25519" state: present register: options_update @@ -107,6 +112,7 @@ host: "options.example.com" proxycommand: "ssh new-jumphost.example.com -W %h:%p" forward_agent: no + host_key_algorithms: "+ssh-ed25519" state: present register: options_update @@ -129,6 +135,7 @@ that: - "'proxycommand ssh new-jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode" - "'forwardagent no' in slurp_ssh_config['content'] | b64decode" + - "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode" - name: Options - Ensure no update in case option exist in ssh_config file but wasn't defined in playbook community.general.ssh_config: @@ -156,6 +163,11 @@ that: - "'proxycommand ssh new-jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode" - "'forwardagent no' in slurp_ssh_config['content'] | b64decode" + - "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode" + +- name: Debug + debug: + msg: "{{ slurp_ssh_config['content'] | b64decode }}" - name: Options - Delete a host community.general.ssh_config: @@ -197,3 +209,4 @@ that: - "'proxycommand ssh new-jumphost.example.com -W %h:%p' not in slurp_ssh_config['content'] | b64decode" - "'forwardagent no' not in slurp_ssh_config['content'] | b64decode" + - "'hostkeyalgorithms +ssh-ed25519' not in slurp_ssh_config['content'] | b64decode" From 2fa36592e446cd7520a09607006e72a84c88ca58 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Sun, 4 Dec 2022 21:44:59 +0100 Subject: [PATCH 055/134] Prepare 6.1.0 release. --- changelogs/fragments/6.1.0.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/fragments/6.1.0.yml diff --git a/changelogs/fragments/6.1.0.yml b/changelogs/fragments/6.1.0.yml new file mode 100644 index 0000000000..4b1469c9fe --- /dev/null +++ b/changelogs/fragments/6.1.0.yml @@ -0,0 +1 @@ +release_summary: Regular bugfix and feature release. From 671f85006942e69c75228750ac2b45b9be4942eb Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 5 Dec 2022 05:47:11 +0000 Subject: [PATCH 056/134] [PR #5619/f0b3bba0 backport][stable-6] Fix keycloak_client_rolemapping role removal and diff (#5656) Fix keycloak_client_rolemapping role removal and diff (#5619) * Keycloak: Fix client rolemapping removal Keycloak's delete_group_rolemapping API wrapper didn't pass data about the roles to remove to keycloak, resulting in removal of all roles. Follow the intended behaviour and delete only the roles listed in the module invocation. Signed-off-by: Florian Achleitner * Keycloak: Fix client_rolemapping diff The module's diff output wrongly showed the changed roles list as 'after' state. This is obviously wrong for role removal and also wrong for role addition, if there are other roles assigned. Use the result of the API query for 'end_state' for 'diff' as well. Signed-off-by: Florian Achleitner * Keycloak: Calculate client_rolemapping proposed state properly Signed-off-by: Florian Achleitner * Add changelog fragment Signed-off-by: Florian Achleitner Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein * Fix for python2 unit test Signed-off-by: Florian Achleitner Co-authored-by: Felix Fontein (cherry picked from commit f0b3bba030055183b864678208e187c24d2ca581) Co-authored-by: fachleitner --- changelogs/fragments/5619-keycloak-improvements.yml | 3 +++ plugins/module_utils/identity/keycloak/keycloak.py | 2 +- plugins/modules/keycloak_client_rolemapping.py | 11 +++++++---- 3 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/5619-keycloak-improvements.yml diff --git a/changelogs/fragments/5619-keycloak-improvements.yml b/changelogs/fragments/5619-keycloak-improvements.yml new file mode 100644 index 0000000000..2e5a739dad --- /dev/null +++ b/changelogs/fragments/5619-keycloak-improvements.yml @@ -0,0 +1,3 @@ +bugfixes: + - "keycloak_client_rolemapping - remove only listed mappings with ``state=absent`` (https://github.com/ansible-collections/community.general/pull/5619)." + - "keycloak_client_rolemapping - calculate ``proposed`` and ``after`` return values properly (https://github.com/ansible-collections/community.general/pull/5619)." diff --git a/plugins/module_utils/identity/keycloak/keycloak.py b/plugins/module_utils/identity/keycloak/keycloak.py index 078925ef71..ce22800334 100644 --- a/plugins/module_utils/identity/keycloak/keycloak.py +++ b/plugins/module_utils/identity/keycloak/keycloak.py @@ -606,7 +606,7 @@ class KeycloakAPI(object): """ available_rolemappings_url = URL_CLIENT_GROUP_ROLEMAPPINGS.format(url=self.baseurl, realm=realm, id=gid, client=cid) try: - open_url(available_rolemappings_url, method="DELETE", http_agent=self.http_agent, headers=self.restheaders, + open_url(available_rolemappings_url, method="DELETE", http_agent=self.http_agent, headers=self.restheaders, data=json.dumps(role_rep), validate_certs=self.validate_certs, timeout=self.connection_timeout) except Exception as e: self.module.fail_json(msg="Could not delete available rolemappings for client %s in group %s, realm %s: %s" diff --git a/plugins/modules/keycloak_client_rolemapping.py b/plugins/modules/keycloak_client_rolemapping.py index 4f1f9b0d0f..f0da97ef59 100644 --- a/plugins/modules/keycloak_client_rolemapping.py +++ b/plugins/modules/keycloak_client_rolemapping.py @@ -295,7 +295,7 @@ def main(): assigned_roles_before = kc.get_client_group_composite_rolemappings(gid, cid, realm=realm) result['existing'] = assigned_roles_before - result['proposed'] = roles + result['proposed'] = list(assigned_roles_before) if assigned_roles_before else [] update_roles = [] for role_index, role in enumerate(roles, start=0): @@ -307,6 +307,7 @@ def main(): 'id': role['id'], 'name': role['name'], }) + result['proposed'].append(available_role) # Fetch roles to remove if state absent else: for assigned_role in assigned_roles_before: @@ -315,13 +316,15 @@ def main(): 'id': role['id'], 'name': role['name'], }) + if assigned_role in result['proposed']: # Handle double removal + result['proposed'].remove(assigned_role) if len(update_roles): if state == 'present': # Assign roles result['changed'] = True if module._diff: - result['diff'] = dict(before=assigned_roles_before, after=update_roles) + result['diff'] = dict(before=assigned_roles_before, after=result['proposed']) if module.check_mode: module.exit_json(**result) kc.add_group_rolemapping(gid, cid, update_roles, realm=realm) @@ -333,7 +336,7 @@ def main(): # Remove mapping of role result['changed'] = True if module._diff: - result['diff'] = dict(before=assigned_roles_before, after=update_roles) + result['diff'] = dict(before=assigned_roles_before, after=result['proposed']) if module.check_mode: module.exit_json(**result) kc.delete_group_rolemapping(gid, cid, update_roles, realm=realm) @@ -344,7 +347,7 @@ def main(): # Do nothing else: result['changed'] = False - result['msg'] = 'Nothing to do, roles %s are correctly mapped with group %s.' % (roles, group_name) + result['msg'] = 'Nothing to do, roles %s are %s with group %s.' % (roles, 'mapped' if state == 'present' else 'not mapped', group_name) module.exit_json(**result) From 8a231e4b36cd5d0e884a4062ff9696bc73a87ad4 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 5 Dec 2022 05:47:23 +0000 Subject: [PATCH 057/134] [PR #5606/7ea544a6 backport][stable-6] New Module: Keycloak ClientSecret with PR changes (#5654) New Module: Keycloak ClientSecret with PR changes (#5606) * feat(plugins/keycloak): add get and create util function for client secret * feat(plugins/keycloak): add client secret module * chore: add maintainer in BOTMETA * Update plugins/modules/identity/keycloak/keycloak_clientsecret.py Co-authored-by: Felix Fontein * Make changes to keycloak_clientsecret from PR * Add SPDX identifier for keycloak_clientsecret * Add copyright in keycloak_clientsecret for REUSE * Add integration test for keycloak_clientsecret * rm clientsecret from keycloak_clientsecret result - end_state used instead * keycloak_clientsecret: Undo meta/runtime.yml change * Fix sanity tests for keycloak_clientsecret * New keycloak_clientsecret_info module - Replaces keycloak_clientsecret - Module definition and some common logic moved into module_utils - Update documentation, tests, etc. - Add myself as author * Misc fixes to keycloak_clientsecret_info * Add keycloak_clientsecret_regenerate module * keycloak_clientsecret* Update .github/BOTMETA.yml * keycloak_clientsecret_regenerate: Fix sanity tests * Fix README for keycloak_clientsecret integration test * Separate out keycloak_clientsecret module_utils * Keycloak_clientsecret module_utils: boilerplate * Update plugins/modules/keycloak_clientsecret_info.py Co-authored-by: Felix Fontein * Update plugins/modules/keycloak_clientsecret_info.py Co-authored-by: Felix Fontein * Update plugins/modules/keycloak_clientsecret_info.py Co-authored-by: Felix Fontein * Update plugins/modules/keycloak_clientsecret_info.py Co-authored-by: Felix Fontein * Update plugins/modules/keycloak_clientsecret_info.py Co-authored-by: Felix Fontein * Update plugins/modules/keycloak_clientsecret_info.py Co-authored-by: Felix Fontein * keycloak_clientsecret: Add no_log to examples and docs * keycloak_clientsecret: Update BOTMETA * Update .github/BOTMETA.yml Co-authored-by: Felix Fontein Co-authored-by: fynncfchen Co-authored-by: Fynnnnn Co-authored-by: Felix Fontein (cherry picked from commit 7ea544a6244c7324e45c6972cdf0b6674797e0e9) Co-authored-by: John Cant --- .github/BOTMETA.yml | 6 + .../identity/keycloak/keycloak.py | 48 +++++ .../keycloak/keycloak_clientsecret.py | 77 ++++++++ plugins/modules/keycloak_clientsecret_info.py | 161 +++++++++++++++++ .../keycloak_clientsecret_regenerate.py | 167 ++++++++++++++++++ .../keycloak_clientsecret_info/README.md | 17 ++ .../docker-compose.yml | 31 ++++ .../keycloak_clientsecret_info/tasks/main.yml | 48 +++++ .../keycloak_clientsecret_info/vars/main.yml | 20 +++ .../README.md | 17 ++ .../docker-compose.yml | 31 ++++ .../tasks/main.yml | 49 +++++ .../vars/main.yml | 20 +++ 13 files changed, 692 insertions(+) create mode 100644 plugins/module_utils/identity/keycloak/keycloak_clientsecret.py create mode 100644 plugins/modules/keycloak_clientsecret_info.py create mode 100644 plugins/modules/keycloak_clientsecret_regenerate.py create mode 100644 tests/integration/targets/keycloak_clientsecret_info/README.md create mode 100644 tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml create mode 100644 tests/integration/targets/keycloak_clientsecret_info/tasks/main.yml create mode 100644 tests/integration/targets/keycloak_clientsecret_info/vars/main.yml create mode 100644 tests/integration/targets/keycloak_clientsecret_regenerate/README.md create mode 100644 tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml create mode 100644 tests/integration/targets/keycloak_clientsecret_regenerate/tasks/main.yml create mode 100644 tests/integration/targets/keycloak_clientsecret_regenerate/vars/main.yml diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 6aacdc9cad..89751fc622 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -281,6 +281,8 @@ files: maintainers: $team_huawei $module_utils/identity/keycloak/keycloak.py: maintainers: $team_keycloak + $module_utils/identity/keycloak/keycloak_clientsecret.py: + maintainers: $team_keycloak fynncfchen johncant $module_utils/ipa.py: labels: ipa maintainers: $team_ipa @@ -670,6 +672,10 @@ files: maintainers: Gaetan2907 $modules/keycloak_clientscope.py: maintainers: Gaetan2907 + $modules/keycloak_clientsecret_info.py: + maintainers: fynncfchen johncant + $modules/keycloak_clientsecret_regenerate.py: + maintainers: fynncfchen johncant $modules/keycloak_group.py: maintainers: adamgoossens $modules/keycloak_identity_provider.py: diff --git a/plugins/module_utils/identity/keycloak/keycloak.py b/plugins/module_utils/identity/keycloak/keycloak.py index ce22800334..09b22b7561 100644 --- a/plugins/module_utils/identity/keycloak/keycloak.py +++ b/plugins/module_utils/identity/keycloak/keycloak.py @@ -58,6 +58,8 @@ URL_CLIENT_USER_ROLEMAPPINGS = "{url}/admin/realms/{realm}/users/{id}/role-mappi URL_CLIENT_USER_ROLEMAPPINGS_AVAILABLE = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client}/available" URL_CLIENT_USER_ROLEMAPPINGS_COMPOSITE = "{url}/admin/realms/{realm}/users/{id}/role-mappings/clients/{client}/composite" +URL_CLIENTSECRET = "{url}/admin/realms/{realm}/clients/{id}/client-secret" + URL_AUTHENTICATION_FLOWS = "{url}/admin/realms/{realm}/authentication/flows" URL_AUTHENTICATION_FLOW = "{url}/admin/realms/{realm}/authentication/flows/{id}" URL_AUTHENTICATION_FLOW_COPY = "{url}/admin/realms/{realm}/authentication/flows/{copyfrom}/copy" @@ -1160,6 +1162,52 @@ class KeycloakAPI(object): self.module.fail_json(msg='Could not update protocolmappers for clientscope %s in realm %s: %s' % (mapper_rep, realm, str(e))) + def create_clientsecret(self, id, realm="master"): + """ Generate a new client secret by id + + :param id: id (not clientId) of client to be queried + :param realm: client from this realm + :return: dict of credential representation + """ + clientsecret_url = URL_CLIENTSECRET.format(url=self.baseurl, realm=realm, id=id) + + try: + return json.loads(to_native(open_url(clientsecret_url, method='POST', headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s' + % (id, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s' + % (id, realm, str(e))) + + def get_clientsecret(self, id, realm="master"): + """ Obtain client secret by id + + :param id: id (not clientId) of client to be queried + :param realm: client from this realm + :return: dict of credential representation + """ + clientsecret_url = URL_CLIENTSECRET.format(url=self.baseurl, realm=realm, id=id) + + try: + return json.loads(to_native(open_url(clientsecret_url, method='GET', headers=self.restheaders, timeout=self.connection_timeout, + validate_certs=self.validate_certs).read())) + + except HTTPError as e: + if e.code == 404: + return None + else: + self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s' + % (id, realm, str(e))) + except Exception as e: + self.module.fail_json(msg='Could not obtain clientsecret of client %s for realm %s: %s' + % (id, realm, str(e))) + def get_groups(self, realm="master"): """ Fetch the name and ID of all groups on the Keycloak server. diff --git a/plugins/module_utils/identity/keycloak/keycloak_clientsecret.py b/plugins/module_utils/identity/keycloak/keycloak_clientsecret.py new file mode 100644 index 0000000000..85caa8e16b --- /dev/null +++ b/plugins/module_utils/identity/keycloak/keycloak_clientsecret.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2022, John Cant +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import \ + keycloak_argument_spec + + +def keycloak_clientsecret_module(): + """ + Returns an AnsibleModule definition for modules that interact with a client + secret. + + :return: argument_spec dict + """ + argument_spec = keycloak_argument_spec() + + meta_args = dict( + realm=dict(default='master'), + id=dict(type='str'), + client_id=dict(type='str', aliases=['clientId']), + ) + + argument_spec.update(meta_args) + + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_one_of=([['id', 'client_id'], + ['token', 'auth_realm', 'auth_username', 'auth_password']]), + required_together=([['auth_realm', 'auth_username', 'auth_password']]), + mutually_exclusive=[ + ['token', 'auth_realm'], + ['token', 'auth_username'], + ['token', 'auth_password'] + ]) + + return module + + +def keycloak_clientsecret_module_resolve_params(module, kc): + """ + Given an AnsibleModule definition for keycloak_clientsecret_*, and a + KeycloakAPI client, resolve the params needed to interact with the Keycloak + client secret, looking up the client by clientId if necessary via an API + call. + + :return: tuple of id, realm + """ + + realm = module.params.get('realm') + id = module.params.get('id') + client_id = module.params.get('client_id') + + # only lookup the client_id if id isn't provided. + # in the case that both are provided, prefer the ID, since it's one + # less lookup. + if id is None: + # Due to the required_one_of spec, client_id is guaranteed to not be None + client = kc.get_client_by_clientid(client_id, realm=realm) + + if client is None: + module.fail_json( + msg='Client does not exist {client_id}'.format(client_id=client_id) + ) + + id = client['id'] + + return id, realm diff --git a/plugins/modules/keycloak_clientsecret_info.py b/plugins/modules/keycloak_clientsecret_info.py new file mode 100644 index 0000000000..98a41ad20a --- /dev/null +++ b/plugins/modules/keycloak_clientsecret_info.py @@ -0,0 +1,161 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2022, Fynn Chen +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: keycloak_clientsecret_info + +short_description: Retrieve client secret via Keycloak API + +version_added: 6.1.0 + +description: + - This module allows you to get a Keycloak client secret via the Keycloak + REST API. It requires access to the REST API via OpenID Connect; the user + connecting and the client being used must have the requisite access rights. + In a default Keycloak installation, admin-cli and an admin user would work, + as would a separate client definition with the scope tailored to your needs + and a user having the expected roles. + + - When retrieving a new client secret, where possible provide the client's + I(id) (not I(client_id)) to the module. This removes a lookup to the API to + translate the I(client_id) into the client ID. + + - "Note that this module returns the client secret. To avoid this showing up in the logs, + please add C(no_log: true) to the task." + +options: + realm: + type: str + description: + - They Keycloak realm under which this client resides. + default: 'master' + + id: + description: + - The unique identifier for this client. + - This parameter is not required for getting or generating a client secret but + providing it will reduce the number of API calls required. + type: str + + client_id: + description: + - The I(client_id) of the client. Passing this instead of I(id) results in an + extra API call. + aliases: + - clientId + type: str + + +extends_documentation_fragment: + - community.general.keycloak + - community.general.attributes + - community.general.attributes.info_module + +author: + - Fynn Chen (@fynncfchen) + - John Cant (@johncant) +''' + +EXAMPLES = ''' +- name: Get a Keycloak client secret, authentication with credentials + community.general.keycloak_clientsecret_info: + id: '9d59aa76-2755-48c6-b1af-beb70a82c3cd' + realm: MyCustomRealm + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + delegate_to: localhost + no_log: true + +- name: Get a new Keycloak client secret, authentication with token + community.general.keycloak_clientsecret_info: + id: '9d59aa76-2755-48c6-b1af-beb70a82c3cd' + realm: MyCustomRealm + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + token: TOKEN + delegate_to: localhost + no_log: true + +- name: Get a new Keycloak client secret, passing client_id instead of id + community.general.keycloak_clientsecret_info: + client_id: 'myClientId' + realm: MyCustomRealm + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + token: TOKEN + delegate_to: localhost + no_log: true +''' + +RETURN = ''' +msg: + description: Textual description of whether we succeeded or failed + returned: always + type: str + +clientsecret_info: + description: Representation of the client secret + returned: on success + type: complex + contains: + type: + description: Credential type. + type: str + returned: always + sample: secret + value: + description: Client secret. + type: str + returned: always + sample: cUGnX1EIeTtPPAkcyGMv0ncyqDPu68P1 +''' + +from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import ( + KeycloakAPI, KeycloakError, get_token) +from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak_clientsecret import ( + keycloak_clientsecret_module, keycloak_clientsecret_module_resolve_params) + + +def main(): + """ + Module keycloak_clientsecret_info + + :return: + """ + + module = keycloak_clientsecret_module() + + # Obtain access token, initialize API + try: + connection_header = get_token(module.params) + except KeycloakError as e: + module.fail_json(msg=str(e)) + + kc = KeycloakAPI(module, connection_header) + + id, realm = keycloak_clientsecret_module_resolve_params(module, kc) + + clientsecret = kc.get_clientsecret(id=id, realm=realm) + + result = { + 'clientsecret_info': clientsecret, + 'msg': 'Get client secret successful for ID {id}'.format(id=id) + } + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/keycloak_clientsecret_regenerate.py b/plugins/modules/keycloak_clientsecret_regenerate.py new file mode 100644 index 0000000000..7a48a25d25 --- /dev/null +++ b/plugins/modules/keycloak_clientsecret_regenerate.py @@ -0,0 +1,167 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2022, Fynn Chen +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: keycloak_clientsecret_regenerate + +short_description: Regenerate Keycloak client secret via Keycloak API + +version_added: 6.1.0 + +description: + - This module allows you to regenerate a Keycloak client secret via the + Keycloak REST API. It requires access to the REST API via OpenID Connect; + the user connecting and the client being used must have the requisite access + rights. In a default Keycloak installation, admin-cli and an admin user + would work, as would a separate client definition with the scope tailored to + your needs and a user having the expected roles. + + - When regenerating a client secret, where possible provide the client's id + (not client_id) to the module. This removes a lookup to the API to + translate the client_id into the client ID. + + - "Note that this module returns the client secret. To avoid this showing up in the logs, + please add C(no_log: true) to the task." + +options: + realm: + type: str + description: + - They Keycloak realm under which this client resides. + default: 'master' + + id: + description: + - The unique identifier for this client. + - This parameter is not required for getting or generating a client secret but + providing it will reduce the number of API calls required. + type: str + + client_id: + description: + - The client_id of the client. Passing this instead of id results in an + extra API call. + aliases: + - clientId + type: str + + +extends_documentation_fragment: + - community.general.keycloak + +author: + - Fynn Chen (@fynncfchen) + - John Cant (@johncant) +''' + +EXAMPLES = ''' +- name: Regenerate a Keycloak client secret, authentication with credentials + community.general.keycloak_clientsecret_regenerate: + id: '9d59aa76-2755-48c6-b1af-beb70a82c3cd' + realm: MyCustomRealm + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + auth_realm: master + auth_username: USERNAME + auth_password: PASSWORD + delegate_to: localhost + no_log: true + +- name: Regenerate a Keycloak client secret, authentication with token + community.general.keycloak_clientsecret_regenerate: + id: '9d59aa76-2755-48c6-b1af-beb70a82c3cd' + realm: MyCustomRealm + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + token: TOKEN + delegate_to: localhost + no_log: true + +- name: Regenerate a Keycloak client secret, passing client_id instead of id + community.general.keycloak_clientsecret_info: + client_id: 'myClientId' + realm: MyCustomRealm + auth_client_id: admin-cli + auth_keycloak_url: https://auth.example.com/auth + token: TOKEN + delegate_to: localhost + no_log: true +''' + +RETURN = ''' +msg: + description: Message as to what action was taken. + returned: always + type: str + +end_state: + description: Representation of the client credential after module execution + returned: on success + type: complex + contains: + type: + description: Credential type. + type: str + returned: always + sample: secret + value: + description: Client secret. + type: str + returned: always + sample: cUGnX1EIeTtPPAkcyGMv0ncyqDPu68P1 + +''' + +from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak import ( + KeycloakAPI, KeycloakError, get_token) +from ansible_collections.community.general.plugins.module_utils.identity.keycloak.keycloak_clientsecret import ( + keycloak_clientsecret_module, keycloak_clientsecret_module_resolve_params) + + +def main(): + """ + Module keycloak_clientsecret_regenerate + + :return: + """ + + module = keycloak_clientsecret_module() + + # Obtain access token, initialize API + try: + connection_header = get_token(module.params) + except KeycloakError as e: + module.fail_json(msg=str(e)) + + kc = KeycloakAPI(module, connection_header) + + id, realm = keycloak_clientsecret_module_resolve_params(module, kc) + + if module.check_mode: + dummy_result = { + "msg": 'No action taken while in check mode', + "end_state": {'type': 'secret', 'value': 'X' * 32} + } + module.exit_json(**dummy_result) + + # Create new secret + clientsecret = kc.create_clientsecret(id=id, realm=realm) + + result = { + "msg": 'New client secret has been generated for ID {id}'.format(id=id), + "end_state": clientsecret + } + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/tests/integration/targets/keycloak_clientsecret_info/README.md b/tests/integration/targets/keycloak_clientsecret_info/README.md new file mode 100644 index 0000000000..fb721801da --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_info/README.md @@ -0,0 +1,17 @@ + + +The integration test can be performed as follows: + +``` +# 1. Start docker-compose: +docker-compose -f tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml stop +docker-compose -f tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml rm -f -v +docker-compose -f tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml up -d + +# 2. Run the integration tests: +ansible-test integration keycloak_clientsecret_info --allow-unsupported -v +``` diff --git a/tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml b/tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml new file mode 100644 index 0000000000..5e14e9aac1 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml @@ -0,0 +1,31 @@ +--- +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +version: '3.4' + +services: + postgres: + image: postgres:9.6 + restart: always + environment: + POSTGRES_USER: postgres + POSTGRES_DB: postgres + POSTGRES_PASSWORD: postgres + + keycloak: + image: jboss/keycloak:12.0.4 + ports: + - 8080:8080 + + environment: + DB_VENDOR: postgres + DB_ADDR: postgres + DB_DATABASE: postgres + DB_USER: postgres + DB_SCHEMA: public + DB_PASSWORD: postgres + + KEYCLOAK_USER: admin + KEYCLOAK_PASSWORD: password diff --git a/tests/integration/targets/keycloak_clientsecret_info/tasks/main.yml b/tests/integration/targets/keycloak_clientsecret_info/tasks/main.yml new file mode 100644 index 0000000000..a0cacf1889 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_info/tasks/main.yml @@ -0,0 +1,48 @@ +--- +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +- name: Create realm + community.general.keycloak_realm: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + id: "{{ realm }}" + realm: "{{ realm }}" + state: present + +- name: Keycloak Client + community.general.keycloak_client: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + realm: "{{ realm }}" + client_id: "{{ client_id }}" + state: present + register: client + +- name: Keycloak Client fetch clientsecret by client_id + community.general.keycloak_clientsecret_info: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + realm: "{{ realm }}" + client_id: "{{ client_id }}" + register: fetch_by_client_id_result + +- name: Assert that the client secret was retrieved + assert: + that: + - fetch_by_client_id_result.clientsecret_info.type == "secret" + - "{{ fetch_by_client_id_result.clientsecret_info.value | length }} >= 32" + +- name: Keycloak Client fetch clientsecret by id + community.general.keycloak_clientsecret_info: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + realm: "{{ realm }}" + id: "{{ client.end_state.id }}" + register: fetch_by_id_result + +- name: Assert that the same client secret was retrieved both times + assert: + that: + - fetch_by_id_result.clientsecret_info.value == fetch_by_client_id_result.clientsecret_info.value diff --git a/tests/integration/targets/keycloak_clientsecret_info/vars/main.yml b/tests/integration/targets/keycloak_clientsecret_info/vars/main.yml new file mode 100644 index 0000000000..8c913705f7 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_info/vars/main.yml @@ -0,0 +1,20 @@ +--- +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +url: http://localhost:8080/auth +admin_realm: master +admin_user: admin +admin_password: password +realm: myrealm +client_id: myclient +role: myrole +description_1: desc 1 +description_2: desc 2 + +auth_args: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" diff --git a/tests/integration/targets/keycloak_clientsecret_regenerate/README.md b/tests/integration/targets/keycloak_clientsecret_regenerate/README.md new file mode 100644 index 0000000000..08251b4c52 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_regenerate/README.md @@ -0,0 +1,17 @@ + + +The integration test can be performed as follows: + +``` +# 1. Start docker-compose: +docker-compose -f tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml stop +docker-compose -f tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml rm -f -v +docker-compose -f tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml up -d + +# 2. Run the integration tests: +ansible-test integration keycloak_clientsecret_regenerate --allow-unsupported -v +``` diff --git a/tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml b/tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml new file mode 100644 index 0000000000..5e14e9aac1 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml @@ -0,0 +1,31 @@ +--- +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +version: '3.4' + +services: + postgres: + image: postgres:9.6 + restart: always + environment: + POSTGRES_USER: postgres + POSTGRES_DB: postgres + POSTGRES_PASSWORD: postgres + + keycloak: + image: jboss/keycloak:12.0.4 + ports: + - 8080:8080 + + environment: + DB_VENDOR: postgres + DB_ADDR: postgres + DB_DATABASE: postgres + DB_USER: postgres + DB_SCHEMA: public + DB_PASSWORD: postgres + + KEYCLOAK_USER: admin + KEYCLOAK_PASSWORD: password diff --git a/tests/integration/targets/keycloak_clientsecret_regenerate/tasks/main.yml b/tests/integration/targets/keycloak_clientsecret_regenerate/tasks/main.yml new file mode 100644 index 0000000000..9bd52698a2 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_regenerate/tasks/main.yml @@ -0,0 +1,49 @@ +--- +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +- name: Create realm + community.general.keycloak_realm: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + id: "{{ realm }}" + realm: "{{ realm }}" + state: present + +- name: Keycloak Client + community.general.keycloak_client: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + realm: "{{ realm }}" + client_id: "{{ client_id }}" + state: present + register: client + +- name: Keycloak Client regenerate clientsecret by client_id + community.general.keycloak_clientsecret_regenerate: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + realm: "{{ realm }}" + client_id: "{{ client_id }}" + register: regenerate_by_client_id + +- name: Assert that the client secret was retrieved + assert: + that: + - regenerate_by_client_id.end_state.type == "secret" + - "{{ regenerate_by_client_id.end_state.value | length }} >= 32" + +- name: Keycloak Client regenerate clientsecret by id + community.general.keycloak_clientsecret_regenerate: "{{ auth_args | combine(call_args) }}" + vars: + call_args: + realm: "{{ realm }}" + id: "{{ client.end_state.id }}" + register: regenerate_by_id + +- name: Assert that client secret was regenerated + assert: + that: + - "{{ regenerate_by_id.end_state.value | length }} >= 32" + - regenerate_by_id.end_state.value != regenerate_by_client_id.end_state.value diff --git a/tests/integration/targets/keycloak_clientsecret_regenerate/vars/main.yml b/tests/integration/targets/keycloak_clientsecret_regenerate/vars/main.yml new file mode 100644 index 0000000000..8c913705f7 --- /dev/null +++ b/tests/integration/targets/keycloak_clientsecret_regenerate/vars/main.yml @@ -0,0 +1,20 @@ +--- +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +url: http://localhost:8080/auth +admin_realm: master +admin_user: admin +admin_password: password +realm: myrealm +client_id: myclient +role: myrole +description_1: desc 1 +description_2: desc 2 + +auth_args: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" From df8bfad9b9463997ac9e8e80f61c26ac333c839d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 5 Dec 2022 18:42:37 +0100 Subject: [PATCH 058/134] [PR #5507/b22638ba backport][stable-6] Adding PUT functionality to redfish_utils (Updated) (#5660) Adding PUT functionality to redfish_utils (Updated) (#5507) * adding changelog fragment * adding PUT functionality * sanity fix Co-authored-by: Kushal (cherry picked from commit b22638ba0cea86994006aa399b94fa45a1c2ff0e) Co-authored-by: TSKushal <44438079+TSKushal@users.noreply.github.com> --- .../5490-adding-put-functionality.yml | 2 + plugins/module_utils/redfish_utils.py | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 changelogs/fragments/5490-adding-put-functionality.yml diff --git a/changelogs/fragments/5490-adding-put-functionality.yml b/changelogs/fragments/5490-adding-put-functionality.yml new file mode 100644 index 0000000000..09141d2822 --- /dev/null +++ b/changelogs/fragments/5490-adding-put-functionality.yml @@ -0,0 +1,2 @@ +minor_changes: + - redfish_utils module utils - added PUT (``put_request()``) functionality (https://github.com/ansible-collections/community.general/pull/5490). diff --git a/plugins/module_utils/redfish_utils.py b/plugins/module_utils/redfish_utils.py index a86baa1066..4a56346c3f 100644 --- a/plugins/module_utils/redfish_utils.py +++ b/plugins/module_utils/redfish_utils.py @@ -19,6 +19,8 @@ POST_HEADERS = {'content-type': 'application/json', 'accept': 'application/json' 'OData-Version': '4.0'} PATCH_HEADERS = {'content-type': 'application/json', 'accept': 'application/json', 'OData-Version': '4.0'} +PUT_HEADERS = {'content-type': 'application/json', 'accept': 'application/json', + 'OData-Version': '4.0'} DELETE_HEADERS = {'accept': 'application/json', 'OData-Version': '4.0'} FAIL_MSG = 'Issuing a data modification command without specifying the '\ @@ -224,6 +226,41 @@ class RedfishUtils(object): 'msg': "Failed PATCH request to '%s': '%s'" % (uri, to_text(e))} return {'ret': True, 'changed': True, 'resp': resp, 'msg': 'Modified %s' % uri} + def put_request(self, uri, pyld): + req_headers = dict(PUT_HEADERS) + r = self.get_request(uri) + if r['ret']: + # Get etag from etag header or @odata.etag property + etag = r['headers'].get('etag') + if not etag: + etag = r['data'].get('@odata.etag') + if etag: + if self.strip_etag_quotes: + etag = etag.strip('"') + req_headers['If-Match'] = etag + username, password, basic_auth = self._auth_params(req_headers) + try: + resp = open_url(uri, data=json.dumps(pyld), + headers=req_headers, method="PUT", + url_username=username, url_password=password, + force_basic_auth=basic_auth, validate_certs=False, + follow_redirects='all', + use_proxy=True, timeout=self.timeout) + except HTTPError as e: + msg = self._get_extended_message(e) + return {'ret': False, + 'msg': "HTTP Error %s on PUT request to '%s', extended message: '%s'" + % (e.code, uri, msg), + 'status': e.code} + except URLError as e: + return {'ret': False, 'msg': "URL Error on PUT request to '%s': '%s'" + % (uri, e.reason)} + # Almost all errors should be caught above, but just in case + except Exception as e: + return {'ret': False, + 'msg': "Failed PUT request to '%s': '%s'" % (uri, to_text(e))} + return {'ret': True, 'resp': resp} + def delete_request(self, uri, pyld=None): req_headers = dict(DELETE_HEADERS) username, password, basic_auth = self._auth_params(req_headers) From f3f7b2776fc66db1ada278042ee0dd7f613388ee Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 6 Dec 2022 07:30:35 +0100 Subject: [PATCH 059/134] Release 6.1.0. --- CHANGELOG.rst | 57 +++++++++ changelogs/changelog.yaml | 108 ++++++++++++++++++ ...-operation-apply-time-to-simple-update.yml | 2 - ...pdates-for-full-simple-update-workflow.yml | 4 - .../5490-adding-put-functionality.yml | 2 - .../fragments/5538-cmd-runner-as-fixed.yml | 3 - .../fragments/5545-gconftool-cmd-runner.yml | 2 - .../fragments/5549-lxd-project-sanity.yml | 2 - ...50-java_certs-not-enough-info-on-error.yml | 2 - .../5553-spotinst-aws-elasticgroup-sanity.yml | 2 - .../fragments/5557-udm-share-sanity.yml | 2 - changelogs/fragments/5559-udm-user-sanity.yml | 2 - .../5563-rax-scaling-group-sanity.yml | 2 - .../fragments/5565-jenkins-plugin-sanity.yml | 2 - .../fragments/5566-additional-flags-nmap.yml | 3 - ...-plugin-fix-default-inventory_hostname.yml | 2 - ...hat_subscription-subscribe-parameters.yaml | 3 - ...5601-unixy-callback-use-config-manager.yml | 2 - changelogs/fragments/5602-proxmox-tags.yml | 2 - ...05-ssh-config-add-host-key-algorithms.yaml | 2 - .../fragments/5619-keycloak-improvements.yml | 3 - ...t_subscription-subscribe-parameters-2.yaml | 3 - .../fragments/5628-fix-vmadm-off-by-one.yml | 2 - ...add-prepend-hash-option-for-channel-id.yml | 2 - ...se-yaml-safe-load-instead-of-yaml-load.yml | 2 - .../5640-fix-typo-proxmox-inventory.yml | 2 - .../5647-cmd-runner-as-bool-false.yml | 2 - changelogs/fragments/6.1.0.yml | 1 - changelogs/fragments/sap-removal.yml | 5 - 29 files changed, 165 insertions(+), 63 deletions(-) delete mode 100644 changelogs/fragments/3910-redfish-add-operation-apply-time-to-simple-update.yml delete mode 100644 changelogs/fragments/4276-redfish-command-updates-for-full-simple-update-workflow.yml delete mode 100644 changelogs/fragments/5490-adding-put-functionality.yml delete mode 100644 changelogs/fragments/5538-cmd-runner-as-fixed.yml delete mode 100644 changelogs/fragments/5545-gconftool-cmd-runner.yml delete mode 100644 changelogs/fragments/5549-lxd-project-sanity.yml delete mode 100644 changelogs/fragments/5550-java_certs-not-enough-info-on-error.yml delete mode 100644 changelogs/fragments/5553-spotinst-aws-elasticgroup-sanity.yml delete mode 100644 changelogs/fragments/5557-udm-share-sanity.yml delete mode 100644 changelogs/fragments/5559-udm-user-sanity.yml delete mode 100644 changelogs/fragments/5563-rax-scaling-group-sanity.yml delete mode 100644 changelogs/fragments/5565-jenkins-plugin-sanity.yml delete mode 100644 changelogs/fragments/5566-additional-flags-nmap.yml delete mode 100644 changelogs/fragments/5570-chroot-plugin-fix-default-inventory_hostname.yml delete mode 100644 changelogs/fragments/5583-redhat_subscription-subscribe-parameters.yaml delete mode 100644 changelogs/fragments/5601-unixy-callback-use-config-manager.yml delete mode 100644 changelogs/fragments/5602-proxmox-tags.yml delete mode 100644 changelogs/fragments/5605-ssh-config-add-host-key-algorithms.yaml delete mode 100644 changelogs/fragments/5619-keycloak-improvements.yml delete mode 100644 changelogs/fragments/5627-redhat_subscription-subscribe-parameters-2.yaml delete mode 100644 changelogs/fragments/5628-fix-vmadm-off-by-one.yml delete mode 100644 changelogs/fragments/5629-add-prepend-hash-option-for-channel-id.yml delete mode 100644 changelogs/fragments/5632-vdo-Use-yaml-safe-load-instead-of-yaml-load.yml delete mode 100644 changelogs/fragments/5640-fix-typo-proxmox-inventory.yml delete mode 100644 changelogs/fragments/5647-cmd-runner-as-bool-false.yml delete mode 100644 changelogs/fragments/6.1.0.yml delete mode 100644 changelogs/fragments/sap-removal.yml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 320f2f3745..1a9513cd5a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,63 @@ Community General Release Notes This changelog describes changes after version 5.0.0. +v6.1.0 +====== + +Release Summary +--------------- + +Regular bugfix and feature release. + +Minor Changes +------------- + +- cmd_runner module utils - ``cmd_runner_fmt.as_bool()`` can now take an extra parameter to format when value is false (https://github.com/ansible-collections/community.general/pull/5647). +- gconftool2 - refactor using ``ModuleHelper`` and ``CmdRunner`` (https://github.com/ansible-collections/community.general/pull/5545). +- java_certs - add more detailed error output when extracting certificate from PKCS12 fails (https://github.com/ansible-collections/community.general/pull/5550). +- jenkins_plugin - refactor code to module util to fix sanity check (https://github.com/ansible-collections/community.general/pull/5565). +- lxd_project - refactored code out to module utils to clear sanity check (https://github.com/ansible-collections/community.general/pull/5549). +- nmap inventory plugin - add new options ``udp_scan``, ``icmp_timestamp``, and ``dns_resolve`` for different types of scans (https://github.com/ansible-collections/community.general/pull/5566). +- rax_scaling_group - refactored out code to the ``rax`` module utils to clear the sanity check (https://github.com/ansible-collections/community.general/pull/5563). +- redfish_command - add ``PerformRequestedOperations`` command to perform any operations necessary to continue the update flow (https://github.com/ansible-collections/community.general/issues/4276). +- redfish_command - add ``update_apply_time`` to ``SimpleUpdate`` command (https://github.com/ansible-collections/community.general/issues/3910). +- redfish_command - add ``update_status`` to output of ``SimpleUpdate`` command to allow a user monitor the update in progress (https://github.com/ansible-collections/community.general/issues/4276). +- redfish_info - add ``GetUpdateStatus`` command to check the progress of a previous update request (https://github.com/ansible-collections/community.general/issues/4276). +- redfish_utils module utils - added PUT (``put_request()``) functionality (https://github.com/ansible-collections/community.general/pull/5490). +- slack - add option ``prepend_hash`` which allows to control whether a ``#`` is prepended to ``channel_id``. The current behavior (value ``auto``) is to prepend ``#`` unless some specific prefixes are found. That list of prefixes is incomplete, and there does not seem to exist a documented condition on when exactly ``#`` must not be prepended. We recommend to explicitly set ``prepend_hash=always`` or ``prepend_hash=never`` to avoid any ambiguity (https://github.com/ansible-collections/community.general/pull/5629). +- spotinst_aws_elastigroup - add ``elements`` attribute when missing in ``list`` parameters (https://github.com/ansible-collections/community.general/pull/5553). +- ssh_config - add ``host_key_algorithms`` option (https://github.com/ansible-collections/community.general/pull/5605). +- udm_share - added ``elements`` attribute to ``list`` type parameters (https://github.com/ansible-collections/community.general/pull/5557). +- udm_user - add ``elements`` attribute when missing in ``list`` parameters (https://github.com/ansible-collections/community.general/pull/5559). + +Deprecated Features +------------------- + +- The ``sap`` modules ``sapcar_extract``, ``sap_task_list_execute``, and ``hana_query``, will be removed from this collection in community.general 7.0.0 and replaced with redirects to ``community.sap_libs``. If you want to continue using these modules, make sure to also install ``community.sap_libs`` (it is part of the Ansible package) (https://github.com/ansible-collections/community.general/pull/5614). + +Bugfixes +-------- + +- chroot connection plugin - add ``inventory_hostname`` to vars under ``remote_addr``. This is needed for compatibility with ansible-core 2.13 (https://github.com/ansible-collections/community.general/pull/5570). +- cmd_runner module utils - fixed bug when handling default cases in ``cmd_runner_fmt.as_map()`` (https://github.com/ansible-collections/community.general/pull/5538). +- cmd_runner module utils - formatting arguments ``cmd_runner_fmt.as_fixed()`` was expecting an non-existing argument (https://github.com/ansible-collections/community.general/pull/5538). +- keycloak_client_rolemapping - calculate ``proposed`` and ``after`` return values properly (https://github.com/ansible-collections/community.general/pull/5619). +- keycloak_client_rolemapping - remove only listed mappings with ``state=absent`` (https://github.com/ansible-collections/community.general/pull/5619). +- proxmox inventory plugin - fix bug while templating when using templates for the ``url``, ``user``, ``password``, ``token_id``, or ``token_secret`` options (https://github.com/ansible-collections/community.general/pull/5640). +- proxmox inventory plugin - handle tags delimited by semicolon instead of comma, which happens from Proxmox 7.3 on (https://github.com/ansible-collections/community.general/pull/5602). +- redhat_subscription - do not ignore ``consumer_name`` and other variables if ``activationkey`` is specified (https://github.com/ansible-collections/community.general/issues/3486, https://github.com/ansible-collections/community.general/pull/5627). +- redhat_subscription - do not pass arguments to ``subscription-manager register`` for things already configured; now a specified ``rhsm_baseurl`` is properly set for subscription-manager (https://github.com/ansible-collections/community.general/pull/5583). +- unixy callback plugin - fix plugin to work with ansible-core 2.14 by using Ansible's configuration manager for handling options (https://github.com/ansible-collections/community.general/issues/5600). +- vdo - now uses ``yaml.safe_load()`` to parse command output instead of the deprecated ``yaml.load()`` which is potentially unsafe. Using ``yaml.load()`` without explicitely setting a ``Loader=`` is also an error in pyYAML 6.0 (https://github.com/ansible-collections/community.general/pull/5632). +- vmadm - fix for index out of range error in ``get_vm_uuid`` (https://github.com/ansible-collections/community.general/pull/5628). + +New Modules +----------- + +- gitlab_project_badge - Manage project badges on GitLab Server +- keycloak_clientsecret_info - Retrieve client secret via Keycloak API +- keycloak_clientsecret_regenerate - Regenerate Keycloak client secret via Keycloak API + v6.0.1 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 029f7dc12b..90e6aa2c9a 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -646,3 +646,111 @@ releases: - 5543-dependent-template.yml - 6.0.1.yml release_date: '2022-11-15' + 6.1.0: + changes: + bugfixes: + - chroot connection plugin - add ``inventory_hostname`` to vars under ``remote_addr``. + This is needed for compatibility with ansible-core 2.13 (https://github.com/ansible-collections/community.general/pull/5570). + - cmd_runner module utils - fixed bug when handling default cases in ``cmd_runner_fmt.as_map()`` + (https://github.com/ansible-collections/community.general/pull/5538). + - cmd_runner module utils - formatting arguments ``cmd_runner_fmt.as_fixed()`` + was expecting an non-existing argument (https://github.com/ansible-collections/community.general/pull/5538). + - keycloak_client_rolemapping - calculate ``proposed`` and ``after`` return + values properly (https://github.com/ansible-collections/community.general/pull/5619). + - keycloak_client_rolemapping - remove only listed mappings with ``state=absent`` + (https://github.com/ansible-collections/community.general/pull/5619). + - proxmox inventory plugin - fix bug while templating when using templates for + the ``url``, ``user``, ``password``, ``token_id``, or ``token_secret`` options + (https://github.com/ansible-collections/community.general/pull/5640). + - proxmox inventory plugin - handle tags delimited by semicolon instead of comma, + which happens from Proxmox 7.3 on (https://github.com/ansible-collections/community.general/pull/5602). + - redhat_subscription - do not ignore ``consumer_name`` and other variables + if ``activationkey`` is specified (https://github.com/ansible-collections/community.general/issues/3486, + https://github.com/ansible-collections/community.general/pull/5627). + - redhat_subscription - do not pass arguments to ``subscription-manager register`` + for things already configured; now a specified ``rhsm_baseurl`` is properly + set for subscription-manager (https://github.com/ansible-collections/community.general/pull/5583). + - unixy callback plugin - fix plugin to work with ansible-core 2.14 by using + Ansible's configuration manager for handling options (https://github.com/ansible-collections/community.general/issues/5600). + - vdo - now uses ``yaml.safe_load()`` to parse command output instead of the + deprecated ``yaml.load()`` which is potentially unsafe. Using ``yaml.load()`` + without explicitely setting a ``Loader=`` is also an error in pyYAML 6.0 (https://github.com/ansible-collections/community.general/pull/5632). + - vmadm - fix for index out of range error in ``get_vm_uuid`` (https://github.com/ansible-collections/community.general/pull/5628). + deprecated_features: + - The ``sap`` modules ``sapcar_extract``, ``sap_task_list_execute``, and ``hana_query``, + will be removed from this collection in community.general 7.0.0 and replaced + with redirects to ``community.sap_libs``. If you want to continue using these + modules, make sure to also install ``community.sap_libs`` (it is part of the + Ansible package) (https://github.com/ansible-collections/community.general/pull/5614). + minor_changes: + - cmd_runner module utils - ``cmd_runner_fmt.as_bool()`` can now take an extra + parameter to format when value is false (https://github.com/ansible-collections/community.general/pull/5647). + - gconftool2 - refactor using ``ModuleHelper`` and ``CmdRunner`` (https://github.com/ansible-collections/community.general/pull/5545). + - java_certs - add more detailed error output when extracting certificate from + PKCS12 fails (https://github.com/ansible-collections/community.general/pull/5550). + - jenkins_plugin - refactor code to module util to fix sanity check (https://github.com/ansible-collections/community.general/pull/5565). + - lxd_project - refactored code out to module utils to clear sanity check (https://github.com/ansible-collections/community.general/pull/5549). + - nmap inventory plugin - add new options ``udp_scan``, ``icmp_timestamp``, + and ``dns_resolve`` for different types of scans (https://github.com/ansible-collections/community.general/pull/5566). + - rax_scaling_group - refactored out code to the ``rax`` module utils to clear + the sanity check (https://github.com/ansible-collections/community.general/pull/5563). + - redfish_command - add ``PerformRequestedOperations`` command to perform any + operations necessary to continue the update flow (https://github.com/ansible-collections/community.general/issues/4276). + - redfish_command - add ``update_apply_time`` to ``SimpleUpdate`` command (https://github.com/ansible-collections/community.general/issues/3910). + - redfish_command - add ``update_status`` to output of ``SimpleUpdate`` command + to allow a user monitor the update in progress (https://github.com/ansible-collections/community.general/issues/4276). + - redfish_info - add ``GetUpdateStatus`` command to check the progress of a + previous update request (https://github.com/ansible-collections/community.general/issues/4276). + - redfish_utils module utils - added PUT (``put_request()``) functionality (https://github.com/ansible-collections/community.general/pull/5490). + - slack - add option ``prepend_hash`` which allows to control whether a ``#`` + is prepended to ``channel_id``. The current behavior (value ``auto``) is to + prepend ``#`` unless some specific prefixes are found. That list of prefixes + is incomplete, and there does not seem to exist a documented condition on + when exactly ``#`` must not be prepended. We recommend to explicitly set ``prepend_hash=always`` + or ``prepend_hash=never`` to avoid any ambiguity (https://github.com/ansible-collections/community.general/pull/5629). + - spotinst_aws_elastigroup - add ``elements`` attribute when missing in ``list`` + parameters (https://github.com/ansible-collections/community.general/pull/5553). + - ssh_config - add ``host_key_algorithms`` option (https://github.com/ansible-collections/community.general/pull/5605). + - udm_share - added ``elements`` attribute to ``list`` type parameters (https://github.com/ansible-collections/community.general/pull/5557). + - udm_user - add ``elements`` attribute when missing in ``list`` parameters + (https://github.com/ansible-collections/community.general/pull/5559). + release_summary: Regular bugfix and feature release. + fragments: + - 3910-redfish-add-operation-apply-time-to-simple-update.yml + - 4276-redfish-command-updates-for-full-simple-update-workflow.yml + - 5490-adding-put-functionality.yml + - 5538-cmd-runner-as-fixed.yml + - 5545-gconftool-cmd-runner.yml + - 5549-lxd-project-sanity.yml + - 5550-java_certs-not-enough-info-on-error.yml + - 5553-spotinst-aws-elasticgroup-sanity.yml + - 5557-udm-share-sanity.yml + - 5559-udm-user-sanity.yml + - 5563-rax-scaling-group-sanity.yml + - 5565-jenkins-plugin-sanity.yml + - 5566-additional-flags-nmap.yml + - 5570-chroot-plugin-fix-default-inventory_hostname.yml + - 5583-redhat_subscription-subscribe-parameters.yaml + - 5601-unixy-callback-use-config-manager.yml + - 5602-proxmox-tags.yml + - 5605-ssh-config-add-host-key-algorithms.yaml + - 5619-keycloak-improvements.yml + - 5627-redhat_subscription-subscribe-parameters-2.yaml + - 5628-fix-vmadm-off-by-one.yml + - 5629-add-prepend-hash-option-for-channel-id.yml + - 5632-vdo-Use-yaml-safe-load-instead-of-yaml-load.yml + - 5640-fix-typo-proxmox-inventory.yml + - 5647-cmd-runner-as-bool-false.yml + - 6.1.0.yml + - sap-removal.yml + modules: + - description: Manage project badges on GitLab Server + name: gitlab_project_badge + namespace: '' + - description: Retrieve client secret via Keycloak API + name: keycloak_clientsecret_info + namespace: '' + - description: Regenerate Keycloak client secret via Keycloak API + name: keycloak_clientsecret_regenerate + namespace: '' + release_date: '2022-12-06' diff --git a/changelogs/fragments/3910-redfish-add-operation-apply-time-to-simple-update.yml b/changelogs/fragments/3910-redfish-add-operation-apply-time-to-simple-update.yml deleted file mode 100644 index d52438ca45..0000000000 --- a/changelogs/fragments/3910-redfish-add-operation-apply-time-to-simple-update.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - redfish_command - add ``update_apply_time`` to ``SimpleUpdate`` command (https://github.com/ansible-collections/community.general/issues/3910). diff --git a/changelogs/fragments/4276-redfish-command-updates-for-full-simple-update-workflow.yml b/changelogs/fragments/4276-redfish-command-updates-for-full-simple-update-workflow.yml deleted file mode 100644 index 2f5da1467b..0000000000 --- a/changelogs/fragments/4276-redfish-command-updates-for-full-simple-update-workflow.yml +++ /dev/null @@ -1,4 +0,0 @@ -minor_changes: - - redfish_command - add ``update_status`` to output of ``SimpleUpdate`` command to allow a user monitor the update in progress (https://github.com/ansible-collections/community.general/issues/4276). - - redfish_info - add ``GetUpdateStatus`` command to check the progress of a previous update request (https://github.com/ansible-collections/community.general/issues/4276). - - redfish_command - add ``PerformRequestedOperations`` command to perform any operations necessary to continue the update flow (https://github.com/ansible-collections/community.general/issues/4276). diff --git a/changelogs/fragments/5490-adding-put-functionality.yml b/changelogs/fragments/5490-adding-put-functionality.yml deleted file mode 100644 index 09141d2822..0000000000 --- a/changelogs/fragments/5490-adding-put-functionality.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - redfish_utils module utils - added PUT (``put_request()``) functionality (https://github.com/ansible-collections/community.general/pull/5490). diff --git a/changelogs/fragments/5538-cmd-runner-as-fixed.yml b/changelogs/fragments/5538-cmd-runner-as-fixed.yml deleted file mode 100644 index 714564b09f..0000000000 --- a/changelogs/fragments/5538-cmd-runner-as-fixed.yml +++ /dev/null @@ -1,3 +0,0 @@ -bugfixes: - - cmd_runner module utils - formatting arguments ``cmd_runner_fmt.as_fixed()`` was expecting an non-existing argument (https://github.com/ansible-collections/community.general/pull/5538). - - cmd_runner module utils - fixed bug when handling default cases in ``cmd_runner_fmt.as_map()`` (https://github.com/ansible-collections/community.general/pull/5538). diff --git a/changelogs/fragments/5545-gconftool-cmd-runner.yml b/changelogs/fragments/5545-gconftool-cmd-runner.yml deleted file mode 100644 index a41d5c3657..0000000000 --- a/changelogs/fragments/5545-gconftool-cmd-runner.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - gconftool2 - refactor using ``ModuleHelper`` and ``CmdRunner`` (https://github.com/ansible-collections/community.general/pull/5545). diff --git a/changelogs/fragments/5549-lxd-project-sanity.yml b/changelogs/fragments/5549-lxd-project-sanity.yml deleted file mode 100644 index 0a5e328e1c..0000000000 --- a/changelogs/fragments/5549-lxd-project-sanity.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - lxd_project - refactored code out to module utils to clear sanity check (https://github.com/ansible-collections/community.general/pull/5549). diff --git a/changelogs/fragments/5550-java_certs-not-enough-info-on-error.yml b/changelogs/fragments/5550-java_certs-not-enough-info-on-error.yml deleted file mode 100644 index c2b2be0418..0000000000 --- a/changelogs/fragments/5550-java_certs-not-enough-info-on-error.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - java_certs - add more detailed error output when extracting certificate from PKCS12 fails (https://github.com/ansible-collections/community.general/pull/5550). diff --git a/changelogs/fragments/5553-spotinst-aws-elasticgroup-sanity.yml b/changelogs/fragments/5553-spotinst-aws-elasticgroup-sanity.yml deleted file mode 100644 index 1213f5412a..0000000000 --- a/changelogs/fragments/5553-spotinst-aws-elasticgroup-sanity.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - spotinst_aws_elastigroup - add ``elements`` attribute when missing in ``list`` parameters (https://github.com/ansible-collections/community.general/pull/5553). diff --git a/changelogs/fragments/5557-udm-share-sanity.yml b/changelogs/fragments/5557-udm-share-sanity.yml deleted file mode 100644 index 12bd3d026e..0000000000 --- a/changelogs/fragments/5557-udm-share-sanity.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - udm_share - added ``elements`` attribute to ``list`` type parameters (https://github.com/ansible-collections/community.general/pull/5557). diff --git a/changelogs/fragments/5559-udm-user-sanity.yml b/changelogs/fragments/5559-udm-user-sanity.yml deleted file mode 100644 index 1501591f81..0000000000 --- a/changelogs/fragments/5559-udm-user-sanity.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - udm_user - add ``elements`` attribute when missing in ``list`` parameters (https://github.com/ansible-collections/community.general/pull/5559). diff --git a/changelogs/fragments/5563-rax-scaling-group-sanity.yml b/changelogs/fragments/5563-rax-scaling-group-sanity.yml deleted file mode 100644 index 310257f293..0000000000 --- a/changelogs/fragments/5563-rax-scaling-group-sanity.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - rax_scaling_group - refactored out code to the ``rax`` module utils to clear the sanity check (https://github.com/ansible-collections/community.general/pull/5563). diff --git a/changelogs/fragments/5565-jenkins-plugin-sanity.yml b/changelogs/fragments/5565-jenkins-plugin-sanity.yml deleted file mode 100644 index ea72d90615..0000000000 --- a/changelogs/fragments/5565-jenkins-plugin-sanity.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - jenkins_plugin - refactor code to module util to fix sanity check (https://github.com/ansible-collections/community.general/pull/5565). diff --git a/changelogs/fragments/5566-additional-flags-nmap.yml b/changelogs/fragments/5566-additional-flags-nmap.yml deleted file mode 100644 index d42f3a4695..0000000000 --- a/changelogs/fragments/5566-additional-flags-nmap.yml +++ /dev/null @@ -1,3 +0,0 @@ -minor_changes: - - nmap inventory plugin - add new options ``udp_scan``, ``icmp_timestamp``, and ``dns_resolve`` for different types of scans (https://github.com/ansible-collections/community.general/pull/5566). - diff --git a/changelogs/fragments/5570-chroot-plugin-fix-default-inventory_hostname.yml b/changelogs/fragments/5570-chroot-plugin-fix-default-inventory_hostname.yml deleted file mode 100644 index fc0c074f84..0000000000 --- a/changelogs/fragments/5570-chroot-plugin-fix-default-inventory_hostname.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - "chroot connection plugin - add ``inventory_hostname`` to vars under ``remote_addr``. This is needed for compatibility with ansible-core 2.13 (https://github.com/ansible-collections/community.general/pull/5570)." \ No newline at end of file diff --git a/changelogs/fragments/5583-redhat_subscription-subscribe-parameters.yaml b/changelogs/fragments/5583-redhat_subscription-subscribe-parameters.yaml deleted file mode 100644 index bef3676c3b..0000000000 --- a/changelogs/fragments/5583-redhat_subscription-subscribe-parameters.yaml +++ /dev/null @@ -1,3 +0,0 @@ -bugfixes: - - redhat_subscription - do not pass arguments to ``subscription-manager register`` for things already configured; now a specified ``rhsm_baseurl`` is properly set for subscription-manager - (https://github.com/ansible-collections/community.general/pull/5583). diff --git a/changelogs/fragments/5601-unixy-callback-use-config-manager.yml b/changelogs/fragments/5601-unixy-callback-use-config-manager.yml deleted file mode 100644 index f3d0362f8f..0000000000 --- a/changelogs/fragments/5601-unixy-callback-use-config-manager.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - unixy callback plugin - fix plugin to work with ansible-core 2.14 by using Ansible's configuration manager for handling options (https://github.com/ansible-collections/community.general/issues/5600). diff --git a/changelogs/fragments/5602-proxmox-tags.yml b/changelogs/fragments/5602-proxmox-tags.yml deleted file mode 100644 index 32498f0366..0000000000 --- a/changelogs/fragments/5602-proxmox-tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - "proxmox inventory plugin - handle tags delimited by semicolon instead of comma, which happens from Proxmox 7.3 on (https://github.com/ansible-collections/community.general/pull/5602)." diff --git a/changelogs/fragments/5605-ssh-config-add-host-key-algorithms.yaml b/changelogs/fragments/5605-ssh-config-add-host-key-algorithms.yaml deleted file mode 100644 index 1535d9b13d..0000000000 --- a/changelogs/fragments/5605-ssh-config-add-host-key-algorithms.yaml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - ssh_config - add ``host_key_algorithms`` option (https://github.com/ansible-collections/community.general/pull/5605). diff --git a/changelogs/fragments/5619-keycloak-improvements.yml b/changelogs/fragments/5619-keycloak-improvements.yml deleted file mode 100644 index 2e5a739dad..0000000000 --- a/changelogs/fragments/5619-keycloak-improvements.yml +++ /dev/null @@ -1,3 +0,0 @@ -bugfixes: - - "keycloak_client_rolemapping - remove only listed mappings with ``state=absent`` (https://github.com/ansible-collections/community.general/pull/5619)." - - "keycloak_client_rolemapping - calculate ``proposed`` and ``after`` return values properly (https://github.com/ansible-collections/community.general/pull/5619)." diff --git a/changelogs/fragments/5627-redhat_subscription-subscribe-parameters-2.yaml b/changelogs/fragments/5627-redhat_subscription-subscribe-parameters-2.yaml deleted file mode 100644 index c76f6871d8..0000000000 --- a/changelogs/fragments/5627-redhat_subscription-subscribe-parameters-2.yaml +++ /dev/null @@ -1,3 +0,0 @@ -bugfixes: - - redhat_subscription - do not ignore ``consumer_name`` and other variables if ``activationkey`` is specified - (https://github.com/ansible-collections/community.general/issues/3486, https://github.com/ansible-collections/community.general/pull/5627). diff --git a/changelogs/fragments/5628-fix-vmadm-off-by-one.yml b/changelogs/fragments/5628-fix-vmadm-off-by-one.yml deleted file mode 100644 index bcb7bf63e6..0000000000 --- a/changelogs/fragments/5628-fix-vmadm-off-by-one.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - vmadm - fix for index out of range error in ``get_vm_uuid`` (https://github.com/ansible-collections/community.general/pull/5628). diff --git a/changelogs/fragments/5629-add-prepend-hash-option-for-channel-id.yml b/changelogs/fragments/5629-add-prepend-hash-option-for-channel-id.yml deleted file mode 100644 index f38a6b4e13..0000000000 --- a/changelogs/fragments/5629-add-prepend-hash-option-for-channel-id.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - "slack - add option ``prepend_hash`` which allows to control whether a ``#`` is prepended to ``channel_id``. The current behavior (value ``auto``) is to prepend ``#`` unless some specific prefixes are found. That list of prefixes is incomplete, and there does not seem to exist a documented condition on when exactly ``#`` must not be prepended. We recommend to explicitly set ``prepend_hash=always`` or ``prepend_hash=never`` to avoid any ambiguity (https://github.com/ansible-collections/community.general/pull/5629)." \ No newline at end of file diff --git a/changelogs/fragments/5632-vdo-Use-yaml-safe-load-instead-of-yaml-load.yml b/changelogs/fragments/5632-vdo-Use-yaml-safe-load-instead-of-yaml-load.yml deleted file mode 100644 index c2b0756eca..0000000000 --- a/changelogs/fragments/5632-vdo-Use-yaml-safe-load-instead-of-yaml-load.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - vdo - now uses ``yaml.safe_load()`` to parse command output instead of the deprecated ``yaml.load()`` which is potentially unsafe. Using ``yaml.load()`` without explicitely setting a ``Loader=`` is also an error in pyYAML 6.0 (https://github.com/ansible-collections/community.general/pull/5632). diff --git a/changelogs/fragments/5640-fix-typo-proxmox-inventory.yml b/changelogs/fragments/5640-fix-typo-proxmox-inventory.yml deleted file mode 100644 index d5b8de5aea..0000000000 --- a/changelogs/fragments/5640-fix-typo-proxmox-inventory.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - "proxmox inventory plugin - fix bug while templating when using templates for the ``url``, ``user``, ``password``, ``token_id``, or ``token_secret`` options (https://github.com/ansible-collections/community.general/pull/5640)." diff --git a/changelogs/fragments/5647-cmd-runner-as-bool-false.yml b/changelogs/fragments/5647-cmd-runner-as-bool-false.yml deleted file mode 100644 index 5dc447d235..0000000000 --- a/changelogs/fragments/5647-cmd-runner-as-bool-false.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - cmd_runner module utils - ``cmd_runner_fmt.as_bool()`` can now take an extra parameter to format when value is false (https://github.com/ansible-collections/community.general/pull/5647). diff --git a/changelogs/fragments/6.1.0.yml b/changelogs/fragments/6.1.0.yml deleted file mode 100644 index 4b1469c9fe..0000000000 --- a/changelogs/fragments/6.1.0.yml +++ /dev/null @@ -1 +0,0 @@ -release_summary: Regular bugfix and feature release. diff --git a/changelogs/fragments/sap-removal.yml b/changelogs/fragments/sap-removal.yml deleted file mode 100644 index 603e0fb856..0000000000 --- a/changelogs/fragments/sap-removal.yml +++ /dev/null @@ -1,5 +0,0 @@ -deprecated_features: - - "The ``sap`` modules ``sapcar_extract``, ``sap_task_list_execute``, and ``hana_query``, will be removed - from this collection in community.general 7.0.0 and replaced with redirects to ``community.sap_libs``. - If you want to continue using these modules, make sure to also install ``community.sap_libs`` (it is - part of the Ansible package) (https://github.com/ansible-collections/community.general/pull/5614)." From 377b5d4ccd0bc2ee5ef880e273d5c728b588c78a Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 6 Dec 2022 08:02:06 +0100 Subject: [PATCH 060/134] Next expected release is 6.2.0. --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 1c300da904..f55ebce545 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -5,7 +5,7 @@ namespace: community name: general -version: 6.1.0 +version: 6.2.0 readme: README.md authors: - Ansible (https://github.com/ansible) From c1d6e5c3c2aa09a8ac7d3c8cee8f96443c6653f1 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 8 Dec 2022 22:25:12 +0100 Subject: [PATCH 061/134] [PR #5668/50021d6b backport][stable-6] Fix pipx_info tests (#5670) Fix pipx_info tests (#5668) Update dependencies. (cherry picked from commit 50021d6bfb58b1551cb9ca0bf09a865bd49f895e) Co-authored-by: Felix Fontein --- tests/integration/targets/pipx_info/tasks/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/integration/targets/pipx_info/tasks/main.yml b/tests/integration/targets/pipx_info/tasks/main.yml index 61163afd08..0a01f0af9c 100644 --- a/tests/integration/targets/pipx_info/tasks/main.yml +++ b/tests/integration/targets/pipx_info/tasks/main.yml @@ -56,7 +56,8 @@ - info_all_deps.application|length == 1 - info_all_deps.application[0].name == "tox" - "'version' in info_all_deps.application[0]" - - info_all_deps.application[0].dependencies == ["virtualenv"] + - info_all_deps.application[0].dependencies == ["chardet", "virtualenv"] + or info_all_deps.application[0].dependencies == ["virtualenv"] - "'injected' not in info_all.application[0]" - info_tox.application == info_all_deps.application From ff21afb2279cde5d82c62881ed2f4419ca42f870 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 8 Dec 2022 22:54:18 +0100 Subject: [PATCH 062/134] [PR #5662/471f523f backport][stable-6] redhat_subscription: add `server_proxy_scheme` parameter (#5671) redhat_subscription: add `server_proxy_scheme` parameter (#5662) Add the `server_proxy_scheme` parameter to configure the scheme used for the proxy server. This completes the configuration parameters for the proxy server. (cherry picked from commit 471f523f53220bfbb3e6585b767c7483790c025d) Co-authored-by: Pino Toscano --- .../5662-redhat_subscription-server_proxy_scheme.yaml | 3 +++ plugins/modules/redhat_subscription.py | 6 ++++++ tests/unit/plugins/modules/test_redhat_subscription.py | 2 ++ 3 files changed, 11 insertions(+) create mode 100644 changelogs/fragments/5662-redhat_subscription-server_proxy_scheme.yaml diff --git a/changelogs/fragments/5662-redhat_subscription-server_proxy_scheme.yaml b/changelogs/fragments/5662-redhat_subscription-server_proxy_scheme.yaml new file mode 100644 index 0000000000..293e18311a --- /dev/null +++ b/changelogs/fragments/5662-redhat_subscription-server_proxy_scheme.yaml @@ -0,0 +1,3 @@ +minor_changes: + - redhat_subscription - add a ``server_proxy_scheme`` parameter to configure the scheme for the proxy server + (https://github.com/ansible-collections/community.general/pull/5662). diff --git a/plugins/modules/redhat_subscription.py b/plugins/modules/redhat_subscription.py index 041c1a0097..8836b78564 100644 --- a/plugins/modules/redhat_subscription.py +++ b/plugins/modules/redhat_subscription.py @@ -70,6 +70,11 @@ options: description: - Specify an HTTP proxy hostname. type: str + server_proxy_scheme: + description: + - Specify an HTTP proxy scheme, for example C(http) or C(https). + type: str + version_added: 6.2.0 server_proxy_port: description: - Specify an HTTP proxy port. @@ -806,6 +811,7 @@ def main(): 'consumer_id': {}, 'force_register': {'default': False, 'type': 'bool'}, 'server_proxy_hostname': {}, + 'server_proxy_scheme': {}, 'server_proxy_port': {}, 'server_proxy_user': {}, 'server_proxy_password': {'no_log': True}, diff --git a/tests/unit/plugins/modules/test_redhat_subscription.py b/tests/unit/plugins/modules/test_redhat_subscription.py index f38f1ffe0d..865f041141 100644 --- a/tests/unit/plugins/modules/test_redhat_subscription.py +++ b/tests/unit/plugins/modules/test_redhat_subscription.py @@ -308,6 +308,7 @@ TEST_CASES = [ 'org_id': 'admin', 'force_register': 'true', 'server_proxy_hostname': 'proxy.company.com', + 'server_proxy_scheme': 'https', 'server_proxy_port': '12345', 'server_proxy_user': 'proxy_user', 'server_proxy_password': 'secret_proxy_password' @@ -327,6 +328,7 @@ TEST_CASES = [ '--server.proxy_hostname=proxy.company.com', '--server.proxy_password=secret_proxy_password', '--server.proxy_port=12345', + '--server.proxy_scheme=https', '--server.proxy_user=proxy_user' ], {'check_rc': True}, From c17f5ff3e85d38de11403770f993de0fbcbd311b Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 9 Dec 2022 15:52:27 +0000 Subject: [PATCH 063/134] [PR #5674/b5e58a3b backport][stable-6] CI: Bump CentOS Stream 8 Python from 3.8 to 3.9 (#5677) CI: Bump CentOS Stream 8 Python from 3.8 to 3.9 (#5674) Bump CentOS Stream 8 Python from 3.8 to 3.9. (cherry picked from commit b5e58a3bccd38791e1c8871bf471941c1d1c762f) Co-authored-by: Felix Fontein --- .azure-pipelines/azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index c39a855dd0..a5dcafa422 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -386,7 +386,7 @@ stages: - name: ArchLinux test: archlinux/3.10 - name: CentOS Stream 8 - test: centos-stream8/3.8 + test: centos-stream8/3.9 groups: - 1 - 2 From 6f845f61f03cb5b7924251f6fba05932053d78b1 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 10 Dec 2022 22:42:19 +0100 Subject: [PATCH 064/134] [PR #5667/c3bc172b backport][stable-6] respect new variable property in gitlab_group_variable and gitlab_project_variable (#5679) respect new variable property in gitlab_group_variable and gitlab_project_variable (#5667) * draft * add changelog fragment * rework * rework group variables * add new line at end of file * Update plugins/module_utils/gitlab.py Co-authored-by: Nejc Habjan * rename * revert * return a copy * Update plugins/modules/gitlab_project_variable.py Co-authored-by: Felix Fontein Co-authored-by: Nejc Habjan Co-authored-by: Felix Fontein (cherry picked from commit c3bc172bf6fccdca9c16155da058ce95a57e6076) Co-authored-by: Markus Bergholz --- .../fragments/5666-gitlab-variables.yml | 3 +++ plugins/module_utils/gitlab.py | 11 +++++++++ plugins/modules/gitlab_group_variable.py | 12 +++------- plugins/modules/gitlab_project_variable.py | 23 ++++++++----------- 4 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 changelogs/fragments/5666-gitlab-variables.yml diff --git a/changelogs/fragments/5666-gitlab-variables.yml b/changelogs/fragments/5666-gitlab-variables.yml new file mode 100644 index 0000000000..2070fa8e4a --- /dev/null +++ b/changelogs/fragments/5666-gitlab-variables.yml @@ -0,0 +1,3 @@ +bugfixes: + - gitlab_group_variables - fix dropping variables accidentally when GitLab introduced new properties (https://github.com/ansible-collections/community.general/pull/5667). + - gitlab_project_variables - fix dropping variables accidentally when GitLab introduced new properties (https://github.com/ansible-collections/community.general/pull/5667). \ No newline at end of file diff --git a/plugins/module_utils/gitlab.py b/plugins/module_utils/gitlab.py index 3ed338b401..7cb59e4c2c 100644 --- a/plugins/module_utils/gitlab.py +++ b/plugins/module_utils/gitlab.py @@ -110,3 +110,14 @@ def gitlab_authentication(module): GitLab remove Session API now that private tokens are removed from user API endpoints since version 10.2." % to_native(e)) return gitlab_instance + + +def filter_returned_variables(gitlab_variables): + # pop properties we don't know + existing_variables = [dict(x.attributes) for x in gitlab_variables] + KNOWN = ['key', 'value', 'masked', 'protected', 'variable_type', 'environment_scope'] + for item in existing_variables: + for key in list(item.keys()): + if key not in KNOWN: + item.pop(key) + return existing_variables diff --git a/plugins/modules/gitlab_group_variable.py b/plugins/modules/gitlab_group_variable.py index c273777ca3..4a185b2394 100644 --- a/plugins/modules/gitlab_group_variable.py +++ b/plugins/modules/gitlab_group_variable.py @@ -165,7 +165,7 @@ from ansible.module_utils.six import string_types from ansible.module_utils.six import integer_types from ansible_collections.community.general.plugins.module_utils.gitlab import ( - auth_argument_spec, gitlab_authentication, ensure_gitlab_package + auth_argument_spec, gitlab_authentication, ensure_gitlab_package, filter_returned_variables ) @@ -296,11 +296,7 @@ def native_python_main(this_gitlab, purge, requested_variables, state, module): before = [x.attributes for x in gitlab_keys] gitlab_keys = this_gitlab.list_all_group_variables() - existing_variables = [x.attributes for x in gitlab_keys] - - # preprocessing:filter out and enrich before compare - for item in existing_variables: - item.pop('group_id') + existing_variables = filter_returned_variables(gitlab_keys) for item in requested_variables: item['key'] = item.pop('name') @@ -331,9 +327,7 @@ def native_python_main(this_gitlab, purge, requested_variables, state, module): if purge: # refetch and filter gitlab_keys = this_gitlab.list_all_group_variables() - existing_variables = [x.attributes for x in gitlab_keys] - for item in existing_variables: - item.pop('group_id') + existing_variables = filter_returned_variables(gitlab_keys) remove = [x for x in existing_variables if x not in requested_variables] for item in remove: diff --git a/plugins/modules/gitlab_project_variable.py b/plugins/modules/gitlab_project_variable.py index cdd6402ae8..986847c07b 100644 --- a/plugins/modules/gitlab_project_variable.py +++ b/plugins/modules/gitlab_project_variable.py @@ -189,7 +189,7 @@ except Exception: HAS_GITLAB_PACKAGE = False from ansible_collections.community.general.plugins.module_utils.gitlab import ( - auth_argument_spec, gitlab_authentication, ensure_gitlab_package + auth_argument_spec, gitlab_authentication, ensure_gitlab_package, filter_returned_variables ) @@ -255,9 +255,11 @@ class GitlabProjectVariables(object): return True var = { - "key": var_obj.get('key'), "value": var_obj.get('value'), - "masked": var_obj.get('masked'), "protected": var_obj.get('protected'), - "variable_type": var_obj.get('variable_type') + "key": var_obj.get('key'), + "value": var_obj.get('value'), + "masked": var_obj.get('masked'), + "protected": var_obj.get('protected'), + "variable_type": var_obj.get('variable_type'), } if var_obj.get('environment_scope') is not None: @@ -319,12 +321,9 @@ def native_python_main(this_gitlab, purge, requested_variables, state, module): before = [x.attributes for x in gitlab_keys] gitlab_keys = this_gitlab.list_all_project_variables() - existing_variables = [x.attributes for x in gitlab_keys] - - # preprocessing:filter out and enrich before compare - for item in existing_variables: - item.pop('project_id') + existing_variables = filter_returned_variables(gitlab_keys) + # filter out and enrich before compare for item in requested_variables: item['key'] = item.pop('name') item['value'] = str(item.get('value')) @@ -354,9 +353,7 @@ def native_python_main(this_gitlab, purge, requested_variables, state, module): if purge: # refetch and filter gitlab_keys = this_gitlab.list_all_project_variables() - existing_variables = [x.attributes for x in gitlab_keys] - for item in existing_variables: - item.pop('project_id') + existing_variables = filter_returned_variables(gitlab_keys) remove = [x for x in existing_variables if x not in requested_variables] for item in remove: @@ -409,7 +406,7 @@ def main(): masked=dict(type='bool', default=False), protected=dict(type='bool', default=False), environment_scope=dict(type='str', default='*'), - variable_type=dict(type='str', default='env_var', choices=["env_var", "file"]) + variable_type=dict(type='str', default='env_var', choices=["env_var", "file"]), )), state=dict(type='str', default="present", choices=["absent", "present"]), ) From 1489c080a77b71db1586ae646ef469b706049671 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 14 Dec 2022 22:03:40 +0100 Subject: [PATCH 065/134] [PR #5612/f95e0d77 backport][stable-6] puppet: refactored to use CmdRunner (#5686) puppet: refactored to use CmdRunner (#5612) * puppet: refactored to use CmdRunner * add changelog fragment * add more tests (cherry picked from commit f95e0d775d301ab36d22526d5f2c25b7598084a4) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .github/BOTMETA.yml | 3 + .../fragments/5612-puppet-cmd-runner.yml | 2 + plugins/module_utils/puppet.py | 114 ++++++++++++++ plugins/modules/puppet.py | 108 ++----------- tests/sanity/ignore-2.11.txt | 3 +- tests/sanity/ignore-2.12.txt | 3 +- tests/sanity/ignore-2.13.txt | 3 +- tests/sanity/ignore-2.14.txt | 3 +- tests/sanity/ignore-2.15.txt | 3 +- tests/unit/plugins/modules/test_puppet.py | 145 ++++++++++++++++++ 10 files changed, 282 insertions(+), 105 deletions(-) create mode 100644 changelogs/fragments/5612-puppet-cmd-runner.yml create mode 100644 plugins/module_utils/puppet.py create mode 100644 tests/unit/plugins/modules/test_puppet.py diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 89751fc622..015f2aa37d 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -309,6 +309,9 @@ files: $module_utils/pipx.py: labels: pipx maintainers: russoz + $module_utils/puppet.py: + labels: puppet + maintainers: russoz $module_utils/pure.py: labels: pure pure_storage maintainers: $team_purestorage diff --git a/changelogs/fragments/5612-puppet-cmd-runner.yml b/changelogs/fragments/5612-puppet-cmd-runner.yml new file mode 100644 index 0000000000..a2d14bf5fc --- /dev/null +++ b/changelogs/fragments/5612-puppet-cmd-runner.yml @@ -0,0 +1,2 @@ +minor_changes: + - puppet - refactored module to use ``CmdRunner`` for executing ``puppet`` (https://github.com/ansible-collections/community.general/pull/5612). diff --git a/plugins/module_utils/puppet.py b/plugins/module_utils/puppet.py new file mode 100644 index 0000000000..06369882fb --- /dev/null +++ b/plugins/module_utils/puppet.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2022, Alexei Znamensky +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +import os + +from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt + + +_PUPPET_PATH_PREFIX = ["/opt/puppetlabs/bin"] + + +def get_facter_dir(): + if os.getuid() == 0: + return '/etc/facter/facts.d' + else: + return os.path.expanduser('~/.facter/facts.d') + + +def _puppet_cmd(module): + return module.get_bin_path("puppet", False, _PUPPET_PATH_PREFIX) + + +# If the `timeout` CLI command feature is removed, +# Then we could add this as a fixed param to `puppet_runner` +def ensure_agent_enabled(module): + runner = CmdRunner( + module, + command="puppet", + path_prefix=_PUPPET_PATH_PREFIX, + arg_formats=dict( + _agent_disabled=cmd_runner_fmt.as_fixed(['config', 'print', 'agent_disabled_lockfile']), + ), + check_rc=False, + ) + + rc, stdout, stderr = runner("_agent_disabled").run() + if os.path.exists(stdout.strip()): + module.fail_json( + msg="Puppet agent is administratively disabled.", + disabled=True) + elif rc != 0: + module.fail_json( + msg="Puppet agent state could not be determined.") + + +def puppet_runner(module): + + # Keeping backward compatibility, allow for running with the `timeout` CLI command. + # If this can be replaced with ansible `timeout` parameter in playbook, + # then this function could be removed. + def _prepare_base_cmd(): + _tout_cmd = module.get_bin_path("timeout", False) + if _tout_cmd: + cmd = ["timeout", "-s", "9", module.params["timeout"], _puppet_cmd(module)] + else: + cmd = ["puppet"] + return cmd + + def noop_func(v): + _noop = cmd_runner_fmt.as_map({ + True: "--noop", + False: "--no-noop", + }) + return _noop(module.check_mode or v) + + _logdest_map = { + "syslog": ["--logdest", "syslog"], + "all": ["--logdest", "syslog", "--logdest", "console"], + } + + @cmd_runner_fmt.unpack_args + def execute_func(execute, manifest): + if execute: + return ["--execute", execute] + else: + return [manifest] + + runner = CmdRunner( + module, + command=_prepare_base_cmd(), + path_prefix=_PUPPET_PATH_PREFIX, + arg_formats=dict( + _agent_fixed=cmd_runner_fmt.as_fixed([ + "agent", "--onetime", "--no-daemonize", "--no-usecacheonfailure", + "--no-splay", "--detailed-exitcodes", "--verbose", "--color", "0", + ]), + _apply_fixed=cmd_runner_fmt.as_fixed(["apply", "--detailed-exitcodes"]), + puppetmaster=cmd_runner_fmt.as_opt_val("--server"), + show_diff=cmd_runner_fmt.as_bool("--show-diff"), + confdir=cmd_runner_fmt.as_opt_val("--confdir"), + environment=cmd_runner_fmt.as_opt_val("--environment"), + tags=cmd_runner_fmt.as_func(lambda v: ["--tags", ",".join(v)]), + certname=cmd_runner_fmt.as_opt_eq_val("--certname"), + noop=cmd_runner_fmt.as_func(noop_func), + use_srv_records=cmd_runner_fmt.as_map({ + True: "--usr_srv_records", + False: "--no-usr_srv_records", + }), + logdest=cmd_runner_fmt.as_map(_logdest_map, default=[]), + modulepath=cmd_runner_fmt.as_opt_eq_val("--modulepath"), + _execute=cmd_runner_fmt.as_func(execute_func), + summarize=cmd_runner_fmt.as_bool("--summarize"), + debug=cmd_runner_fmt.as_bool("--debug"), + verbose=cmd_runner_fmt.as_bool("--verbose"), + ), + check_rc=False, + ) + return runner diff --git a/plugins/modules/puppet.py b/plugins/modules/puppet.py index c787a7f00c..8454bb60fd 100644 --- a/plugins/modules/puppet.py +++ b/plugins/modules/puppet.py @@ -152,15 +152,9 @@ import json import os import stat +import ansible_collections.community.general.plugins.module_utils.puppet as puppet_utils + from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.six.moves import shlex_quote - - -def _get_facter_dir(): - if os.getuid() == 0: - return '/etc/facter/facts.d' - else: - return os.path.expanduser('~/.facter/facts.d') def _write_structured_data(basedir, basename, data): @@ -212,16 +206,6 @@ def main(): ) p = module.params - global PUPPET_CMD - PUPPET_CMD = module.get_bin_path("puppet", False, ['/opt/puppetlabs/bin']) - - if not PUPPET_CMD: - module.fail_json( - msg="Could not find puppet. Please ensure it is installed.") - - global TIMEOUT_CMD - TIMEOUT_CMD = module.get_bin_path("timeout", False) - if p['manifest']: if not os.path.exists(p['manifest']): module.fail_json( @@ -230,90 +214,24 @@ def main(): # Check if puppet is disabled here if not p['manifest']: - rc, stdout, stderr = module.run_command( - PUPPET_CMD + " config print agent_disabled_lockfile") - if os.path.exists(stdout.strip()): - module.fail_json( - msg="Puppet agent is administratively disabled.", - disabled=True) - elif rc != 0: - module.fail_json( - msg="Puppet agent state could not be determined.") + puppet_utils.ensure_agent_enabled(module) if module.params['facts'] and not module.check_mode: _write_structured_data( - _get_facter_dir(), + puppet_utils.get_facter_dir(), module.params['facter_basename'], module.params['facts']) - if TIMEOUT_CMD: - base_cmd = "%(timeout_cmd)s -s 9 %(timeout)s %(puppet_cmd)s" % dict( - timeout_cmd=TIMEOUT_CMD, - timeout=shlex_quote(p['timeout']), - puppet_cmd=PUPPET_CMD) - else: - base_cmd = PUPPET_CMD + runner = puppet_utils.puppet_runner(module) if not p['manifest'] and not p['execute']: - cmd = ("%(base_cmd)s agent --onetime" - " --no-daemonize --no-usecacheonfailure --no-splay" - " --detailed-exitcodes --verbose --color 0") % dict(base_cmd=base_cmd) - if p['puppetmaster']: - cmd += " --server %s" % shlex_quote(p['puppetmaster']) - if p['show_diff']: - cmd += " --show_diff" - if p['confdir']: - cmd += " --confdir %s" % shlex_quote(p['confdir']) - if p['environment']: - cmd += " --environment '%s'" % p['environment'] - if p['tags']: - cmd += " --tags '%s'" % ','.join(p['tags']) - if p['certname']: - cmd += " --certname='%s'" % p['certname'] - if module.check_mode: - cmd += " --noop" - elif 'noop' in p: - if p['noop']: - cmd += " --noop" - else: - cmd += " --no-noop" - if p['use_srv_records'] is not None: - if not p['use_srv_records']: - cmd += " --no-use_srv_records" - else: - cmd += " --use_srv_records" + args_order = "_agent_fixed puppetmaster show_diff confdir environment tags certname noop use_srv_records" + with runner(args_order) as ctx: + rc, stdout, stderr = ctx.run() else: - cmd = "%s apply --detailed-exitcodes " % base_cmd - if p['logdest'] == 'syslog': - cmd += "--logdest syslog " - if p['logdest'] == 'all': - cmd += " --logdest syslog --logdest console" - if p['modulepath']: - cmd += "--modulepath='%s'" % p['modulepath'] - if p['environment']: - cmd += "--environment '%s' " % p['environment'] - if p['certname']: - cmd += " --certname='%s'" % p['certname'] - if p['tags']: - cmd += " --tags '%s'" % ','.join(p['tags']) - if module.check_mode: - cmd += "--noop " - elif 'noop' in p: - if p['noop']: - cmd += " --noop" - else: - cmd += " --no-noop" - if p['execute']: - cmd += " --execute '%s'" % p['execute'] - else: - cmd += " %s" % shlex_quote(p['manifest']) - if p['summarize']: - cmd += " --summarize" - if p['debug']: - cmd += " --debug" - if p['verbose']: - cmd += " --verbose" - rc, stdout, stderr = module.run_command(cmd) + args_order = "_apply_fixed logdest modulepath environment certname tags noop _execute summarize debug verbose" + with runner(args_order) as ctx: + rc, stdout, stderr = ctx.run(_execute=[p['execute'], p['manifest']]) if rc == 0: # success @@ -335,11 +253,11 @@ def main(): elif rc == 124: # timeout module.exit_json( - rc=rc, msg="%s timed out" % cmd, stdout=stdout, stderr=stderr) + rc=rc, msg="%s timed out" % ctx.cmd, stdout=stdout, stderr=stderr) else: # failure module.fail_json( - rc=rc, msg="%s failed with return code: %d" % (cmd, rc), + rc=rc, msg="%s failed with return code: %d" % (ctx.cmd, rc), stdout=stdout, stderr=stderr) diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index d12199993a..c79a17493f 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -18,8 +18,7 @@ plugins/modules/manageiq_provider.py validate-modules:undocumented-parameter plugins/modules/manageiq_tags.py validate-modules:parameter-state-invalid-choice plugins/modules/osx_defaults.py validate-modules:parameter-state-invalid-choice plugins/modules/parted.py validate-modules:parameter-state-invalid-choice -plugins/modules/puppet.py use-argspec-type-path -plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - removed in 7.0.0 +plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - removed in 7.0.0 plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index d5dd72b549..d93315938c 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -13,8 +13,7 @@ plugins/modules/manageiq_provider.py validate-modules:undocumented-parameter plugins/modules/manageiq_tags.py validate-modules:parameter-state-invalid-choice plugins/modules/osx_defaults.py validate-modules:parameter-state-invalid-choice plugins/modules/parted.py validate-modules:parameter-state-invalid-choice -plugins/modules/puppet.py use-argspec-type-path -plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - removed in 7.0.0 +plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - removed in 7.0.0 plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index d5dd72b549..d93315938c 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -13,8 +13,7 @@ plugins/modules/manageiq_provider.py validate-modules:undocumented-parameter plugins/modules/manageiq_tags.py validate-modules:parameter-state-invalid-choice plugins/modules/osx_defaults.py validate-modules:parameter-state-invalid-choice plugins/modules/parted.py validate-modules:parameter-state-invalid-choice -plugins/modules/puppet.py use-argspec-type-path -plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - removed in 7.0.0 +plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - removed in 7.0.0 plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index b54479472b..d4c0d0d948 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -14,8 +14,7 @@ plugins/modules/manageiq_provider.py validate-modules:undocumented-parameter plugins/modules/manageiq_tags.py validate-modules:parameter-state-invalid-choice plugins/modules/osx_defaults.py validate-modules:parameter-state-invalid-choice plugins/modules/parted.py validate-modules:parameter-state-invalid-choice -plugins/modules/puppet.py use-argspec-type-path -plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - removed in 7.0.0 +plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - removed in 7.0.0 plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index b54479472b..d4c0d0d948 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -14,8 +14,7 @@ plugins/modules/manageiq_provider.py validate-modules:undocumented-parameter plugins/modules/manageiq_tags.py validate-modules:parameter-state-invalid-choice plugins/modules/osx_defaults.py validate-modules:parameter-state-invalid-choice plugins/modules/parted.py validate-modules:parameter-state-invalid-choice -plugins/modules/puppet.py use-argspec-type-path -plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - removed in 7.0.0 +plugins/modules/puppet.py validate-modules:parameter-invalid # invalid alias - removed in 7.0.0 plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed diff --git a/tests/unit/plugins/modules/test_puppet.py b/tests/unit/plugins/modules/test_puppet.py new file mode 100644 index 0000000000..632385957e --- /dev/null +++ b/tests/unit/plugins/modules/test_puppet.py @@ -0,0 +1,145 @@ +# -*- coding: utf-8 -*- +# Author: Alexei Znamensky (russoz@gmail.com) +# Largely adapted from test_redhat_subscription by +# Jiri Hnidek (jhnidek@redhat.com) +# +# Copyright (c) Alexei Znamensky (russoz@gmail.com) +# Copyright (c) Jiri Hnidek (jhnidek@redhat.com) +# +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json + +from ansible_collections.community.general.plugins.modules import puppet + +import pytest + +TESTED_MODULE = puppet.__name__ + + +@pytest.fixture +def patch_get_bin_path(mocker): + """ + Function used for mocking AnsibleModule.get_bin_path + """ + def mockie(self, path, *args, **kwargs): + return "/testbin/{0}".format(path) + mocker.patch("ansible.module_utils.basic.AnsibleModule.get_bin_path", mockie) + + +TEST_CASES = [ + [ + {}, + { + "id": "puppet_agent_plain", + "run_command.calls": [ + ( + ["/testbin/puppet", "config", "print", "agent_disabled_lockfile"], + {"environ_update": {"LANGUAGE": "C", "LC_ALL": "C"}, "check_rc": False}, + (0, "blah, anything", "",), # output rc, out, err + ), + ( + [ + "/testbin/timeout", "-s", "9", "30m", "/testbin/puppet", "agent", "--onetime", "--no-daemonize", + "--no-usecacheonfailure", "--no-splay", "--detailed-exitcodes", "--verbose", "--color", "0" + ], + {"environ_update": {"LANGUAGE": "C", "LC_ALL": "C"}, "check_rc": False}, + (0, "", "",), # output rc, out, err + ), + ], + "changed": False, + } + ], + [ + { + "certname": "potatobox" + }, + { + "id": "puppet_agent_certname", + "run_command.calls": [ + ( + ["/testbin/puppet", "config", "print", "agent_disabled_lockfile"], + {"environ_update": {"LANGUAGE": "C", "LC_ALL": "C"}, "check_rc": False}, + (0, "blah, anything", "",), # output rc, out, err + ), + ( + [ + "/testbin/timeout", "-s", "9", "30m", "/testbin/puppet", "agent", "--onetime", "--no-daemonize", + "--no-usecacheonfailure", "--no-splay", "--detailed-exitcodes", "--verbose", "--color", "0", "--certname=potatobox" + ], + {"environ_update": {"LANGUAGE": "C", "LC_ALL": "C"}, "check_rc": False}, + (0, "", "",), # output rc, out, err + ), + ], + "changed": False, + } + ], + [ + { + "tags": ["a", "b", "c"] + }, + { + "id": "puppet_agent_tags_abc", + "run_command.calls": [ + ( + ["/testbin/puppet", "config", "print", "agent_disabled_lockfile"], + {"environ_update": {"LANGUAGE": "C", "LC_ALL": "C"}, "check_rc": False}, + (0, "blah, anything", "",), # output rc, out, err + ), + ( + [ + "/testbin/timeout", "-s", "9", "30m", "/testbin/puppet", "agent", "--onetime", "--no-daemonize", + "--no-usecacheonfailure", "--no-splay", "--detailed-exitcodes", "--verbose", "--color", "0", "--tags", "a,b,c" + ], + {"environ_update": {"LANGUAGE": "C", "LC_ALL": "C"}, "check_rc": False}, + (0, "", "",), # output rc, out, err + ), + ], + "changed": False, + } + ], +] +TEST_CASES_IDS = [item[1]["id"] for item in TEST_CASES] + + +@pytest.mark.parametrize("patch_ansible_module, testcase", + TEST_CASES, + ids=TEST_CASES_IDS, + indirect=["patch_ansible_module"]) +@pytest.mark.usefixtures("patch_ansible_module") +def test_puppet(mocker, capfd, patch_get_bin_path, testcase): + """ + Run unit tests for test cases listen in TEST_CASES + """ + + # Mock function used for running commands first + call_results = [item[2] for item in testcase["run_command.calls"]] + mock_run_command = mocker.patch( + "ansible.module_utils.basic.AnsibleModule.run_command", + side_effect=call_results) + + # Try to run test case + with pytest.raises(SystemExit): + puppet.main() + + out, err = capfd.readouterr() + results = json.loads(out) + print("results =\n%s" % results) + + assert mock_run_command.call_count == len(testcase["run_command.calls"]) + if mock_run_command.call_count: + call_args_list = [(item[0][0], item[1]) for item in mock_run_command.call_args_list] + expected_call_args_list = [(item[0], item[1]) for item in testcase["run_command.calls"]] + print("call args list =\n%s" % call_args_list) + print("expected args list =\n%s" % expected_call_args_list) + assert call_args_list == expected_call_args_list + + assert results.get("changed", False) == testcase["changed"] + if "failed" in testcase: + assert results.get("failed", False) == testcase["failed"] + if "msg" in testcase: + assert results.get("msg", "") == testcase["msg"] From 58f74b96efb9f1a5f3ad6f938d1b8ac4a9cd0d87 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 17 Dec 2022 12:22:30 +0100 Subject: [PATCH 066/134] [PR #5659/af53271c backport][stable-6] lxc_container: fix lxc argument when executing lxc command (#5698) lxc_container: fix lxc argument when executing lxc command (#5659) lxc_container fails when executing the lxc command (e.g. when creating a new container) because PR#5358 broke the module argument parsing. The resulting argument dict contained only the module argument name and the argument flag but not the value. E.g. ``` - lxc_container: template: debian ``` would result in lxc command arguments `lxc template --template` instead of `lxc --template debian`. Fixes: 6f88426cf1dc ("lxc_container: minor refactor (#5358)") Fixes #5578 Signed-off-by: Alexander Couzens Signed-off-by: Alexander Couzens (cherry picked from commit af53271c41f14c39696b1ac3f65b3163407ab18b) Co-authored-by: Alexander Couzens --- changelogs/fragments/5659-fix-lxc_container-command.yml | 2 ++ plugins/modules/lxc_container.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5659-fix-lxc_container-command.yml diff --git a/changelogs/fragments/5659-fix-lxc_container-command.yml b/changelogs/fragments/5659-fix-lxc_container-command.yml new file mode 100644 index 0000000000..450d889808 --- /dev/null +++ b/changelogs/fragments/5659-fix-lxc_container-command.yml @@ -0,0 +1,2 @@ +bugfixes: + - lxc_container - fix the arguments of the lxc command which broke the creation and cloning of containers (https://github.com/ansible-collections/community.general/issues/5578). diff --git a/plugins/modules/lxc_container.py b/plugins/modules/lxc_container.py index 7871f13972..9fe27b8d81 100644 --- a/plugins/modules/lxc_container.py +++ b/plugins/modules/lxc_container.py @@ -677,7 +677,7 @@ class LxcContainerManagement(object): false_values = BOOLEANS_FALSE.union([None, '']) result = dict( - (k, v) + (v, self.module.params[k]) for k, v in variables.items() if self.module.params[k] not in false_values ) From 589e8fd5e169eec0bbf9a2a47b9b9eb660c4bcbb Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 18 Dec 2022 09:25:46 +0100 Subject: [PATCH 067/134] [PR #5699/25be366c backport][stable-6] Fixed `github_release` docs: only module-specific returned key is `tag` (#5701) Fixed `github_release` docs: only module-specific returned key is `tag` (#5699) * Fixed github_release docs: only module-specific returned key is "tag" * Update plugins/modules/github_release.py - added a dot Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 25be366cc3dfa99bdc9bb914cece4614c2256d08) Co-authored-by: Or Bin --- plugins/modules/github_release.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/plugins/modules/github_release.py b/plugins/modules/github_release.py index 84ce4ce4ec..0b3a5a886c 100644 --- a/plugins/modules/github_release.py +++ b/plugins/modules/github_release.py @@ -108,17 +108,8 @@ EXAMPLES = ''' ''' RETURN = ''' -create_release: - description: - - Version of the created release - - "For Ansible version 2.5 and later, if specified release version already exists, then State is unchanged" - - "For Ansible versions prior to 2.5, if specified release version already exists, then State is skipped" - type: str - returned: success - sample: 1.1.0 - -latest_release: - description: Version of the latest release +tag: + description: Version of the created/latest release. type: str returned: success sample: 1.1.0 From 82f4b51873648d922dd97e0389e487eba252c8a6 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 19 Dec 2022 20:43:00 +0100 Subject: [PATCH 068/134] [PR #5705/2b39470a backport][stable-6] opkg: fix issue that force=reinstall would not reinstall an existing package (#5711) opkg: fix issue that force=reinstall would not reinstall an existing package (#5705) * opkg: fix issue that force=reinstall would not reinstall an existing package Signed-off-by: Joerg Hofrichter * changelog fragment Signed-off-by: Joerg Hofrichter (cherry picked from commit 2b39470a774c28e26780e4e2e4cc9b998471da3c) Co-authored-by: joergho <48011876+joergho@users.noreply.github.com> --- changelogs/fragments/5705-opkg-fix-force-reinstall.yml | 2 ++ plugins/modules/opkg.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5705-opkg-fix-force-reinstall.yml diff --git a/changelogs/fragments/5705-opkg-fix-force-reinstall.yml b/changelogs/fragments/5705-opkg-fix-force-reinstall.yml new file mode 100644 index 0000000000..27a188ab9e --- /dev/null +++ b/changelogs/fragments/5705-opkg-fix-force-reinstall.yml @@ -0,0 +1,2 @@ +bugfixes: + - opkg - fix issue that ``force=reinstall`` would not reinstall an existing package (https://github.com/ansible-collections/community.general/pull/5705). diff --git a/plugins/modules/opkg.py b/plugins/modules/opkg.py index 60d2adc958..6c5e23093e 100644 --- a/plugins/modules/opkg.py +++ b/plugins/modules/opkg.py @@ -154,7 +154,7 @@ def install_packages(module, opkg_path, packages): install_c = 0 for package in packages: - if query_package(module, opkg_path, package): + if query_package(module, opkg_path, package) and (force != '--force-reinstall'): continue rc, out, err = module.run_command("%s install %s %s" % (opkg_path, force, package)) From 02e6a8608f47ca5616b5b912ce78ddcddae1fdfb Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 19 Dec 2022 20:43:13 +0100 Subject: [PATCH 069/134] [PR #5672/fab73a1d backport][stable-6] Bugfix: Remove redundant VMID parameters (#5709) Bugfix: Remove redundant VMID parameters (#5672) * Remove redundant parameters VMID * Add changelog fragment (cherry picked from commit fab73a1d1e168fc04a5723d45bb3251149d9d856) Co-authored-by: castorsky --- changelogs/fragments/5672-proxmox.yml | 3 +++ plugins/modules/proxmox_disk.py | 4 ++-- plugins/modules/proxmox_nic.py | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/5672-proxmox.yml diff --git a/changelogs/fragments/5672-proxmox.yml b/changelogs/fragments/5672-proxmox.yml new file mode 100644 index 0000000000..4fafe53d14 --- /dev/null +++ b/changelogs/fragments/5672-proxmox.yml @@ -0,0 +1,3 @@ +bugfixes: + - "proxmox_disk - fixed possible issues with redundant ``vmid`` parameter (https://github.com/ansible-collections/community.general/issues/5492, https://github.com/ansible-collections/community.general/pull/5672)." + - "proxmox_nic - fixed possible issues with redundant ``vmid`` parameter (https://github.com/ansible-collections/community.general/issues/5492, https://github.com/ansible-collections/community.general/pull/5672)." diff --git a/plugins/modules/proxmox_disk.py b/plugins/modules/proxmox_disk.py index 8f55e2d130..8a81f18a3f 100644 --- a/plugins/modules/proxmox_disk.py +++ b/plugins/modules/proxmox_disk.py @@ -699,7 +699,7 @@ def main(): module.exit_json(changed=False, vmid=vmid, msg='Disk %s already detached in VM %s' % (disk, vmid)) if disk not in vm_config: module.exit_json(changed=False, vmid=vmid, msg="Disk %s not present in VM %s config" % (disk, vmid)) - proxmox.proxmox_api.nodes(vm['node']).qemu(vmid).unlink.put(vmid=vmid, idlist=disk, force=0) + proxmox.proxmox_api.nodes(vm['node']).qemu(vmid).unlink.put(idlist=disk, force=0) module.exit_json(changed=True, vmid=vmid, msg="Disk %s detached from VM %s" % (disk, vmid)) except Exception as e: module.fail_json(msg="Failed to detach disk %s from VM %s with exception: %s" % (disk, vmid, str(e))) @@ -734,7 +734,7 @@ def main(): try: if disk not in vm_config: module.exit_json(changed=False, vmid=vmid, msg="Disk %s is already absent in VM %s" % (disk, vmid)) - proxmox.proxmox_api.nodes(vm['node']).qemu(vmid).unlink.put(vmid=vmid, idlist=disk, force=1) + proxmox.proxmox_api.nodes(vm['node']).qemu(vmid).unlink.put(idlist=disk, force=1) module.exit_json(changed=True, vmid=vmid, msg="Disk %s removed from VM %s" % (disk, vmid)) except Exception as e: module.fail_json(vmid=vmid, msg='Unable to remove disk %s from VM %s: %s' % (disk, vmid, str(e))) diff --git a/plugins/modules/proxmox_nic.py b/plugins/modules/proxmox_nic.py index bcc56de57e..5c8c3f47df 100644 --- a/plugins/modules/proxmox_nic.py +++ b/plugins/modules/proxmox_nic.py @@ -223,7 +223,7 @@ class ProxmoxNicAnsible(ProxmoxAnsible): if interface in vminfo: if not self.module.check_mode: - self.proxmox_api.nodes(vm['node']).qemu(vmid).config.set(vmid=vmid, delete=interface) + self.proxmox_api.nodes(vm['node']).qemu(vmid).config.set(delete=interface) return True return False From bc50b48205eb4d66884f4909bd515413183f9502 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 20 Dec 2022 12:59:26 +0100 Subject: [PATCH 070/134] [PR #5703/77fde030 backport][stable-6] Add support for host restriction in sudoers module (#5716) Add support for host restriction in sudoers module (#5703) * Add support to restrict privileges by host * Missing comma * Making linter happy. * Add version 6.2.0 as when sudoers host parameter added Co-authored-by: Felix Fontein * Changelog fragment for PR #5703 * Test for sudoers host-based restriction Co-authored-by: Felix Fontein (cherry picked from commit 77fde030cdb89c1c5532974fb2d827dc1156a097) Co-authored-by: Laurence --- .../fragments/5703-sudoers-host-support.yml | 2 ++ plugins/modules/sudoers.py | 22 +++++++++++++++++-- .../targets/sudoers/tasks/main.yml | 14 ++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/5703-sudoers-host-support.yml diff --git a/changelogs/fragments/5703-sudoers-host-support.yml b/changelogs/fragments/5703-sudoers-host-support.yml new file mode 100644 index 0000000000..1aaa30d8d9 --- /dev/null +++ b/changelogs/fragments/5703-sudoers-host-support.yml @@ -0,0 +1,2 @@ +minor_changes: + - sudoers - adds ``host`` parameter for setting hostname restrictions in sudoers rules (https://github.com/ansible-collections/community.general/issues/5702). diff --git a/plugins/modules/sudoers.py b/plugins/modules/sudoers.py index 2c0aa879bc..f2bcb20b75 100644 --- a/plugins/modules/sudoers.py +++ b/plugins/modules/sudoers.py @@ -43,6 +43,12 @@ options: - Whether a password will be required to run the sudo'd command. default: true type: bool + host: + description: + - Specify the host the rule is for. + default: ALL + type: str + version_added: 6.2.0 runas: description: - Specify the target user the command(s) will run as. @@ -95,10 +101,11 @@ EXAMPLES = ''' - name: >- Allow the monitoring group to run sudo /usr/local/bin/gather-app-metrics - without requiring a password + without requiring a password on the host called webserver community.general.sudoers: name: monitor-app group: monitoring + host: webserver commands: /usr/local/bin/gather-app-metrics - name: >- @@ -136,6 +143,7 @@ class Sudoers(object): self.group = module.params['group'] self.state = module.params['state'] self.nopassword = module.params['nopassword'] + self.host = module.params['host'] self.runas = module.params['runas'] self.sudoers_path = module.params['sudoers_path'] self.file = os.path.join(self.sudoers_path, self.name) @@ -178,7 +186,13 @@ class Sudoers(object): commands_str = ', '.join(self.commands) nopasswd_str = 'NOPASSWD:' if self.nopassword else '' runas_str = '({runas})'.format(runas=self.runas) if self.runas is not None else '' - return "{owner} ALL={runas}{nopasswd} {commands}\n".format(owner=owner, runas=runas_str, nopasswd=nopasswd_str, commands=commands_str) + return "{owner} {host}={runas}{nopasswd} {commands}\n".format( + owner=owner, + host=self.host, + runas=runas_str, + nopasswd=nopasswd_str, + commands=commands_str + ) def validate(self): if self.validation == 'absent': @@ -225,6 +239,10 @@ def main(): 'type': 'bool', 'default': True, }, + 'host': { + 'type': 'str', + 'default': 'ALL', + }, 'runas': { 'type': 'str', 'default': None, diff --git a/tests/integration/targets/sudoers/tasks/main.yml b/tests/integration/targets/sudoers/tasks/main.yml index 682bd7efff..a44307ad9e 100644 --- a/tests/integration/targets/sudoers/tasks/main.yml +++ b/tests/integration/targets/sudoers/tasks/main.yml @@ -131,6 +131,19 @@ src: "{{ sudoers_path }}/my-sudo-rule-6" register: rule_6_contents +- name: Create rule to allow user to sudo just on host-1 + community.general.sudoers: + name: my-sudo-rule-7 + state: present + user: alice + host: host-1 + commands: /usr/local/bin/command + register: rule_7 + +- name: Grab contents of my-sudo-rule-7 + ansible.builtin.slurp: + src: "{{ sudoers_path }}/my-sudo-rule-7" + register: rule_7_contents - name: Revoke rule 1 community.general.sudoers: @@ -229,6 +242,7 @@ - "rule_4_contents['content'] | b64decode == '%students ALL=NOPASSWD: /usr/local/bin/command\n'" - "rule_5_contents['content'] | b64decode == 'alice ALL=NOPASSWD: /usr/local/bin/command\n'" - "rule_6_contents['content'] | b64decode == 'alice ALL=(bob)NOPASSWD: /usr/local/bin/command\n'" + - "rule_7_contents['content'] | b64decode == 'alice host-1=NOPASSWD: /usr/local/bin/command\n'" - name: Check revocation stat ansible.builtin.assert: From a70d9773dd07d1f9a3aeb18995289876d04e83d1 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 21 Dec 2022 08:13:06 +0100 Subject: [PATCH 071/134] [PR #5713/1f492414 backport][stable-6] CI: add extra VMs for certain tests (#5717) CI: add extra VMs for certain tests (#5713) * Remove superfluous VM. * Add extra VM group. * More platforms, add scripts. * [REVERT THIS] Shrink matrix to only the tests we are interested in. * Fix some tests. * Skip snap tests on Ubuntu VMs for now. * Skip xfs_quota tests on Alpine VMs due to ansible.posix.mount failing. * Revert "[REVERT THIS] Shrink matrix to only the tests we are interested in." This reverts commit 2e98e163db643f5b06290d2f1fa99fe14ca4eebd. * Stick to Alpine and Ubuntu 22.04 for now. (cherry picked from commit 1f492414816f5455de27afe659f22272a0829514) Co-authored-by: Felix Fontein --- .azure-pipelines/azure-pipelines.yml | 25 ++++++++++++++++--- tests/integration/targets/filesize/aliases | 1 + tests/integration/targets/filesystem/aliases | 1 + .../filesystem/tasks/create_device.yml | 8 ++++-- .../targets/iptables_state/aliases | 1 + .../iptables_state/tasks/tests/01-tables.yml | 11 +------- tests/integration/targets/lvg/aliases | 1 + tests/integration/targets/lvg/tasks/setup.yml | 19 ++++++++++---- .../targets/lvg/tasks/teardown.yml | 13 +++++----- .../targets/lvg/tasks/test_grow_reduce.yml | 16 ++++++------ .../targets/lvg/tasks/test_indempotency.yml | 4 +-- .../targets/lvg/tasks/test_pvresize.yml | 10 ++++---- tests/integration/targets/snap/aliases | 4 +++ tests/integration/targets/snap_alias/aliases | 4 +++ tests/integration/targets/ufw/aliases | 1 + tests/integration/targets/xattr/aliases | 1 + tests/integration/targets/xfs_quota/aliases | 2 ++ tests/utils/shippable/alpine.sh | 1 + tests/utils/shippable/fedora.sh | 1 + tests/utils/shippable/ubuntu.sh | 1 + 20 files changed, 83 insertions(+), 42 deletions(-) create mode 120000 tests/utils/shippable/alpine.sh create mode 120000 tests/utils/shippable/fedora.sh create mode 120000 tests/utils/shippable/ubuntu.sh diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index a5dcafa422..c8e03a164b 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -189,6 +189,24 @@ stages: - test: 3.5 ## Remote + - stage: Remote_devel_extra_vms + displayName: Remote devel extra VMs + dependsOn: [] + jobs: + - template: templates/matrix.yml + parameters: + testFormat: devel/{0} + targets: + - name: Alpine 3.16 + test: alpine/3.16 + # - name: Fedora 36 + # test: fedora/36 + # - name: Ubuntu 20.04 + # test: ubuntu/20.04 + - name: Ubuntu 22.04 + test: ubuntu/22.04 + groups: + - vm - stage: Remote_devel displayName: Remote devel dependsOn: [] @@ -203,8 +221,6 @@ stages: test: rhel/7.9 - name: RHEL 9.0 test: rhel/9.0 - - name: FreeBSD 12.3 - test: freebsd/12.3 - name: FreeBSD 13.1 test: freebsd/13.1 groups: @@ -221,8 +237,8 @@ stages: targets: - name: RHEL 9.0 test: rhel/9.0 - - name: FreeBSD 13.1 - test: freebsd/13.1 + - name: FreeBSD 12.3 + test: freebsd/12.3 groups: - 1 - 2 @@ -459,6 +475,7 @@ stages: - Units_2_12 - Units_2_13 - Units_2_14 + - Remote_devel_extra_vms - Remote_devel - Remote_2_11 - Remote_2_12 diff --git a/tests/integration/targets/filesize/aliases b/tests/integration/targets/filesize/aliases index afda346c4e..7642e70daf 100644 --- a/tests/integration/targets/filesize/aliases +++ b/tests/integration/targets/filesize/aliases @@ -3,3 +3,4 @@ # SPDX-License-Identifier: GPL-3.0-or-later azp/posix/1 +azp/posix/vm diff --git a/tests/integration/targets/filesystem/aliases b/tests/integration/targets/filesystem/aliases index 007bed5386..a666f7a142 100644 --- a/tests/integration/targets/filesystem/aliases +++ b/tests/integration/targets/filesystem/aliases @@ -3,6 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later azp/posix/1 +azp/posix/vm destructive skip/aix skip/osx diff --git a/tests/integration/targets/filesystem/tasks/create_device.yml b/tests/integration/targets/filesystem/tasks/create_device.yml index 5229e19f25..8966ec2e61 100644 --- a/tests/integration/targets/filesystem/tasks/create_device.yml +++ b/tests/integration/targets/filesystem/tasks/create_device.yml @@ -14,10 +14,14 @@ block: - when: fstype == 'lvm' block: + - name: 'Show next free loop device' + ansible.builtin.command: + cmd: 'losetup -f' + register: loop_device_cmd + - name: 'Create a loop device for LVM' ansible.builtin.command: - cmd: 'losetup --show -f {{ dev }}' - register: loop_device_cmd + cmd: 'losetup -f {{ dev }}' - name: 'Switch to loop device target for further tasks' ansible.builtin.set_fact: diff --git a/tests/integration/targets/iptables_state/aliases b/tests/integration/targets/iptables_state/aliases index 80f7c7e32f..5a02a630bc 100644 --- a/tests/integration/targets/iptables_state/aliases +++ b/tests/integration/targets/iptables_state/aliases @@ -3,6 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later azp/posix/1 +azp/posix/vm destructive skip/docker # kernel modules not loadable skip/freebsd # no iptables/netfilter (Linux specific) diff --git a/tests/integration/targets/iptables_state/tasks/tests/01-tables.yml b/tests/integration/targets/iptables_state/tasks/tests/01-tables.yml index 2f00e175b4..929928c8e7 100644 --- a/tests/integration/targets/iptables_state/tasks/tests/01-tables.yml +++ b/tests/integration/targets/iptables_state/tasks/tests/01-tables.yml @@ -167,13 +167,12 @@ -- name: "get security, raw and mangle tables states" +- name: "get raw and mangle tables states" iptables_state: path: "{{ iptables_saved }}" state: saved table: "{{ item }}" loop: - - security - raw - mangle changed_when: false @@ -198,8 +197,6 @@ - "'*nat' in iptables_state.saved" - "'raw' in iptables_state.tables" - "'*raw' in iptables_state.saved" - - "'security' in iptables_state.tables" - - "'*security' in iptables_state.saved" quiet: yes @@ -233,17 +230,14 @@ - "'*mangle' in iptables_state.initial_state" - "'*nat' in iptables_state.initial_state" - "'*raw' in iptables_state.initial_state" - - "'*security' in iptables_state.initial_state" - "'filter' in iptables_state.tables" - "'mangle' not in iptables_state.tables" - "'nat' not in iptables_state.tables" - "'raw' not in iptables_state.tables" - - "'security' not in iptables_state.tables" - "'*filter' in iptables_state.restored" - "'*mangle' not in iptables_state.restored" - "'*nat' not in iptables_state.restored" - "'*raw' not in iptables_state.restored" - - "'*security' not in iptables_state.restored" - iptables_state is not changed quiet: yes @@ -264,17 +258,14 @@ - "'*mangle' in iptables_state.initial_state" - "'*nat' in iptables_state.initial_state" - "'*raw' in iptables_state.initial_state" - - "'*security' in iptables_state.initial_state" - "'filter' in iptables_state.tables" - "'mangle' in iptables_state.tables" - "'nat' in iptables_state.tables" - "'raw' in iptables_state.tables" - - "'security' in iptables_state.tables" - "'*filter' in iptables_state.restored" - "'*mangle' in iptables_state.restored" - "'*nat' in iptables_state.restored" - "'*raw' in iptables_state.restored" - - "'*security' in iptables_state.restored" - iptables_state is not changed quiet: yes diff --git a/tests/integration/targets/lvg/aliases b/tests/integration/targets/lvg/aliases index f4617b3377..3b92ba75c4 100644 --- a/tests/integration/targets/lvg/aliases +++ b/tests/integration/targets/lvg/aliases @@ -3,6 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later azp/posix/1 +azp/posix/vm destructive needs/privileged skip/aix diff --git a/tests/integration/targets/lvg/tasks/setup.yml b/tests/integration/targets/lvg/tasks/setup.yml index 92785e6d3d..3984b9fc3a 100644 --- a/tests/integration/targets/lvg/tasks/setup.yml +++ b/tests/integration/targets/lvg/tasks/setup.yml @@ -7,12 +7,21 @@ command: "dd if=/dev/zero of={{ remote_tmp_dir }}/img{{ item }} bs=1M count=10" with_sequence: 'count=2' +- name: "Show next free loop device" + command: "losetup -f" + register: loop_device1 + - name: "Create loop device for file" - command: "losetup --show -f {{ remote_tmp_dir }}/img{{ item }}" - with_sequence: 'count=2' - register: loop_devices + command: "losetup -f {{ remote_tmp_dir }}/img1" + +- name: "Show next free loop device" + command: "losetup -f" + register: loop_device2 + +- name: "Create loop device for file" + command: "losetup -f {{ remote_tmp_dir }}/img2" - name: "Affect name on disk to work on" set_fact: - loop_device1: "{{ loop_devices.results[0] }}" - loop_device2: "{{ loop_devices.results[1] }}" + loop_device1: "{{ loop_device1.stdout }}" + loop_device2: "{{ loop_device2.stdout }}" diff --git a/tests/integration/targets/lvg/tasks/teardown.yml b/tests/integration/targets/lvg/tasks/teardown.yml index 027c1257fe..de49573214 100644 --- a/tests/integration/targets/lvg/tasks/teardown.yml +++ b/tests/integration/targets/lvg/tasks/teardown.yml @@ -8,15 +8,16 @@ vg: testvg state: absent -- name: Detach loop device - command: "losetup -d {{ item.stdout }}" - loop: "{{ loop_devices.results|default([]) }}" +- name: Detach loop devices + command: "losetup -d {{ item }}" + loop: + - "{{ loop_device1 | default('') }}" + - "{{ loop_device2 | default('') }}" when: - - item.stdout is defined - - item.stdout is match("/dev/.*") + - item != '' - name: Remove device files file: path: "{{ remote_tmp_dir }}/img{{ item }}" state: absent - with_sequence: 'count={{ loop_devices.results|length }}' + with_sequence: 'count=2' diff --git a/tests/integration/targets/lvg/tasks/test_grow_reduce.yml b/tests/integration/targets/lvg/tasks/test_grow_reduce.yml index 5974a88aaf..857df92464 100644 --- a/tests/integration/targets/lvg/tasks/test_grow_reduce.yml +++ b/tests/integration/targets/lvg/tasks/test_grow_reduce.yml @@ -6,7 +6,7 @@ - name: "Create volume group on first disk" lvg: vg: testvg - pvs: "{{ loop_device1.stdout }}" + pvs: "{{ loop_device1 }}" - name: "get lvm facts" setup: @@ -16,14 +16,14 @@ - name: "Assert the testvg span only on first disk" assert: that: - - ansible_lvm.pvs[loop_device1.stdout].vg == "testvg" - - 'loop_device2.stdout not in ansible_lvm.pvs or - ansible_lvm.pvs[loop_device2.stdout].vg == ""' + - ansible_lvm.pvs[loop_device1].vg == "testvg" + - 'loop_device2 not in ansible_lvm.pvs or + ansible_lvm.pvs[loop_device2].vg == ""' - name: "Extend to second disk AND reduce from the first disk" lvg: vg: testvg - pvs: "{{ loop_device2.stdout }}" + pvs: "{{ loop_device2 }}" - name: "get lvm facts" setup: @@ -33,6 +33,6 @@ - name: "Assert the testvg span only on first disk" assert: that: - - 'loop_device1.stdout not in ansible_lvm.pvs or - ansible_lvm.pvs[loop_device1.stdout].vg == ""' - - ansible_lvm.pvs[loop_device2.stdout].vg == "testvg" + - 'loop_device1 not in ansible_lvm.pvs or + ansible_lvm.pvs[loop_device1].vg == ""' + - ansible_lvm.pvs[loop_device2].vg == "testvg" diff --git a/tests/integration/targets/lvg/tasks/test_indempotency.yml b/tests/integration/targets/lvg/tasks/test_indempotency.yml index abaa262881..758912484c 100644 --- a/tests/integration/targets/lvg/tasks/test_indempotency.yml +++ b/tests/integration/targets/lvg/tasks/test_indempotency.yml @@ -6,12 +6,12 @@ - name: Create volume group on disk device lvg: vg: testvg - pvs: "{{ loop_device1.stdout }}" + pvs: "{{ loop_device1 }}" - name: Create the volume group again to verify idempotence lvg: vg: testvg - pvs: "{{ loop_device1.stdout }}" + pvs: "{{ loop_device1 }}" register: repeat_vg_create - name: Do all assertions to verify expected results diff --git a/tests/integration/targets/lvg/tasks/test_pvresize.yml b/tests/integration/targets/lvg/tasks/test_pvresize.yml index c8a2c8edb5..eef9503040 100644 --- a/tests/integration/targets/lvg/tasks/test_pvresize.yml +++ b/tests/integration/targets/lvg/tasks/test_pvresize.yml @@ -6,7 +6,7 @@ - name: "Create volume group on first disk" lvg: vg: testvg - pvs: "{{ loop_device1.stdout }}" + pvs: "{{ loop_device1 }}" - name: Gets current vg size shell: vgs -v testvg -o pv_size --noheading --units b | xargs @@ -21,12 +21,12 @@ command: "dd if=/dev/zero bs=8MiB count=1 of={{ remote_tmp_dir }}/img1 conv=notrunc oflag=append" - name: "Reread size of file associated with loop_device1" - command: "losetup -c {{ loop_device1.stdout }}" + command: "losetup -c {{ loop_device1 }}" - name: "Reruns lvg with pvresize:no" lvg: vg: testvg - pvs: "{{ loop_device1.stdout }}" + pvs: "{{ loop_device1 }}" pvresize: no register: cmd_result @@ -46,7 +46,7 @@ - name: "Reruns lvg with pvresize:yes and check_mode:yes" lvg: vg: testvg - pvs: "{{ loop_device1.stdout }}" + pvs: "{{ loop_device1 }}" pvresize: yes check_mode: yes register: cmd_result @@ -68,7 +68,7 @@ - name: "Reruns lvg with pvresize:yes" lvg: vg: testvg - pvs: "{{ loop_device1.stdout }}" + pvs: "{{ loop_device1 }}" pvresize: yes - name: Gets current vg size diff --git a/tests/integration/targets/snap/aliases b/tests/integration/targets/snap/aliases index dcb4aa199e..a50e25cc5c 100644 --- a/tests/integration/targets/snap/aliases +++ b/tests/integration/targets/snap/aliases @@ -3,8 +3,12 @@ # SPDX-License-Identifier: GPL-3.0-or-later azp/posix/1 +azp/posix/vm skip/aix +skip/alpine +skip/fedora skip/freebsd skip/osx skip/macos skip/docker +skip/ubuntu # FIXME! diff --git a/tests/integration/targets/snap_alias/aliases b/tests/integration/targets/snap_alias/aliases index dcb4aa199e..a50e25cc5c 100644 --- a/tests/integration/targets/snap_alias/aliases +++ b/tests/integration/targets/snap_alias/aliases @@ -3,8 +3,12 @@ # SPDX-License-Identifier: GPL-3.0-or-later azp/posix/1 +azp/posix/vm skip/aix +skip/alpine +skip/fedora skip/freebsd skip/osx skip/macos skip/docker +skip/ubuntu # FIXME! diff --git a/tests/integration/targets/ufw/aliases b/tests/integration/targets/ufw/aliases index fa4f2a6cd3..1f974ecd19 100644 --- a/tests/integration/targets/ufw/aliases +++ b/tests/integration/targets/ufw/aliases @@ -3,6 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later azp/posix/2 +azp/posix/vm skip/aix skip/osx skip/macos diff --git a/tests/integration/targets/xattr/aliases b/tests/integration/targets/xattr/aliases index db3751be49..5cd9c012e1 100644 --- a/tests/integration/targets/xattr/aliases +++ b/tests/integration/targets/xattr/aliases @@ -3,6 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later azp/posix/2 +azp/posix/vm skip/aix skip/docker skip/freebsd diff --git a/tests/integration/targets/xfs_quota/aliases b/tests/integration/targets/xfs_quota/aliases index 56dffecaa4..dd4714509e 100644 --- a/tests/integration/targets/xfs_quota/aliases +++ b/tests/integration/targets/xfs_quota/aliases @@ -3,9 +3,11 @@ # SPDX-License-Identifier: GPL-3.0-or-later azp/posix/1 +azp/posix/vm needs/privileged needs/root skip/aix +skip/alpine # FIXME skip/osx skip/macos skip/freebsd diff --git a/tests/utils/shippable/alpine.sh b/tests/utils/shippable/alpine.sh new file mode 120000 index 0000000000..6ddb776854 --- /dev/null +++ b/tests/utils/shippable/alpine.sh @@ -0,0 +1 @@ +remote.sh \ No newline at end of file diff --git a/tests/utils/shippable/fedora.sh b/tests/utils/shippable/fedora.sh new file mode 120000 index 0000000000..6ddb776854 --- /dev/null +++ b/tests/utils/shippable/fedora.sh @@ -0,0 +1 @@ +remote.sh \ No newline at end of file diff --git a/tests/utils/shippable/ubuntu.sh b/tests/utils/shippable/ubuntu.sh new file mode 120000 index 0000000000..6ddb776854 --- /dev/null +++ b/tests/utils/shippable/ubuntu.sh @@ -0,0 +1 @@ +remote.sh \ No newline at end of file From 6037c5d1e6f35a4a2c9c516df842f4deddfcbd33 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 22 Dec 2022 06:00:34 +0000 Subject: [PATCH 072/134] [PR #5680/488e828f backport][stable-6] ansible_galaxy_install: use locale C tentatively, else en_US (#5722) ansible_galaxy_install: use locale C tentatively, else en_US (#5680) * ansible_galaxy_install: use locale C tentatively, else en_US * use custom exception to signal unsupported locale * add step to remove artefacts at the end of the test * add step to remove artefacts at the beginning of the test * comment out context controller * trying with temporary dir as destination * remove collection before test with reqs file * ensure collections are installed in temp dir in tests + check_force * simplified the change * added extra condition for failing locale * improved exception handling * add changelog fragment (cherry picked from commit 488e828f9b7dcf2867edec72ce35f766d7b54ff0) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- ...5680-ansible_galaxy_install-fx-locale.yaml | 3 ++ plugins/modules/ansible_galaxy_install.py | 35 ++++++++++++++----- .../ansible_galaxy_install/tasks/main.yml | 6 ++-- 3 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 changelogs/fragments/5680-ansible_galaxy_install-fx-locale.yaml diff --git a/changelogs/fragments/5680-ansible_galaxy_install-fx-locale.yaml b/changelogs/fragments/5680-ansible_galaxy_install-fx-locale.yaml new file mode 100644 index 0000000000..35fd88bc25 --- /dev/null +++ b/changelogs/fragments/5680-ansible_galaxy_install-fx-locale.yaml @@ -0,0 +1,3 @@ +bugfixes: + - ansible_galaxy_install - try ``C.UTF-8`` and then fall back to ``en_US.UTF-8`` before failing (https://github.com/ansible-collections/community.general/pull/5680). + - ansible_galaxy_install - set default to raise exception if command's return code is different from zero (https://github.com/ansible-collections/community.general/pull/5680). diff --git a/plugins/modules/ansible_galaxy_install.py b/plugins/modules/ansible_galaxy_install.py index 5e5ec54eb0..694591d8cb 100644 --- a/plugins/modules/ansible_galaxy_install.py +++ b/plugins/modules/ansible_galaxy_install.py @@ -20,6 +20,10 @@ notes: - > B(Ansible 2.9/2.10): The C(ansible-galaxy) command changed significantly between Ansible 2.9 and ansible-base 2.10 (later ansible-core 2.11). See comments in the parameters. + - > + The module will try and run using the C(C.UTF-8) locale. + If that fails, it will try C(en_US.UTF-8). + If that one also fails, the module will fail. requirements: - Ansible 2.9, ansible-base 2.10, or ansible-core 2.11 or newer options: @@ -185,7 +189,7 @@ RETURN = """ import re from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt as fmt -from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper +from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper, ModuleHelperException class AnsibleGalaxyInstall(ModuleHelper): @@ -226,11 +230,17 @@ class AnsibleGalaxyInstall(ModuleHelper): version=fmt.as_bool("--version"), name=fmt.as_list(), ) - force_lang = "en_US.UTF-8" - check_rc = True + + def _make_runner(self, lang): + return CmdRunner(self.module, command=self.command, arg_formats=self.command_args_formats, force_lang=lang, check_rc=True) def _get_ansible_galaxy_version(self): + class UnsupportedLocale(ModuleHelperException): + pass + def process(rc, out, err): + if (rc != 0 and "unsupported locale setting" in err) or (rc == 0 and "cannot change locale" in err): + raise UnsupportedLocale(msg=err) line = out.splitlines()[0] match = self._RE_GALAXY_VERSION.match(line) if not match: @@ -239,12 +249,18 @@ class AnsibleGalaxyInstall(ModuleHelper): version = tuple(int(x) for x in version.split('.')[:3]) return version - with self.runner("version", check_rc=True, output_process=process) as ctx: - return ctx.run(version=True) + try: + runner = self._make_runner("C.UTF-8") + with runner("version", check_rc=False, output_process=process) as ctx: + return runner, ctx.run(version=True) + except UnsupportedLocale as e: + runner = self._make_runner("en_US.UTF-8") + with runner("version", check_rc=True, output_process=process) as ctx: + return runner, ctx.run(version=True) def __init_module__(self): - self.runner = CmdRunner(self.module, command=self.command, arg_formats=self.command_args_formats, force_lang=self.force_lang) - self.ansible_version = self._get_ansible_galaxy_version() + # self.runner = CmdRunner(self.module, command=self.command, arg_formats=self.command_args_formats, force_lang=self.force_lang) + self.runner, self.ansible_version = self._get_ansible_galaxy_version() if self.ansible_version < (2, 11) and not self.vars.ack_min_ansiblecore211: self.module.deprecate( "Support for Ansible 2.9 and ansible-base 2.10 is being deprecated. " @@ -339,11 +355,12 @@ class AnsibleGalaxyInstall(ModuleHelper): self._setup210plus() with self.runner("type galaxy_cmd force no_deps dest requirements_file name", output_process=process) as ctx: ctx.run(galaxy_cmd="install") + if self.verbosity > 2: + self.vars.set("run_info", ctx.run_info) def main(): - galaxy = AnsibleGalaxyInstall() - galaxy.run() + AnsibleGalaxyInstall.execute() if __name__ == '__main__': diff --git a/tests/integration/targets/ansible_galaxy_install/tasks/main.yml b/tests/integration/targets/ansible_galaxy_install/tasks/main.yml index 44ad697930..1ecd9980d4 100644 --- a/tests/integration/targets/ansible_galaxy_install/tasks/main.yml +++ b/tests/integration/targets/ansible_galaxy_install/tasks/main.yml @@ -10,7 +10,7 @@ name: netbox.netbox register: install_c0 -- name: Assert collection was installed +- name: Assert collection netbox.netbox was installed assert: that: - install_c0 is changed @@ -34,7 +34,7 @@ name: ansistrano.deploy register: install_r0 -- name: Assert collection was installed +- name: Assert collection ansistrano.deploy was installed assert: that: - install_r0 is changed @@ -52,7 +52,7 @@ - install_r1 is not changed ################################################### -- name: +- name: Set requirements file path set_fact: reqs_file: '{{ remote_tmp_dir }}/reqs.yaml' From 95f3109ddc86d82bb53804eac27fc4421781a38e Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 22 Dec 2022 07:11:24 +0100 Subject: [PATCH 073/134] [PR #5721/28969c61 backport][stable-6] manageiq_policies: deprecate list state (#5723) manageiq_policies: deprecate list state (#5721) * manageiq_policies: deprecate list state * add changelog fragment (cherry picked from commit 28969c61ad0dadb79061ec313e901b93df6c2bdf) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../5721-manageiq-policies-deprecate-list-state.yaml | 2 ++ plugins/modules/manageiq_policies.py | 12 +++++++++++- tests/sanity/ignore-2.11.txt | 2 +- tests/sanity/ignore-2.12.txt | 2 +- tests/sanity/ignore-2.13.txt | 2 +- tests/sanity/ignore-2.14.txt | 2 +- tests/sanity/ignore-2.15.txt | 2 +- 7 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/5721-manageiq-policies-deprecate-list-state.yaml diff --git a/changelogs/fragments/5721-manageiq-policies-deprecate-list-state.yaml b/changelogs/fragments/5721-manageiq-policies-deprecate-list-state.yaml new file mode 100644 index 0000000000..109a2103e4 --- /dev/null +++ b/changelogs/fragments/5721-manageiq-policies-deprecate-list-state.yaml @@ -0,0 +1,2 @@ +deprecated_features: + - manageiq_policies - deprecate ``state=list`` in favour of using ``community.general.manageiq_policies_info`` (https://github.com/ansible-collections/community.general/pull/5721). diff --git a/plugins/modules/manageiq_policies.py b/plugins/modules/manageiq_policies.py index c5b2d88287..fc185fcd58 100644 --- a/plugins/modules/manageiq_policies.py +++ b/plugins/modules/manageiq_policies.py @@ -27,7 +27,10 @@ options: description: - C(absent) - policy_profiles should not exist, - C(present) - policy_profiles should exist, - - C(list) - list current policy_profiles and policies. + - > + C(list) - list current policy_profiles and policies. + This state is deprecated and will be removed 8.0.0. + Please use the module M(community.general.manageiq_policies_info) instead. choices: ['absent', 'present', 'list'] default: 'present' policy_profiles: @@ -163,6 +166,13 @@ def main(): resource_name = module.params['resource_name'] state = module.params['state'] + if state == "list": + module.deprecate( + 'The value "list" for "state" is deprecated. Please use community.general.manageiq_policies_info instead.', + version='8.0.0', + collection_name='community.general' + ) + # get the action and resource type action = actions[state] resource_type = manageiq_entities()[resource_type_key] diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index c79a17493f..e49b216f6e 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -10,7 +10,7 @@ plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choic plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0 plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen -plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice +plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice # state=list - removed in 8.0.0 plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:doc-missing-type # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index d93315938c..0cf9b73046 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -5,7 +5,7 @@ plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choic plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0 plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen -plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice +plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice # state=list - removed in 8.0.0 plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:doc-missing-type # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index d93315938c..0cf9b73046 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -5,7 +5,7 @@ plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choic plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0 plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen -plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice +plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice # state=list - removed in 8.0.0 plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:doc-missing-type # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index d4c0d0d948..efdb15f969 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -6,7 +6,7 @@ plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice plugins/modules/homectl.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen -plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice +plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice # state=list - removed in 8.0.0 plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:doc-missing-type # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index d4c0d0d948..efdb15f969 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -6,7 +6,7 @@ plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice plugins/modules/homectl.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/iptables_state.py validate-modules:undocumented-parameter plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen -plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice +plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice # state=list - removed in 8.0.0 plugins/modules/manageiq_provider.py validate-modules:doc-choices-do-not-match-spec # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:doc-missing-type # missing docs on suboptions plugins/modules/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions From 0f0ad6b6d1b23c7f2ff9ad7a9bc812535f676ec7 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 22 Dec 2022 20:58:43 +0100 Subject: [PATCH 074/134] [PR #5688/b3485b8f backport][stable-6] opkg module: allow installing a package in a certain version (#5724) opkg module: allow installing a package in a certain version (#5688) * opkg: allow installing a package in a certain version example: - name: Install foo in version 1.2 community.general.opkg: name: foo=1.2 state: present Signed-off-by: Joerg Hofrichter * opkg: use list for passing arguments to run_command Signed-off-by: Joerg Hofrichter Signed-off-by: Joerg Hofrichter (cherry picked from commit b3485b8fcab59e47d7460c3473329a9d516c3ea0) Co-authored-by: joergho <48011876+joergho@users.noreply.github.com> --- ...88-opkg-module-install-certain-version.yml | 2 + plugins/modules/opkg.py | 62 +++++++++++++++---- 2 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 changelogs/fragments/5688-opkg-module-install-certain-version.yml diff --git a/changelogs/fragments/5688-opkg-module-install-certain-version.yml b/changelogs/fragments/5688-opkg-module-install-certain-version.yml new file mode 100644 index 0000000000..88168bd202 --- /dev/null +++ b/changelogs/fragments/5688-opkg-module-install-certain-version.yml @@ -0,0 +1,2 @@ +minor_changes: + - opkg - allow installing a package in a certain version (https://github.com/ansible-collections/community.general/pull/5688). diff --git a/plugins/modules/opkg.py b/plugins/modules/opkg.py index 6c5e23093e..7e2b8c4ac2 100644 --- a/plugins/modules/opkg.py +++ b/plugins/modules/opkg.py @@ -22,6 +22,9 @@ options: name: description: - Name of package(s) to install/remove. + - C(NAME=VERSION) syntax is also supported to install a package + in a certain version. See the examples. This is supported since + community.general 6.2.0. aliases: [pkg] required: true type: list @@ -64,6 +67,11 @@ EXAMPLES = ''' name: foo state: present +- name: Install foo in version 1.2 + community.general.opkg: + name: foo=1.2 + state: present + - name: Update cache and install foo community.general.opkg: name: foo @@ -96,22 +104,39 @@ from ansible.module_utils.six.moves import shlex_quote def update_package_db(module, opkg_path): """ Updates packages list. """ - rc, out, err = module.run_command("%s update" % opkg_path) + rc, out, err = module.run_command([opkg_path, "update"]) if rc != 0: module.fail_json(msg="could not update package db") -def query_package(module, opkg_path, name, state="present"): +def query_package(module, opkg_path, name, version=None, state="present"): """ Returns whether a package is installed or not. """ if state == "present": + rc, out, err = module.run_command([opkg_path, "list-installed", name]) + if rc != 0: + return False + # variable out is one line if the package is installed: + # "NAME - VERSION - DESCRIPTION" + if version is not None: + if not out.startswith("%s - %s " % (name, version)): + return False + else: + if not out.startswith(name + " "): + return False + return True + else: + raise NotImplementedError() - rc, out, err = module.run_command("%s list-installed | grep -q \"^%s \"" % (shlex_quote(opkg_path), shlex_quote(name)), use_unsafe_shell=True) - if rc == 0: - return True - return False +def split_name_and_version(module, package): + """ Split the name and the version when using the NAME=VERSION syntax """ + splitted = package.split('=', 1) + if len(splitted) == 1: + return splitted[0], None + else: + return splitted[0], splitted[1] def remove_packages(module, opkg_path, packages): @@ -125,11 +150,16 @@ def remove_packages(module, opkg_path, packages): remove_c = 0 # Using a for loop in case of error, we can report the package that failed for package in packages: + package, version = split_name_and_version(module, package) + # Query the package first, to see if we even need to remove if not query_package(module, opkg_path, package): continue - rc, out, err = module.run_command("%s remove %s %s" % (opkg_path, force, package)) + if force: + rc, out, err = module.run_command([opkg_path, "remove", force, package]) + else: + rc, out, err = module.run_command([opkg_path, "remove", package]) if query_package(module, opkg_path, package): module.fail_json(msg="failed to remove %s: %s" % (package, out)) @@ -154,13 +184,23 @@ def install_packages(module, opkg_path, packages): install_c = 0 for package in packages: - if query_package(module, opkg_path, package) and (force != '--force-reinstall'): + package, version = split_name_and_version(module, package) + + if query_package(module, opkg_path, package, version) and (force != '--force-reinstall'): continue - rc, out, err = module.run_command("%s install %s %s" % (opkg_path, force, package)) + if version is not None: + version_str = "=%s" % version + else: + version_str = "" - if not query_package(module, opkg_path, package): - module.fail_json(msg="failed to install %s: %s" % (package, out)) + if force: + rc, out, err = module.run_command([opkg_path, "install", force, package + version_str]) + else: + rc, out, err = module.run_command([opkg_path, "install", package + version_str]) + + if not query_package(module, opkg_path, package, version): + module.fail_json(msg="failed to install %s%s: %s" % (package, version_str, out)) install_c += 1 From 5fcf5d0c8b61ae4cab4e9a6372327880240b7ba2 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 23 Dec 2022 06:41:39 +0100 Subject: [PATCH 075/134] [PR #5720/6383c823 backport][stable-6] ssh_config: fixed sanity (#5726) ssh_config: fixed sanity (#5720) * ssh_config: fix sanity checks * fixed mod utils and removed sanity ignores * update BOTMETA * add changelog fragment * Update plugins/module_utils/ssh.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 6383c82328f32a6221fa7dd88fc92910966b5457) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .github/BOTMETA.yml | 2 ++ .../5720-ssh_config-plugin-sanity.yml | 2 ++ plugins/module_utils/ssh.py | 21 +++++++++++++++++++ plugins/modules/ssh_config.py | 6 ++---- tests/sanity/ignore-2.11.txt | 1 - tests/sanity/ignore-2.12.txt | 1 - tests/sanity/ignore-2.13.txt | 1 - tests/sanity/ignore-2.14.txt | 1 - tests/sanity/ignore-2.15.txt | 1 - 9 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 changelogs/fragments/5720-ssh_config-plugin-sanity.yml create mode 100644 plugins/module_utils/ssh.py diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 015f2aa37d..422048ca88 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -323,6 +323,8 @@ files: $module_utils/scaleway.py: labels: cloud scaleway maintainers: $team_scaleway + $module_utils/ssh.py: + maintainers: russoz $module_utils/storage/hpe3par/hpe3par.py: maintainers: farhan7500 gautamphegde $module_utils/utm_utils.py: diff --git a/changelogs/fragments/5720-ssh_config-plugin-sanity.yml b/changelogs/fragments/5720-ssh_config-plugin-sanity.yml new file mode 100644 index 0000000000..19d57ea145 --- /dev/null +++ b/changelogs/fragments/5720-ssh_config-plugin-sanity.yml @@ -0,0 +1,2 @@ +minor_changes: + - ssh_config - refactor code to module util to fix sanity check (https://github.com/ansible-collections/community.general/pull/5720). diff --git a/plugins/module_utils/ssh.py b/plugins/module_utils/ssh.py new file mode 100644 index 0000000000..082839e26d --- /dev/null +++ b/plugins/module_utils/ssh.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, BjΓΆrn Andersson +# Copyright (c) 2021, Ansible Project +# Copyright (c) 2021, Abhijeet Kasurde +# Copyright (c) 2022, Alexei Znamensky +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +import os + + +def determine_config_file(user, config_file): + if user: + config_file = os.path.join(os.path.expanduser('~%s' % user), '.ssh', 'config') + elif config_file is None: + config_file = '/etc/ssh/ssh_config' + return config_file diff --git a/plugins/modules/ssh_config.py b/plugins/modules/ssh_config.py index cb028ac8e5..f2fa8aa457 100644 --- a/plugins/modules/ssh_config.py +++ b/plugins/modules/ssh_config.py @@ -169,6 +169,7 @@ except ImportError: from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.common.text.converters import to_native +from ansible_collections.community.general.plugins.module_utils.ssh import determine_config_file class SSHConfig(): @@ -188,10 +189,7 @@ class SSHConfig(): self.config.load() def check_ssh_config_path(self): - if self.user: - self.config_file = os.path.join(os.path.expanduser('~%s' % self.user), '.ssh', 'config') - elif self.config_file is None: - self.config_file = '/etc/ssh/ssh_config' + self.config_file = determine_config_file(self.user, self.config_file) # See if the identity file exists or not, relative to the config file if os.path.exists(self.config_file) and self.identity_file is not None: diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index e49b216f6e..77738afd40 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -23,7 +23,6 @@ plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice -plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path tests/integration/targets/django_manage/files/base_test/simple_project/p1/manage.py compile-2.6 # django generated code diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index 0cf9b73046..61494a1ab1 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -18,6 +18,5 @@ plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice -plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index 0cf9b73046..61494a1ab1 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -18,6 +18,5 @@ plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice -plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index efdb15f969..6b9026caea 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -19,7 +19,6 @@ plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice -plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index efdb15f969..6b9026caea 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -19,7 +19,6 @@ plugins/modules/rax_files_objects.py use-argspec-type-path plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice -plugins/modules/ssh_config.py use-argspec-type-path # Required since module uses other methods to specify path plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/xfconf.py validate-modules:return-syntax-error plugins/modules/yarn.py use-argspec-type-path From 2ab26db197a73b2cd192731a060518efc01dc787 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 23 Dec 2022 11:47:47 +0100 Subject: [PATCH 076/134] [PR #5658/669d0925 backport][stable-6] Feature: Provide project field for LXD inventory plugin (#5729) Feature: Provide project field for LXD inventory plugin (#5658) * Provide project field for LXD inventory plugin if field `project` exists in `lxd.yml`, the instances are searched in the given LXD project. if project field is not defined the default project named `default` will be used. Signed-off-by: omani <3346207+omani@users.noreply.github.com> * Update plugins/inventory/lxd.py Signed-off-by: omani <3346207+omani@users.noreply.github.com> Co-authored-by: Felix Fontein (cherry picked from commit 669d0925f71cf591b45bf890b33625d182ae4fc8) Co-authored-by: HAH! Sun <3346207+omani@users.noreply.github.com> --- plugins/inventory/lxd.py | 55 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/plugins/inventory/lxd.py b/plugins/inventory/lxd.py index 291d12b037..2e37de70c1 100644 --- a/plugins/inventory/lxd.py +++ b/plugins/inventory/lxd.py @@ -55,6 +55,11 @@ DOCUMENTATION = r''' type: str default: none choices: [ 'STOPPED', 'STARTING', 'RUNNING', 'none' ] + project: + description: Filter the instance according to the given project. + type: str + default: default + version_added: 6.2.0 type_filter: description: - Filter the instances by type C(virtual-machine), C(container) or C(both). @@ -140,6 +145,9 @@ groupby: vlan666: type: vlanid attribute: 666 + projectInternals: + type: project + attribute: internals ''' import binascii @@ -153,6 +161,7 @@ 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.module_utils.six.moves.urllib.parse import urlencode from ansible_collections.community.general.plugins.module_utils.lxd import LXDClient, LXDClientException try: @@ -330,7 +339,15 @@ class InventoryModule(BaseInventoryPlugin): # "status_code": 200, # "type": "sync" # } - instances = self.socket.do('GET', '/1.0/instances') + url = '/1.0/instances' + if self.project: + url = url + '?{0}'.format(urlencode(dict(project=self.project))) + + instances = self.socket.do('GET', url) + + if self.project: + return [m.split('/')[3].split('?')[0] for m in instances['metadata']] + return [m.split('/')[3] for m in instances['metadata']] def _get_config(self, branch, name): @@ -351,9 +368,11 @@ class InventoryModule(BaseInventoryPlugin): dict(config): Config of the instance""" config = {} if isinstance(branch, (tuple, list)): - config[name] = {branch[1]: self.socket.do('GET', '/1.0/{0}/{1}/{2}'.format(to_native(branch[0]), to_native(name), to_native(branch[1])))} + config[name] = {branch[1]: self.socket.do( + 'GET', '/1.0/{0}/{1}/{2}?{3}'.format(to_native(branch[0]), to_native(name), to_native(branch[1]), urlencode(dict(project=self.project))))} else: - config[name] = {branch: self.socket.do('GET', '/1.0/{0}/{1}'.format(to_native(branch), to_native(name)))} + config[name] = {branch: self.socket.do( + 'GET', '/1.0/{0}/{1}?{2}'.format(to_native(branch), to_native(name), urlencode(dict(project=self.project))))} return config def get_instance_data(self, names): @@ -583,6 +602,8 @@ class InventoryModule(BaseInventoryPlugin): self._set_data_entry(instance_name, 'network_interfaces', self.extract_network_information_from_instance_config(instance_name)) self._set_data_entry(instance_name, 'preferred_interface', self.get_prefered_instance_network_interface(instance_name)) self._set_data_entry(instance_name, 'vlan_ids', self.get_instance_vlans(instance_name)) + self._set_data_entry(instance_name, 'project', self._get_data_entry( + 'instances/{0}/instances/metadata/project'.format(instance_name))) def build_inventory_network(self, instance_name): """Add the network interfaces of the instance to the inventory @@ -686,6 +707,8 @@ class InventoryModule(BaseInventoryPlugin): # add VLAN_ID information if self._get_data_entry('inventory/{0}/vlan_ids'.format(instance_name)): self.inventory.set_variable(instance_name, 'ansible_lxd_vlan_ids', self._get_data_entry('inventory/{0}/vlan_ids'.format(instance_name))) + # add project + self.inventory.set_variable(instance_name, 'ansible_lxd_project', self._get_data_entry('inventory/{0}/project'.format(instance_name))) def build_inventory_groups_location(self, group_name): """create group by attribute: location @@ -761,6 +784,28 @@ class InventoryModule(BaseInventoryPlugin): # Ignore invalid IP addresses returned by lxd pass + def build_inventory_groups_project(self, group_name): + """create group by attribute: project + + Args: + str(group_name): Group name + Kwargs: + None + Raises: + None + Returns: + None""" + # maybe we just want to expand one group + if group_name not in self.inventory.groups: + self.inventory.add_group(group_name) + + gen_instances = [ + instance_name for instance_name in self.inventory.hosts + if 'ansible_lxd_project' in self.inventory.get_host(instance_name).get_vars()] + for instance_name in gen_instances: + if self.groupby[group_name].get('attribute').lower() == self.inventory.get_host(instance_name).get_vars().get('ansible_lxd_project'): + self.inventory.add_child(group_name, instance_name) + def build_inventory_groups_os(self, group_name): """create group by attribute: os @@ -899,6 +944,7 @@ class InventoryModule(BaseInventoryPlugin): * 'profile' * 'vlanid' * 'type' + * 'project' Args: str(group_name): Group name @@ -926,6 +972,8 @@ class InventoryModule(BaseInventoryPlugin): self.build_inventory_groups_vlanid(group_name) elif self.groupby[group_name].get('type') == 'type': self.build_inventory_groups_type(group_name) + elif self.groupby[group_name].get('type') == 'project': + self.build_inventory_groups_project(group_name) else: raise AnsibleParserError('Unknown group type: {0}'.format(to_native(group_name))) @@ -1032,6 +1080,7 @@ class InventoryModule(BaseInventoryPlugin): try: self.client_key = self.get_option('client_key') self.client_cert = self.get_option('client_cert') + self.project = self.get_option('project') self.debug = self.DEBUG self.data = {} # store for inventory-data self.groupby = self.get_option('groupby') From 50b9855ace9ae0fe125472ac6a84af34def5f52d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 30 Dec 2022 22:18:40 +0100 Subject: [PATCH 077/134] [PR #5714/2d4ce9f2 backport][stable-6] feat: add tags to proxmox containers (#5745) feat: add tags to proxmox containers (#5714) * feat: add tags to proxmox containers * fix: correct version added * fix: code style * feat: changelog fragment * fix: correct version_added Co-authored-by: Felix Fontein * feat: fail on unsupported params, rather than silently ignoring them * fix: actually check unsupported feature presence before failing Co-authored-by: Felix Fontein (cherry picked from commit 2d4ce9f21970a2d126550135ba35f7c9a0cfb449) Co-authored-by: GuillaumeV-cemea <101114641+GuillaumeV-cemea@users.noreply.github.com> --- .../5714-proxmox-lxc-tag-support.yml | 3 ++ plugins/modules/proxmox.py | 35 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5714-proxmox-lxc-tag-support.yml diff --git a/changelogs/fragments/5714-proxmox-lxc-tag-support.yml b/changelogs/fragments/5714-proxmox-lxc-tag-support.yml new file mode 100644 index 0000000000..5e3dcc8fcf --- /dev/null +++ b/changelogs/fragments/5714-proxmox-lxc-tag-support.yml @@ -0,0 +1,3 @@ +--- +minor_changes: +- proxmox - added new module parameter ``tags`` for use with PVE 7+ (https://github.com/ansible-collections/community.general/pull/5714). diff --git a/plugins/modules/proxmox.py b/plugins/modules/proxmox.py index 89706655f2..640f9b4114 100644 --- a/plugins/modules/proxmox.py +++ b/plugins/modules/proxmox.py @@ -106,6 +106,14 @@ options: description: - sets DNS search domain for a container type: str + tags: + description: + - List of tags to apply to the container. + - Tags must start with C([a-z0-9_]) followed by zero or more of the following characters C([a-z0-9_-+.]). + - Tags are only available in Proxmox 7+. + type: list + elements: str + version_added: 6.2.0 timeout: description: - timeout for operations @@ -391,6 +399,7 @@ EXAMPLES = r''' state: absent ''' +import re import time from ansible_collections.community.general.plugins.module_utils.version import LooseVersion @@ -415,11 +424,25 @@ class ProxmoxLxcAnsible(ProxmoxAnsible): return config['template'] def create_instance(self, vmid, node, disk, storage, cpus, memory, swap, timeout, clone, **kwargs): + + # Version limited features + minimum_version = { + 'tags': 7, + } proxmox_node = self.proxmox_api.nodes(node) # Remove all empty kwarg entries kwargs = dict((k, v) for k, v in kwargs.items() if v is not None) + version = self.version() + pve_major_version = 3 if version < LooseVersion('4.0') else version.version[0] + + # Fail on unsupported features + for option, version in minimum_version.items(): + if pve_major_version < version and option in kwargs: + self.module.fail_json(changed=False, msg="Feature {option} is only supported in PVE {version}+, and you're using PVE {pve_major_version}". + format(option=option, version=version, pve_major_version=pve_major_version)) + if VZ_TYPE == 'lxc': kwargs['cpulimit'] = cpus kwargs['rootfs'] = disk @@ -437,6 +460,14 @@ class ProxmoxLxcAnsible(ProxmoxAnsible): kwargs['cpus'] = cpus kwargs['disk'] = disk + # LXC tags are expected to be valid and presented as a comma/semi-colon delimited string + if 'tags' in kwargs: + re_tag = re.compile(r'^[a-z0-9_][a-z0-9_\-\+\.]*$') + for tag in kwargs['tags']: + if not re_tag.match(tag): + self.module.fail_json(msg='%s is not a valid tag' % tag) + kwargs['tags'] = ",".join(kwargs['tags']) + if clone is not None: if VZ_TYPE != 'lxc': self.module.fail_json(changed=False, msg="Clone operator is only supported for LXC enabled proxmox clusters.") @@ -569,6 +600,7 @@ def main(): proxmox_default_behavior=dict(type='str', default='no_defaults', choices=['compatibility', 'no_defaults']), clone=dict(type='int'), clone_type=dict(default='opportunistic', choices=['full', 'linked', 'opportunistic']), + tags=dict(type='list', elements='str') ) module_args.update(proxmox_args) @@ -674,7 +706,8 @@ def main(): features=",".join(module.params['features']) if module.params['features'] is not None else None, unprivileged=ansible_to_proxmox_bool(module.params['unprivileged']), description=module.params['description'], - hookscript=module.params['hookscript']) + hookscript=module.params['hookscript'], + tags=module.params['tags']) module.exit_json(changed=True, msg="Deployed VM %s from template %s" % (vmid, module.params['ostemplate'])) except Exception as e: From ac35bf4acb986c48890b38571728c7adda50f5af Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 31 Dec 2022 07:54:09 +0100 Subject: [PATCH 078/134] [PR #5744/568e1880 backport][stable-6] unixy Callback: Fix typo using ansibles config manager (#5747) unixy Callback: Fix typo using ansibles config manager (#5744) Fixes typo introduced in 53da86c. Signed-off-by: Fabian P. Schmidt Signed-off-by: Fabian P. Schmidt (cherry picked from commit 568e18809c7cb0b7057feb77bbc919efe5752d8d) Co-authored-by: Fabian P. Schmidt --- .../fragments/5744-unixy-callback-fix-config-manager-typo.yml | 2 ++ plugins/callback/unixy.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5744-unixy-callback-fix-config-manager-typo.yml diff --git a/changelogs/fragments/5744-unixy-callback-fix-config-manager-typo.yml b/changelogs/fragments/5744-unixy-callback-fix-config-manager-typo.yml new file mode 100644 index 0000000000..d60b43d3d4 --- /dev/null +++ b/changelogs/fragments/5744-unixy-callback-fix-config-manager-typo.yml @@ -0,0 +1,2 @@ +bugfixes: + - unixy callback plugin - fix typo introduced when updating to use Ansible's configuration manager for handling options (https://github.com/ansible-collections/community.general/issues/5600). diff --git a/plugins/callback/unixy.py b/plugins/callback/unixy.py index 55f46afd32..02a2e46ba6 100644 --- a/plugins/callback/unixy.py +++ b/plugins/callback/unixy.py @@ -142,7 +142,7 @@ class CallbackModule(CallbackModule_default): display_color = C.COLOR_CHANGED task_result = self._process_result_output(result, msg) self._display.display(" " + task_result, display_color) - elif self.get('display_ok_hosts'): + elif self.get_option('display_ok_hosts'): task_result = self._process_result_output(result, msg) self._display.display(" " + task_result, display_color) From c10e9e26503fe0ad6ceddb86fe9375019c442ed4 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 31 Dec 2022 08:13:04 +0100 Subject: [PATCH 079/134] [PR #5741/06d72dfe backport][stable-6] htpasswd: improve documentation on crypt_scheme (#5749) htpasswd: improve documentation on crypt_scheme (#5741) * htpasswd: improve documentation on crypt_scheme * htpasswd: formatting in documentation Co-authored-by: Felix Fontein * htpasswd: formatting in documentation Co-authored-by: Felix Fontein * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Felix Fontein (cherry picked from commit 06d72dfed9c19b7995c7d4665365e112d08c4427) Co-authored-by: bluikko <14869000+bluikko@users.noreply.github.com> --- plugins/modules/htpasswd.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/modules/htpasswd.py b/plugins/modules/htpasswd.py index f24eaa0087..231506984a 100644 --- a/plugins/modules/htpasswd.py +++ b/plugins/modules/htpasswd.py @@ -41,9 +41,12 @@ options: description: - Encryption scheme to be used. As well as the four choices listed here, you can also use any other hash supported by passlib, such as - md5_crypt and sha256_crypt, which are linux passwd hashes. If you - do so the password file will not be compatible with Apache or Nginx - - 'Some of the available choices might be: C(apr_md5_crypt), C(des_crypt), C(ldap_sha1), C(plaintext)' + C(portable_apache22) and C(host_apache24); or C(md5_crypt) and C(sha256_crypt), + which are Linux passwd hashes. Only some schemes in addition to + the four choices below will be compatible with Apache or Nginx, and + supported schemes depend on passlib version and its dependencies. + - See U(https://passlib.readthedocs.io/en/stable/lib/passlib.apache.html#passlib.apache.HtpasswdFile) parameter C(default_scheme). + - 'Some of the available choices might be: C(apr_md5_crypt), C(des_crypt), C(ldap_sha1), C(plaintext).' state: type: str required: false From 95beb452a84bb60dc13e81d2738fbafbe8b87859 Mon Sep 17 00:00:00 2001 From: Alexei Znamensky <103110+russoz@users.noreply.github.com> Date: Wed, 4 Jan 2023 11:35:26 +1300 Subject: [PATCH 080/134] rax modules: deprecation notice for branch stable-6 (#5733) * rax modules: deprecation notice for branch stable-6 * add changelog fragment * adjust changelog message * adjust changelog message --- .../fragments/5733-rax-deprecation-notice.yml | 27 +++++++++++++++++++ plugins/modules/rax_cbs.py | 4 ++- plugins/modules/rax_cbs_attachments.py | 4 ++- plugins/modules/rax_cdb.py | 2 ++ plugins/modules/rax_cdb_database.py | 2 ++ plugins/modules/rax_cdb_user.py | 2 ++ plugins/modules/rax_clb.py | 4 ++- plugins/modules/rax_clb_nodes.py | 4 ++- plugins/modules/rax_clb_ssl.py | 4 ++- plugins/modules/rax_dns.py | 4 ++- plugins/modules/rax_dns_record.py | 4 ++- plugins/modules/rax_facts.py | 2 ++ plugins/modules/rax_files.py | 4 ++- plugins/modules/rax_files_objects.py | 2 ++ plugins/modules/rax_identity.py | 4 ++- plugins/modules/rax_keypair.py | 4 ++- plugins/modules/rax_meta.py | 4 ++- plugins/modules/rax_mon_alarm.py | 14 +++++----- plugins/modules/rax_mon_check.py | 14 +++++----- plugins/modules/rax_mon_entity.py | 12 +++++---- plugins/modules/rax_mon_notification_plan.py | 10 ++++--- 21 files changed, 99 insertions(+), 32 deletions(-) create mode 100644 changelogs/fragments/5733-rax-deprecation-notice.yml diff --git a/changelogs/fragments/5733-rax-deprecation-notice.yml b/changelogs/fragments/5733-rax-deprecation-notice.yml new file mode 100644 index 0000000000..ac9d3d9b32 --- /dev/null +++ b/changelogs/fragments/5733-rax-deprecation-notice.yml @@ -0,0 +1,27 @@ +deprecated_features: + - rax_cbs_attachments - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_cbs - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_cdb_database - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_cdb - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_cdb_user - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_clb_nodes - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_clb - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_clb_ssl - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_dns - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_dns_record - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_facts - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_files_objects - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_files - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_identity - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_keypair - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_meta - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_mon_alarm - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_mon_check - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_mon_entity - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_mon_notification_plan - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_mon_notification - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_network - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_queue - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_scaling_group - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_scaling_policy - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). diff --git a/plugins/modules/rax_cbs.py b/plugins/modules/rax_cbs.py index dd8bcefa35..42e5693614 100644 --- a/plugins/modules/rax_cbs.py +++ b/plugins/modules/rax_cbs.py @@ -13,7 +13,9 @@ DOCUMENTATION = ''' module: rax_cbs short_description: Manipulate Rackspace Cloud Block Storage Volumes description: - - Manipulate Rackspace Cloud Block Storage Volumes + - Manipulate Rackspace Cloud Block Storage Volumes + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: description: type: str diff --git a/plugins/modules/rax_cbs_attachments.py b/plugins/modules/rax_cbs_attachments.py index 82a1f30cfb..7cb68cf2b3 100644 --- a/plugins/modules/rax_cbs_attachments.py +++ b/plugins/modules/rax_cbs_attachments.py @@ -13,7 +13,9 @@ DOCUMENTATION = ''' module: rax_cbs_attachments short_description: Manipulate Rackspace Cloud Block Storage Volume Attachments description: - - Manipulate Rackspace Cloud Block Storage Volume Attachments + - Manipulate Rackspace Cloud Block Storage Volume Attachments + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: device: type: str diff --git a/plugins/modules/rax_cdb.py b/plugins/modules/rax_cdb.py index 3fb6194d9d..a6c3ca56c3 100644 --- a/plugins/modules/rax_cdb.py +++ b/plugins/modules/rax_cdb.py @@ -16,6 +16,8 @@ description: - creates / deletes or resize a Rackspace Cloud Databases instance and optionally waits for it to be 'running'. The name option needs to be unique since it's used to identify the instance. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: name: type: str diff --git a/plugins/modules/rax_cdb_database.py b/plugins/modules/rax_cdb_database.py index 6e0e8411c2..6a1995f771 100644 --- a/plugins/modules/rax_cdb_database.py +++ b/plugins/modules/rax_cdb_database.py @@ -13,6 +13,8 @@ module: rax_cdb_database short_description: Create / delete a database in the Cloud Databases description: - create / delete a database in the Cloud Databases. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: cdb_id: type: str diff --git a/plugins/modules/rax_cdb_user.py b/plugins/modules/rax_cdb_user.py index 63cb00b608..e489bd2e5c 100644 --- a/plugins/modules/rax_cdb_user.py +++ b/plugins/modules/rax_cdb_user.py @@ -14,6 +14,8 @@ module: rax_cdb_user short_description: Create / delete a Rackspace Cloud Database description: - create / delete a database in the Cloud Databases. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: cdb_id: type: str diff --git a/plugins/modules/rax_clb.py b/plugins/modules/rax_clb.py index 8355a42921..091a33d81c 100644 --- a/plugins/modules/rax_clb.py +++ b/plugins/modules/rax_clb.py @@ -13,7 +13,9 @@ DOCUMENTATION = ''' module: rax_clb short_description: Create / delete a load balancer in Rackspace Public Cloud description: - - creates / deletes a Rackspace Public Cloud load balancer. + - creates / deletes a Rackspace Public Cloud load balancer. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: algorithm: type: str diff --git a/plugins/modules/rax_clb_nodes.py b/plugins/modules/rax_clb_nodes.py index e6d050de46..8c72107372 100644 --- a/plugins/modules/rax_clb_nodes.py +++ b/plugins/modules/rax_clb_nodes.py @@ -13,7 +13,9 @@ DOCUMENTATION = ''' module: rax_clb_nodes short_description: Add, modify and remove nodes from a Rackspace Cloud Load Balancer description: - - Adds, modifies and removes nodes from a Rackspace Cloud Load Balancer + - Adds, modifies and removes nodes from a Rackspace Cloud Load Balancer. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: address: type: str diff --git a/plugins/modules/rax_clb_ssl.py b/plugins/modules/rax_clb_ssl.py index 85110d3390..f31c5b37f7 100644 --- a/plugins/modules/rax_clb_ssl.py +++ b/plugins/modules/rax_clb_ssl.py @@ -12,7 +12,9 @@ DOCUMENTATION = ''' module: rax_clb_ssl short_description: Manage SSL termination for a Rackspace Cloud Load Balancer description: -- Set up, reconfigure, or remove SSL termination for an existing load balancer. + - Set up, reconfigure, or remove SSL termination for an existing load balancer. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: loadbalancer: type: str diff --git a/plugins/modules/rax_dns.py b/plugins/modules/rax_dns.py index a97a4bb175..646d296589 100644 --- a/plugins/modules/rax_dns.py +++ b/plugins/modules/rax_dns.py @@ -13,7 +13,9 @@ DOCUMENTATION = ''' module: rax_dns short_description: Manage domains on Rackspace Cloud DNS description: - - Manage domains on Rackspace Cloud DNS + - Manage domains on Rackspace Cloud DNS. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: comment: type: str diff --git a/plugins/modules/rax_dns_record.py b/plugins/modules/rax_dns_record.py index e51424dc04..0175161c68 100644 --- a/plugins/modules/rax_dns_record.py +++ b/plugins/modules/rax_dns_record.py @@ -13,7 +13,9 @@ DOCUMENTATION = ''' module: rax_dns_record short_description: Manage DNS records on Rackspace Cloud DNS description: - - Manage DNS records on Rackspace Cloud DNS + - Manage DNS records on Rackspace Cloud DNS. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: comment: type: str diff --git a/plugins/modules/rax_facts.py b/plugins/modules/rax_facts.py index 53657f3c9a..a2e4f2a901 100644 --- a/plugins/modules/rax_facts.py +++ b/plugins/modules/rax_facts.py @@ -14,6 +14,8 @@ module: rax_facts short_description: Gather facts for Rackspace Cloud Servers description: - Gather facts for Rackspace Cloud Servers. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: address: type: str diff --git a/plugins/modules/rax_files.py b/plugins/modules/rax_files.py index 1c549827cc..7a07bc6356 100644 --- a/plugins/modules/rax_files.py +++ b/plugins/modules/rax_files.py @@ -13,7 +13,9 @@ DOCUMENTATION = ''' module: rax_files short_description: Manipulate Rackspace Cloud Files Containers description: - - Manipulate Rackspace Cloud Files Containers + - Manipulate Rackspace Cloud Files Containers. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: clear_meta: description: diff --git a/plugins/modules/rax_files_objects.py b/plugins/modules/rax_files_objects.py index 82bedffddb..96ab0a5731 100644 --- a/plugins/modules/rax_files_objects.py +++ b/plugins/modules/rax_files_objects.py @@ -14,6 +14,8 @@ module: rax_files_objects short_description: Upload, download, and delete objects in Rackspace Cloud Files description: - Upload, download, and delete objects in Rackspace Cloud Files. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: clear_meta: description: diff --git a/plugins/modules/rax_identity.py b/plugins/modules/rax_identity.py index 6f7472bcf4..f78d5d7329 100644 --- a/plugins/modules/rax_identity.py +++ b/plugins/modules/rax_identity.py @@ -13,7 +13,9 @@ DOCUMENTATION = ''' module: rax_identity short_description: Load Rackspace Cloud Identity description: - - Verifies Rackspace Cloud credentials and returns identity information + - Verifies Rackspace Cloud credentials and returns identity information. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: state: type: str diff --git a/plugins/modules/rax_keypair.py b/plugins/modules/rax_keypair.py index 6664ac8bd0..5a8dae334d 100644 --- a/plugins/modules/rax_keypair.py +++ b/plugins/modules/rax_keypair.py @@ -13,7 +13,9 @@ DOCUMENTATION = ''' module: rax_keypair short_description: Create a keypair for use with Rackspace Cloud Servers description: - - Create a keypair for use with Rackspace Cloud Servers + - Create a keypair for use with Rackspace Cloud Servers. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: name: type: str diff --git a/plugins/modules/rax_meta.py b/plugins/modules/rax_meta.py index 33acad365c..0cb21832ec 100644 --- a/plugins/modules/rax_meta.py +++ b/plugins/modules/rax_meta.py @@ -13,7 +13,9 @@ DOCUMENTATION = ''' module: rax_meta short_description: Manipulate metadata for Rackspace Cloud Servers description: - - Manipulate metadata for Rackspace Cloud Servers + - Manipulate metadata for Rackspace Cloud Servers. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: address: type: str diff --git a/plugins/modules/rax_mon_alarm.py b/plugins/modules/rax_mon_alarm.py index d167420341..5b34e3cf9f 100644 --- a/plugins/modules/rax_mon_alarm.py +++ b/plugins/modules/rax_mon_alarm.py @@ -13,12 +13,14 @@ DOCUMENTATION = ''' module: rax_mon_alarm short_description: Create or delete a Rackspace Cloud Monitoring alarm description: -- Create or delete a Rackspace Cloud Monitoring alarm that associates an - existing rax_mon_entity, rax_mon_check, and rax_mon_notification_plan with - criteria that specify what conditions will trigger which levels of - notifications. Rackspace monitoring module flow | rax_mon_entity -> - rax_mon_check -> rax_mon_notification -> rax_mon_notification_plan -> - *rax_mon_alarm* + - Create or delete a Rackspace Cloud Monitoring alarm that associates an + existing rax_mon_entity, rax_mon_check, and rax_mon_notification_plan with + criteria that specify what conditions will trigger which levels of + notifications. Rackspace monitoring module flow | rax_mon_entity -> + rax_mon_check -> rax_mon_notification -> rax_mon_notification_plan -> + *rax_mon_alarm*. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: state: type: str diff --git a/plugins/modules/rax_mon_check.py b/plugins/modules/rax_mon_check.py index c6259dab47..b9c543e723 100644 --- a/plugins/modules/rax_mon_check.py +++ b/plugins/modules/rax_mon_check.py @@ -14,12 +14,14 @@ module: rax_mon_check short_description: Create or delete a Rackspace Cloud Monitoring check for an existing entity. description: -- Create or delete a Rackspace Cloud Monitoring check associated with an - existing rax_mon_entity. A check is a specific test or measurement that is - performed, possibly from different monitoring zones, on the systems you - monitor. Rackspace monitoring module flow | rax_mon_entity -> - *rax_mon_check* -> rax_mon_notification -> rax_mon_notification_plan -> - rax_mon_alarm + - Create or delete a Rackspace Cloud Monitoring check associated with an + existing rax_mon_entity. A check is a specific test or measurement that is + performed, possibly from different monitoring zones, on the systems you + monitor. Rackspace monitoring module flow | rax_mon_entity -> + *rax_mon_check* -> rax_mon_notification -> rax_mon_notification_plan -> + rax_mon_alarm + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: state: type: str diff --git a/plugins/modules/rax_mon_entity.py b/plugins/modules/rax_mon_entity.py index cc502496dc..cd5526719b 100644 --- a/plugins/modules/rax_mon_entity.py +++ b/plugins/modules/rax_mon_entity.py @@ -13,11 +13,13 @@ DOCUMENTATION = ''' module: rax_mon_entity short_description: Create or delete a Rackspace Cloud Monitoring entity description: -- Create or delete a Rackspace Cloud Monitoring entity, which represents a device - to monitor. Entities associate checks and alarms with a target system and - provide a convenient, centralized place to store IP addresses. Rackspace - monitoring module flow | *rax_mon_entity* -> rax_mon_check -> - rax_mon_notification -> rax_mon_notification_plan -> rax_mon_alarm + - Create or delete a Rackspace Cloud Monitoring entity, which represents a device + to monitor. Entities associate checks and alarms with a target system and + provide a convenient, centralized place to store IP addresses. Rackspace + monitoring module flow | *rax_mon_entity* -> rax_mon_check -> + rax_mon_notification -> rax_mon_notification_plan -> rax_mon_alarm. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: label: type: str diff --git a/plugins/modules/rax_mon_notification_plan.py b/plugins/modules/rax_mon_notification_plan.py index 7800ea0fe9..84de4a2fa3 100644 --- a/plugins/modules/rax_mon_notification_plan.py +++ b/plugins/modules/rax_mon_notification_plan.py @@ -14,10 +14,12 @@ module: rax_mon_notification_plan short_description: Create or delete a Rackspace Cloud Monitoring notification plan. description: -- Create or delete a Rackspace Cloud Monitoring notification plan by - associating existing rax_mon_notifications with severity levels. Rackspace - monitoring module flow | rax_mon_entity -> rax_mon_check -> - rax_mon_notification -> *rax_mon_notification_plan* -> rax_mon_alarm + - Create or delete a Rackspace Cloud Monitoring notification plan by + associating existing rax_mon_notifications with severity levels. Rackspace + monitoring module flow | rax_mon_entity -> rax_mon_check -> + rax_mon_notification -> *rax_mon_notification_plan* -> rax_mon_alarm. + - This module relies on the C(pyrax) package which is deprecated in favour of using Openstack API. + - Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0. options: state: type: str From 6fc8492ecfbee40c127cd3c8075e361ee3e4f684 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 3 Jan 2023 23:53:45 +0100 Subject: [PATCH 081/134] Prepare 6.2.0 release. --- changelogs/fragments/6.2.0.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/fragments/6.2.0.yml diff --git a/changelogs/fragments/6.2.0.yml b/changelogs/fragments/6.2.0.yml new file mode 100644 index 0000000000..4b1469c9fe --- /dev/null +++ b/changelogs/fragments/6.2.0.yml @@ -0,0 +1 @@ +release_summary: Regular bugfix and feature release. From e978fd4d61b56339154e1082aa2ff4763c823dae Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Wed, 4 Jan 2023 07:29:45 +0100 Subject: [PATCH 082/134] Release 6.2.0. --- CHANGELOG.rst | 62 +++++++++ changelogs/changelog.yaml | 129 ++++++++++++++++++ .../fragments/5612-puppet-cmd-runner.yml | 2 - .../5659-fix-lxc_container-command.yml | 2 - ...dhat_subscription-server_proxy_scheme.yaml | 3 - .../fragments/5666-gitlab-variables.yml | 3 - changelogs/fragments/5672-proxmox.yml | 3 - ...5680-ansible_galaxy_install-fx-locale.yaml | 3 - ...88-opkg-module-install-certain-version.yml | 2 - .../fragments/5703-sudoers-host-support.yml | 2 - .../5705-opkg-fix-force-reinstall.yml | 2 - .../5714-proxmox-lxc-tag-support.yml | 3 - .../5720-ssh_config-plugin-sanity.yml | 2 - ...anageiq-policies-deprecate-list-state.yaml | 2 - .../fragments/5733-rax-deprecation-notice.yml | 27 ---- ...unixy-callback-fix-config-manager-typo.yml | 2 - changelogs/fragments/6.2.0.yml | 1 - 17 files changed, 191 insertions(+), 59 deletions(-) delete mode 100644 changelogs/fragments/5612-puppet-cmd-runner.yml delete mode 100644 changelogs/fragments/5659-fix-lxc_container-command.yml delete mode 100644 changelogs/fragments/5662-redhat_subscription-server_proxy_scheme.yaml delete mode 100644 changelogs/fragments/5666-gitlab-variables.yml delete mode 100644 changelogs/fragments/5672-proxmox.yml delete mode 100644 changelogs/fragments/5680-ansible_galaxy_install-fx-locale.yaml delete mode 100644 changelogs/fragments/5688-opkg-module-install-certain-version.yml delete mode 100644 changelogs/fragments/5703-sudoers-host-support.yml delete mode 100644 changelogs/fragments/5705-opkg-fix-force-reinstall.yml delete mode 100644 changelogs/fragments/5714-proxmox-lxc-tag-support.yml delete mode 100644 changelogs/fragments/5720-ssh_config-plugin-sanity.yml delete mode 100644 changelogs/fragments/5721-manageiq-policies-deprecate-list-state.yaml delete mode 100644 changelogs/fragments/5733-rax-deprecation-notice.yml delete mode 100644 changelogs/fragments/5744-unixy-callback-fix-config-manager-typo.yml delete mode 100644 changelogs/fragments/6.2.0.yml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1a9513cd5a..b74e399820 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,68 @@ Community General Release Notes This changelog describes changes after version 5.0.0. +v6.2.0 +====== + +Release Summary +--------------- + +Regular bugfix and feature release. + +Minor Changes +------------- + +- opkg - allow installing a package in a certain version (https://github.com/ansible-collections/community.general/pull/5688). +- proxmox - added new module parameter ``tags`` for use with PVE 7+ (https://github.com/ansible-collections/community.general/pull/5714). +- puppet - refactored module to use ``CmdRunner`` for executing ``puppet`` (https://github.com/ansible-collections/community.general/pull/5612). +- redhat_subscription - add a ``server_proxy_scheme`` parameter to configure the scheme for the proxy server (https://github.com/ansible-collections/community.general/pull/5662). +- ssh_config - refactor code to module util to fix sanity check (https://github.com/ansible-collections/community.general/pull/5720). +- sudoers - adds ``host`` parameter for setting hostname restrictions in sudoers rules (https://github.com/ansible-collections/community.general/issues/5702). + +Deprecated Features +------------------- + +- manageiq_policies - deprecate ``state=list`` in favour of using ``community.general.manageiq_policies_info`` (https://github.com/ansible-collections/community.general/pull/5721). +- rax - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_cbs - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_cbs_attachments - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_cdb - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_cdb_database - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_cdb_user - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_clb - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_clb_nodes - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_clb_ssl - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_dns - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_dns_record - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_facts - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_files - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_files_objects - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_identity - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_keypair - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_meta - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_mon_alarm - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_mon_check - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_mon_entity - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_mon_notification - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_mon_notification_plan - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_network - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_queue - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_scaling_group - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). +- rax_scaling_policy - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + +Bugfixes +-------- + +- ansible_galaxy_install - set default to raise exception if command's return code is different from zero (https://github.com/ansible-collections/community.general/pull/5680). +- ansible_galaxy_install - try ``C.UTF-8`` and then fall back to ``en_US.UTF-8`` before failing (https://github.com/ansible-collections/community.general/pull/5680). +- gitlab_group_variables - fix dropping variables accidentally when GitLab introduced new properties (https://github.com/ansible-collections/community.general/pull/5667). +- gitlab_project_variables - fix dropping variables accidentally when GitLab introduced new properties (https://github.com/ansible-collections/community.general/pull/5667). +- lxc_container - fix the arguments of the lxc command which broke the creation and cloning of containers (https://github.com/ansible-collections/community.general/issues/5578). +- opkg - fix issue that ``force=reinstall`` would not reinstall an existing package (https://github.com/ansible-collections/community.general/pull/5705). +- proxmox_disk - fixed possible issues with redundant ``vmid`` parameter (https://github.com/ansible-collections/community.general/issues/5492, https://github.com/ansible-collections/community.general/pull/5672). +- proxmox_nic - fixed possible issues with redundant ``vmid`` parameter (https://github.com/ansible-collections/community.general/issues/5492, https://github.com/ansible-collections/community.general/pull/5672). +- unixy callback plugin - fix typo introduced when updating to use Ansible's configuration manager for handling options (https://github.com/ansible-collections/community.general/issues/5600). + v6.1.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 90e6aa2c9a..5d45cc7534 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -754,3 +754,132 @@ releases: name: keycloak_clientsecret_regenerate namespace: '' release_date: '2022-12-06' + 6.2.0: + changes: + bugfixes: + - ansible_galaxy_install - set default to raise exception if command's return + code is different from zero (https://github.com/ansible-collections/community.general/pull/5680). + - ansible_galaxy_install - try ``C.UTF-8`` and then fall back to ``en_US.UTF-8`` + before failing (https://github.com/ansible-collections/community.general/pull/5680). + - gitlab_group_variables - fix dropping variables accidentally when GitLab introduced + new properties (https://github.com/ansible-collections/community.general/pull/5667). + - gitlab_project_variables - fix dropping variables accidentally when GitLab + introduced new properties (https://github.com/ansible-collections/community.general/pull/5667). + - lxc_container - fix the arguments of the lxc command which broke the creation + and cloning of containers (https://github.com/ansible-collections/community.general/issues/5578). + - opkg - fix issue that ``force=reinstall`` would not reinstall an existing + package (https://github.com/ansible-collections/community.general/pull/5705). + - proxmox_disk - fixed possible issues with redundant ``vmid`` parameter (https://github.com/ansible-collections/community.general/issues/5492, + https://github.com/ansible-collections/community.general/pull/5672). + - proxmox_nic - fixed possible issues with redundant ``vmid`` parameter (https://github.com/ansible-collections/community.general/issues/5492, + https://github.com/ansible-collections/community.general/pull/5672). + - unixy callback plugin - fix typo introduced when updating to use Ansible's + configuration manager for handling options (https://github.com/ansible-collections/community.general/issues/5600). + deprecated_features: + - manageiq_policies - deprecate ``state=list`` in favour of using ``community.general.manageiq_policies_info`` + (https://github.com/ansible-collections/community.general/pull/5721). + - rax - module relies on deprecates library ``pyrax``. Unless maintainers step + up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_cbs - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_cbs_attachments - module relies on deprecates library ``pyrax``. Unless + maintainers step up to work on the module, it will be marked as deprecated + in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_cdb - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_cdb_database - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_cdb_user - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_clb - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_clb_nodes - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_clb_ssl - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_dns - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_dns_record - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_facts - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_files - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_files_objects - module relies on deprecates library ``pyrax``. Unless + maintainers step up to work on the module, it will be marked as deprecated + in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_identity - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_keypair - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_meta - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_mon_alarm - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_mon_check - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_mon_entity - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_mon_notification - module relies on deprecates library ``pyrax``. Unless + maintainers step up to work on the module, it will be marked as deprecated + in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_mon_notification_plan - module relies on deprecates library ``pyrax``. + Unless maintainers step up to work on the module, it will be marked as deprecated + in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_network - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_queue - module relies on deprecates library ``pyrax``. Unless maintainers + step up to work on the module, it will be marked as deprecated in community.general + 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_scaling_group - module relies on deprecates library ``pyrax``. Unless + maintainers step up to work on the module, it will be marked as deprecated + in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + - rax_scaling_policy - module relies on deprecates library ``pyrax``. Unless + maintainers step up to work on the module, it will be marked as deprecated + in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). + minor_changes: + - opkg - allow installing a package in a certain version (https://github.com/ansible-collections/community.general/pull/5688). + - proxmox - added new module parameter ``tags`` for use with PVE 7+ (https://github.com/ansible-collections/community.general/pull/5714). + - puppet - refactored module to use ``CmdRunner`` for executing ``puppet`` (https://github.com/ansible-collections/community.general/pull/5612). + - redhat_subscription - add a ``server_proxy_scheme`` parameter to configure + the scheme for the proxy server (https://github.com/ansible-collections/community.general/pull/5662). + - ssh_config - refactor code to module util to fix sanity check (https://github.com/ansible-collections/community.general/pull/5720). + - sudoers - adds ``host`` parameter for setting hostname restrictions in sudoers + rules (https://github.com/ansible-collections/community.general/issues/5702). + release_summary: Regular bugfix and feature release. + fragments: + - 5612-puppet-cmd-runner.yml + - 5659-fix-lxc_container-command.yml + - 5662-redhat_subscription-server_proxy_scheme.yaml + - 5666-gitlab-variables.yml + - 5672-proxmox.yml + - 5680-ansible_galaxy_install-fx-locale.yaml + - 5688-opkg-module-install-certain-version.yml + - 5703-sudoers-host-support.yml + - 5705-opkg-fix-force-reinstall.yml + - 5714-proxmox-lxc-tag-support.yml + - 5720-ssh_config-plugin-sanity.yml + - 5721-manageiq-policies-deprecate-list-state.yaml + - 5733-rax-deprecation-notice.yml + - 5744-unixy-callback-fix-config-manager-typo.yml + - 6.2.0.yml + release_date: '2023-01-04' diff --git a/changelogs/fragments/5612-puppet-cmd-runner.yml b/changelogs/fragments/5612-puppet-cmd-runner.yml deleted file mode 100644 index a2d14bf5fc..0000000000 --- a/changelogs/fragments/5612-puppet-cmd-runner.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - puppet - refactored module to use ``CmdRunner`` for executing ``puppet`` (https://github.com/ansible-collections/community.general/pull/5612). diff --git a/changelogs/fragments/5659-fix-lxc_container-command.yml b/changelogs/fragments/5659-fix-lxc_container-command.yml deleted file mode 100644 index 450d889808..0000000000 --- a/changelogs/fragments/5659-fix-lxc_container-command.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - lxc_container - fix the arguments of the lxc command which broke the creation and cloning of containers (https://github.com/ansible-collections/community.general/issues/5578). diff --git a/changelogs/fragments/5662-redhat_subscription-server_proxy_scheme.yaml b/changelogs/fragments/5662-redhat_subscription-server_proxy_scheme.yaml deleted file mode 100644 index 293e18311a..0000000000 --- a/changelogs/fragments/5662-redhat_subscription-server_proxy_scheme.yaml +++ /dev/null @@ -1,3 +0,0 @@ -minor_changes: - - redhat_subscription - add a ``server_proxy_scheme`` parameter to configure the scheme for the proxy server - (https://github.com/ansible-collections/community.general/pull/5662). diff --git a/changelogs/fragments/5666-gitlab-variables.yml b/changelogs/fragments/5666-gitlab-variables.yml deleted file mode 100644 index 2070fa8e4a..0000000000 --- a/changelogs/fragments/5666-gitlab-variables.yml +++ /dev/null @@ -1,3 +0,0 @@ -bugfixes: - - gitlab_group_variables - fix dropping variables accidentally when GitLab introduced new properties (https://github.com/ansible-collections/community.general/pull/5667). - - gitlab_project_variables - fix dropping variables accidentally when GitLab introduced new properties (https://github.com/ansible-collections/community.general/pull/5667). \ No newline at end of file diff --git a/changelogs/fragments/5672-proxmox.yml b/changelogs/fragments/5672-proxmox.yml deleted file mode 100644 index 4fafe53d14..0000000000 --- a/changelogs/fragments/5672-proxmox.yml +++ /dev/null @@ -1,3 +0,0 @@ -bugfixes: - - "proxmox_disk - fixed possible issues with redundant ``vmid`` parameter (https://github.com/ansible-collections/community.general/issues/5492, https://github.com/ansible-collections/community.general/pull/5672)." - - "proxmox_nic - fixed possible issues with redundant ``vmid`` parameter (https://github.com/ansible-collections/community.general/issues/5492, https://github.com/ansible-collections/community.general/pull/5672)." diff --git a/changelogs/fragments/5680-ansible_galaxy_install-fx-locale.yaml b/changelogs/fragments/5680-ansible_galaxy_install-fx-locale.yaml deleted file mode 100644 index 35fd88bc25..0000000000 --- a/changelogs/fragments/5680-ansible_galaxy_install-fx-locale.yaml +++ /dev/null @@ -1,3 +0,0 @@ -bugfixes: - - ansible_galaxy_install - try ``C.UTF-8`` and then fall back to ``en_US.UTF-8`` before failing (https://github.com/ansible-collections/community.general/pull/5680). - - ansible_galaxy_install - set default to raise exception if command's return code is different from zero (https://github.com/ansible-collections/community.general/pull/5680). diff --git a/changelogs/fragments/5688-opkg-module-install-certain-version.yml b/changelogs/fragments/5688-opkg-module-install-certain-version.yml deleted file mode 100644 index 88168bd202..0000000000 --- a/changelogs/fragments/5688-opkg-module-install-certain-version.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - opkg - allow installing a package in a certain version (https://github.com/ansible-collections/community.general/pull/5688). diff --git a/changelogs/fragments/5703-sudoers-host-support.yml b/changelogs/fragments/5703-sudoers-host-support.yml deleted file mode 100644 index 1aaa30d8d9..0000000000 --- a/changelogs/fragments/5703-sudoers-host-support.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - sudoers - adds ``host`` parameter for setting hostname restrictions in sudoers rules (https://github.com/ansible-collections/community.general/issues/5702). diff --git a/changelogs/fragments/5705-opkg-fix-force-reinstall.yml b/changelogs/fragments/5705-opkg-fix-force-reinstall.yml deleted file mode 100644 index 27a188ab9e..0000000000 --- a/changelogs/fragments/5705-opkg-fix-force-reinstall.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - opkg - fix issue that ``force=reinstall`` would not reinstall an existing package (https://github.com/ansible-collections/community.general/pull/5705). diff --git a/changelogs/fragments/5714-proxmox-lxc-tag-support.yml b/changelogs/fragments/5714-proxmox-lxc-tag-support.yml deleted file mode 100644 index 5e3dcc8fcf..0000000000 --- a/changelogs/fragments/5714-proxmox-lxc-tag-support.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: -- proxmox - added new module parameter ``tags`` for use with PVE 7+ (https://github.com/ansible-collections/community.general/pull/5714). diff --git a/changelogs/fragments/5720-ssh_config-plugin-sanity.yml b/changelogs/fragments/5720-ssh_config-plugin-sanity.yml deleted file mode 100644 index 19d57ea145..0000000000 --- a/changelogs/fragments/5720-ssh_config-plugin-sanity.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - ssh_config - refactor code to module util to fix sanity check (https://github.com/ansible-collections/community.general/pull/5720). diff --git a/changelogs/fragments/5721-manageiq-policies-deprecate-list-state.yaml b/changelogs/fragments/5721-manageiq-policies-deprecate-list-state.yaml deleted file mode 100644 index 109a2103e4..0000000000 --- a/changelogs/fragments/5721-manageiq-policies-deprecate-list-state.yaml +++ /dev/null @@ -1,2 +0,0 @@ -deprecated_features: - - manageiq_policies - deprecate ``state=list`` in favour of using ``community.general.manageiq_policies_info`` (https://github.com/ansible-collections/community.general/pull/5721). diff --git a/changelogs/fragments/5733-rax-deprecation-notice.yml b/changelogs/fragments/5733-rax-deprecation-notice.yml deleted file mode 100644 index ac9d3d9b32..0000000000 --- a/changelogs/fragments/5733-rax-deprecation-notice.yml +++ /dev/null @@ -1,27 +0,0 @@ -deprecated_features: - - rax_cbs_attachments - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_cbs - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_cdb_database - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_cdb - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_cdb_user - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_clb_nodes - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_clb - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_clb_ssl - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_dns - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_dns_record - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_facts - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_files_objects - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_files - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_identity - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_keypair - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_meta - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_mon_alarm - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_mon_check - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_mon_entity - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_mon_notification_plan - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_mon_notification - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_network - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_queue - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_scaling_group - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). - - rax_scaling_policy - module relies on deprecates library ``pyrax``. Unless maintainers step up to work on the module, it will be marked as deprecated in community.general 7.0.0 and removed in version 9.0.0 (https://github.com/ansible-collections/community.general/pull/5733). diff --git a/changelogs/fragments/5744-unixy-callback-fix-config-manager-typo.yml b/changelogs/fragments/5744-unixy-callback-fix-config-manager-typo.yml deleted file mode 100644 index d60b43d3d4..0000000000 --- a/changelogs/fragments/5744-unixy-callback-fix-config-manager-typo.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - unixy callback plugin - fix typo introduced when updating to use Ansible's configuration manager for handling options (https://github.com/ansible-collections/community.general/issues/5600). diff --git a/changelogs/fragments/6.2.0.yml b/changelogs/fragments/6.2.0.yml deleted file mode 100644 index 4b1469c9fe..0000000000 --- a/changelogs/fragments/6.2.0.yml +++ /dev/null @@ -1 +0,0 @@ -release_summary: Regular bugfix and feature release. From 80206b5a538d0d570646a92a04d244b4edaf450a Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Wed, 4 Jan 2023 10:29:58 +0100 Subject: [PATCH 083/134] Next expected release is 6.3.0. --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index f55ebce545..09c85cf2b8 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -5,7 +5,7 @@ namespace: community name: general -version: 6.2.0 +version: 6.3.0 readme: README.md authors: - Ansible (https://github.com/ansible) From c355f93d6277ebb881f1f695f6c0aff3e7596092 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 21:40:56 +0100 Subject: [PATCH 084/134] [PR #5755/b49bf081 backport][stable-6] ModuleHelper - fix bug when adjusting conflicting output (#5758) ModuleHelper - fix bug when adjusting conflicting output (#5755) * ModuleHelper - fix bug when adjusting conflicting output * add changelog fragment * remove commented test code (cherry picked from commit b49bf081f8fce789f78cbf996d201c1ac99add01) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../fragments/5755-mh-fix-output-conflict.yml | 2 ++ plugins/module_utils/mh/module_helper.py | 2 +- .../targets/module_helper/library/msimple.py | 6 +++- .../targets/module_helper/tasks/main.yml | 1 + .../tasks/msimple_output_conflict.yml | 31 +++++++++++++++++++ 5 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/5755-mh-fix-output-conflict.yml create mode 100644 tests/integration/targets/module_helper/tasks/msimple_output_conflict.yml diff --git a/changelogs/fragments/5755-mh-fix-output-conflict.yml b/changelogs/fragments/5755-mh-fix-output-conflict.yml new file mode 100644 index 0000000000..f433cc0290 --- /dev/null +++ b/changelogs/fragments/5755-mh-fix-output-conflict.yml @@ -0,0 +1,2 @@ +bugfixes: + - ModuleHelper - fix bug when adjusting the name of reserved output variables (https://github.com/ansible-collections/community.general/pull/5755). diff --git a/plugins/module_utils/mh/module_helper.py b/plugins/module_utils/mh/module_helper.py index c844acba50..51696b6ff6 100644 --- a/plugins/module_utils/mh/module_helper.py +++ b/plugins/module_utils/mh/module_helper.py @@ -60,7 +60,7 @@ class ModuleHelper(DeprecateAttrsMixin, VarsMixin, DependencyMixin, ModuleHelper vars_diff = self.vars.diff() or {} result['diff'] = dict_merge(dict(diff), vars_diff) - for varname in result: + for varname in list(result): if varname in self._output_conflict_list: result["_" + varname] = result[varname] del result[varname] diff --git a/tests/integration/targets/module_helper/library/msimple.py b/tests/integration/targets/module_helper/library/msimple.py index 60a49dccb1..3729b6c702 100644 --- a/tests/integration/targets/module_helper/library/msimple.py +++ b/tests/integration/targets/module_helper/library/msimple.py @@ -35,12 +35,13 @@ from ansible_collections.community.general.plugins.module_utils.mh.deco import c class MSimple(ModuleHelper): - output_params = ('a', 'b', 'c') + output_params = ('a', 'b', 'c', 'm') module = dict( argument_spec=dict( a=dict(type='int', default=0), b=dict(type='str'), c=dict(type='str'), + m=dict(type='str'), ), supports_check_mode=True, ) @@ -65,6 +66,9 @@ class MSimple(ModuleHelper): self.vars['c'] = str(self.vars.c) * 2 self.process_a3_bc() + if self.vars.m: + self.vars.msg = self.vars.m + def main(): msimple = MSimple() diff --git a/tests/integration/targets/module_helper/tasks/main.yml b/tests/integration/targets/module_helper/tasks/main.yml index 90006f701d..2368cfcbb5 100644 --- a/tests/integration/targets/module_helper/tasks/main.yml +++ b/tests/integration/targets/module_helper/tasks/main.yml @@ -3,6 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later - include_tasks: msimple.yml +- include_tasks: msimple_output_conflict.yml - include_tasks: mdepfail.yml - include_tasks: mstate.yml - include_tasks: msimpleda.yml diff --git a/tests/integration/targets/module_helper/tasks/msimple_output_conflict.yml b/tests/integration/targets/module_helper/tasks/msimple_output_conflict.yml new file mode 100644 index 0000000000..21ffd37d35 --- /dev/null +++ b/tests/integration/targets/module_helper/tasks/msimple_output_conflict.yml @@ -0,0 +1,31 @@ +# Copyright (c) 2023, Alexei Znamensky +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +- name: test msimple (set a=80) + msimple: + a: 80 + register: simple1 + +- name: assert simple1 + assert: + that: + - simple1.a == 80 + - simple1.abc == "abc" + - simple1 is not changed + - simple1.value is none + +- name: test msimple 2 + msimple: + a: 80 + m: a message in a bottle + register: simple2 + +- name: assert simple2 + assert: + that: + - simple1.a == 80 + - simple1.abc == "abc" + - simple1 is not changed + - simple1.value is none + - 'simple2._msg == "a message in a bottle"' From e08412c345e0964561a90a7045727e4e34953b05 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 23:46:31 +0100 Subject: [PATCH 085/134] [PR #5761/84ebda65 backport][stable-6] Fix callback plugin types (#5764) Fix callback plugin types (#5761) Fix callback types. (cherry picked from commit 84ebda65f1479b9b338bfca7294e4c28fba79576) Co-authored-by: Felix Fontein --- changelogs/fragments/5761-callback-types.yml | 7 +++++++ plugins/callback/loganalytics.py | 4 ++-- plugins/callback/logdna.py | 4 ++-- plugins/callback/logstash.py | 2 +- plugins/callback/splunk.py | 4 ++-- plugins/callback/sumologic.py | 4 ++-- plugins/callback/syslog_json.py | 2 +- 7 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 changelogs/fragments/5761-callback-types.yml diff --git a/changelogs/fragments/5761-callback-types.yml b/changelogs/fragments/5761-callback-types.yml new file mode 100644 index 0000000000..62466f46a5 --- /dev/null +++ b/changelogs/fragments/5761-callback-types.yml @@ -0,0 +1,7 @@ +bugfixes: + - "loganalytics callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761)." + - "logdna callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761)." + - "logstash callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761)." + - "splunk callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761)." + - "sumologic callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761)." + - "syslog_json callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761)." diff --git a/plugins/callback/loganalytics.py b/plugins/callback/loganalytics.py index 54acf846a3..8690aac934 100644 --- a/plugins/callback/loganalytics.py +++ b/plugins/callback/loganalytics.py @@ -8,7 +8,7 @@ __metaclass__ = type DOCUMENTATION = ''' name: loganalytics - type: aggregate + type: notification short_description: Posts task results to Azure Log Analytics author: "Cyrus Li (@zhcli) " description: @@ -155,7 +155,7 @@ class AzureLogAnalyticsSource(object): class CallbackModule(CallbackBase): CALLBACK_VERSION = 2.0 - CALLBACK_TYPE = 'aggregate' + CALLBACK_TYPE = 'notification' CALLBACK_NAME = 'loganalytics' CALLBACK_NEEDS_WHITELIST = True diff --git a/plugins/callback/logdna.py b/plugins/callback/logdna.py index ee0a1eb022..2d0880ce19 100644 --- a/plugins/callback/logdna.py +++ b/plugins/callback/logdna.py @@ -9,7 +9,7 @@ __metaclass__ = type DOCUMENTATION = ''' author: Unknown (!UNKNOWN) name: logdna - type: aggregate + type: notification short_description: Sends playbook logs to LogDNA description: - This callback will report logs from playbook actions, tasks, and events to LogDNA (https://app.logdna.com) @@ -111,7 +111,7 @@ def isJSONable(obj): class CallbackModule(CallbackBase): CALLBACK_VERSION = 0.1 - CALLBACK_TYPE = 'aggregate' + CALLBACK_TYPE = 'notification' CALLBACK_NAME = 'community.general.logdna' CALLBACK_NEEDS_WHITELIST = True diff --git a/plugins/callback/logstash.py b/plugins/callback/logstash.py index 5d3c1e50b8..7666b47876 100644 --- a/plugins/callback/logstash.py +++ b/plugins/callback/logstash.py @@ -113,7 +113,7 @@ from ansible.plugins.callback import CallbackBase class CallbackModule(CallbackBase): CALLBACK_VERSION = 2.0 - CALLBACK_TYPE = 'aggregate' + CALLBACK_TYPE = 'notification' CALLBACK_NAME = 'community.general.logstash' CALLBACK_NEEDS_WHITELIST = True diff --git a/plugins/callback/splunk.py b/plugins/callback/splunk.py index 701cbfdebd..32e77f4eb4 100644 --- a/plugins/callback/splunk.py +++ b/plugins/callback/splunk.py @@ -8,7 +8,7 @@ __metaclass__ = type DOCUMENTATION = ''' name: splunk - type: aggregate + type: notification short_description: Sends task result events to Splunk HTTP Event Collector author: "Stuart Hirst (!UNKNOWN) " description: @@ -165,7 +165,7 @@ class SplunkHTTPCollectorSource(object): class CallbackModule(CallbackBase): CALLBACK_VERSION = 2.0 - CALLBACK_TYPE = 'aggregate' + CALLBACK_TYPE = 'notification' CALLBACK_NAME = 'community.general.splunk' CALLBACK_NEEDS_WHITELIST = True diff --git a/plugins/callback/sumologic.py b/plugins/callback/sumologic.py index 0b6c9b6fee..6fd950d991 100644 --- a/plugins/callback/sumologic.py +++ b/plugins/callback/sumologic.py @@ -8,7 +8,7 @@ __metaclass__ = type DOCUMENTATION = ''' name: sumologic -type: aggregate +type: notification short_description: Sends task result events to Sumologic author: "Ryan Currah (@ryancurrah)" description: @@ -111,7 +111,7 @@ class SumologicHTTPCollectorSource(object): class CallbackModule(CallbackBase): CALLBACK_VERSION = 2.0 - CALLBACK_TYPE = 'aggregate' + CALLBACK_TYPE = 'notification' CALLBACK_NAME = 'community.general.sumologic' CALLBACK_NEEDS_WHITELIST = True diff --git a/plugins/callback/syslog_json.py b/plugins/callback/syslog_json.py index 7ca99a9edd..4b2c7e79b8 100644 --- a/plugins/callback/syslog_json.py +++ b/plugins/callback/syslog_json.py @@ -71,7 +71,7 @@ class CallbackModule(CallbackBase): """ CALLBACK_VERSION = 2.0 - CALLBACK_TYPE = 'aggregate' + CALLBACK_TYPE = 'notification' CALLBACK_NAME = 'community.general.syslog_json' CALLBACK_NEEDS_WHITELIST = True From 2d450a5a361653e8cf443696a54d22eafcb563cb Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 5 Jan 2023 21:51:21 +0100 Subject: [PATCH 086/134] [PR #5725/4dc897d5 backport][stable-6] redhat_subscription: Add support for Red Hat API token (#5768) redhat_subscription: Add support for Red Hat API token (#5725) Add support for Red Hat API token fix mixed up fix version (cherry picked from commit 4dc897d559cd631554691a2a4d3d82e34325686c) Co-authored-by: Eric C Chong --- ...hat_subscription-add-red-hat-api-token.yml | 2 ++ plugins/modules/redhat_subscription.py | 24 ++++++++++---- .../modules/test_redhat_subscription.py | 31 +++++++++++++++++++ 3 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/5725-redhat_subscription-add-red-hat-api-token.yml diff --git a/changelogs/fragments/5725-redhat_subscription-add-red-hat-api-token.yml b/changelogs/fragments/5725-redhat_subscription-add-red-hat-api-token.yml new file mode 100644 index 0000000000..980e91ceb2 --- /dev/null +++ b/changelogs/fragments/5725-redhat_subscription-add-red-hat-api-token.yml @@ -0,0 +1,2 @@ +minor_changes: + - redhat_subscription - adds ``token`` parameter for subscription-manager authentication using Red Hat API token (https://github.com/ansible-collections/community.general/pull/5725). diff --git a/plugins/modules/redhat_subscription.py b/plugins/modules/redhat_subscription.py index 8836b78564..2649092e8a 100644 --- a/plugins/modules/redhat_subscription.py +++ b/plugins/modules/redhat_subscription.py @@ -40,6 +40,11 @@ options: description: - access.redhat.com or Red Hat Satellite or Katello password type: str + token: + description: + - sso.redhat.com API access token. + type: str + version_added: 6.3.0 server_hostname: description: - Specify an alternative Red Hat Subscription Management or Red Hat Satellite or Katello server @@ -294,10 +299,11 @@ class RegistrationBase(object): REDHAT_REPO = "/etc/yum.repos.d/redhat.repo" - def __init__(self, module, username=None, password=None): + def __init__(self, module, username=None, password=None, token=None): self.module = module self.username = username self.password = password + self.token = token def configure(self): raise NotImplementedError("Must be implemented by a sub-class") @@ -340,8 +346,8 @@ class RegistrationBase(object): class Rhsm(RegistrationBase): - def __init__(self, module, username=None, password=None): - RegistrationBase.__init__(self, module, username, password) + def __init__(self, module, username=None, password=None, token=None): + RegistrationBase.__init__(self, module, username, password, token) self.module = module def enable(self): @@ -397,7 +403,7 @@ class Rhsm(RegistrationBase): else: return False - def register(self, username, password, auto_attach, activationkey, org_id, + def register(self, username, password, token, auto_attach, activationkey, org_id, consumer_type, consumer_name, consumer_id, force_register, environment, release): ''' @@ -433,6 +439,8 @@ class Rhsm(RegistrationBase): if activationkey: args.extend(['--activationkey', activationkey]) + elif token: + args.extend(['--token', token]) else: if username: args.extend(['--username', username]) @@ -794,6 +802,7 @@ def main(): 'state': {'default': 'present', 'choices': ['present', 'absent']}, 'username': {}, 'password': {'no_log': True}, + 'token': {'no_log': True}, 'server_hostname': {}, 'server_insecure': {}, 'server_prefix': {}, @@ -831,17 +840,20 @@ def main(): ['server_proxy_hostname', 'server_proxy_port'], ['server_proxy_user', 'server_proxy_password']], mutually_exclusive=[['activationkey', 'username'], + ['activationkey', 'token'], + ['token', 'username'], ['activationkey', 'consumer_id'], ['activationkey', 'environment'], ['activationkey', 'auto_attach'], ['pool', 'pool_ids']], - required_if=[['state', 'present', ['username', 'activationkey'], True]], + required_if=[['state', 'present', ['username', 'activationkey', 'token'], True]], ) rhsm.module = module state = module.params['state'] username = module.params['username'] password = module.params['password'] + token = module.params['token'] server_hostname = module.params['server_hostname'] server_insecure = module.params['server_insecure'] server_prefix = module.params['server_prefix'] @@ -914,7 +926,7 @@ def main(): try: rhsm.enable() rhsm.configure(**module.params) - rhsm.register(username, password, auto_attach, activationkey, org_id, + rhsm.register(username, password, token, auto_attach, activationkey, org_id, consumer_type, consumer_name, consumer_id, force_register, environment, release) if syspurpose and 'sync' in syspurpose and syspurpose['sync'] is True: diff --git a/tests/unit/plugins/modules/test_redhat_subscription.py b/tests/unit/plugins/modules/test_redhat_subscription.py index 865f041141..e3f4cdd812 100644 --- a/tests/unit/plugins/modules/test_redhat_subscription.py +++ b/tests/unit/plugins/modules/test_redhat_subscription.py @@ -102,6 +102,37 @@ TEST_CASES = [ 'msg': "System successfully registered to 'satellite.company.com'." } ], + # Test simple registration using token + [ + { + 'state': 'present', + 'server_hostname': 'satellite.company.com', + 'token': 'fake_token', + }, + { + 'id': 'test_registeration_token', + 'run_command.calls': [ + ( + ['/testbin/subscription-manager', 'identity'], + {'check_rc': False}, + (1, '', '') + ), + ( + ['/testbin/subscription-manager', 'config', '--server.hostname=satellite.company.com'], + {'check_rc': True}, + (0, '', '') + ), + ( + ['/testbin/subscription-manager', 'register', + '--token', 'fake_token'], + {'check_rc': True, 'expand_user_and_vars': False}, + (0, '', '') + ) + ], + 'changed': True, + 'msg': "System successfully registered to 'satellite.company.com'." + } + ], # Test unregistration, when system is unregistered [ { From c8b8668212384024568dfeb2cc413151aae05250 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 6 Jan 2023 15:17:46 +0100 Subject: [PATCH 087/134] [PR #5767/217a62ac backport][stable-6] consul: minor fixes in docs (#5771) consul: minor fixes in docs (#5767) * consul: minor fixes in docs * additional docs fixes * adjustments from review (cherry picked from commit 217a62aca2aa673708621d1c963def9e068681e0) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- plugins/modules/consul.py | 57 ++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/plugins/modules/consul.py b/plugins/modules/consul.py index aabc1bd4b7..ea329254a1 100644 --- a/plugins/modules/consul.py +++ b/plugins/modules/consul.py @@ -23,7 +23,7 @@ description: by Consul from the Service name and id respectively by appending 'service:' Node level checks require a I(check_name) and optionally a I(check_id)." - Currently, there is no complete way to retrieve the script, interval or ttl - metadata for a registered check. Without this metadata it is not possible to + metadata for a registered check. Without this metadata it is not possible to tell if the data supplied with ansible represents a change to a check. As a result this does not attempt to determine changes and will always report a changed occurred. An API method is planned to supply this metadata so at that @@ -37,7 +37,7 @@ options: state: type: str description: - - register or deregister the consul service, defaults to present + - Register or deregister the consul service, defaults to present. default: present choices: ['present', 'absent'] service_name: @@ -45,30 +45,30 @@ options: description: - Unique name for the service on a node, must be unique per node, required if registering a service. May be omitted if registering - a node level check + a node level check. service_id: type: str description: - - the ID for the service, must be unique per node. If I(state=absent), + - The ID for the service, must be unique per node. If I(state=absent), defaults to the service name if supplied. host: type: str description: - - host of the consul agent defaults to localhost + - Host of the consul agent defaults to localhost. default: localhost port: type: int description: - - the port on which the consul agent is running + - The port on which the consul agent is running. default: 8500 scheme: type: str description: - - the protocol scheme on which the consul agent is running + - The protocol scheme on which the consul agent is running. default: http validate_certs: description: - - whether to verify the TLS certificate of the consul agent + - Whether to verify the TLS certificate of the consul agent. type: bool default: true notes: @@ -78,12 +78,12 @@ options: service_port: type: int description: - - the port on which the service is listening. Can optionally be supplied for - registration of a service, i.e. if I(service_name) or I(service_id) is set + - The port on which the service is listening. Can optionally be supplied for + registration of a service, i.e. if I(service_name) or I(service_id) is set. service_address: type: str description: - - the address to advertise that the service will be listening on. + - The address to advertise that the service will be listening on. This value will be passed as the I(address) parameter to Consul's C(/v1/agent/service/register) API method, so refer to the Consul API documentation for further details. @@ -91,63 +91,64 @@ options: type: list elements: str description: - - tags that will be attached to the service registration. + - Tags that will be attached to the service registration. script: type: str description: - - the script/command that will be run periodically to check the health - of the service. Scripts require I(interval) and vice versa. + - The script/command that will be run periodically to check the health of the service. + - Requires I(interval) to be provided. interval: type: str description: - - the interval at which the service check will be run. This is a number - with a s or m suffix to signify the units of seconds or minutes e.g - C(15s) or C(1m). If no suffix is supplied, m will be used by default e.g. - C(1) will be C(1m). Required if the I(script) parameter is specified. + - The interval at which the service check will be run. + This is a number with a C(s) or C(m) suffix to signify the units of seconds or minutes e.g C(15s) or C(1m). + If no suffix is supplied C(s) will be used by default, e.g. C(10) will be C(10s). + - Required if one of the parameters I(script), I(http), or I(tcp) is specified. check_id: type: str description: - - an ID for the service check. If I(state=absent), defaults to + - An ID for the service check. If I(state=absent), defaults to I(check_name). Ignored if part of a service definition. check_name: type: str description: - - a name for the service check. Required if standalone, ignored if + - Name for the service check. Required if standalone, ignored if part of service definition. ttl: type: str description: - - checks can be registered with a ttl instead of a I(script) and I(interval) + - Checks can be registered with a ttl instead of a I(script) and I(interval) this means that the service will check in with the agent before the ttl expires. If it doesn't the check will be considered failed. Required if registering a check and the script an interval are missing - Similar to the interval this is a number with a s or m suffix to - signify the units of seconds or minutes e.g C(15s) or C(1m). If no suffix - is supplied, C(m) will be used by default e.g. C(1) will be C(1m) + Similar to the interval this is a number with a C(s) or C(m) suffix to + signify the units of seconds or minutes e.g C(15s) or C(1m). + If no suffix is supplied C(s) will be used by default, e.g. C(10) will be C(10s). tcp: type: str description: - Checks can be registered with a TCP port. This means that consul will check if the connection attempt to that port is successful (that is, the port is currently accepting connections). The format is C(host:port), for example C(localhost:80). - I(interval) must also be provided with this option. + - Requires I(interval) to be provided. version_added: '1.3.0' http: type: str description: - - checks can be registered with an HTTP endpoint. This means that consul + - Checks can be registered with an HTTP endpoint. This means that consul will check that the http endpoint returns a successful HTTP status. - I(interval) must also be provided with this option. + - Requires I(interval) to be provided. timeout: type: str description: - A custom HTTP check timeout. The consul default is 10 seconds. Similar to the interval this is a number with a C(s) or C(m) suffix to signify the units of seconds or minutes, e.g. C(15s) or C(1m). + If no suffix is supplied C(s) will be used by default, e.g. C(10) will be C(10s). token: type: str description: - - the token key identifying an ACL rule set. May be required to register services. + - The token key identifying an ACL rule set. May be required to register services. ''' EXAMPLES = ''' From 5cf7ce705a1397e7297f724c7fdace7e7026adb0 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 7 Jan 2023 10:52:22 +0100 Subject: [PATCH 088/134] [PR #5773/02431341 backport][stable-6] snap: use MH execute() static method (#5774) snap: use MH execute() static method (#5773) * use MH execute() static method * add changelog fragment (cherry picked from commit 02431341b7ecf24432f4082a6005721c624ae550) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- changelogs/fragments/5773-snap-mh-execute.yml | 2 ++ plugins/modules/snap.py | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/5773-snap-mh-execute.yml diff --git a/changelogs/fragments/5773-snap-mh-execute.yml b/changelogs/fragments/5773-snap-mh-execute.yml new file mode 100644 index 0000000000..43b9b6a1ac --- /dev/null +++ b/changelogs/fragments/5773-snap-mh-execute.yml @@ -0,0 +1,2 @@ +minor_changes: + - snap - minor refactor when executing module (https://github.com/ansible-collections/community.general/pull/5773). diff --git a/plugins/modules/snap.py b/plugins/modules/snap.py index a432504472..1b5e27071a 100644 --- a/plugins/modules/snap.py +++ b/plugins/modules/snap.py @@ -399,8 +399,7 @@ class Snap(CmdStateModuleHelper): def main(): - snap = Snap() - snap.run() + Snap.execute() if __name__ == '__main__': From 16e05ab5f3a680b0cbfd36b616cc73f26b5b3d89 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 7 Jan 2023 10:52:32 +0100 Subject: [PATCH 089/134] [PR #5751/2670215c backport][stable-6] Fix gem.py, hang on uninstall specific gem version (#5780) Fix gem.py, hang on uninstall specific gem version (#5751) * Update gem.py move 'cmd.append('--executable')' to all uninstalls rather than only all versions * Create 5751-gem-fix-uninstall-hang * Rename 5751-gem-fix-uninstall-hang to 5751-gem-fix-uninstall-hang.yml (cherry picked from commit 2670215c8ad6b18aac2220e1261818ed7f5f45cb) Co-authored-by: rietvelde <99407273+rietvelde@users.noreply.github.com> --- changelogs/fragments/5751-gem-fix-uninstall-hang.yml | 2 ++ plugins/modules/gem.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5751-gem-fix-uninstall-hang.yml diff --git a/changelogs/fragments/5751-gem-fix-uninstall-hang.yml b/changelogs/fragments/5751-gem-fix-uninstall-hang.yml new file mode 100644 index 0000000000..3fdd0056de --- /dev/null +++ b/changelogs/fragments/5751-gem-fix-uninstall-hang.yml @@ -0,0 +1,2 @@ +bugfixes: + - gem - fix hang due to interactive prompt for confirmation on specific version uninstall (https://github.com/ansible-collections/community.general/pull/5751). diff --git a/plugins/modules/gem.py b/plugins/modules/gem.py index 8d7f7dade0..21e9efea58 100644 --- a/plugins/modules/gem.py +++ b/plugins/modules/gem.py @@ -234,7 +234,7 @@ def uninstall(module): cmd.extend(['--version', module.params['version']]) else: cmd.append('--all') - cmd.append('--executable') + cmd.append('--executable') cmd.append(module.params['name']) module.run_command(cmd, environ_update=environ, check_rc=True) From b7697fe3deb50ca342130212d43cdb6c8b02a769 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 7 Jan 2023 10:52:40 +0100 Subject: [PATCH 090/134] [PR #5694/e3f02cb1 backport][stable-6] Add Support to Bitwarden Lookup for Custom Fields (#5781) Add Support to Bitwarden Lookup for Custom Fields (#5694) * Add Support to Bitwarden Lookup for Custom Fields This adds support to the Bitwarden lookup for retrieving values from custom fields, such as api keys. * Need to Return Whole Record if Field is Not Defined * whitespace * Add Changelog Fragment * Need to Make Sure All Login Fields are Represented We need to make sure that all login fields are accounted for, since there will be no other way to retrieve them with this change, and we don't want to break backwards compatibility. Looking at this code from the official client, https://github.com/bitwarden/clients/blob/master/libs/common/spec/models/domain/login.spec.ts, autofillOnPageLoad might be another login field. * Update changelogs/fragments/5694-add-custom-fields-to-bitwarden.yml Clarify changelog fragment Co-authored-by: Felix Fontein * Update plugins/lookup/bitwarden.py Fix logic. Should only error if matches were found, but are missing the custom field. Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit e3f02cb161b7bf351ebab9335b31056a6125348b) Co-authored-by: reverendj1 --- .../5694-add-custom-fields-to-bitwarden.yml | 2 ++ plugins/lookup/bitwarden.py | 20 ++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/5694-add-custom-fields-to-bitwarden.yml diff --git a/changelogs/fragments/5694-add-custom-fields-to-bitwarden.yml b/changelogs/fragments/5694-add-custom-fields-to-bitwarden.yml new file mode 100644 index 0000000000..55006f06a9 --- /dev/null +++ b/changelogs/fragments/5694-add-custom-fields-to-bitwarden.yml @@ -0,0 +1,2 @@ +minor_changes: + - bitwarden lookup plugin - can now retrieve secrets from custom fields (https://github.com/ansible-collections/community.general/pull/5694). diff --git a/plugins/lookup/bitwarden.py b/plugins/lookup/bitwarden.py index 1cc2e44c74..dbcb88d456 100644 --- a/plugins/lookup/bitwarden.py +++ b/plugins/lookup/bitwarden.py @@ -47,6 +47,11 @@ EXAMPLES = """ ansible.builtin.debug: msg: >- {{ lookup('community.general.bitwarden', 'a_test') }} + +- name: "Get custom field 'api_key' from Bitwarden record named 'a_test'" + ansible.builtin.debug: + msg: >- + {{ lookup('community.general.bitwarden', 'a_test', field='api_key') }} """ RETURN = """ @@ -109,10 +114,19 @@ class Bitwarden(object): """ matches = self._get_matches(search_value, search_field) - if field: + if field in ['autofillOnPageLoad', 'password', 'passwordRevisionDate', 'totp', 'uris', 'username']: return [match['login'][field] for match in matches] - - return matches + elif not field: + return matches + else: + custom_field_matches = [] + for match in matches: + for custom_field in match['fields']: + if custom_field['name'] == field: + custom_field_matches.append(custom_field['value']) + if matches and not custom_field_matches: + raise AnsibleError("Custom field {field} does not exist in {search_value}".format(field=field, search_value=search_value)) + return custom_field_matches class LookupModule(LookupBase): From d95a821d5bfe53262cf6a3c76977618610b6b60a Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 7 Jan 2023 10:52:49 +0100 Subject: [PATCH 091/134] [PR #5735/fc2b1aac backport][stable-6] terraform: bugfix: init command when default workspace doesn't exists (#5777) terraform: bugfix: init command when default workspace doesn't exists (#5735) * feat: init when default workspace doesn't exists * doc: add changelogs fragment and docs update * fix: changelog formating fix (cherry picked from commit fc2b1aac4aca701f3e87706266ac2e32a905d9fe) Co-authored-by: Teodor Janez Podobnik <48418580+dorkamotorka@users.noreply.github.com> --- ...init-fix-when-default-workspace-doesnt-exists.yaml | 3 +++ plugins/modules/terraform.py | 11 +++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 changelogs/fragments/5735-terraform-init-fix-when-default-workspace-doesnt-exists.yaml diff --git a/changelogs/fragments/5735-terraform-init-fix-when-default-workspace-doesnt-exists.yaml b/changelogs/fragments/5735-terraform-init-fix-when-default-workspace-doesnt-exists.yaml new file mode 100644 index 0000000000..3ec348aed9 --- /dev/null +++ b/changelogs/fragments/5735-terraform-init-fix-when-default-workspace-doesnt-exists.yaml @@ -0,0 +1,3 @@ +bugfixes: + - terraform - fix ``current`` workspace never getting appended to the ``all`` key in the ``workspace_ctf`` object (https://github.com/ansible-collections/community.general/pull/5735). + - terraform - fix ``terraform init`` failure when there are multiple workspaces on the remote backend and when ``default`` workspace is missing by setting ``TF_WORKSPACE`` environmental variable to the value of ``workspace`` when used (https://github.com/ansible-collections/community.general/pull/5735). diff --git a/plugins/modules/terraform.py b/plugins/modules/terraform.py index 615c125cf3..2a018ea03c 100644 --- a/plugins/modules/terraform.py +++ b/plugins/modules/terraform.py @@ -48,7 +48,9 @@ options: version_added: 3.0.0 workspace: description: - - The terraform workspace to work with. + - The terraform workspace to work with. This sets the C(TF_WORKSPACE) environmental variable + that is used to override workspace selection. For more information about workspaces + have a look at U(https://developer.hashicorp.com/terraform/language/state/workspaces). type: str default: default purge_workspace: @@ -310,7 +312,7 @@ def _state_args(state_file): return [] -def init_plugins(bin_path, project_path, backend_config, backend_config_files, init_reconfigure, provider_upgrade, plugin_paths): +def init_plugins(bin_path, project_path, backend_config, backend_config_files, init_reconfigure, provider_upgrade, plugin_paths, workspace): command = [bin_path, 'init', '-input=false', '-no-color'] if backend_config: for key, val in backend_config.items(): @@ -328,7 +330,7 @@ def init_plugins(bin_path, project_path, backend_config, backend_config_files, i if plugin_paths: for plugin_path in plugin_paths: command.extend(['-plugin-dir', plugin_path]) - rc, out, err = module.run_command(command, check_rc=True, cwd=project_path) + rc, out, err = module.run_command(command, check_rc=True, cwd=project_path, environ_update={"TF_WORKSPACE": workspace}) def get_workspace_context(bin_path, project_path): @@ -343,6 +345,7 @@ def get_workspace_context(bin_path, project_path): continue elif stripped_item.startswith('* '): workspace_ctx["current"] = stripped_item.replace('* ', '') + workspace_ctx["all"].append(stripped_item.replace('* ', '')) else: workspace_ctx["all"].append(stripped_item) return workspace_ctx @@ -485,7 +488,7 @@ def main(): if force_init: if overwrite_init or not os.path.isfile(os.path.join(project_path, ".terraform", "terraform.tfstate")): - init_plugins(command[0], project_path, backend_config, backend_config_files, init_reconfigure, provider_upgrade, plugin_paths) + init_plugins(command[0], project_path, backend_config, backend_config_files, init_reconfigure, provider_upgrade, plugin_paths, workspace) workspace_ctx = get_workspace_context(command[0], project_path) if workspace_ctx["current"] != workspace: From 8bc5494ad53964ba9809a2ec77a1cc15112b37fe Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 7 Jan 2023 10:52:56 +0100 Subject: [PATCH 092/134] [PR #5765/dc531b18 backport][stable-6] ModuleHelper - lax handling of conflicting output (#5775) ModuleHelper - lax handling of conflicting output (#5765) * ModuleHelper - lax handling of conflicting output * add changelog fragment * only create _var when really needed * adjust changelog * Update changelogs/fragments/5765-mh-lax-output-conflict.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit dc531b183d2f1b48378ddfd3dd976e067bc02eb6) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../fragments/5765-mh-lax-output-conflict.yml | 9 ++++++ plugins/module_utils/mh/deco.py | 17 +++++++++-- plugins/module_utils/mh/module_helper.py | 5 ---- .../targets/module_helper/library/msimple.py | 5 ++-- .../tasks/msimple_output_conflict.yml | 29 +++++++++++++++++-- 5 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 changelogs/fragments/5765-mh-lax-output-conflict.yml diff --git a/changelogs/fragments/5765-mh-lax-output-conflict.yml b/changelogs/fragments/5765-mh-lax-output-conflict.yml new file mode 100644 index 0000000000..2e8cc292bd --- /dev/null +++ b/changelogs/fragments/5765-mh-lax-output-conflict.yml @@ -0,0 +1,9 @@ +breaking_changes: + - > + ModuleHelper module utils - when the module sets output variables named ``msg``, ``exception``, ``output``, ``vars``, or ``changed``, + the actual output will prefix those names with ``_`` (underscore symbol) only when they clash with output variables generated by ModuleHelper + itself, which only occurs when handling exceptions. Please note that this breaking + change does not require a new major release since before this release, it was not possible + to add such variables to the output + `due to a bug `__ + (https://github.com/ansible-collections/community.general/pull/5765). diff --git a/plugins/module_utils/mh/deco.py b/plugins/module_utils/mh/deco.py index 3073e4e9e7..5138b212c7 100644 --- a/plugins/module_utils/mh/deco.py +++ b/plugins/module_utils/mh/deco.py @@ -37,8 +37,17 @@ def cause_changes(on_success=None, on_failure=None): def module_fails_on_exception(func): + conflict_list = ('msg', 'exception', 'output', 'vars', 'changed') + @wraps(func) def wrapper(self, *args, **kwargs): + def fix_var_conflicts(output): + result = dict([ + (k if k not in conflict_list else "_" + k, v) + for k, v in output.items() + ]) + return result + try: func(self, *args, **kwargs) except SystemExit: @@ -46,12 +55,16 @@ def module_fails_on_exception(func): except ModuleHelperException as e: if e.update_output: self.update_output(e.update_output) + # patchy solution to resolve conflict with output variables + output = fix_var_conflicts(self.output) self.module.fail_json(msg=e.msg, exception=traceback.format_exc(), - output=self.output, vars=self.vars.output(), **self.output) + output=self.output, vars=self.vars.output(), **output) except Exception as e: + # patchy solution to resolve conflict with output variables + output = fix_var_conflicts(self.output) msg = "Module failed with exception: {0}".format(str(e).strip()) self.module.fail_json(msg=msg, exception=traceback.format_exc(), - output=self.output, vars=self.vars.output(), **self.output) + output=self.output, vars=self.vars.output(), **output) return wrapper diff --git a/plugins/module_utils/mh/module_helper.py b/plugins/module_utils/mh/module_helper.py index 51696b6ff6..6813b5454b 100644 --- a/plugins/module_utils/mh/module_helper.py +++ b/plugins/module_utils/mh/module_helper.py @@ -18,7 +18,6 @@ from ansible_collections.community.general.plugins.module_utils.mh.mixins.deprec class ModuleHelper(DeprecateAttrsMixin, VarsMixin, DependencyMixin, ModuleHelperBase): - _output_conflict_list = ('msg', 'exception', 'output', 'vars', 'changed') facts_name = None output_params = () diff_params = () @@ -60,10 +59,6 @@ class ModuleHelper(DeprecateAttrsMixin, VarsMixin, DependencyMixin, ModuleHelper vars_diff = self.vars.diff() or {} result['diff'] = dict_merge(dict(diff), vars_diff) - for varname in list(result): - if varname in self._output_conflict_list: - result["_" + varname] = result[varname] - del result[varname] return result diff --git a/tests/integration/targets/module_helper/library/msimple.py b/tests/integration/targets/module_helper/library/msimple.py index 3729b6c702..096e515247 100644 --- a/tests/integration/targets/module_helper/library/msimple.py +++ b/tests/integration/targets/module_helper/library/msimple.py @@ -57,6 +57,8 @@ class MSimple(ModuleHelper): self.vars['c'] = str(self.vars.c) * 3 def __run__(self): + if self.vars.m: + self.vars.msg = self.vars.m if self.vars.a >= 100: raise Exception("a >= 100") if self.vars.c == "abc change": @@ -66,9 +68,6 @@ class MSimple(ModuleHelper): self.vars['c'] = str(self.vars.c) * 2 self.process_a3_bc() - if self.vars.m: - self.vars.msg = self.vars.m - def main(): msimple = MSimple() diff --git a/tests/integration/targets/module_helper/tasks/msimple_output_conflict.yml b/tests/integration/targets/module_helper/tasks/msimple_output_conflict.yml index 21ffd37d35..55e0a06eca 100644 --- a/tests/integration/targets/module_helper/tasks/msimple_output_conflict.yml +++ b/tests/integration/targets/module_helper/tasks/msimple_output_conflict.yml @@ -2,7 +2,7 @@ # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # SPDX-License-Identifier: GPL-3.0-or-later -- name: test msimple (set a=80) +- name: test msimple conflict output (set a=80) msimple: a: 80 register: simple1 @@ -15,7 +15,7 @@ - simple1 is not changed - simple1.value is none -- name: test msimple 2 +- name: test msimple conflict output 2 msimple: a: 80 m: a message in a bottle @@ -28,4 +28,27 @@ - simple1.abc == "abc" - simple1 is not changed - simple1.value is none - - 'simple2._msg == "a message in a bottle"' + - > + "_msg" not in simple2 + - > + simple2.msg == "a message in a bottle" + +- name: test msimple 3 + msimple: + a: 101 + m: a message in a bottle + ignore_errors: yes + register: simple3 + +- name: assert simple3 + assert: + that: + - simple3.a == 101 + - > + simple3.msg == "Module failed with exception: a >= 100" + - > + simple3._msg == "a message in a bottle" + - simple3.abc == "abc" + - simple3 is failed + - simple3 is not changed + - simple3.value is none From ef5ac023cfc19bae2d8cc88a37ab0bd098e596b5 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 7 Jan 2023 11:45:12 +0000 Subject: [PATCH 093/134] [PR #5760/9e3a729d backport][stable-6] Improve callback docs (#5784) Improve callback docs (#5760) * Improve callback docs. * Apply suggestions from code review Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> * Update plugins/callback/logentries.py Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> * More improvements. 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 9e3a729da9599aa2751a7ed0afb4bf68401ab400) Co-authored-by: Felix Fontein --- plugins/callback/cgroup_memory_recap.py | 12 ++++++------ plugins/callback/context_demo.py | 4 ++-- plugins/callback/counter_enabled.py | 2 +- plugins/callback/dense.py | 2 +- plugins/callback/jabber.py | 4 ++-- plugins/callback/log_plays.py | 4 ++-- plugins/callback/logdna.py | 12 ++++++------ plugins/callback/logentries.py | 18 +++++++++--------- plugins/callback/logstash.py | 12 ++++++------ plugins/callback/null.py | 2 +- plugins/callback/say.py | 6 +++--- plugins/callback/selective.py | 2 +- plugins/callback/slack.py | 6 +++--- plugins/callback/splunk.py | 10 +++++----- plugins/callback/sumologic.py | 6 +++--- plugins/callback/syslog_json.py | 10 +++++----- plugins/callback/yaml.py | 2 +- 17 files changed, 57 insertions(+), 57 deletions(-) diff --git a/plugins/callback/cgroup_memory_recap.py b/plugins/callback/cgroup_memory_recap.py index eedacfeecb..ccdbcc9cf0 100644 --- a/plugins/callback/cgroup_memory_recap.py +++ b/plugins/callback/cgroup_memory_recap.py @@ -16,15 +16,15 @@ DOCUMENTATION = ''' - cgroups short_description: Profiles maximum memory usage of tasks and full execution using cgroups description: - - This is an ansible callback plugin that profiles maximum memory usage of ansible and individual tasks, and displays a recap at the end using cgroups + - This is an ansible callback plugin that profiles maximum memory usage of ansible and individual tasks, and displays a recap at the end using cgroups. notes: - - Requires ansible to be run from within a cgroup, such as with C(cgexec -g memory:ansible_profile ansible-playbook ...) - - This cgroup should only be used by ansible to get accurate results - - To create the cgroup, first use a command such as C(sudo cgcreate -a ec2-user:ec2-user -t ec2-user:ec2-user -g memory:ansible_profile) + - Requires ansible to be run from within a cgroup, such as with C(cgexec -g memory:ansible_profile ansible-playbook ...). + - This cgroup should only be used by ansible to get accurate results. + - To create the cgroup, first use a command such as C(sudo cgcreate -a ec2-user:ec2-user -t ec2-user:ec2-user -g memory:ansible_profile). options: max_mem_file: required: true - description: Path to cgroups C(memory.max_usage_in_bytes) file. Example C(/sys/fs/cgroup/memory/ansible_profile/memory.max_usage_in_bytes) + description: Path to cgroups C(memory.max_usage_in_bytes) file. Example C(/sys/fs/cgroup/memory/ansible_profile/memory.max_usage_in_bytes). env: - name: CGROUP_MAX_MEM_FILE ini: @@ -32,7 +32,7 @@ DOCUMENTATION = ''' key: max_mem_file cur_mem_file: required: true - description: Path to C(memory.usage_in_bytes) file. Example C(/sys/fs/cgroup/memory/ansible_profile/memory.usage_in_bytes) + description: Path to C(memory.usage_in_bytes) file. Example C(/sys/fs/cgroup/memory/ansible_profile/memory.usage_in_bytes). env: - name: CGROUP_CUR_MEM_FILE ini: diff --git a/plugins/callback/context_demo.py b/plugins/callback/context_demo.py index 9c3c9c5afc..b9558fc064 100644 --- a/plugins/callback/context_demo.py +++ b/plugins/callback/context_demo.py @@ -13,8 +13,8 @@ DOCUMENTATION = ''' type: aggregate short_description: demo callback that adds play/task context description: - - Displays some play and task context along with normal output - - This is mostly for demo purposes + - Displays some play and task context along with normal output. + - This is mostly for demo purposes. requirements: - whitelist in configuration ''' diff --git a/plugins/callback/counter_enabled.py b/plugins/callback/counter_enabled.py index e0e040c9d4..555ebd29a6 100644 --- a/plugins/callback/counter_enabled.py +++ b/plugins/callback/counter_enabled.py @@ -21,7 +21,7 @@ DOCUMENTATION = ''' extends_documentation_fragment: - default_callback requirements: - - set as stdout callback in ansible.cfg (stdout_callback = counter_enabled) + - set as stdout callback in C(ansible.cfg) (C(stdout_callback = counter_enabled)) ''' from ansible import constants as C diff --git a/plugins/callback/dense.py b/plugins/callback/dense.py index 18e4f162ff..490705fd27 100644 --- a/plugins/callback/dense.py +++ b/plugins/callback/dense.py @@ -14,7 +14,7 @@ short_description: minimal stdout output extends_documentation_fragment: - default_callback description: -- When in verbose mode it will act the same as the default callback +- When in verbose mode it will act the same as the default callback. author: - Dag Wieers (@dagwieers) requirements: diff --git a/plugins/callback/jabber.py b/plugins/callback/jabber.py index 823ae20144..d2d00496d8 100644 --- a/plugins/callback/jabber.py +++ b/plugins/callback/jabber.py @@ -13,10 +13,10 @@ DOCUMENTATION = ''' type: notification short_description: post task events to a jabber server description: - - The chatty part of ChatOps with a Hipchat server as a target + - The chatty part of ChatOps with a Hipchat server as a target. - This callback plugin sends status updates to a HipChat channel during playbook execution. requirements: - - xmpp (python lib https://github.com/ArchipelProject/xmpppy) + - xmpp (Python library U(https://github.com/ArchipelProject/xmpppy)) options: server: description: connection info to jabber server diff --git a/plugins/callback/log_plays.py b/plugins/callback/log_plays.py index b1dc69364c..e99054e176 100644 --- a/plugins/callback/log_plays.py +++ b/plugins/callback/log_plays.py @@ -13,10 +13,10 @@ DOCUMENTATION = ''' type: notification short_description: write playbook output to log file description: - - This callback writes playbook output to a file per host in the C(/var/log/ansible/hosts) directory + - This callback writes playbook output to a file per host in the C(/var/log/ansible/hosts) directory. requirements: - Whitelist in configuration - - A writeable /var/log/ansible/hosts directory by the user executing Ansible on the controller + - A writeable C(/var/log/ansible/hosts) directory by the user executing Ansible on the controller options: log_folder: default: /var/log/ansible/hosts diff --git a/plugins/callback/logdna.py b/plugins/callback/logdna.py index 2d0880ce19..fc9a81ac8a 100644 --- a/plugins/callback/logdna.py +++ b/plugins/callback/logdna.py @@ -12,14 +12,14 @@ DOCUMENTATION = ''' type: notification short_description: Sends playbook logs to LogDNA description: - - This callback will report logs from playbook actions, tasks, and events to LogDNA (https://app.logdna.com) + - This callback will report logs from playbook actions, tasks, and events to LogDNA (U(https://app.logdna.com)). requirements: - - LogDNA Python Library (https://github.com/logdna/python) + - LogDNA Python Library (U(https://github.com/logdna/python)) - whitelisting in configuration options: conf_key: required: true - description: LogDNA Ingestion Key + description: LogDNA Ingestion Key. type: string env: - name: LOGDNA_INGESTION_KEY @@ -28,7 +28,7 @@ DOCUMENTATION = ''' key: conf_key plugin_ignore_errors: required: false - description: Whether to ignore errors on failing or not + description: Whether to ignore errors on failing or not. type: boolean env: - name: ANSIBLE_IGNORE_ERRORS @@ -38,7 +38,7 @@ DOCUMENTATION = ''' default: false conf_hostname: required: false - description: Alternative Host Name; the current host name by default + description: Alternative Host Name; the current host name by default. type: string env: - name: LOGDNA_HOSTNAME @@ -47,7 +47,7 @@ DOCUMENTATION = ''' key: conf_hostname conf_tags: required: false - description: Tags + description: Tags. type: string env: - name: LOGDNA_TAGS diff --git a/plugins/callback/logentries.py b/plugins/callback/logentries.py index d40939b0ab..22322a4df2 100644 --- a/plugins/callback/logentries.py +++ b/plugins/callback/logentries.py @@ -13,15 +13,15 @@ DOCUMENTATION = ''' short_description: Sends events to Logentries description: - This callback plugin will generate JSON objects and send them to Logentries via TCP for auditing/debugging purposes. - - Before 2.4, if you wanted to use an ini configuration, the file must be placed in the same directory as this plugin and named logentries.ini + - Before 2.4, if you wanted to use an ini configuration, the file must be placed in the same directory as this plugin and named C(logentries.ini). - In 2.4 and above you can just put it in the main Ansible configuration file. requirements: - whitelisting in configuration - - certifi (python library) - - flatdict (python library), if you want to use the 'flatten' option + - certifi (Python library) + - flatdict (Python library), if you want to use the 'flatten' option options: api: - description: URI to the Logentries API + description: URI to the Logentries API. env: - name: LOGENTRIES_API default: data.logentries.com @@ -29,7 +29,7 @@ DOCUMENTATION = ''' - section: callback_logentries key: api port: - description: HTTP port to use when connecting to the API + description: HTTP port to use when connecting to the API. env: - name: LOGENTRIES_PORT default: 80 @@ -37,7 +37,7 @@ DOCUMENTATION = ''' - section: callback_logentries key: port tls_port: - description: Port to use when connecting to the API when TLS is enabled + description: Port to use when connecting to the API when TLS is enabled. env: - name: LOGENTRIES_TLS_PORT default: 443 @@ -45,7 +45,7 @@ DOCUMENTATION = ''' - section: callback_logentries key: tls_port token: - description: The logentries "TCP token" + description: The logentries C(TCP token). env: - name: LOGENTRIES_ANSIBLE_TOKEN required: true @@ -54,7 +54,7 @@ DOCUMENTATION = ''' key: token use_tls: description: - - Toggle to decide whether to use TLS to encrypt the communications with the API server + - Toggle to decide whether to use TLS to encrypt the communications with the API server. env: - name: LOGENTRIES_USE_TLS default: false @@ -63,7 +63,7 @@ DOCUMENTATION = ''' - section: callback_logentries key: use_tls flatten: - description: flatten complex data structures into a single dictionary with complex keys + description: Flatten complex data structures into a single dictionary with complex keys. type: boolean default: false env: diff --git a/plugins/callback/logstash.py b/plugins/callback/logstash.py index 7666b47876..144e1f9915 100644 --- a/plugins/callback/logstash.py +++ b/plugins/callback/logstash.py @@ -13,13 +13,13 @@ DOCUMENTATION = r''' type: notification short_description: Sends events to Logstash description: - - This callback will report facts and task events to Logstash https://www.elastic.co/products/logstash + - This callback will report facts and task events to Logstash U(https://www.elastic.co/products/logstash). requirements: - whitelisting in configuration - - logstash (python library) + - logstash (Python library) options: server: - description: Address of the Logstash server + description: Address of the Logstash server. env: - name: LOGSTASH_SERVER ini: @@ -28,7 +28,7 @@ DOCUMENTATION = r''' version_added: 1.0.0 default: localhost port: - description: Port on which logstash is listening + description: Port on which logstash is listening. env: - name: LOGSTASH_PORT ini: @@ -37,7 +37,7 @@ DOCUMENTATION = r''' version_added: 1.0.0 default: 5000 type: - description: Message type + description: Message type. env: - name: LOGSTASH_TYPE ini: @@ -54,7 +54,7 @@ DOCUMENTATION = r''' env: - name: LOGSTASH_PRE_COMMAND format_version: - description: Logging format + description: Logging format. type: str version_added: 2.0.0 ini: diff --git a/plugins/callback/null.py b/plugins/callback/null.py index 01f5f6ca06..f53a242945 100644 --- a/plugins/callback/null.py +++ b/plugins/callback/null.py @@ -15,7 +15,7 @@ DOCUMENTATION = ''' - set as main display callback short_description: Don't display stuff to screen description: - - This callback prevents outputing events to screen + - This callback prevents outputing events to screen. ''' from ansible.plugins.callback import CallbackBase diff --git a/plugins/callback/say.py b/plugins/callback/say.py index 03d7060352..005725a22b 100644 --- a/plugins/callback/say.py +++ b/plugins/callback/say.py @@ -14,12 +14,12 @@ DOCUMENTATION = ''' type: notification requirements: - whitelisting in configuration - - the '/usr/bin/say' command line program (standard on macOS) or 'espeak' command line program + - the C(/usr/bin/say) command line program (standard on macOS) or C(espeak) command line program short_description: notify using software speech synthesizer description: - - This plugin will use the 'say' or 'espeak' program to "speak" about play events. + - This plugin will use the C(say) or C(espeak) program to "speak" about play events. notes: - - In 2.8, this callback has been renamed from C(osx_say) into M(community.general.say). + - In Ansible 2.8, this callback has been renamed from C(osx_say) into M(community.general.say). ''' import platform diff --git a/plugins/callback/selective.py b/plugins/callback/selective.py index 6476f5ba53..526975bd2c 100644 --- a/plugins/callback/selective.py +++ b/plugins/callback/selective.py @@ -22,7 +22,7 @@ DOCUMENTATION = ''' options: nocolor: default: false - description: This setting allows suppressing colorizing output + description: This setting allows suppressing colorizing output. env: - name: ANSIBLE_NOCOLOR - name: ANSIBLE_SELECTIVE_DONT_COLORIZE diff --git a/plugins/callback/slack.py b/plugins/callback/slack.py index 6ca15b43f5..e9b84bbb38 100644 --- a/plugins/callback/slack.py +++ b/plugins/callback/slack.py @@ -18,11 +18,11 @@ DOCUMENTATION = ''' short_description: Sends play events to a Slack channel description: - This is an ansible callback plugin that sends status updates to a Slack channel during playbook execution. - - Before 2.4 only environment variables were available for configuring this plugin + - Before Ansible 2.4 only environment variables were available for configuring this plugin. options: webhook_url: required: true - description: Slack Webhook URL + description: Slack Webhook URL. env: - name: SLACK_WEBHOOK_URL ini: @@ -45,7 +45,7 @@ DOCUMENTATION = ''' - section: callback_slack key: username validate_certs: - description: validate the SSL certificate of the Slack server. (For HTTPS URLs) + description: Validate the SSL certificate of the Slack server for HTTPS URLs. env: - name: SLACK_VALIDATE_CERTS ini: diff --git a/plugins/callback/splunk.py b/plugins/callback/splunk.py index 32e77f4eb4..67ad944d2e 100644 --- a/plugins/callback/splunk.py +++ b/plugins/callback/splunk.py @@ -13,22 +13,22 @@ DOCUMENTATION = ''' author: "Stuart Hirst (!UNKNOWN) " description: - This callback plugin will send task results as JSON formatted events to a Splunk HTTP collector. - - The companion Splunk Monitoring & Diagnostics App is available here "https://splunkbase.splunk.com/app/4023/" + - The companion Splunk Monitoring & Diagnostics App is available here U(https://splunkbase.splunk.com/app/4023/). - Credit to "Ryan Currah (@ryancurrah)" for original source upon which this is based. requirements: - Whitelisting this callback plugin - 'Create a HTTP Event Collector in Splunk' - - 'Define the url and token in ansible.cfg' + - 'Define the URL and token in C(ansible.cfg)' options: url: - description: URL to the Splunk HTTP collector source + description: URL to the Splunk HTTP collector source. env: - name: SPLUNK_URL ini: - section: callback_splunk key: url authtoken: - description: Token to authenticate the connection to the Splunk HTTP collector + description: Token to authenticate the connection to the Splunk HTTP collector. env: - name: SPLUNK_AUTHTOKEN ini: @@ -48,7 +48,7 @@ DOCUMENTATION = ''' version_added: '1.0.0' include_milliseconds: description: Whether to include milliseconds as part of the generated timestamp field in the event - sent to the Splunk HTTP collector + sent to the Splunk HTTP collector. env: - name: SPLUNK_INCLUDE_MILLISECONDS ini: diff --git a/plugins/callback/sumologic.py b/plugins/callback/sumologic.py index 6fd950d991..998081c35b 100644 --- a/plugins/callback/sumologic.py +++ b/plugins/callback/sumologic.py @@ -12,14 +12,14 @@ type: notification short_description: Sends task result events to Sumologic author: "Ryan Currah (@ryancurrah)" description: - - This callback plugin will send task results as JSON formatted events to a Sumologic HTTP collector source + - This callback plugin will send task results as JSON formatted events to a Sumologic HTTP collector source. requirements: - Whitelisting this callback plugin - 'Create a HTTP collector source in Sumologic and specify a custom timestamp format of C(yyyy-MM-dd HH:mm:ss ZZZZ) and a custom timestamp locator of C("timestamp": "(.*)")' options: url: - description: URL to the Sumologic HTTP collector source + description: URL to the Sumologic HTTP collector source. env: - name: SUMOLOGIC_URL ini: @@ -28,7 +28,7 @@ options: ''' EXAMPLES = ''' -examples: > +examples: | To enable, add this to your ansible.cfg file in the defaults block [defaults] callback_whitelist = community.general.sumologic diff --git a/plugins/callback/syslog_json.py b/plugins/callback/syslog_json.py index 4b2c7e79b8..2bd8f6e604 100644 --- a/plugins/callback/syslog_json.py +++ b/plugins/callback/syslog_json.py @@ -15,11 +15,11 @@ DOCUMENTATION = ''' - whitelist in configuration short_description: sends JSON events to syslog description: - - This plugin logs ansible-playbook and ansible runs to a syslog server in JSON format - - Before Ansible 2.9 only environment variables were available for configuration + - This plugin logs ansible-playbook and ansible runs to a syslog server in JSON format. + - Before Ansible 2.9 only environment variables were available for configuration. options: server: - description: syslog server that will receive the event + description: Syslog server that will receive the event. env: - name: SYSLOG_SERVER default: localhost @@ -27,7 +27,7 @@ DOCUMENTATION = ''' - section: callback_syslog_json key: syslog_server port: - description: port on which the syslog server is listening + description: Port on which the syslog server is listening. env: - name: SYSLOG_PORT default: 514 @@ -35,7 +35,7 @@ DOCUMENTATION = ''' - section: callback_syslog_json key: syslog_port facility: - description: syslog facility to log as + description: Syslog facility to log as. env: - name: SYSLOG_FACILITY default: user diff --git a/plugins/callback/yaml.py b/plugins/callback/yaml.py index 81d59e2e70..73782de151 100644 --- a/plugins/callback/yaml.py +++ b/plugins/callback/yaml.py @@ -11,7 +11,7 @@ DOCUMENTATION = ''' author: Unknown (!UNKNOWN) name: yaml type: stdout - short_description: yaml-ized Ansible screen output + short_description: YAML-ized Ansible screen output description: - Ansible output that can be quite a bit easier to read than the default JSON formatting. From dd70419d18783895e611fd7d1edf52b201852e8c Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 7 Jan 2023 15:20:24 +0100 Subject: [PATCH 094/134] [PR #5785/0ff003d3 backport][stable-6] Fix CI (#5789) Fix CI (#5785) Try to fix CI. (cherry picked from commit 0ff003d31246ca03a891a28a9ecbca8e0b27bb46) Co-authored-by: Felix Fontein --- tests/utils/constraints.txt | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/utils/constraints.txt b/tests/utils/constraints.txt index af2b326ddd..87db256f41 100644 --- a/tests/utils/constraints.txt +++ b/tests/utils/constraints.txt @@ -7,7 +7,7 @@ coverage >= 4.2, < 5.0.0, != 4.3.2 ; python_version <= '3.7' # features in 4.2+ coverage >= 4.5.4, < 5.0.0 ; python_version > '3.7' # coverage had a bug in < 4.5.4 that would cause unit tests to hang in Python 3.8, coverage 5.0+ incompatible cryptography < 2.2 ; python_version < '2.7' # cryptography 2.2 drops support for python 2.6 cryptography >= 3.0, < 3.4 ; python_version < '3.6' and python_version >= '2.7' # cryptography 3.4 drops support for python 2.7 -cryptography >= 3.3, < 3.4 ; python_version >= '2.7' # FIXME: the upper limit is needed for RHEL8.2, CentOS 8, Ubuntu 18.04, and OpenSuSE 15 +cryptography >= 3.3, < 3.4 ; python_version >= '2.7' and python_version < '3.9' # FIXME: the upper limit is needed for RHEL8.2, CentOS 8, Ubuntu 18.04, and OpenSuSE 15 deepdiff < 4.0.0 ; python_version < '3' # deepdiff 4.0.0 and later require python 3 jinja2 < 2.11 ; python_version < '2.7' # jinja2 2.11 and later require python 2.7 or later urllib3 < 1.24 ; python_version < '2.7' # urllib3 1.24 and later require python 2.7 or later @@ -56,12 +56,3 @@ redis ; python_version >= '3.6' pycdlib < 1.13.0 ; python_version < '3' # 1.13.0 does not work with Python 2, while not declaring that python-daemon <= 2.3.0 ; python_version < '3' bcrypt < 4.0.0 # TEMP: restrict to < 4.0.0 since installing 4.0.0 fails on RHEL 8 - -# freeze pylint and its requirements for consistent test results -astroid == 2.2.5 -isort == 4.3.15 -lazy-object-proxy == 1.3.1 -mccabe == 0.6.1 -pylint == 2.3.1 -typed-ast == 1.4.0 # 1.4.0 is required to compile on Python 3.8 -wrapt == 1.11.1 From a1ca89b0580385e0ec0945f1f0c505e4e8099539 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 7 Jan 2023 15:24:47 +0100 Subject: [PATCH 095/134] [PR #5786/759ca9a0 backport][stable-6] Remove currently unneeded generic tests from CI (#5791) Remove currently unneeded generic tests from CI (#5786) Remove currently unneeded generic tests from CI. (cherry picked from commit 759ca9a0ab5a6c68dea342e0840b6803ac008a63) Co-authored-by: Felix Fontein --- .azure-pipelines/azure-pipelines.yml | 11 ++++++----- tests/integration/targets/one_host/aliases | 2 +- tests/integration/targets/one_template/aliases | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index c8e03a164b..77463e2c79 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -487,10 +487,11 @@ stages: - Docker_2_13 - Docker_2_14 - Docker_community_devel - - Generic_devel - - Generic_2_11 - - Generic_2_12 - - Generic_2_13 - - Generic_2_14 +# Right now all generic tests are disabled. Uncomment when at least one of them is re-enabled. +# - Generic_devel +# - Generic_2_11 +# - Generic_2_12 +# - Generic_2_13 +# - Generic_2_14 jobs: - template: templates/coverage.yml diff --git a/tests/integration/targets/one_host/aliases b/tests/integration/targets/one_host/aliases index 02a31bcd55..100ba0f979 100644 --- a/tests/integration/targets/one_host/aliases +++ b/tests/integration/targets/one_host/aliases @@ -4,4 +4,4 @@ azp/generic/1 cloud/opennebula -disabled # FIXME +disabled # FIXME - when this is fixed, also re-enable the generic tests in CI! diff --git a/tests/integration/targets/one_template/aliases b/tests/integration/targets/one_template/aliases index 02a31bcd55..100ba0f979 100644 --- a/tests/integration/targets/one_template/aliases +++ b/tests/integration/targets/one_template/aliases @@ -4,4 +4,4 @@ azp/generic/1 cloud/opennebula -disabled # FIXME +disabled # FIXME - when this is fixed, also re-enable the generic tests in CI! From aa136aca4cbdce6454e4450bbd4b4742412e0f05 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 7 Jan 2023 16:55:57 +0100 Subject: [PATCH 096/134] [PR #5794/3b73e7ed backport][stable-6] alternatives: make work with Fedora 37 (#5797) alternatives: make work with Fedora 37 (#5794) * alternatives in Fedora 37 uses follower instead of slave. * Add changelog fragment. (cherry picked from commit 3b73e7ed2a550480892854ffb48314665a9b52c5) Co-authored-by: Felix Fontein --- changelogs/fragments/5794-alternatives-fedora37.yml | 2 ++ plugins/modules/alternatives.py | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/5794-alternatives-fedora37.yml diff --git a/changelogs/fragments/5794-alternatives-fedora37.yml b/changelogs/fragments/5794-alternatives-fedora37.yml new file mode 100644 index 0000000000..bfb77142cc --- /dev/null +++ b/changelogs/fragments/5794-alternatives-fedora37.yml @@ -0,0 +1,2 @@ +bugfixes: + - "alternatives - support subcommands on Fedora 37, which uses ``follower`` instead of ``slave`` (https://github.com/ansible-collections/community.general/pull/5794)." diff --git a/plugins/modules/alternatives.py b/plugins/modules/alternatives.py index 4566144493..48cacb4540 100644 --- a/plugins/modules/alternatives.py +++ b/plugins/modules/alternatives.py @@ -60,6 +60,8 @@ options: description: - A list of subcommands. - Each subcommand needs a name, a link and a path parameter. + - Subcommands are also named 'slaves' or 'followers', depending on the version + of alternatives. type: list elements: dict aliases: ['slaves'] @@ -310,10 +312,10 @@ class AlternativesModule(object): current_mode_regex = re.compile(r'\s-\s(?:status\sis\s)?(\w*)(?:\smode|.)$', re.MULTILINE) current_path_regex = re.compile(r'^\s*link currently points to (.*)$', re.MULTILINE) current_link_regex = re.compile(r'^\s*link \w+ is (.*)$', re.MULTILINE) - subcmd_path_link_regex = re.compile(r'^\s*slave (\S+) is (.*)$', re.MULTILINE) + subcmd_path_link_regex = re.compile(r'^\s*(?:slave|follower) (\S+) is (.*)$', re.MULTILINE) - alternative_regex = re.compile(r'^(\/.*)\s-\s(?:family\s\S+\s)?priority\s(\d+)((?:\s+slave.*)*)', re.MULTILINE) - subcmd_regex = re.compile(r'^\s+slave (.*): (.*)$', re.MULTILINE) + alternative_regex = re.compile(r'^(\/.*)\s-\s(?:family\s\S+\s)?priority\s(\d+)((?:\s+(?:slave|follower).*)*)', re.MULTILINE) + subcmd_regex = re.compile(r'^\s+(?:slave|follower) (.*): (.*)$', re.MULTILINE) match = current_mode_regex.search(display_output) if not match: From efc2cbf8405cc9a048c27408a4f15503d7b735c3 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 7 Jan 2023 18:17:12 +0100 Subject: [PATCH 097/134] [PR #5782/6fb212b1 backport][stable-6] Update CI matrix (#5798) Update CI matrix (#5782) * Update CI matrix. * Disable RHEL 9.1 for tests where RHEL 9.0 was disabled as well. * Skip iso_extract on FreeBSD 12.4. * Fix cloud_init_data_facts test for Fedora 37. * Do not try to install snap on RHEL 9.1. * Skip pkgng jail tests on FreeBSD 12.4 as well. (cherry picked from commit 6fb212b1042f730b7a92c6508a6d249b53f12fae) Co-authored-by: Felix Fontein --- .azure-pipelines/azure-pipelines.yml | 22 ++++++++++--------- .../cloud_init_data_facts/tasks/main.yml | 6 +++++ .../integration/targets/django_manage/aliases | 1 + tests/integration/targets/homectl/aliases | 1 + tests/integration/targets/iso_extract/aliases | 2 ++ tests/integration/targets/odbc/aliases | 1 + .../targets/pkgng/tasks/freebsd.yml | 7 +++++- .../targets/setup_snap/tasks/D-RedHat-9.1.yml | 6 +++++ tests/integration/targets/ufw/aliases | 1 + 9 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 tests/integration/targets/setup_snap/tasks/D-RedHat-9.1.yml diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index 77463e2c79..3816369497 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -197,10 +197,10 @@ stages: parameters: testFormat: devel/{0} targets: - - name: Alpine 3.16 - test: alpine/3.16 - # - name: Fedora 36 - # test: fedora/36 + - name: Alpine 3.17 + test: alpine/3.17 + # - name: Fedora 37 + # test: fedora/37 # - name: Ubuntu 20.04 # test: ubuntu/20.04 - name: Ubuntu 22.04 @@ -219,10 +219,12 @@ stages: test: macos/12.0 - name: RHEL 7.9 test: rhel/7.9 - - name: RHEL 9.0 - test: rhel/9.0 + - name: RHEL 9.1 + test: rhel/9.1 - name: FreeBSD 13.1 test: freebsd/13.1 + - name: FreeBSD 12.4 + test: freebsd/12.4 groups: - 1 - 2 @@ -305,8 +307,8 @@ stages: targets: - name: CentOS 7 test: centos7 - - name: Fedora 36 - test: fedora36 + - name: Fedora 37 + test: fedora37 - name: openSUSE 15 test: opensuse15 - name: Ubuntu 20.04 @@ -327,8 +329,8 @@ stages: parameters: testFormat: 2.14/linux/{0} targets: - - name: Ubuntu 20.04 - test: ubuntu2004 + - name: Fedora 36 + test: fedora36 groups: - 1 - 2 diff --git a/tests/integration/targets/cloud_init_data_facts/tasks/main.yml b/tests/integration/targets/cloud_init_data_facts/tasks/main.yml index fc634a972f..fe38d4ca5b 100644 --- a/tests/integration/targets/cloud_init_data_facts/tasks/main.yml +++ b/tests/integration/targets/cloud_init_data_facts/tasks/main.yml @@ -29,6 +29,12 @@ - cloud-init - udev + - name: Ensure systemd-network user exists + user: + name: systemd-network + state: present + when: ansible_distribution == 'Fedora' and ansible_distribution_major_version|int >= 37 + - name: setup run cloud-init service: name: cloud-init-local diff --git a/tests/integration/targets/django_manage/aliases b/tests/integration/targets/django_manage/aliases index 025fe0ec48..98aed9e9d4 100644 --- a/tests/integration/targets/django_manage/aliases +++ b/tests/integration/targets/django_manage/aliases @@ -12,3 +12,4 @@ skip/rhel8.3 skip/rhel8.4 skip/rhel8.5 skip/rhel9.0 +skip/rhel9.1 diff --git a/tests/integration/targets/homectl/aliases b/tests/integration/targets/homectl/aliases index 8d80bf12c3..b87db2e43c 100644 --- a/tests/integration/targets/homectl/aliases +++ b/tests/integration/targets/homectl/aliases @@ -8,3 +8,4 @@ skip/freebsd skip/osx skip/macos skip/rhel9.0 # See https://www.reddit.com/r/Fedora/comments/si7nzk/homectl/ +skip/rhel9.1 # See https://www.reddit.com/r/Fedora/comments/si7nzk/homectl/ diff --git a/tests/integration/targets/iso_extract/aliases b/tests/integration/targets/iso_extract/aliases index 5b0ab153c8..2815959456 100644 --- a/tests/integration/targets/iso_extract/aliases +++ b/tests/integration/targets/iso_extract/aliases @@ -8,3 +8,5 @@ destructive skip/aix skip/osx # FIXME skip/rhel9.0 # FIXME +skip/rhel9.1 # FIXME +skip/freebsd12.4 # FIXME diff --git a/tests/integration/targets/odbc/aliases b/tests/integration/targets/odbc/aliases index 2dbf0eac3e..e8465c50e8 100644 --- a/tests/integration/targets/odbc/aliases +++ b/tests/integration/targets/odbc/aliases @@ -8,4 +8,5 @@ skip/osx skip/macos skip/rhel8.0 skip/rhel9.0 +skip/rhel9.1 skip/freebsd diff --git a/tests/integration/targets/pkgng/tasks/freebsd.yml b/tests/integration/targets/pkgng/tasks/freebsd.yml index a7cb90b11d..a822b4c7e9 100644 --- a/tests/integration/targets/pkgng/tasks/freebsd.yml +++ b/tests/integration/targets/pkgng/tasks/freebsd.yml @@ -501,14 +501,19 @@ # NOTE: FreeBSD 12.0 test runner receives a "connection reset by peer" after ~20% downloaded so we are # only running this on 12.1 or higher # + # NOTE: FreeBSD 12.4 fails to update repositories because it cannot load certificates from /usr/share/keys/pkg/trusted + # knowledge has to take a look) + # # NOTE: FreeBSD 13.0 fails to update the package catalogue for unknown reasons (someone with FreeBSD # knowledge has to take a look) # # NOTE: FreeBSD 13.1 fails to update the package catalogue for unknown reasons (someone with FreeBSD # knowledge has to take a look) # + # See also + # https://github.com/ansible-collections/community.general/issues/5795 when: >- - (ansible_distribution_version is version('12.01', '>=') and ansible_distribution_version is version('13.0', '<')) + (ansible_distribution_version is version('12.01', '>=') and ansible_distribution_version is version('12.4', '<')) or ansible_distribution_version is version('13.2', '>=') block: - name: Setup testjail diff --git a/tests/integration/targets/setup_snap/tasks/D-RedHat-9.1.yml b/tests/integration/targets/setup_snap/tasks/D-RedHat-9.1.yml new file mode 100644 index 0000000000..5bbfaff128 --- /dev/null +++ b/tests/integration/targets/setup_snap/tasks/D-RedHat-9.1.yml @@ -0,0 +1,6 @@ +--- +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +# Do nothing diff --git a/tests/integration/targets/ufw/aliases b/tests/integration/targets/ufw/aliases index 1f974ecd19..2ef1a41338 100644 --- a/tests/integration/targets/ufw/aliases +++ b/tests/integration/targets/ufw/aliases @@ -10,6 +10,7 @@ skip/macos skip/freebsd skip/rhel8.0 # FIXME skip/rhel9.0 # FIXME +skip/rhel9.1 # FIXME skip/docker needs/root needs/target/setup_epel From a17124f3c46a664142ef6bdfb8f7e9d8f5d6a19e Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 8 Jan 2023 22:02:27 +0100 Subject: [PATCH 098/134] [PR #5486/4caa6574 backport][stable-6] snap_alias: using CmdRunner (#5801) snap_alias: using CmdRunner (#5486) * snap_alias: using CmdRunner * add changelog fragment * fix changelog fragment * invert order of initialization in __init_module__() * comment extra changed=True from code * add extra info when verbose * add extra info when verbose - fix blank line * handle check_mode the old way * fix logical test * fix error when using multiple aliases * fix error when using multiple aliases, part 2 * revert to using check_mode_skip=True again (cherry picked from commit 4caa6574de486d6840ac50affe48501f9d895bf4) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../fragments/5486-snap-alias-cmd-runner.yml | 2 + plugins/modules/snap_alias.py | 53 ++++++++++--------- 2 files changed, 31 insertions(+), 24 deletions(-) create mode 100644 changelogs/fragments/5486-snap-alias-cmd-runner.yml diff --git a/changelogs/fragments/5486-snap-alias-cmd-runner.yml b/changelogs/fragments/5486-snap-alias-cmd-runner.yml new file mode 100644 index 0000000000..59ae0c5abf --- /dev/null +++ b/changelogs/fragments/5486-snap-alias-cmd-runner.yml @@ -0,0 +1,2 @@ +minor_changes: + - snap_alias - refactored module to use ``CmdRunner`` to execute ``snap`` (https://github.com/ansible-collections/community.general/pull/5486). diff --git a/plugins/modules/snap_alias.py b/plugins/modules/snap_alias.py index 818dbbce31..1611c06719 100644 --- a/plugins/modules/snap_alias.py +++ b/plugins/modules/snap_alias.py @@ -79,9 +79,8 @@ snap_aliases: import re -from ansible_collections.community.general.plugins.module_utils.module_helper import ( - CmdStateModuleHelper -) +from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt +from ansible_collections.community.general.plugins.module_utils.module_helper import StateModuleHelper _state_map = dict( @@ -91,7 +90,7 @@ _state_map = dict( ) -class SnapAlias(CmdStateModuleHelper): +class SnapAlias(StateModuleHelper): _RE_ALIAS_LIST = re.compile(r"^(?P[\w-]+)\s+(?P[\w-]+)\s+.*$") module = dict( @@ -106,25 +105,26 @@ class SnapAlias(CmdStateModuleHelper): ], 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 + + command_args_formats = { + "state": cmd_runner_fmt.as_map(_state_map), + "name": cmd_runner_fmt.as_list(), + "alias": cmd_runner_fmt.as_list(), + } 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.runner = CmdRunner(self.module, "snap", self.command_args_formats, check_rc=False) 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): + def process(rc, out, err): if err: return {} aliases = [self._RE_ALIAS_LIST.match(a.strip()) for a in out.splitlines()[1:]] @@ -134,9 +134,8 @@ class SnapAlias(CmdStateModuleHelper): 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) + with self.runner("state name", check_rc=True, output_process=process) as ctx: + return ctx.run(state="info") def _get_aliases_for(self, name): return self._get_aliases().get(name, []) @@ -152,24 +151,30 @@ class SnapAlias(CmdStateModuleHelper): 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): + 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}]) + with self.runner("state name alias", check_mode_skip=True) as ctx: + ctx.run(alias=_alias) + if self.verbosity >= 4: + self.vars.run_info = ctx.run_info 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']) + with self.runner("state name", check_mode_skip=True) as ctx: + ctx.run() + if self.verbosity >= 4: + self.vars.run_info = ctx.run_info else: - for alias in self.vars.alias: - if self._has_alias(self.vars.name, alias): + 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}]) + with self.runner("state alias", check_mode_skip=True) as ctx: + ctx.run(alias=_alias) + if self.verbosity >= 4: + self.vars.run_info = ctx.run_info def main(): From 3fd84d71b8979e6911c7af3dbc5b14a983efb1d8 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 8 Jan 2023 22:02:42 +0100 Subject: [PATCH 099/134] [PR #5486/4caa6574 backport][stable-6] snap_alias: using CmdRunner (#5801) snap_alias: using CmdRunner (#5486) * snap_alias: using CmdRunner * add changelog fragment * fix changelog fragment * invert order of initialization in __init_module__() * comment extra changed=True from code * add extra info when verbose * add extra info when verbose - fix blank line * handle check_mode the old way * fix logical test * fix error when using multiple aliases * fix error when using multiple aliases, part 2 * revert to using check_mode_skip=True again (cherry picked from commit 4caa6574de486d6840ac50affe48501f9d895bf4) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> From 82a9db97388eaa24e963961cc6307e225ec73f15 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 12 Jan 2023 21:06:11 +0100 Subject: [PATCH 100/134] [PR #5718/682bb4b8 backport][stable-6] opkg: refactor module to use StateModuleHelper and CmdRunner (#5824) opkg: refactor module to use StateModuleHelper and CmdRunner (#5718) * opkg: refactor module to use StateModuleHelper and CmdRunner * add changelog fragment * Update plugins/modules/opkg.py Co-authored-by: joergho <48011876+joergho@users.noreply.github.com> * Update plugins/modules/opkg.py Co-authored-by: joergho <48011876+joergho@users.noreply.github.com> * Update plugins/modules/opkg.py Co-authored-by: joergho <48011876+joergho@users.noreply.github.com> * Update plugins/modules/opkg.py Co-authored-by: joergho <48011876+joergho@users.noreply.github.com> * Update plugins/modules/opkg.py Co-authored-by: joergho <48011876+joergho@users.noreply.github.com> * Update plugins/modules/opkg.py Co-authored-by: joergho <48011876+joergho@users.noreply.github.com> * Update plugins/modules/opkg.py Co-authored-by: joergho <48011876+joergho@users.noreply.github.com> * generate message outcome as before * aggregated changes from 5688 * fix package query * add unit tests * fix sanity error * Update plugins/modules/opkg.py Co-authored-by: joergho <48011876+joergho@users.noreply.github.com> * add test for specifying version * refactor parameter name Co-authored-by: joergho <48011876+joergho@users.noreply.github.com> (cherry picked from commit 682bb4b88a00b880756a891f9280083164dc8fb2) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- changelogs/fragments/5718-opkg-refactor.yaml | 2 + plugins/modules/opkg.py | 208 ++++++++----------- tests/unit/plugins/modules/test_opkg.py | 193 +++++++++++++++++ 3 files changed, 280 insertions(+), 123 deletions(-) create mode 100644 changelogs/fragments/5718-opkg-refactor.yaml create mode 100644 tests/unit/plugins/modules/test_opkg.py diff --git a/changelogs/fragments/5718-opkg-refactor.yaml b/changelogs/fragments/5718-opkg-refactor.yaml new file mode 100644 index 0000000000..fb8b5680da --- /dev/null +++ b/changelogs/fragments/5718-opkg-refactor.yaml @@ -0,0 +1,2 @@ +minor_changes: + - opkg - refactored module to use ``CmdRunner`` for executing ``opkg`` (https://github.com/ansible-collections/community.general/pull/5718). diff --git a/plugins/modules/opkg.py b/plugins/modules/opkg.py index 7e2b8c4ac2..d736c1f3ff 100644 --- a/plugins/modules/opkg.py +++ b/plugins/modules/opkg.py @@ -97,144 +97,106 @@ EXAMPLES = ''' force: overwrite ''' -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.six.moves import shlex_quote +from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt +from ansible_collections.community.general.plugins.module_utils.module_helper import StateModuleHelper -def update_package_db(module, opkg_path): - """ Updates packages list. """ - - rc, out, err = module.run_command([opkg_path, "update"]) - - if rc != 0: - module.fail_json(msg="could not update package db") - - -def query_package(module, opkg_path, name, version=None, state="present"): - """ Returns whether a package is installed or not. """ - - if state == "present": - rc, out, err = module.run_command([opkg_path, "list-installed", name]) - if rc != 0: - return False - # variable out is one line if the package is installed: - # "NAME - VERSION - DESCRIPTION" - if version is not None: - if not out.startswith("%s - %s " % (name, version)): - return False - else: - if not out.startswith(name + " "): - return False - return True - else: - raise NotImplementedError() - - -def split_name_and_version(module, package): - """ Split the name and the version when using the NAME=VERSION syntax """ - splitted = package.split('=', 1) - if len(splitted) == 1: - return splitted[0], None - else: - return splitted[0], splitted[1] - - -def remove_packages(module, opkg_path, packages): - """ Uninstalls one or more packages if installed. """ - - p = module.params - force = p["force"] - if force: - force = "--force-%s" % force - - remove_c = 0 - # Using a for loop in case of error, we can report the package that failed - for package in packages: - package, version = split_name_and_version(module, package) - - # Query the package first, to see if we even need to remove - if not query_package(module, opkg_path, package): - continue - - if force: - rc, out, err = module.run_command([opkg_path, "remove", force, package]) - else: - rc, out, err = module.run_command([opkg_path, "remove", package]) - - if query_package(module, opkg_path, package): - module.fail_json(msg="failed to remove %s: %s" % (package, out)) - - remove_c += 1 - - if remove_c > 0: - - module.exit_json(changed=True, msg="removed %s package(s)" % remove_c) - - module.exit_json(changed=False, msg="package(s) already absent") - - -def install_packages(module, opkg_path, packages): - """ Installs one or more packages if not already installed. """ - - p = module.params - force = p["force"] - if force: - force = "--force-%s" % force - - install_c = 0 - - for package in packages: - package, version = split_name_and_version(module, package) - - if query_package(module, opkg_path, package, version) and (force != '--force-reinstall'): - continue - - if version is not None: - version_str = "=%s" % version - else: - version_str = "" - - if force: - rc, out, err = module.run_command([opkg_path, "install", force, package + version_str]) - else: - rc, out, err = module.run_command([opkg_path, "install", package + version_str]) - - if not query_package(module, opkg_path, package, version): - module.fail_json(msg="failed to install %s%s: %s" % (package, version_str, out)) - - install_c += 1 - - if install_c > 0: - module.exit_json(changed=True, msg="installed %s package(s)" % (install_c)) - - module.exit_json(changed=False, msg="package(s) already present") - - -def main(): - module = AnsibleModule( +class Opkg(StateModuleHelper): + module = dict( argument_spec=dict( name=dict(aliases=["pkg"], required=True, type="list", elements="str"), 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"]), update_cache=dict(default=False, type='bool'), - ) + ), ) - opkg_path = module.get_bin_path('opkg', True, ['/bin']) + def __init_module__(self): + self.vars.set("install_c", 0, output=False, change=True) + self.vars.set("remove_c", 0, output=False, change=True) - p = module.params + state_map = dict( + query="list-installed", + present="install", + installed="install", + absent="remove", + removed="remove", + ) - if p["update_cache"]: - update_package_db(module, opkg_path) + def _force(value): + if value == "": + value = None + return cmd_runner_fmt.as_optval("--force-")(value, ctx_ignore_none=True) - pkgs = p["name"] + self.runner = CmdRunner( + self.module, + command="opkg", + arg_formats=dict( + package=cmd_runner_fmt.as_list(), + state=cmd_runner_fmt.as_map(state_map), + force=cmd_runner_fmt.as_func(_force), + update_cache=cmd_runner_fmt.as_bool("update") + ), + ) - if p["state"] in ["present", "installed"]: - install_packages(module, opkg_path, pkgs) + @staticmethod + def split_name_and_version(package): + """ Split the name and the version when using the NAME=VERSION syntax """ + splitted = package.split('=', 1) + if len(splitted) == 1: + return splitted[0], None + else: + return splitted[0], splitted[1] - elif p["state"] in ["absent", "removed"]: - remove_packages(module, opkg_path, pkgs) + def _package_in_desired_state(self, name, want_installed, version=None): + dummy, out, dummy = self.runner("state package").run(state="query", package=name) + + has_package = out.startswith(name + " - %s" % ("" if not version else (version + " "))) + return want_installed == has_package + + def state_present(self): + if self.vars.update_cache: + dummy, rc, dummy = self.runner("update_cache").run() + if rc != 0: + self.do_raise("could not update package db") + with self.runner("state force package") as ctx: + for package in self.vars.name: + pkg_name, pkg_version = self.split_name_and_version(package) + if not self._package_in_desired_state(pkg_name, want_installed=True, version=pkg_version) or self.vars.force == "reinstall": + ctx.run(package=package) + if not self._package_in_desired_state(pkg_name, want_installed=True, version=pkg_version): + self.do_raise("failed to install %s" % package) + self.vars.install_c += 1 + if self.vars.install_c > 0: + self.vars.msg = "installed %s package(s)" % (self.vars.install_c) + else: + self.vars.msg = "package(s) already present" + + def state_absent(self): + if self.vars.update_cache: + dummy, rc, dummy = self.runner("update_cache").run() + if rc != 0: + self.do_raise("could not update package db") + with self.runner("state force package") as ctx: + for package in self.vars.name: + package, dummy = self.split_name_and_version(package) + if not self._package_in_desired_state(package, want_installed=False): + ctx.run(package=package) + if not self._package_in_desired_state(package, want_installed=False): + self.do_raise("failed to remove %s" % package) + self.vars.remove_c += 1 + if self.vars.remove_c > 0: + self.vars.msg = "removed %s package(s)" % (self.vars.remove_c) + else: + self.vars.msg = "package(s) already absent" + + state_installed = state_present + state_removed = state_absent + + +def main(): + Opkg.execute() if __name__ == '__main__': diff --git a/tests/unit/plugins/modules/test_opkg.py b/tests/unit/plugins/modules/test_opkg.py new file mode 100644 index 0000000000..f11347facc --- /dev/null +++ b/tests/unit/plugins/modules/test_opkg.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Alexei Znamensky (russoz@gmail.com) +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json + +from collections import namedtuple +from ansible_collections.community.general.plugins.modules import opkg + +import pytest + +TESTED_MODULE = opkg.__name__ + + +ModuleTestCase = namedtuple("ModuleTestCase", ["id", "input", "output", "run_command_calls"]) +RunCmdCall = namedtuple("RunCmdCall", ["command", "environ", "rc", "out", "err"]) + + +@pytest.fixture +def patch_opkg(mocker): + mocker.patch('ansible.module_utils.basic.AnsibleModule.get_bin_path', return_value='/testbin/opkg') + + +TEST_CASES = [ + ModuleTestCase( + id="install_zlibdev", + input={"name": "zlib-dev", "state": "present"}, + output={ + "msg": "installed 1 package(s)" + }, + run_command_calls=[ + RunCmdCall( + command=["/testbin/opkg", "list-installed", "zlib-dev"], + environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, + rc=0, + out="", + err="", + ), + RunCmdCall( + command=["/testbin/opkg", "install", "zlib-dev"], + environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, + rc=0, + out=( + "Installing zlib-dev (1.2.11-6) to root..." + "Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib-dev_1.2.11-6_mips_24kc.ipk" + "Installing zlib (1.2.11-6) to root..." + "Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib_1.2.11-6_mips_24kc.ipk" + "Configuring zlib." + "Configuring zlib-dev." + ), + err="", + ), + RunCmdCall( + command=["/testbin/opkg", "list-installed", "zlib-dev"], + environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, + rc=0, + out="zlib-dev - 1.2.11-6\n", + err="", + ), + ], + ), + ModuleTestCase( + id="install_zlibdev_present", + input={"name": "zlib-dev", "state": "present"}, + output={ + "msg": "package(s) already present" + }, + run_command_calls=[ + RunCmdCall( + command=["/testbin/opkg", "list-installed", "zlib-dev"], + environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, + rc=0, + out="zlib-dev - 1.2.11-6\n", + err="", + ), + ], + ), + ModuleTestCase( + id="install_zlibdev_force_reinstall", + input={"name": "zlib-dev", "state": "present", "force": "reinstall"}, + output={ + "msg": "installed 1 package(s)" + }, + run_command_calls=[ + RunCmdCall( + command=["/testbin/opkg", "list-installed", "zlib-dev"], + environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, + rc=0, + out="zlib-dev - 1.2.11-6\n", + err="", + ), + RunCmdCall( + command=["/testbin/opkg", "install", "--force-reinstall", "zlib-dev"], + environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, + rc=0, + out=( + "Installing zlib-dev (1.2.11-6) to root...\n" + "Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib-dev_1.2.11-6_mips_24kc.ipk\n" + "Configuring zlib-dev.\n" + ), + err="", + ), + RunCmdCall( + command=["/testbin/opkg", "list-installed", "zlib-dev"], + environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, + rc=0, + out="zlib-dev - 1.2.11-6\n", + err="", + ), + ], + ), + ModuleTestCase( + id="install_zlibdev_with_version", + input={"name": "zlib-dev=1.2.11-6", "state": "present"}, + output={ + "msg": "installed 1 package(s)" + }, + run_command_calls=[ + RunCmdCall( + command=["/testbin/opkg", "list-installed", "zlib-dev"], + environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, + rc=0, + out="", + err="", + ), + RunCmdCall( + command=["/testbin/opkg", "install", "zlib-dev=1.2.11-6"], + environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, + rc=0, + out=( + "Installing zlib-dev (1.2.11-6) to root..." + "Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib-dev_1.2.11-6_mips_24kc.ipk" + "Installing zlib (1.2.11-6) to root..." + "Downloading https://downloads.openwrt.org/releases/22.03.0/packages/mips_24kc/base/zlib_1.2.11-6_mips_24kc.ipk" + "Configuring zlib." + "Configuring zlib-dev." + ), + err="", + ), + RunCmdCall( + command=["/testbin/opkg", "list-installed", "zlib-dev"], + environ={'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, + rc=0, + out="zlib-dev - 1.2.11-6 \n", # This output has the extra space at the end, to satisfy the behaviour of Yocto/OpenEmbedded's opkg + err="", + ), + ], + ), +] +TEST_CASES_IDS = [item.id for item in TEST_CASES] + + +@pytest.mark.parametrize('patch_ansible_module, testcase', + [[x.input, x] for x in TEST_CASES], + ids=TEST_CASES_IDS, + indirect=['patch_ansible_module']) +@pytest.mark.usefixtures('patch_ansible_module') +def test_opkg(mocker, capfd, patch_opkg, testcase): + """ + Run unit tests for test cases listen in TEST_CASES + """ + + run_cmd_calls = testcase.run_command_calls + + # Mock function used for running commands first + call_results = [(x.rc, x.out, x.err) for x in run_cmd_calls] + mock_run_command = mocker.patch('ansible.module_utils.basic.AnsibleModule.run_command', side_effect=call_results) + + # Try to run test case + with pytest.raises(SystemExit): + opkg.main() + + out, err = capfd.readouterr() + results = json.loads(out) + print("testcase =\n%s" % str(testcase)) + print("results =\n%s" % results) + + for test_result in testcase.output: + assert results[test_result] == testcase.output[test_result], \ + "'{0}': '{1}' != '{2}'".format(test_result, results[test_result], testcase.output[test_result]) + + call_args_list = [(item[0][0], item[1]) for item in mock_run_command.call_args_list] + expected_call_args_list = [(item.command, item.environ) for item in run_cmd_calls] + print("call args list =\n%s" % call_args_list) + print("expected args list =\n%s" % expected_call_args_list) + + assert mock_run_command.call_count == len(run_cmd_calls) + if mock_run_command.call_count: + assert call_args_list == expected_call_args_list From 91cca4ae496e77af44393a188d3f92cfca95229a Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 12 Jan 2023 21:06:21 +0100 Subject: [PATCH 101/134] [PR #5810/b9ac2dcd backport][stable-6] opkg: extend docu about compatibilty with OpenWrt vs. Yocto based Linux distribitions (#5825) opkg: extend docu about compatibilty with OpenWrt vs. Yocto based Linux distribitions (#5810) * opkg: extend documentation: opkg also works on Yocto ... based linux distributions Signed-off-by: Joerg Hofrichter * opkg: extend documentation: PACKAGE=VERSION only works on Yocto ... based linux distributions Signed-off-by: Joerg Hofrichter Signed-off-by: Joerg Hofrichter (cherry picked from commit b9ac2dcda5fe44b8c6c10b2649a9d682a053c069) Co-authored-by: joergho <48011876+joergho@users.noreply.github.com> --- plugins/modules/opkg.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/plugins/modules/opkg.py b/plugins/modules/opkg.py index d736c1f3ff..73c2597de2 100644 --- a/plugins/modules/opkg.py +++ b/plugins/modules/opkg.py @@ -15,16 +15,17 @@ DOCUMENTATION = ''' --- module: opkg author: "Patrick Pelletier (@skinp)" -short_description: Package manager for OpenWrt +short_description: Package manager for OpenWrt and Openembedded/Yocto based Linux distributions description: - - Manages OpenWrt packages + - Manages ipk packages for OpenWrt and Openembedded/Yocto based Linux distributions options: name: description: - Name of package(s) to install/remove. - C(NAME=VERSION) syntax is also supported to install a package - in a certain version. See the examples. This is supported since - community.general 6.2.0. + in a certain version. See the examples. This only works on Yocto based + Linux distributions (opkg>=0.3.2) and not for OpenWrt. This is + supported since community.general 6.2.0. aliases: [pkg] required: true type: list @@ -67,7 +68,7 @@ EXAMPLES = ''' name: foo state: present -- name: Install foo in version 1.2 +- name: Install foo in version 1.2 (opkg>=0.3.2 on Yocto based Linux distributions) community.general.opkg: name: foo=1.2 state: present From 559c914e36b0918ceb98cdd1c8893c9ee9c1234d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 12 Jan 2023 21:56:18 +0100 Subject: [PATCH 102/134] [PR #5706/58eb4957 backport][stable-6] Fixes #5691. Support gitlab forking_access_level, builds_access_level and container_registry_access_level fields (#5828) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #5691. Support gitlab forking_access_level, builds_access_level and container_registry_access_level fields (#5706) * Fixes #5691. Support gitlab forking_access_level, builds_access_level and container_registry_access_level fields * Add changelog fragment * Fix revision issues (cherry picked from commit 58eb49579762f78d04c5c15c9089c62670f7078d) Co-authored-by: Juan Antonio ValiΓ±o GarcΓ­a --- ...06-add-builds-forks-container-registry.yml | 2 ++ plugins/modules/gitlab_project.py | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 changelogs/fragments/5706-add-builds-forks-container-registry.yml diff --git a/changelogs/fragments/5706-add-builds-forks-container-registry.yml b/changelogs/fragments/5706-add-builds-forks-container-registry.yml new file mode 100644 index 0000000000..5635241b64 --- /dev/null +++ b/changelogs/fragments/5706-add-builds-forks-container-registry.yml @@ -0,0 +1,2 @@ +minor_changes: + - gitlab_project - add ``builds_access_level``, ``container_registry_access_level`` and ``forking_access_level`` options (https://github.com/ansible-collections/community.general/pull/5706). diff --git a/plugins/modules/gitlab_project.py b/plugins/modules/gitlab_project.py index ca1f8a6c64..1ab8ae220c 100644 --- a/plugins/modules/gitlab_project.py +++ b/plugins/modules/gitlab_project.py @@ -172,6 +172,30 @@ options: - This option is only used on creation, not for updates. This is also only used if I(initialize_with_readme=true). type: str version_added: "4.2.0" + builds_access_level: + description: + - C(private) means that repository CI/CD is allowed only to project members. + - C(disabled) means that repository CI/CD is disabled. + - C(enabled) means that repository CI/CD is enabled. + type: str + choices: ["private", "disabled", "enabled"] + version_added: "6.2.0" + forking_access_level: + description: + - C(private) means that repository forks is allowed only to project members. + - C(disabled) means that repository forks are disabled. + - C(enabled) means that repository forks are enabled. + type: str + choices: ["private", "disabled", "enabled"] + version_added: "6.2.0" + container_registry_access_level: + description: + - C(private) means that container registry is allowed only to project members. + - C(disabled) means that container registry is disabled. + - C(enabled) means that container registry is enabled. + type: str + choices: ["private", "disabled", "enabled"] + version_added: "6.2.0" ''' EXAMPLES = r''' @@ -287,6 +311,9 @@ class GitLabProject(object): 'squash_option': options['squash_option'], 'ci_config_path': options['ci_config_path'], 'shared_runners_enabled': options['shared_runners_enabled'], + 'builds_access_level': options['builds_access_level'], + 'forking_access_level': options['forking_access_level'], + 'container_registry_access_level': options['container_registry_access_level'], } # Because we have already call userExists in main() if self.project_object is None: @@ -417,6 +444,9 @@ def main(): ci_config_path=dict(type='str'), shared_runners_enabled=dict(type='bool'), avatar_path=dict(type='path'), + builds_access_level=dict(type='str', choices=['private', 'disabled', 'enabled']), + forking_access_level=dict(type='str', choices=['private', 'disabled', 'enabled']), + container_registry_access_level=dict(type='str', choices=['private', 'disabled', 'enabled']), )) module = AnsibleModule( @@ -464,6 +494,9 @@ def main(): shared_runners_enabled = module.params['shared_runners_enabled'] avatar_path = module.params['avatar_path'] default_branch = module.params['default_branch'] + builds_access_level = module.params['builds_access_level'] + forking_access_level = module.params['forking_access_level'] + container_registry_access_level = module.params['container_registry_access_level'] if default_branch and not initialize_with_readme: module.fail_json(msg="Param default_branch need param initialize_with_readme set to true") @@ -533,6 +566,9 @@ def main(): "ci_config_path": ci_config_path, "shared_runners_enabled": shared_runners_enabled, "avatar_path": avatar_path, + "builds_access_level": builds_access_level, + "forking_access_level": forking_access_level, + "container_registry_access_level": container_registry_access_level, }): module.exit_json(changed=True, msg="Successfully created or updated the project %s" % project_name, project=gitlab_project.project_object._attrs) From 1da5f7dc546b214c704c8bef225f1aba55b740d7 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 12 Jan 2023 21:56:31 +0100 Subject: [PATCH 103/134] [PR #5766/317f79ff backport][stable-6] multiple scaleway modules: fixed markups in doc (#5827) multiple scaleway modules: fixed markups in doc (#5766) * multiple scaleway modules: fixed markups in doc * Update plugins/modules/scaleway_ip.py Co-authored-by: Felix Fontein * Update plugins/modules/scaleway_volume.py Co-authored-by: Felix Fontein * Update plugins/modules/scaleway_private_network.py Co-authored-by: Felix Fontein * Update plugins/modules/scaleway_security_group.py Co-authored-by: Felix Fontein * Update plugins/modules/scaleway_security_group_rule.py Co-authored-by: Felix Fontein * Update plugins/modules/scaleway_sshkey.py Co-authored-by: Felix Fontein * further docs adjustments Co-authored-by: Felix Fontein (cherry picked from commit 317f79ff1f4a590d73455054c3235cdef684b4f8) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../scaleway_compute_private_network.py | 2 +- plugins/modules/scaleway_database_backup.py | 12 ++++----- plugins/modules/scaleway_image_info.py | 2 +- plugins/modules/scaleway_ip.py | 4 +-- plugins/modules/scaleway_lb.py | 14 +++++----- plugins/modules/scaleway_organization_info.py | 4 +-- plugins/modules/scaleway_private_network.py | 5 ++-- plugins/modules/scaleway_security_group.py | 7 +++-- .../modules/scaleway_security_group_rule.py | 19 +++++++------ plugins/modules/scaleway_sshkey.py | 9 +++---- plugins/modules/scaleway_user_data.py | 10 +++---- plugins/modules/scaleway_volume.py | 27 +++++++++---------- 12 files changed, 55 insertions(+), 60 deletions(-) diff --git a/plugins/modules/scaleway_compute_private_network.py b/plugins/modules/scaleway_compute_private_network.py index f85b2f2444..201ec257f7 100644 --- a/plugins/modules/scaleway_compute_private_network.py +++ b/plugins/modules/scaleway_compute_private_network.py @@ -92,7 +92,7 @@ EXAMPLES = ''' RETURN = ''' scaleway_compute_private_network: description: Information on the VPC. - returned: success when C(state=present) + returned: success when I(state=present) type: dict sample: { diff --git a/plugins/modules/scaleway_database_backup.py b/plugins/modules/scaleway_database_backup.py index f91ce143a0..9daa7921c0 100644 --- a/plugins/modules/scaleway_database_backup.py +++ b/plugins/modules/scaleway_database_backup.py @@ -19,7 +19,7 @@ short_description: Scaleway database backups management module version_added: 1.2.0 author: Guillaume Rodriguez (@guillaume_ro_fr) description: - - This module manages database backups on Scaleway account U(https://developer.scaleway.com). + - "This module manages database backups on Scaleway account U(https://developer.scaleway.com)." extends_documentation_fragment: - community.general.scaleway options: @@ -58,7 +58,7 @@ options: description: - Name used to identify the database backup. - Required for C(present) state. - - Ignored when C(state=absent), C(state=exported) or C(state=restored). + - Ignored when I(state=absent), I(state=exported) or I(state=restored). type: str required: false @@ -66,7 +66,7 @@ options: description: - Name used to identify the database. - Required for C(present) and C(restored) states. - - Ignored when C(state=absent) or C(state=exported). + - Ignored when I(state=absent) or I(state=exported). type: str required: false @@ -74,14 +74,14 @@ options: description: - UUID of the instance associated to the database backup. - Required for C(present) and C(restored) states. - - Ignored when C(state=absent) or C(state=exported). + - Ignored when I(state=absent) or I(state=exported). type: str required: false expires_at: description: - Expiration datetime of the database backup (ISO 8601 format). - - Ignored when C(state=absent), C(state=exported) or C(state=restored). + - Ignored when I(state=absent), I(state=exported) or I(state=restored). type: str required: false @@ -139,7 +139,7 @@ EXAMPLES = ''' RETURN = ''' metadata: description: Backup metadata. - returned: when C(state=present), C(state=exported) or C(state=restored) + returned: when I(state=present), I(state=exported) or I(state=restored) type: dict sample: { "metadata": { diff --git a/plugins/modules/scaleway_image_info.py b/plugins/modules/scaleway_image_info.py index 56ca689c38..bdae185148 100644 --- a/plugins/modules/scaleway_image_info.py +++ b/plugins/modules/scaleway_image_info.py @@ -26,7 +26,7 @@ options: region: type: str description: - - Scaleway compute zone + - Scaleway compute zone. required: true choices: - ams1 diff --git a/plugins/modules/scaleway_ip.py b/plugins/modules/scaleway_ip.py index eccd64e47b..a49e9c9f31 100644 --- a/plugins/modules/scaleway_ip.py +++ b/plugins/modules/scaleway_ip.py @@ -88,8 +88,8 @@ EXAMPLES = ''' RETURN = ''' data: - description: This is only present when C(state=present) - returned: when C(state=present) + description: This is only present when I(state=present). + returned: when I(state=present) type: dict sample: { "ips": [ diff --git a/plugins/modules/scaleway_lb.py b/plugins/modules/scaleway_lb.py index 124cba5945..578f4ae894 100644 --- a/plugins/modules/scaleway_lb.py +++ b/plugins/modules/scaleway_lb.py @@ -29,19 +29,19 @@ options: name: type: str description: - - Name of the load-balancer + - Name of the load-balancer. required: true description: type: str description: - - Description of the load-balancer + - Description of the load-balancer. required: true organization_id: type: str description: - - Organization identifier + - Organization identifier. required: true state: @@ -56,7 +56,7 @@ options: region: type: str description: - - Scaleway zone + - Scaleway zone. required: true choices: - nl-ams @@ -68,7 +68,7 @@ options: elements: str default: [] description: - - List of tags to apply to the load-balancer + - List of tags to apply to the load-balancer. wait: description: @@ -79,14 +79,14 @@ options: wait_timeout: type: int description: - - Time to wait for the load-balancer to reach the expected state + - Time to wait for the load-balancer to reach the expected state. required: false default: 300 wait_sleep_time: type: int description: - - Time to wait before every attempt to check the state of the load-balancer + - Time to wait before every attempt to check the state of the load-balancer. required: false default: 3 ''' diff --git a/plugins/modules/scaleway_organization_info.py b/plugins/modules/scaleway_organization_info.py index 717c47db19..e9e272c988 100644 --- a/plugins/modules/scaleway_organization_info.py +++ b/plugins/modules/scaleway_organization_info.py @@ -20,7 +20,7 @@ author: options: api_url: description: - - Scaleway API URL + - Scaleway API URL. default: 'https://account.scaleway.com' aliases: ['base_url'] extends_documentation_fragment: @@ -42,7 +42,7 @@ EXAMPLES = r''' RETURN = r''' --- scaleway_organization_info: - description: Response from Scaleway API + description: Response from Scaleway API. returned: success type: list elements: dict diff --git a/plugins/modules/scaleway_private_network.py b/plugins/modules/scaleway_private_network.py index 6a611fa32b..57cf67ec1f 100644 --- a/plugins/modules/scaleway_private_network.py +++ b/plugins/modules/scaleway_private_network.py @@ -18,8 +18,7 @@ short_description: Scaleway private network management version_added: 4.5.0 author: Pascal MANGIN (@pastral) description: - - This module manages private network on Scaleway account - (U(https://developer.scaleway.com)). + - "This module manages private network on Scaleway account (U(https://developer.scaleway.com))." extends_documentation_fragment: - community.general.scaleway @@ -88,7 +87,7 @@ EXAMPLES = ''' RETURN = ''' scaleway_private_network: description: Information on the VPC. - returned: success when C(state=present) + returned: success when I(state=present) type: dict sample: { diff --git a/plugins/modules/scaleway_security_group.py b/plugins/modules/scaleway_security_group.py index 635309947a..d863156fa3 100644 --- a/plugins/modules/scaleway_security_group.py +++ b/plugins/modules/scaleway_security_group.py @@ -18,8 +18,7 @@ module: scaleway_security_group short_description: Scaleway Security Group management module author: Antoine Barbare (@abarbare) description: - - This module manages Security Group on Scaleway account - U(https://developer.scaleway.com). + - "This module manages Security Group on Scaleway account U(https://developer.scaleway.com)." extends_documentation_fragment: - community.general.scaleway @@ -105,8 +104,8 @@ EXAMPLES = ''' RETURN = ''' data: - description: This is only present when C(state=present) - returned: when C(state=present) + description: This is only present when I(state=present). + returned: when I(state=present) type: dict sample: { "scaleway_security_group": { diff --git a/plugins/modules/scaleway_security_group_rule.py b/plugins/modules/scaleway_security_group_rule.py index d0b16aeb50..cd27543a7b 100644 --- a/plugins/modules/scaleway_security_group_rule.py +++ b/plugins/modules/scaleway_security_group_rule.py @@ -18,8 +18,7 @@ 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: @@ -53,7 +52,7 @@ options: protocol: type: str description: - - Network protocol to use + - Network protocol to use. choices: - TCP - UDP @@ -62,20 +61,20 @@ options: port: description: - - Port related to the rule, null value for all the ports + - Port related to the rule, null value for all the ports. required: true type: int ip_range: type: str description: - - IPV4 CIDR notation to apply to the rule + - IPV4 CIDR notation to apply to the rule. default: 0.0.0.0/0 direction: type: str description: - - Rule direction + - Rule direction. choices: - inbound - outbound @@ -84,7 +83,7 @@ options: action: type: str description: - - Rule action + - Rule action. choices: - accept - drop @@ -93,7 +92,7 @@ options: security_group: type: str description: - - Security Group unique identifier + - Security Group unique identifier. required: true ''' @@ -113,8 +112,8 @@ EXAMPLES = ''' RETURN = ''' data: - description: This is only present when C(state=present) - returned: when C(state=present) + description: This is only present when I(state=present). + returned: when I(state=present) type: dict sample: { "scaleway_security_group_rule": { diff --git a/plugins/modules/scaleway_sshkey.py b/plugins/modules/scaleway_sshkey.py index 13dc211d36..8bb804165a 100644 --- a/plugins/modules/scaleway_sshkey.py +++ b/plugins/modules/scaleway_sshkey.py @@ -19,8 +19,7 @@ module: scaleway_sshkey short_description: Scaleway SSH keys management module author: Remy Leone (@remyleone) description: - - This module manages SSH keys on Scaleway account - U(https://developer.scaleway.com) + - "This module manages SSH keys on Scaleway account U(https://developer.scaleway.com)." extends_documentation_fragment: - community.general.scaleway @@ -42,7 +41,7 @@ options: api_url: type: str description: - - Scaleway API URL + - Scaleway API URL. default: 'https://account.scaleway.com' aliases: ['base_url'] ''' @@ -67,8 +66,8 @@ EXAMPLES = ''' RETURN = ''' data: - description: This is only present when C(state=present) - returned: when C(state=present) + description: This is only present when I(state=present). + returned: when I(state=present) type: dict sample: { "ssh_public_keys": [ diff --git a/plugins/modules/scaleway_user_data.py b/plugins/modules/scaleway_user_data.py index 37d9e94142..509ae44cc0 100644 --- a/plugins/modules/scaleway_user_data.py +++ b/plugins/modules/scaleway_user_data.py @@ -19,8 +19,8 @@ module: scaleway_user_data short_description: Scaleway user_data management module author: Remy Leone (@remyleone) description: - - "This module manages user_data on compute instances on Scaleway." - - "It can be used to configure cloud-init for instance" + - This module manages user_data on compute instances on Scaleway. + - It can be used to configure cloud-init for instance. extends_documentation_fragment: - community.general.scaleway @@ -30,20 +30,20 @@ options: server_id: type: str description: - - Scaleway Compute instance ID of the server + - Scaleway Compute instance ID of the server. required: true user_data: type: dict description: - User defined data. Typically used with C(cloud-init). - - Pass your cloud-init script here as a string + - Pass your C(cloud-init) script here as a string. required: false region: type: str description: - - Scaleway compute zone + - Scaleway compute zone. required: true choices: - ams1 diff --git a/plugins/modules/scaleway_volume.py b/plugins/modules/scaleway_volume.py index 315b5e7334..e633b4a1a7 100644 --- a/plugins/modules/scaleway_volume.py +++ b/plugins/modules/scaleway_volume.py @@ -18,8 +18,7 @@ module: scaleway_volume short_description: Scaleway volumes management module author: Henryk Konsek (@hekonsek) description: - - This module manages volumes on Scaleway account - U(https://developer.scaleway.com) + - "This module manages volumes on Scaleway account U(https://developer.scaleway.com)." extends_documentation_fragment: - community.general.scaleway @@ -28,7 +27,7 @@ options: state: type: str description: - - Indicate desired state of the volume. + - Indicate desired state of the volume. default: present choices: - present @@ -36,7 +35,7 @@ options: region: type: str description: - - Scaleway region to use (for example par1). + - Scaleway region to use (for example par1). required: true choices: - ams1 @@ -50,25 +49,25 @@ options: name: type: str description: - - Name used to identify the volume. + - Name used to identify the volume. required: true project: type: str description: - - Scaleway project ID to which volume belongs. + - Scaleway project ID to which volume belongs. version_added: 4.3.0 organization: type: str description: - - ScaleWay organization ID to which volume belongs. + - ScaleWay organization ID to which volume belongs. size: type: int description: - - Size of the volume in bytes. + - Size of the volume in bytes. volume_type: type: str description: - - Type of the volume (for example 'l_ssd'). + - Type of the volume (for example 'l_ssd'). ''' EXAMPLES = ''' @@ -91,8 +90,8 @@ EXAMPLES = ''' RETURN = ''' data: - description: This is only present when C(state=present) - returned: when C(state=present) + description: This is only present when I(state=present). + returned: when I(state=present) type: dict sample: { "volume": { @@ -100,9 +99,9 @@ data: "id": "c675f420-cfeb-48ff-ba2a-9d2a4dbe3fcd", "name": "volume-0-3", "project": "000a115d-2852-4b0a-9ce8-47f1134ba95a", - "server": null, - "size": 10000000000, - "volume_type": "l_ssd" + "server": null, + "size": 10000000000, + "volume_type": "l_ssd" } } ''' From 474364c862d23bdf8b23c18d613181391c914f79 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 13 Jan 2023 21:23:08 +0100 Subject: [PATCH 104/134] [PR #5772/cc79c24c backport][stable-6] consul: deprecate params incompatible with state=absent (#5831) consul: deprecate params incompatible with state=absent (#5772) * consul: deprecate params incompatible with state=absent * Refrain from handling SystemExit exception * preposition * add changelog fragment * Update plugins/modules/consul.py * Update changelogs/fragments/5772-consul-deprecate-params-when-absent.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit cc79c24c01010ed75b2dee116ddf36276ffd2763) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- ...72-consul-deprecate-params-when-absent.yml | 2 ++ plugins/modules/consul.py | 26 ++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/5772-consul-deprecate-params-when-absent.yml diff --git a/changelogs/fragments/5772-consul-deprecate-params-when-absent.yml b/changelogs/fragments/5772-consul-deprecate-params-when-absent.yml new file mode 100644 index 0000000000..44d681765f --- /dev/null +++ b/changelogs/fragments/5772-consul-deprecate-params-when-absent.yml @@ -0,0 +1,2 @@ +deprecated_features: + - consul - deprecate using parameters unused for ``state=absent`` (https://github.com/ansible-collections/community.general/pull/5772). diff --git a/plugins/modules/consul.py b/plugins/modules/consul.py index ea329254a1..dea853b98e 100644 --- a/plugins/modules/consul.py +++ b/plugins/modules/consul.py @@ -149,6 +149,10 @@ options: type: str description: - The token key identifying an ACL rule set. May be required to register services. + ack_params_state_absent: + type: bool + description: + - Disable deprecation warning when using parameters incompatible with I(state=absent). ''' EXAMPLES = ''' @@ -584,7 +588,8 @@ def main(): http=dict(type='str'), timeout=dict(type='str'), tags=dict(type='list', elements='str'), - token=dict(no_log=True) + token=dict(no_log=True), + ack_params_state_absent=dict(type='bool'), ), required_if=[ ('state', 'present', ['service_name']), @@ -592,14 +597,29 @@ def main(): ], supports_check_mode=False, ) + p = module.params test_dependencies(module) + if p['state'] == 'absent' and any(p[x] for x in ['script', 'ttl', 'tcp', 'http', 'interval']) and not p['ack_params_state_absent']: + module.deprecate( + "The use of parameters 'script', 'ttl', 'tcp', 'http', 'interval' along with 'state=absent' is deprecated. " + "In community.general 8.0.0 their use will become an error. " + "To suppress this deprecation notice, set parameter ack_params_state_absent=true.", + version="8.0.0", + collection_name="community.general", + ) + # When reaching c.g 8.0.0: + # - Replace the deprecation with a fail_json(), remove the "ack_params_state_absent" condition from the "if" + # - Add mutually_exclusive for ('script', 'ttl', 'tcp', 'http'), then remove that validation from parse_check() + # - Add required_by {'script': 'interval', 'http': 'interval', 'tcp': 'interval'}, then remove checks for 'interval' in ConsulCheck.__init__() + # - Deprecate the parameter ack_params_state_absent try: register_with_consul(module) + except SystemExit: + raise except ConnectionError as e: - module.fail_json(msg='Could not connect to consul agent at %s:%s, error was %s' % ( - module.params['host'], module.params['port'], str(e))) + module.fail_json(msg='Could not connect to consul agent at %s:%s, error was %s' % (p['host'], p['port'], str(e))) except Exception as e: module.fail_json(msg=str(e)) From 16c7615b825c42db0b1f2f0d37e7a77de2215c81 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 14 Jan 2023 18:30:18 +0100 Subject: [PATCH 105/134] [PR #5833/08b0ea70 backport][stable-6] ldap.py: capitalize one letter (#5836) ldap.py: capitalize one letter (#5833) (cherry picked from commit 08b0ea700d98d6d05724a435aa73c90ff841f4d5) Co-authored-by: bluikko <14869000+bluikko@users.noreply.github.com> --- plugins/doc_fragments/ldap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/doc_fragments/ldap.py b/plugins/doc_fragments/ldap.py index c73e5080be..1f04c0f600 100644 --- a/plugins/doc_fragments/ldap.py +++ b/plugins/doc_fragments/ldap.py @@ -60,7 +60,7 @@ options: sasl_class: description: - The class to use for SASL authentication. - - possible choices are C(external), C(gssapi). + - Possible choices are C(external), C(gssapi). type: str choices: ['external', 'gssapi'] default: external From c0fde76b79261e0cc76bed96ec8764ebf0bd3d07 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 14 Jan 2023 18:40:20 +0100 Subject: [PATCH 106/134] [PR #5808/6ec04973 backport][stable-6] xml children module parameter does not exist (#5839) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xml children module parameter does not exist (#5808) * Add changelog * Add integration tests * Rename children to set_children * Add PR information * Update changelogs/fragments/5808-xml-children-parameter-does-not-exist.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 6ec049734e4b54edcf8dffbad64bf777fc9701e6) Co-authored-by: CΓ©dric Servais --- ...-xml-children-parameter-does-not-exist.yml | 2 ++ plugins/modules/xml.py | 4 +-- .../test-set-children-elements-empty-list.xml | 11 ++++++++ ...t-children-elements-empty-list.xml.license | 3 +++ .../xml/tasks/test-set-children-elements.yml | 26 +++++++++++++++++++ 5 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/5808-xml-children-parameter-does-not-exist.yml create mode 100644 tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml create mode 100644 tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml.license diff --git a/changelogs/fragments/5808-xml-children-parameter-does-not-exist.yml b/changelogs/fragments/5808-xml-children-parameter-does-not-exist.yml new file mode 100644 index 0000000000..2bad2c9886 --- /dev/null +++ b/changelogs/fragments/5808-xml-children-parameter-does-not-exist.yml @@ -0,0 +1,2 @@ +bugfixes: +- xml - fixed a bug where empty ``children`` list would not be set (https://github.com/ansible-collections/community.general/pull/5808). \ No newline at end of file diff --git a/plugins/modules/xml.py b/plugins/modules/xml.py index a35cc31ef0..9f16ee1344 100644 --- a/plugins/modules/xml.py +++ b/plugins/modules/xml.py @@ -266,7 +266,7 @@ EXAMPLES = r''' community.general.xml: path: /foo/bar.xml xpath: /business/website - children: [] + set_children: [] # In case of namespaces, like in below XML, they have to be explicitly stated. # @@ -961,7 +961,7 @@ def main(): # add_children && set_children both set?: should have already aborted by now # set_children set? - if set_children: + if set_children is not None: set_target_children(module, doc, xpath, namespaces, set_children, input_type) # add_children set? diff --git a/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml b/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml new file mode 100644 index 0000000000..51eb98f16b --- /dev/null +++ b/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml @@ -0,0 +1,11 @@ + + + Tasty Beverage Co. + + + 10 + + +
http://tastybeverageco.com
+
+
\ No newline at end of file diff --git a/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml.license b/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml.license new file mode 100644 index 0000000000..edff8c7685 --- /dev/null +++ b/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml.license @@ -0,0 +1,3 @@ +GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +SPDX-License-Identifier: GPL-3.0-or-later +SPDX-FileCopyrightText: Ansible Project diff --git a/tests/integration/targets/xml/tasks/test-set-children-elements.yml b/tests/integration/targets/xml/tasks/test-set-children-elements.yml index 8ab14d5080..147f493c97 100644 --- a/tests/integration/targets/xml/tasks/test-set-children-elements.yml +++ b/tests/integration/targets/xml/tasks/test-set-children-elements.yml @@ -8,6 +8,32 @@ src: fixtures/ansible-xml-beers.xml dest: /tmp/ansible-xml-beers.xml + - name: Set child elements - empty list + xml: + path: /tmp/ansible-xml-beers.xml + xpath: /business/beers + set_children: [] + register: set_children_elements + + - name: Compare to expected result + copy: + src: results/test-set-children-elements-empty-list.xml + dest: /tmp/ansible-xml-beers.xml + check_mode: yes + diff: yes + register: comparison + + - name: Test expected result + assert: + that: + - set_children_elements is changed + - comparison is not changed # identical + #command: diff -u {{ role_path }}/results/test-set-children-elements.xml /tmp/ansible-xml-beers.xml + + - name: Setup test fixture + copy: + src: fixtures/ansible-xml-beers.xml + dest: /tmp/ansible-xml-beers.xml - name: Set child elements xml: From 811c4a304ab3bdfb40825aac4ad029a6c5bc5739 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 14 Jan 2023 19:04:17 +0100 Subject: [PATCH 107/134] [PR #5793/756c0776 backport][stable-6] apache2_module generates false/misleading warning (#5841) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit apache2_module generates false/misleading warning (#5793) * Add parameter warn_mpm_module to control when warning are raised * Remoe whitespace * Add changelog fragment * Add missing license * Update changelogs/fragments/5793-apache2-module-npm-warnings.yml Co-authored-by: Felix Fontein * Update plugins/modules/apache2_module.py Co-authored-by: Felix Fontein * Update plugins/modules/apache2_module.py Co-authored-by: Felix Fontein * Update tests/integration/targets/apache2_module/tasks/635-apache2-misleading-warning.yml Co-authored-by: Felix Fontein * Refining integration test - previous was invalid * False to false * refactor assertion for suse * Revert "refactor assertion for suse" This reverts commit 61b86e7493c15a88160d0c0b955f2b08fa538a40. * Excluding test on Suse Co-authored-by: Felix Fontein (cherry picked from commit 756c0776d623ce928149db2d664451e549273ad8) Co-authored-by: CΓ©dric Servais --- .../5793-apache2-module-npm-warnings.yml | 2 + plugins/modules/apache2_module.py | 28 +++++++++-- .../tasks/635-apache2-misleading-warning.yml | 47 +++++++++++++++++++ .../apache2_module/tasks/actualtest.yml | 2 +- .../targets/apache2_module/tasks/main.yml | 5 ++ 5 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/5793-apache2-module-npm-warnings.yml create mode 100644 tests/integration/targets/apache2_module/tasks/635-apache2-misleading-warning.yml diff --git a/changelogs/fragments/5793-apache2-module-npm-warnings.yml b/changelogs/fragments/5793-apache2-module-npm-warnings.yml new file mode 100644 index 0000000000..a4750790a4 --- /dev/null +++ b/changelogs/fragments/5793-apache2-module-npm-warnings.yml @@ -0,0 +1,2 @@ +minor_changes: + - apache2_module - add module argument ``warn_mpm_absent`` to control whether warning are raised in some edge cases (https://github.com/ansible-collections/community.general/pull/5793). \ No newline at end of file diff --git a/plugins/modules/apache2_module.py b/plugins/modules/apache2_module.py index a58c0f0c54..e6998ad3f5 100644 --- a/plugins/modules/apache2_module.py +++ b/plugins/modules/apache2_module.py @@ -49,6 +49,12 @@ options: - Ignore configuration checks about inconsistent module configuration. Especially for mpm_* modules. type: bool default: false + warn_mpm_absent: + description: + - Control the behavior of the warning process for MPM modules. + type: bool + default: true + version_added: 6.3.0 requirements: ["a2enmod","a2dismod"] notes: - This does not work on RedHat-based distributions. It does work on Debian- and SuSE-based distributions. @@ -78,6 +84,18 @@ EXAMPLES = ''' name: mpm_worker ignore_configcheck: true +- name: Disable mpm_event, enable mpm_prefork and ignore warnings about missing mpm module + community.general.apache2_module: + name: "{{ item.module }}" + state: "{{ item.state }}" + warn_mpm_absent: false + ignore_configcheck: true + loop: + - module: mpm_event + state: absent + - module: mpm_prefork + state: present + - name: Enable dump_io module, which is identified as dumpio_module inside apache2 community.general.apache2_module: state: present @@ -140,10 +158,11 @@ def _module_is_enabled(module): error_msg = "Error executing %s: %s" % (control_binary, stderr) if module.params['ignore_configcheck']: if 'AH00534' in stderr and 'mpm_' in module.params['name']: - module.warnings.append( - "No MPM module loaded! apache2 reload AND other module actions" - " will fail if no MPM module is loaded immediately." - ) + if module.params['warn_mpm_absent']: + module.warnings.append( + "No MPM module loaded! apache2 reload AND other module actions" + " will fail if no MPM module is loaded immediately." + ) else: module.warnings.append(error_msg) return False @@ -249,6 +268,7 @@ def main(): force=dict(type='bool', default=False), state=dict(default='present', choices=['absent', 'present']), ignore_configcheck=dict(type='bool', default=False), + warn_mpm_absent=dict(type='bool', default=True), ), supports_check_mode=True, ) diff --git a/tests/integration/targets/apache2_module/tasks/635-apache2-misleading-warning.yml b/tests/integration/targets/apache2_module/tasks/635-apache2-misleading-warning.yml new file mode 100644 index 0000000000..5d93a9d300 --- /dev/null +++ b/tests/integration/targets/apache2_module/tasks/635-apache2-misleading-warning.yml @@ -0,0 +1,47 @@ +--- +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later +# This test represent the misleading behavior of the following issue: https://github.com/ansible-collections/community.general/issues/635 +- name: Disable MPM event module + apache2_module: + name: "{{ item.module}}" + state: "{{ item.state}}" + ignore_configcheck: true + register: disable_mpm_modules + with_items: + - { module: mpm_event, state: absent } + - { module: mpm_prefork, state: present } + +- assert: + that: + - "'warnings' in disable_mpm_modules" + - disable_mpm_modules["warnings"] == [ + "No MPM module loaded! apache2 reload AND other module actions will fail if no MPM module is loaded immediately.", + "No MPM module loaded! apache2 reload AND other module actions will fail if no MPM module is loaded immediately." + ] + +- name: Enable MPM event module - Revert previous change + apache2_module: + name: "{{ item.module}}" + state: "{{ item.state}}" + ignore_configcheck: true + register: disable_mpm_modules + with_items: + - { module: mpm_prefork, state: absent } + - { module: mpm_event, state: present } + +- name: Disable MPM event module + apache2_module: + name: "{{ item.module}}" + state: "{{ item.state}}" + ignore_configcheck: true + warn_mpm_absent: false + register: disable_mpm_modules + with_items: + - { module: mpm_event, state: absent } + - { module: mpm_prefork, state: present } + +- assert: + that: + - "'warnings' not in disable_mpm_modules" diff --git a/tests/integration/targets/apache2_module/tasks/actualtest.yml b/tests/integration/targets/apache2_module/tasks/actualtest.yml index 156b54047d..1902cac5ee 100644 --- a/tests/integration/targets/apache2_module/tasks/actualtest.yml +++ b/tests/integration/targets/apache2_module/tasks/actualtest.yml @@ -180,7 +180,7 @@ - mpm_worker - mpm_event - mpm_prefork - ignore_errors: yes + ignore_errors: true register: remove_with_configcheck - name: ensure configcheck fails task with when run without mpm modules diff --git a/tests/integration/targets/apache2_module/tasks/main.yml b/tests/integration/targets/apache2_module/tasks/main.yml index 650e36474c..70ba14ea24 100644 --- a/tests/integration/targets/apache2_module/tasks/main.yml +++ b/tests/integration/targets/apache2_module/tasks/main.yml @@ -45,3 +45,8 @@ that: modules_before.stdout == modules_after.stdout when: ansible_os_family in ['Debian', 'Suse'] # centos/RHEL does not have a2enmod/a2dismod + +- name: include misleading warning test + include: 635-apache2-misleading-warning.yml + when: ansible_os_family in ['Debian'] + # Suse has mpm_event module compiled within the base apache2 \ No newline at end of file From 490baed566491cc90763e3ea4c7c6f42d59611fa Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 14 Jan 2023 19:04:28 +0100 Subject: [PATCH 108/134] [PR #5837/3985ade3 backport][stable-6] Add PLATFORM docs fragment (#5840) Add PLATFORM docs fragment (#5837) Add PLATFORM docs fragment. (cherry picked from commit 3985ade3fc7e97595bb3b17a15720681a16d9a5e) Co-authored-by: Felix Fontein --- plugins/doc_fragments/attributes.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/doc_fragments/attributes.py b/plugins/doc_fragments/attributes.py index da089dff21..e7ab495916 100644 --- a/plugins/doc_fragments/attributes.py +++ b/plugins/doc_fragments/attributes.py @@ -20,9 +20,11 @@ attributes: description: Will return details on what has changed (or possibly needs changing in C(check_mode)), when in diff mode. ''' -# platform: -# description: Target OS/families that can be operated against. -# support: N/A + PLATFORM = r''' + platform: + description: Target OS/families that can be operated against. + support: N/A +''' # Should be used together with the standard fragment INFO_MODULE = r''' From b400491ef3cdc644fd24c62388d35095e6b69ea3 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 16 Jan 2023 23:11:08 +0100 Subject: [PATCH 109/134] [PR #5843/44172dda backport][stable-6] Add -no-color argument to terraform validation (#5847) Add -no-color argument to terraform validation (#5843) (cherry picked from commit 44172ddaa6130d2441954da54da0ea70caf41521) Co-authored-by: Kristian Heljas <11139388+kristianheljas@users.noreply.github.com> --- changelogs/fragments/5843-terraform-validate-no-color.yml | 2 ++ plugins/modules/terraform.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/5843-terraform-validate-no-color.yml diff --git a/changelogs/fragments/5843-terraform-validate-no-color.yml b/changelogs/fragments/5843-terraform-validate-no-color.yml new file mode 100644 index 0000000000..25cc6045ad --- /dev/null +++ b/changelogs/fragments/5843-terraform-validate-no-color.yml @@ -0,0 +1,2 @@ +bugfixes: +- terraform module - disable ANSI escape sequences during validation phase (https://github.com/ansible-collections/community.general/pull/5843). \ No newline at end of file diff --git a/plugins/modules/terraform.py b/plugins/modules/terraform.py index 2a018ea03c..b6b09b0eb2 100644 --- a/plugins/modules/terraform.py +++ b/plugins/modules/terraform.py @@ -299,9 +299,9 @@ def preflight_validation(bin_path, project_path, version, variables_args=None, p if not os.path.isdir(project_path): module.fail_json(msg="Path for Terraform project '{0}' doesn't exist on this host - check the path and try again please.".format(project_path)) if LooseVersion(version) < LooseVersion('0.15.0'): - rc, out, err = module.run_command([bin_path, 'validate'] + variables_args, check_rc=True, cwd=project_path) + module.run_command([bin_path, 'validate', '-no-color'] + variables_args, check_rc=True, cwd=project_path) else: - rc, out, err = module.run_command([bin_path, 'validate'], check_rc=True, cwd=project_path) + module.run_command([bin_path, 'validate', '-no-color'], check_rc=True, cwd=project_path) def _state_args(state_file): From 585dbc3171b82b8147413946b58cb206063a439c Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 17 Jan 2023 21:32:11 +0100 Subject: [PATCH 110/134] [PR #5818/5ad703ac backport][stable-6] nsupdate: fix zone lookup (#5853) nsupdate: fix zone lookup (#5818) The SOA record for an existing zone is returned as an answer RR and not as an authority RR. It can be returned as an authority RR for subdomains of a zone. $ dig -t SOA example.com ;; ANSWER SECTION: example.com. 3530 IN SOA ns.icann.org. noc.dns.icann.org. 2022091184 7200 3600 1209600 3600 $ dig -t SOA www.example.com ;; AUTHORITY SECTION: example.com. 3600 IN SOA ns.icann.org. noc.dns.icann.org. 2022091184 7200 3600 1209600 3600 (cherry picked from commit 5ad703ac64026f88a401880b52fb25dab49237bc) Co-authored-by: n0p90 <36303164+n0p90@users.noreply.github.com> --- .../fragments/5818-nsupdate-fix-zone-lookup.yml | 2 ++ plugins/modules/nsupdate.py | 16 ++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/5818-nsupdate-fix-zone-lookup.yml diff --git a/changelogs/fragments/5818-nsupdate-fix-zone-lookup.yml b/changelogs/fragments/5818-nsupdate-fix-zone-lookup.yml new file mode 100644 index 0000000000..4f6ed6a125 --- /dev/null +++ b/changelogs/fragments/5818-nsupdate-fix-zone-lookup.yml @@ -0,0 +1,2 @@ +bugfixes: + - nsupdate - fix zone lookup. The SOA record for an existing zone is returned as an answer RR and not as an authority RR (https://github.com/ansible-collections/community.general/issues/5817, https://github.com/ansible-collections/community.general/pull/5818). diff --git a/plugins/modules/nsupdate.py b/plugins/modules/nsupdate.py index 2be4863b68..bc31521cdb 100644 --- a/plugins/modules/nsupdate.py +++ b/plugins/modules/nsupdate.py @@ -269,12 +269,16 @@ class RecordManager(object): if lookup.rcode() in [dns.rcode.SERVFAIL, dns.rcode.REFUSED]: self.module.fail_json(msg='Zone lookup failure: \'%s\' will not respond to queries regarding \'%s\'.' % ( self.module.params['server'], self.module.params['record'])) - try: - zone = lookup.authority[0].name - if zone == name: - return zone.to_text() - except IndexError: - pass + # If the response contains an Answer SOA RR whose name matches the queried name, + # this is the name of the zone in which the record needs to be inserted. + for rr in lookup.answer: + if rr.rdtype == dns.rdatatype.SOA and rr.name == name: + return rr.name.to_text() + # If the response contains an Authority SOA RR whose name is a subdomain of the queried name, + # this SOA name is the zone in which the record needs to be inserted. + for rr in lookup.authority: + if rr.rdtype == dns.rdatatype.SOA and name.fullcompare(rr.name)[0] == dns.name.NAMERELN_SUBDOMAIN: + return rr.name.to_text() try: name = name.parent() except dns.name.NoParent: From c0e769e5f5ebdc9fe574a317196fdafe86a1023b Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 08:09:20 +0100 Subject: [PATCH 111/134] [PR #5804/b92542de backport][stable-6] Minor changes to HPE iLO collection (#5854) Minor changes to HPE iLO collection (#5804) * Minor changes to setting IPs of servers * Lint fix * Added change log * Update changelogs/fragments/5804-minor-changes-to-hpe-ilo-collection.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit b92542dea2bf542c95bc2f4b494276bda2a5d18f) Co-authored-by: Bhavya <44067558+Bhavya06@users.noreply.github.com> --- ...04-minor-changes-to-hpe-ilo-collection.yml | 2 ++ plugins/module_utils/ilo_redfish_utils.py | 35 +++++++++---------- plugins/modules/ilo_redfish_config.py | 2 +- 3 files changed, 19 insertions(+), 20 deletions(-) create mode 100644 changelogs/fragments/5804-minor-changes-to-hpe-ilo-collection.yml diff --git a/changelogs/fragments/5804-minor-changes-to-hpe-ilo-collection.yml b/changelogs/fragments/5804-minor-changes-to-hpe-ilo-collection.yml new file mode 100644 index 0000000000..b53bd9eecf --- /dev/null +++ b/changelogs/fragments/5804-minor-changes-to-hpe-ilo-collection.yml @@ -0,0 +1,2 @@ +minor_changes: + - ilo_redfish_utils module utils - change implementation of DNS Server IP and NTP Server IP update (https://github.com/ansible-collections/community.general/pull/5804). diff --git a/plugins/module_utils/ilo_redfish_utils.py b/plugins/module_utils/ilo_redfish_utils.py index 2d4d999cef..a6ab42dba6 100644 --- a/plugins/module_utils/ilo_redfish_utils.py +++ b/plugins/module_utils/ilo_redfish_utils.py @@ -85,17 +85,16 @@ class iLORedfishUtils(RedfishUtils): datetime_uri = self.manager_uri + "DateTime" - response = self.get_request(self.root_uri + datetime_uri) - if not response['ret']: - return response + listofips = mgr_attributes['mgr_attr_value'].split(" ") + if len(listofips) > 2: + return {'ret': False, 'changed': False, 'msg': "More than 2 NTP Servers mentioned"} - data = response['data'] + ntp_list = [] + for ips in listofips: + ntp_list.append(ips) - ntp_list = data[setkey] - if len(ntp_list) == 2: - ntp_list.pop(0) - - ntp_list.append(mgr_attributes['mgr_attr_value']) + while len(ntp_list) < 2: + ntp_list.append("0.0.0.0") payload = {setkey: ntp_list} @@ -137,18 +136,16 @@ class iLORedfishUtils(RedfishUtils): nic_info = self.get_manager_ethernet_uri() uri = nic_info["nic_addr"] - response = self.get_request(self.root_uri + uri) - if not response['ret']: - return response + listofips = attr['mgr_attr_value'].split(" ") + if len(listofips) > 3: + return {'ret': False, 'changed': False, 'msg': "More than 3 DNS Servers mentioned"} - data = response['data'] + dns_list = [] + for ips in listofips: + dns_list.append(ips) - dns_list = data["Oem"]["Hpe"]["IPv4"][key] - - if len(dns_list) == 3: - dns_list.pop(0) - - dns_list.append(attr['mgr_attr_value']) + while len(dns_list) < 3: + dns_list.append("0.0.0.0") payload = { "Oem": { diff --git a/plugins/modules/ilo_redfish_config.py b/plugins/modules/ilo_redfish_config.py index d13d10dfdc..1c68127fa4 100644 --- a/plugins/modules/ilo_redfish_config.py +++ b/plugins/modules/ilo_redfish_config.py @@ -125,7 +125,7 @@ def main(): password=dict(no_log=True), auth_token=dict(no_log=True), attribute_name=dict(required=True), - attribute_value=dict(), + attribute_value=dict(type='str'), timeout=dict(type='int', default=10) ), required_together=[ From ca177a0cebabc83e72314cef52d00a421147aa84 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 08:17:56 +0100 Subject: [PATCH 112/134] [PR #5844/a35b2eda backport][stable-6] iptables_state: minor pythonisms (#5855) iptables_state: minor pythonisms (#5844) * iptables_state: minor pythonisms * add changelog fragment * fix typo (cherry picked from commit a35b2eda4c7dec53677063cb183a89b1236af608) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../5844-iptables-state-refactor.yml | 2 ++ plugins/modules/iptables_state.py | 20 +++++-------------- 2 files changed, 7 insertions(+), 15 deletions(-) create mode 100644 changelogs/fragments/5844-iptables-state-refactor.yml diff --git a/changelogs/fragments/5844-iptables-state-refactor.yml b/changelogs/fragments/5844-iptables-state-refactor.yml new file mode 100644 index 0000000000..a69b88de24 --- /dev/null +++ b/changelogs/fragments/5844-iptables-state-refactor.yml @@ -0,0 +1,2 @@ +minor_changes: + - iptables_state - minor refactoring within the module (https://github.com/ansible-collections/community.general/pull/5844). diff --git a/plugins/modules/iptables_state.py b/plugins/modules/iptables_state.py index 1e94631c7f..17f8d9eb70 100644 --- a/plugins/modules/iptables_state.py +++ b/plugins/modules/iptables_state.py @@ -260,10 +260,7 @@ def read_state(b_path): ''' with open(b_path, 'r') as f: text = f.read() - lines = text.splitlines() - while '' in lines: - lines.remove('') - return lines + return [t for t in text.splitlines() if t != ''] def write_state(b_path, lines, changed): @@ -273,8 +270,7 @@ def write_state(b_path, lines, changed): # Populate a temporary file tmpfd, tmpfile = tempfile.mkstemp() with os.fdopen(tmpfd, 'w') as f: - for line in lines: - f.write('%s\n' % line) + f.write("{0}\n".format("\n".join(lines))) # Prepare to copy temporary file to the final destination if not os.path.exists(b_path): @@ -335,9 +331,7 @@ def filter_and_format_state(string): string = re.sub(r'((^|\n)# (Generated|Completed)[^\n]*) on [^\n]*', r'\1', string) if not module.params['counters']: string = re.sub(r'\[[0-9]+:[0-9]+\]', r'[0:0]', string) - lines = string.splitlines() - while '' in lines: - lines.remove('') + lines = [line for line in string.splitlines() if line != ''] return lines @@ -354,10 +348,7 @@ def per_table_state(command, state): dummy, out, dummy = module.run_command(COMMAND, check_rc=True) out = re.sub(r'(^|\n)(# Generated|# Completed|[*]%s|COMMIT)[^\n]*' % t, r'', out) out = re.sub(r' *\[[0-9]+:[0-9]+\] *', r'', out) - table = out.splitlines() - while '' in table: - table.remove('') - tables[t] = table + tables[t] = [tt for tt in out.splitlines() if tt != ''] return tables @@ -548,8 +539,7 @@ def main(): if module.check_mode: tmpfd, tmpfile = tempfile.mkstemp() with os.fdopen(tmpfd, 'w') as f: - for line in initial_state: - f.write('%s\n' % line) + f.write("{0}\n".format("\n".join(initial_state))) if filecmp.cmp(tmpfile, b_path): restored_state = initial_state From 7c8cc96d8ba6a2ebb1bcd0040f38883cba4fd72f Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Wed, 18 Jan 2023 08:18:55 +0100 Subject: [PATCH 113/134] Prepare 6.3.0 release. --- changelogs/fragments/6.3.0.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/fragments/6.3.0.yml diff --git a/changelogs/fragments/6.3.0.yml b/changelogs/fragments/6.3.0.yml new file mode 100644 index 0000000000..4b1469c9fe --- /dev/null +++ b/changelogs/fragments/6.3.0.yml @@ -0,0 +1 @@ +release_summary: Regular bugfix and feature release. From 1ade62c5bca68321300de83a3135327079612902 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 21:43:16 +0100 Subject: [PATCH 114/134] [PR #5845/1430ed00 backport][stable-6] pipx: add testcase w/ env vars PIPX_xxxx (#5859) pipx: add testcase w/ env vars PIPX_xxxx (#5845) * pipx: add testcase w/ env vars PIPX_xxxx * add note to the docs about env vars * add note to the docs about env vars * Apply suggestions from code review * Update plugins/modules/pipx.py Co-authored-by: Felix Fontein * Update plugins/modules/pipx_info.py Co-authored-by: Felix Fontein * break long lines into smaller ones Co-authored-by: Felix Fontein (cherry picked from commit 1430ed000c704fb03f0ad65d25285c0921f012a0) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- plugins/modules/pipx.py | 3 +++ plugins/modules/pipx_info.py | 3 +++ tests/integration/targets/pipx/tasks/main.yml | 27 +++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/plugins/modules/pipx.py b/plugins/modules/pipx.py index a94b7d8d03..773fbef8ea 100644 --- a/plugins/modules/pipx.py +++ b/plugins/modules/pipx.py @@ -95,6 +95,9 @@ options: notes: - This module does not install the C(pipx) python package, however that can be easily done with the module M(ansible.builtin.pip). - This module does not require C(pipx) to be in the shell C(PATH), but it must be loadable by Python as a module. + - > + This module will honor C(pipx) environment variables such as but not limited to C(PIPX_HOME) and C(PIPX_BIN_DIR) + passed using the R(environment Ansible keyword, playbooks_environment). - Please note that C(pipx) requires Python 3.6 or above. - > This first implementation does not verify whether a specified version constraint has been installed or not. diff --git a/plugins/modules/pipx_info.py b/plugins/modules/pipx_info.py index ff9698e31d..4487cdab5a 100644 --- a/plugins/modules/pipx_info.py +++ b/plugins/modules/pipx_info.py @@ -50,6 +50,9 @@ options: notes: - This module does not install the C(pipx) python package, however that can be easily done with the module M(ansible.builtin.pip). - This module does not require C(pipx) to be in the shell C(PATH), but it must be loadable by Python as a module. + - > + This module will honor C(pipx) environment variables such as but not limited to C(PIPX_HOME) and C(PIPX_BIN_DIR) + passed using the R(environment Ansible keyword, playbooks_environment). - Please note that C(pipx) requires Python 3.6 or above. - See also the C(pipx) documentation at U(https://pypa.github.io/pipx/). author: diff --git a/tests/integration/targets/pipx/tasks/main.yml b/tests/integration/targets/pipx/tasks/main.yml index 2318a59ba4..00f54aeb24 100644 --- a/tests/integration/targets/pipx/tasks/main.yml +++ b/tests/integration/targets/pipx/tasks/main.yml @@ -230,3 +230,30 @@ that: - install_jupyter is changed - '"ipython" in install_jupyter.stdout' + +############################################################################## +- name: ensure /opt/pipx + ansible.builtin.file: + path: /opt/pipx + state: directory + mode: 0755 + +- name: install tox site-wide + community.general.pipx: + name: tox + state: latest + register: install_tox_sitewide + environment: + PIPX_HOME: /opt/pipx + PIPX_BIN_DIR: /usr/local/bin + +- name: stat /usr/local/bin/tox + ansible.builtin.stat: + path: /usr/local/bin/tox + register: usrlocaltox + +- name: check assertions + ansible.builtin.assert: + that: + - install_tox_sitewide is changed + - usrlocaltox.stat.exists From 60addb332d3ccb84e9279e4635f63cb7c2834776 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 21:44:08 +0100 Subject: [PATCH 115/134] [PR #5499/c4b18361 backport][stable-6] scaleway module utils: make function private that should be removed (#5860) scaleway module utils: make function private that should be removed (#5499) * Make function private that should be removed (ref: #5497). * Maybe it works as a comment? * Try something else. * Ok, let's just add a comment. * Last try: docstring instead of comment. (cherry picked from commit c4b18361b990fac683e0438a154eeac23b38d590) Co-authored-by: Felix Fontein --- plugins/module_utils/scaleway.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/module_utils/scaleway.py b/plugins/module_utils/scaleway.py index a44c52aa78..43f2094800 100644 --- a/plugins/module_utils/scaleway.py +++ b/plugins/module_utils/scaleway.py @@ -84,6 +84,10 @@ def parse_pagination_link(header): def filter_sensitive_attributes(container, attributes): + ''' + WARNING: This function is effectively private, **do not use it**! + It will be removed or renamed once changing its name no longer triggers a pylint bug. + ''' for attr in attributes: container[attr] = "SENSITIVE_VALUE" From ea9b272043fc8a6b8848ceab0bcc88e18b9f4501 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 22 Jan 2023 17:23:28 +0100 Subject: [PATCH 116/134] [PR #5754/59a9d342 backport][stable-6] Remote management modules for OCAPI-based devices. (#5869) Remote management modules for OCAPI-based devices. (#5754) * Remote management modules for OCAPI-based devices. Open Composable API (OCAPI) is a REST-based API designed for data center composability. For more information, see https://www.opencompute.org/documents/open-composable-api-for-ocp-2019-06-24-pdf This PR introduces ocapi_command and ocapi_info modules. These are based on the existing redfish_command and redfish_info modules and follow similar patterns. This initial implementation includes support for the folowing operations: - Indicator LED toggling - Power state toggling - Enclosure reset (reboot) - Firmware upload - Firmware update - Firmware activate - Job deletion - Job status These modules have been tested against Western Digital OpenFlex(tm) Data24 storage enclosures. API reference is at https://documents.westerndigital.com/content/dam/doc-library/en_us/assets/public/western-digital/product/platforms/openflex/reference-architecture-open-composable-api.pdf * Fix licensing issue for ocapi_utils.py * PR Feedback * Apply suggestions from code review Co-authored-by: Felix Fontein * Update plugins/module_utils/ocapi_utils.py Co-authored-by: Felix Fontein * Update plugins/modules/ocapi_info.py Co-authored-by: Felix Fontein * Apply suggestions from code review Co-authored-by: Felix Fontein * PR Feedback Use six module for urlparse * Apply suggestions from code review Documentation fixes. Co-authored-by: Felix Fontein * Fix sanity test line too long error. Co-authored-by: Felix Fontein (cherry picked from commit 59a9d34250aaf4bb213acf4ecda4ea91da1ae7ac) Co-authored-by: Mike Moerk --- .github/BOTMETA.yml | 4 + plugins/module_utils/ocapi_utils.py | 502 ++++++++++++++ plugins/modules/ocapi_command.py | 267 ++++++++ plugins/modules/ocapi_info.py | 221 ++++++ .../plugins/module_utils/test_ocapi_utils.py | 54 ++ .../plugins/modules/test_ocapi_command.py | 639 ++++++++++++++++++ tests/unit/plugins/modules/test_ocapi_info.py | 240 +++++++ 7 files changed, 1927 insertions(+) create mode 100644 plugins/module_utils/ocapi_utils.py create mode 100644 plugins/modules/ocapi_command.py create mode 100644 plugins/modules/ocapi_info.py create mode 100644 tests/unit/plugins/module_utils/test_ocapi_utils.py create mode 100644 tests/unit/plugins/modules/test_ocapi_command.py create mode 100644 tests/unit/plugins/modules/test_ocapi_info.py diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 422048ca88..7d014c9e96 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -830,6 +830,10 @@ files: maintainers: shane-walker xcambar $modules/nsupdate.py: maintainers: nerzhul + $modules/ocapi_command.py: + maintainers: $team_wdc + $modules/ocapi_info.py: + maintainers: $team_wdc $modules/oci_vcn.py: maintainers: $team_oracle rohitChaware $modules/odbc.py: diff --git a/plugins/module_utils/ocapi_utils.py b/plugins/module_utils/ocapi_utils.py new file mode 100644 index 0000000000..acc2ceae49 --- /dev/null +++ b/plugins/module_utils/ocapi_utils.py @@ -0,0 +1,502 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2022 Western Digital Corporation +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +import json +import os +import uuid + +from ansible.module_utils.urls import open_url +from ansible.module_utils.common.text.converters import to_native +from ansible.module_utils.common.text.converters import to_text +from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError +from ansible.module_utils.six.moves.urllib.parse import urlparse + + +GET_HEADERS = {'accept': 'application/json'} +PUT_HEADERS = {'content-type': 'application/json', 'accept': 'application/json'} +POST_HEADERS = {'content-type': 'application/json', 'accept': 'application/json'} +DELETE_HEADERS = {'accept': 'application/json'} + +HEALTH_OK = 5 + + +class OcapiUtils(object): + + def __init__(self, creds, base_uri, proxy_slot_number, timeout, module): + self.root_uri = base_uri + self.proxy_slot_number = proxy_slot_number + self.creds = creds + self.timeout = timeout + self.module = module + + def _auth_params(self): + """ + Return tuple of required authentication params based on the username and password. + + :return: tuple of username, password + """ + username = self.creds['user'] + password = self.creds['pswd'] + force_basic_auth = True + return username, password, force_basic_auth + + def get_request(self, uri): + req_headers = dict(GET_HEADERS) + username, password, basic_auth = self._auth_params() + try: + resp = open_url(uri, method="GET", headers=req_headers, + url_username=username, url_password=password, + force_basic_auth=basic_auth, validate_certs=False, + follow_redirects='all', + use_proxy=True, timeout=self.timeout) + data = json.loads(to_native(resp.read())) + headers = dict((k.lower(), v) for (k, v) in resp.info().items()) + except HTTPError as e: + return {'ret': False, + 'msg': "HTTP Error %s on GET request to '%s'" + % (e.code, uri), + 'status': e.code} + except URLError as e: + return {'ret': False, 'msg': "URL Error on GET request to '%s': '%s'" + % (uri, e.reason)} + # Almost all errors should be caught above, but just in case + except Exception as e: + return {'ret': False, + 'msg': "Failed GET request to '%s': '%s'" % (uri, to_text(e))} + return {'ret': True, 'data': data, 'headers': headers} + + def delete_request(self, uri, etag=None): + req_headers = dict(DELETE_HEADERS) + if etag is not None: + req_headers['If-Match'] = etag + username, password, basic_auth = self._auth_params() + try: + resp = open_url(uri, method="DELETE", headers=req_headers, + url_username=username, url_password=password, + force_basic_auth=basic_auth, validate_certs=False, + follow_redirects='all', + use_proxy=True, timeout=self.timeout) + if resp.status != 204: + data = json.loads(to_native(resp.read())) + else: + data = "" + headers = dict((k.lower(), v) for (k, v) in resp.info().items()) + except HTTPError as e: + return {'ret': False, + 'msg': "HTTP Error %s on DELETE request to '%s'" + % (e.code, uri), + 'status': e.code} + except URLError as e: + return {'ret': False, 'msg': "URL Error on DELETE request to '%s': '%s'" + % (uri, e.reason)} + # Almost all errors should be caught above, but just in case + except Exception as e: + return {'ret': False, + 'msg': "Failed DELETE request to '%s': '%s'" % (uri, to_text(e))} + return {'ret': True, 'data': data, 'headers': headers} + + def put_request(self, uri, payload, etag=None): + req_headers = dict(PUT_HEADERS) + if etag is not None: + req_headers['If-Match'] = etag + username, password, basic_auth = self._auth_params() + try: + resp = open_url(uri, data=json.dumps(payload), + headers=req_headers, method="PUT", + url_username=username, url_password=password, + force_basic_auth=basic_auth, validate_certs=False, + follow_redirects='all', + use_proxy=True, timeout=self.timeout) + headers = dict((k.lower(), v) for (k, v) in resp.info().items()) + except HTTPError as e: + return {'ret': False, + 'msg': "HTTP Error %s on PUT request to '%s'" + % (e.code, uri), + 'status': e.code} + except URLError as e: + return {'ret': False, 'msg': "URL Error on PUT request to '%s': '%s'" + % (uri, e.reason)} + # Almost all errors should be caught above, but just in case + except Exception as e: + return {'ret': False, + 'msg': "Failed PUT request to '%s': '%s'" % (uri, to_text(e))} + return {'ret': True, 'headers': headers, 'resp': resp} + + def post_request(self, uri, payload, content_type="application/json", timeout=None): + req_headers = dict(POST_HEADERS) + if content_type != "application/json": + req_headers["content-type"] = content_type + username, password, basic_auth = self._auth_params() + if content_type == "application/json": + request_data = json.dumps(payload) + else: + request_data = payload + try: + resp = open_url(uri, data=request_data, + headers=req_headers, method="POST", + url_username=username, url_password=password, + force_basic_auth=basic_auth, validate_certs=False, + follow_redirects='all', + use_proxy=True, timeout=self.timeout if timeout is None else timeout) + headers = dict((k.lower(), v) for (k, v) in resp.info().items()) + except HTTPError as e: + return {'ret': False, + 'msg': "HTTP Error %s on POST request to '%s'" + % (e.code, uri), + 'status': e.code} + except URLError as e: + return {'ret': False, 'msg': "URL Error on POST request to '%s': '%s'" + % (uri, e.reason)} + # Almost all errors should be caught above, but just in case + except Exception as e: + return {'ret': False, + 'msg': "Failed POST request to '%s': '%s'" % (uri, to_text(e))} + return {'ret': True, 'headers': headers, 'resp': resp} + + def get_uri_with_slot_number_query_param(self, uri): + """Return the URI with proxy slot number added as a query param, if there is one. + + If a proxy slot number is provided, to access it, we must append it as a query parameter. + This method returns the given URI with the slotnumber query param added, if there is one. + If there is not a proxy slot number, it just returns the URI as it was passed in. + """ + if self.proxy_slot_number is not None: + parsed_url = urlparse(uri) + return parsed_url._replace(query="slotnumber=" + str(self.proxy_slot_number)).geturl() + else: + return uri + + def manage_system_power(self, command): + """Process a command to manage the system power. + + :param str command: The Ansible command being processed. + """ + if command == "PowerGracefulRestart": + resource_uri = self.root_uri + resource_uri = self.get_uri_with_slot_number_query_param(resource_uri) + + # Get the resource so that we have the Etag + response = self.get_request(resource_uri) + if 'etag' not in response['headers']: + return {'ret': False, 'msg': 'Etag not found in response.'} + etag = response['headers']['etag'] + if response['ret'] is False: + return response + + # Issue the PUT to do the reboot (unless we are in check mode) + if self.module.check_mode: + return { + 'ret': True, + 'changed': True, + 'msg': 'Update not performed in check mode.' + } + payload = {'Reboot': True} + response = self.put_request(resource_uri, payload, etag) + if response['ret'] is False: + return response + elif command.startswith("PowerMode"): + return self.manage_power_mode(command) + else: + return {'ret': False, 'msg': 'Invalid command: ' + command} + + return {'ret': True} + + def manage_chassis_indicator_led(self, command): + """Process a command to manage the chassis indicator LED. + + :param string command: The Ansible command being processed. + """ + return self.manage_indicator_led(command, self.root_uri) + + def manage_indicator_led(self, command, resource_uri=None): + """Process a command to manage an indicator LED. + + :param string command: The Ansible command being processed. + :param string resource_uri: URI of the resource whose indicator LED is being managed. + """ + key = "IndicatorLED" + if resource_uri is None: + resource_uri = self.root_uri + resource_uri = self.get_uri_with_slot_number_query_param(resource_uri) + + payloads = { + 'IndicatorLedOn': { + 'ID': 2 + }, + 'IndicatorLedOff': { + 'ID': 4 + } + } + + response = self.get_request(resource_uri) + if 'etag' not in response['headers']: + return {'ret': False, 'msg': 'Etag not found in response.'} + etag = response['headers']['etag'] + if response['ret'] is False: + return response + data = response['data'] + if key not in data: + return {'ret': False, 'msg': "Key %s not found" % key} + if 'ID' not in data[key]: + return {'ret': False, 'msg': 'IndicatorLED for resource has no ID.'} + + if command in payloads.keys(): + # See if the LED is already set as requested. + current_led_status = data[key]['ID'] + if current_led_status == payloads[command]['ID']: + return {'ret': True, 'changed': False} + + # Set the LED (unless we are in check mode) + if self.module.check_mode: + return { + 'ret': True, + 'changed': True, + 'msg': 'Update not performed in check mode.' + } + payload = {'IndicatorLED': payloads[command]} + response = self.put_request(resource_uri, payload, etag) + if response['ret'] is False: + return response + else: + return {'ret': False, 'msg': 'Invalid command'} + + return {'ret': True} + + def manage_power_mode(self, command): + key = "PowerState" + resource_uri = self.get_uri_with_slot_number_query_param(self.root_uri) + + payloads = { + "PowerModeNormal": 2, + "PowerModeLow": 4 + } + + response = self.get_request(resource_uri) + if 'etag' not in response['headers']: + return {'ret': False, 'msg': 'Etag not found in response.'} + etag = response['headers']['etag'] + if response['ret'] is False: + return response + data = response['data'] + if key not in data: + return {'ret': False, 'msg': "Key %s not found" % key} + if 'ID' not in data[key]: + return {'ret': False, 'msg': 'PowerState for resource has no ID.'} + + if command in payloads.keys(): + # See if the PowerState is already set as requested. + current_power_state = data[key]['ID'] + if current_power_state == payloads[command]: + return {'ret': True, 'changed': False} + + # Set the Power State (unless we are in check mode) + if self.module.check_mode: + return { + 'ret': True, + 'changed': True, + 'msg': 'Update not performed in check mode.' + } + payload = {'PowerState': {"ID": payloads[command]}} + response = self.put_request(resource_uri, payload, etag) + if response['ret'] is False: + return response + else: + return {'ret': False, 'msg': 'Invalid command: ' + command} + + return {'ret': True} + + def prepare_multipart_firmware_upload(self, filename): + """Prepare a multipart/form-data body for OCAPI firmware upload. + + :arg filename: The name of the file to upload. + :returns: tuple of (content_type, body) where ``content_type`` is + the ``multipart/form-data`` ``Content-Type`` header including + ``boundary`` and ``body`` is the prepared bytestring body + + Prepares the body to include "FirmwareFile" field with the contents of the file. + Because some OCAPI targets do not support Base-64 encoding for multipart/form-data, + this method sends the file as binary. + """ + boundary = str(uuid.uuid4()) # Generate a random boundary + body = "--" + boundary + '\r\n' + body += 'Content-Disposition: form-data; name="FirmwareFile"; filename="%s"\r\n' % to_native(os.path.basename(filename)) + body += 'Content-Type: application/octet-stream\r\n\r\n' + body_bytes = bytearray(body, 'utf-8') + with open(filename, 'rb') as f: + body_bytes += f.read() + body_bytes += bytearray("\r\n--%s--" % boundary, 'utf-8') + return ("multipart/form-data; boundary=%s" % boundary, + body_bytes) + + def upload_firmware_image(self, update_image_path): + """Perform Firmware Upload to the OCAPI storage device. + + :param str update_image_path: The path/filename of the firmware image, on the local filesystem. + """ + if not (os.path.exists(update_image_path) and os.path.isfile(update_image_path)): + return {'ret': False, 'msg': 'File does not exist.'} + url = self.root_uri + "OperatingSystem" + url = self.get_uri_with_slot_number_query_param(url) + content_type, b_form_data = self.prepare_multipart_firmware_upload(update_image_path) + + # Post the firmware (unless we are in check mode) + if self.module.check_mode: + return { + 'ret': True, + 'changed': True, + 'msg': 'Update not performed in check mode.' + } + result = self.post_request(url, b_form_data, content_type=content_type, timeout=300) + if result['ret'] is False: + return result + return {'ret': True} + + def update_firmware_image(self): + """Perform a Firmware Update on the OCAPI storage device.""" + resource_uri = self.root_uri + resource_uri = self.get_uri_with_slot_number_query_param(resource_uri) + # We have to do a GET to obtain the Etag. It's required on the PUT. + response = self.get_request(resource_uri) + if response['ret'] is False: + return response + if 'etag' not in response['headers']: + return {'ret': False, 'msg': 'Etag not found in response.'} + etag = response['headers']['etag'] + + # Issue the PUT (unless we are in check mode) + if self.module.check_mode: + return { + 'ret': True, + 'changed': True, + 'msg': 'Update not performed in check mode.' + } + payload = {'FirmwareUpdate': True} + response = self.put_request(resource_uri, payload, etag) + if response['ret'] is False: + return response + + return {'ret': True, 'jobUri': response["headers"]["location"]} + + def activate_firmware_image(self): + """Perform a Firmware Activate on the OCAPI storage device.""" + resource_uri = self.root_uri + resource_uri = self.get_uri_with_slot_number_query_param(resource_uri) + # We have to do a GET to obtain the Etag. It's required on the PUT. + response = self.get_request(resource_uri) + if 'etag' not in response['headers']: + return {'ret': False, 'msg': 'Etag not found in response.'} + etag = response['headers']['etag'] + if response['ret'] is False: + return response + + # Issue the PUT (unless we are in check mode) + if self.module.check_mode: + return { + 'ret': True, + 'changed': True, + 'msg': 'Update not performed in check mode.' + } + payload = {'FirmwareActivate': True} + response = self.put_request(resource_uri, payload, etag) + if response['ret'] is False: + return response + + return {'ret': True, 'jobUri': response["headers"]["location"]} + + def get_job_status(self, job_uri): + """Get the status of a job. + + :param str job_uri: The URI of the job's status monitor. + """ + job_uri = self.get_uri_with_slot_number_query_param(job_uri) + response = self.get_request(job_uri) + if response['ret'] is False: + if response.get('status') == 404: + # Job not found -- assume 0% + return { + "ret": True, + "percentComplete": 0, + "operationStatus": "Not Available", + "operationStatusId": 1, + "operationHealth": None, + "operationHealthId": None, + "details": "Job does not exist.", + "jobExists": False + } + else: + return response + details = response["data"]["Status"].get("Details") + if type(details) is str: + details = [details] + health_list = response["data"]["Status"]["Health"] + return_value = { + "ret": True, + "percentComplete": response["data"]["PercentComplete"], + "operationStatus": response["data"]["Status"]["State"]["Name"], + "operationStatusId": response["data"]["Status"]["State"]["ID"], + "operationHealth": health_list[0]["Name"] if len(health_list) > 0 else None, + "operationHealthId": health_list[0]["ID"] if len(health_list) > 0 else None, + "details": details, + "jobExists": True + } + return return_value + + def delete_job(self, job_uri): + """Delete the OCAPI job referenced by the specified job_uri.""" + job_uri = self.get_uri_with_slot_number_query_param(job_uri) + # We have to do a GET to obtain the Etag. It's required on the DELETE. + response = self.get_request(job_uri) + + if response['ret'] is True: + if 'etag' not in response['headers']: + return {'ret': False, 'msg': 'Etag not found in response.'} + else: + etag = response['headers']['etag'] + + if response['data']['PercentComplete'] != 100: + return { + 'ret': False, + 'changed': False, + 'msg': 'Cannot delete job because it is in progress.' + } + + if response['ret'] is False: + if response['status'] == 404: + return { + 'ret': True, + 'changed': False, + 'msg': 'Job already deleted.' + } + return response + if self.module.check_mode: + return { + 'ret': True, + 'changed': True, + 'msg': 'Update not performed in check mode.' + } + + # Do the DELETE (unless we are in check mode) + response = self.delete_request(job_uri, etag) + if response['ret'] is False: + if response['status'] == 404: + return { + 'ret': True, + 'changed': False + } + elif response['status'] == 409: + return { + 'ret': False, + 'changed': False, + 'msg': 'Cannot delete job because it is in progress.' + } + return response + return { + 'ret': True, + 'changed': True + } diff --git a/plugins/modules/ocapi_command.py b/plugins/modules/ocapi_command.py new file mode 100644 index 0000000000..7d8fca8064 --- /dev/null +++ b/plugins/modules/ocapi_command.py @@ -0,0 +1,267 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2022 Western Digital Corporation +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: ocapi_command +version_added: 6.3.0 +short_description: Manages Out-Of-Band controllers using Open Composable API (OCAPI) +description: + - Builds OCAPI URIs locally and sends them to remote OOB controllers to + perform an action. + - Manages OOB controller such as Indicator LED, Reboot, Power Mode, Firmware Update. +options: + category: + required: true + description: + - Category to execute on OOB controller. + type: str + command: + required: true + description: + - Command to execute on OOB controller. + type: str + baseuri: + required: true + description: + - Base URI of OOB controller. + type: str + proxy_slot_number: + description: For proxied inband requests, the slot number of the IOM. Only applies if I(baseuri) is a proxy server. + type: int + update_image_path: + required: false + description: + - For C(FWUpload), the path on the local filesystem of the firmware update image. + type: str + job_name: + required: false + description: + - For C(DeleteJob) command, the name of the job to delete. + type: str + username: + required: true + description: + - Username for authenticating to OOB controller. + type: str + password: + required: true + description: + - Password for authenticating to OOB controller. + type: str + timeout: + description: + - Timeout in seconds for URL requests to OOB controller. + default: 10 + type: int + +author: "Mike Moerk (@mikemoerk)" +''' + +EXAMPLES = ''' + - name: Set the power state to low + community.general.ocapi_command: + category: Chassis + command: PowerModeLow + baseuri: "{{ baseuri }}" + username: "{{ username }}" + password: "{{ password }}" + + - name: Set the power state to normal + community.general.ocapi_command: + category: Chassis + command: PowerModeNormal + baseuri: "{{ baseuri }}" + username: "{{ username }}" + password: "{{ password }}" + - name: Set chassis indicator LED to on + community.general.ocapi_command: + category: Chassis + command: IndicatorLedOn + baseuri: "{{ baseuri }}" + proxy_slot_number: 2 + username: "{{ username }}" + password: "{{ password }}" + - name: Set chassis indicator LED to off + community.general.ocapi_command: + category: Chassis + command: IndicatorLedOff + baseuri: "{{ baseuri }}" + proxy_slot_number: 2 + username: "{{ username }}" + password: "{{ password }}" + - name: Reset Enclosure + community.general.ocapi_command: + category: Systems + command: PowerGracefulRestart + baseuri: "{{ baseuri }}" + proxy_slot_number: 2 + username: "{{ username }}" + password: "{{ password }}" + - name: Firmware Upload + community.general.ocapi_command: + category: Update + command: FWUpload + baseuri: "iom1.wdc.com" + proxy_slot_number: 2 + username: "{{ username }}" + password: "{{ password }}" + update_image_path: "/path/to/firmware.tar.gz" + - name: Firmware Update + community.general.ocapi_command: + category: Update + command: FWUpdate + baseuri: "iom1.wdc.com" + proxy_slot_number: 2 + username: "{{ username }}" + password: "{{ password }}" + - name: Firmware Activate + community.general.ocapi_command: + category: Update + command: FWActivate + baseuri: "iom1.wdc.com" + proxy_slot_number: 2 + username: "{{ username }}" + password: "{{ password }}" + - name: Delete Job + community.general.ocapi_command: + category: Jobs + command: DeleteJob + job_name: FirmwareUpdate + baseuri: "{{ baseuri }}" + proxy_slot_number: 2 + username: "{{ username }}" + password: "{{ password }}" +''' + +RETURN = ''' +msg: + description: Message with action result or error description. + returned: always + type: str + sample: "Action was successful" + +jobUri: + description: URI to use to monitor status of the operation. Returned for async commands such as Firmware Update, Firmware Activate. + returned: when supported + type: str + sample: "https://ioma.wdc.com/Storage/Devices/openflex-data24-usalp03020qb0003/Jobs/FirmwareUpdate/" + +operationStatusId: + description: OCAPI State ID (see OCAPI documentation for possible values). + returned: when supported + type: int + sample: 2 + +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.general.plugins.module_utils.ocapi_utils import OcapiUtils +from ansible.module_utils.common.text.converters import to_native +from ansible.module_utils.six.moves.urllib.parse import quote_plus, urljoin + +# More will be added as module features are expanded +CATEGORY_COMMANDS_ALL = { + "Chassis": ["IndicatorLedOn", "IndicatorLedOff", "PowerModeLow", "PowerModeNormal"], + "Systems": ["PowerGracefulRestart"], + "Update": ["FWUpload", "FWUpdate", "FWActivate"], + "Jobs": ["DeleteJob"] +} + + +def main(): + result = {} + module = AnsibleModule( + argument_spec=dict( + category=dict(required=True), + command=dict(required=True, type='str'), + job_name=dict(type='str'), + baseuri=dict(required=True, type='str'), + proxy_slot_number=dict(type='int'), + update_image_path=dict(type='str'), + username=dict(required=True), + password=dict(required=True, no_log=True), + timeout=dict(type='int', default=10) + ), + supports_check_mode=True + ) + + category = module.params['category'] + command = module.params['command'] + + # admin credentials used for authentication + creds = { + 'user': module.params['username'], + 'pswd': module.params['password'] + } + + # timeout + timeout = module.params['timeout'] + + base_uri = "https://" + module.params["baseuri"] + proxy_slot_number = module.params.get("proxy_slot_number") + ocapi_utils = OcapiUtils(creds, base_uri, proxy_slot_number, timeout, module) + + # Check that Category is valid + if category not in CATEGORY_COMMANDS_ALL: + module.fail_json(msg=to_native("Invalid Category '%s'. Valid Categories = %s" % (category, list(CATEGORY_COMMANDS_ALL.keys())))) + + # Check that the command is valid + if command not in CATEGORY_COMMANDS_ALL[category]: + module.fail_json(msg=to_native("Invalid Command '%s'. Valid Commands = %s" % (command, CATEGORY_COMMANDS_ALL[category]))) + + # Organize by Categories / Commands + if category == "Chassis": + if command.startswith("IndicatorLed"): + result = ocapi_utils.manage_chassis_indicator_led(command) + elif command.startswith("PowerMode"): + result = ocapi_utils.manage_system_power(command) + elif category == "Systems": + if command.startswith("Power"): + result = ocapi_utils.manage_system_power(command) + elif category == "Update": + if command == "FWUpload": + update_image_path = module.params.get("update_image_path") + if update_image_path is None: + module.fail_json(msg=to_native("Missing update_image_path.")) + result = ocapi_utils.upload_firmware_image(update_image_path) + elif command == "FWUpdate": + result = ocapi_utils.update_firmware_image() + elif command == "FWActivate": + result = ocapi_utils.activate_firmware_image() + elif category == "Jobs": + if command == "DeleteJob": + job_name = module.params.get("job_name") + if job_name is None: + module.fail_json("Missing job_name") + job_uri = urljoin(base_uri, "Jobs/" + job_name) + result = ocapi_utils.delete_job(job_uri) + + if result['ret'] is False: + module.fail_json(msg=to_native(result['msg'])) + else: + del result['ret'] + changed = result.get('changed', True) + session = result.get('session', dict()) + kwargs = { + "changed": changed, + "session": session, + "msg": "Action was successful." if not module.check_mode else result.get( + "msg", "No action performed in check mode." + ) + } + result_keys = [result_key for result_key in result if result_key not in kwargs] + for result_key in result_keys: + kwargs[result_key] = result[result_key] + module.exit_json(**kwargs) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/ocapi_info.py b/plugins/modules/ocapi_info.py new file mode 100644 index 0000000000..c827b4522d --- /dev/null +++ b/plugins/modules/ocapi_info.py @@ -0,0 +1,221 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2022 Western Digital Corporation +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = ''' +--- +module: ocapi_info +version_added: 6.3.0 +short_description: Manages Out-Of-Band controllers using Open Composable API (OCAPI) +description: + - Builds OCAPI URIs locally and sends them to remote OOB controllers to + get information back. +options: + category: + required: true + description: + - Category to execute on OOB controller. + type: str + command: + required: true + description: + - Command to execute on OOB controller. + type: str + baseuri: + required: true + description: + - Base URI of OOB controller. + type: str + proxy_slot_number: + description: For proxied inband requests, the slot number of the IOM. Only applies if I(baseuri) is a proxy server. + type: int + username: + required: true + description: + - Username for authenticating to OOB controller. + type: str + password: + required: true + description: + - Password for authenticating to OOB controller. + type: str + timeout: + description: + - Timeout in seconds for URL requests to OOB controller. + default: 10 + type: int + job_name: + description: + - Name of job for fetching status. + type: str + + +author: "Mike Moerk (@mikemoerk)" +''' + +EXAMPLES = ''' + - name: Get job status + community.general.ocapi_info: + category: Status + command: JobStatus + baseuri: "http://iom1.wdc.com" + jobName: FirmwareUpdate + username: "{{ username }}" + password: "{{ password }}" +''' + +RETURN = ''' +msg: + description: Message with action result or error description. + returned: always + type: str + sample: "Action was successful" + +percentComplete: + description: Percent complete of the relevant operation. Applies to C(JobStatus) command. + returned: when supported + type: int + sample: 99 + +operationStatus: + description: Status of the relevant operation. Applies to C(JobStatus) command. See OCAPI documentation for details. + returned: when supported + type: str + sample: "Activate needed" + +operationStatusId: + description: Integer value of status (corresponds to operationStatus). Applies to C(JobStatus) command. See OCAPI documentation for details. + returned: when supported + type: int + sample: 65540 + +operationHealth: + description: Health of the operation. Applies to C(JobStatus) command. See OCAPI documentation for details. + returned: when supported + type: str + sample: "OK" + +operationHealthId: + description: > + Integer value for health of the operation (corresponds to C(operationHealth)). Applies to C(JobStatus) command. + See OCAPI documentation for details. + returned: when supported + type: str + sample: "OK" + +details: + description: Details of the relevant operation. Applies to C(JobStatus) command. + returned: when supported + type: list + elements: str + +status: + description: Dict containing status information. See OCAPI documentation for details. + returned: when supported + type: dict + sample: { + "Details": [ + "None" + ], + "Health": [ + { + "ID": 5, + "Name": "OK" + } + ], + "State": { + "ID": 16, + "Name": "In service" + } + } +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.general.plugins.module_utils.ocapi_utils import OcapiUtils +from ansible.module_utils.common.text.converters import to_native +from ansible.module_utils.six.moves.urllib.parse import quote_plus, urljoin + +# More will be added as module features are expanded +CATEGORY_COMMANDS_ALL = { + "Jobs": ["JobStatus"] +} + + +def main(): + result = {} + module = AnsibleModule( + argument_spec=dict( + category=dict(required=True), + command=dict(required=True, type='str'), + job_name=dict(type='str'), + baseuri=dict(required=True, type='str'), + proxy_slot_number=dict(type='int'), + username=dict(required=True), + password=dict(required=True, no_log=True), + timeout=dict(type='int', default=10) + ), + supports_check_mode=True + ) + + category = module.params['category'] + command = module.params['command'] + + # admin credentials used for authentication + creds = { + 'user': module.params['username'], + 'pswd': module.params['password'] + } + + # timeout + timeout = module.params['timeout'] + + base_uri = "https://" + module.params["baseuri"] + proxy_slot_number = module.params.get("proxy_slot_number") + ocapi_utils = OcapiUtils(creds, base_uri, proxy_slot_number, timeout, module) + + # Check that Category is valid + if category not in CATEGORY_COMMANDS_ALL: + module.fail_json(msg=to_native("Invalid Category '%s'. Valid Categories = %s" % (category, list(CATEGORY_COMMANDS_ALL.keys())))) + + # Check that the command is valid + if command not in CATEGORY_COMMANDS_ALL[category]: + module.fail_json(msg=to_native("Invalid Command '%s'. Valid Commands = %s" % (command, CATEGORY_COMMANDS_ALL[category]))) + + # Organize by Categories / Commands + if category == "Jobs": + if command == "JobStatus": + if module.params.get("job_name") is None: + module.fail_json(msg=to_native( + "job_name required for JobStatus command.")) + job_uri = urljoin(base_uri, 'Jobs/' + module.params["job_name"]) + result = ocapi_utils.get_job_status(job_uri) + + if result['ret'] is False: + module.fail_json(msg=to_native(result['msg'])) + else: + del result['ret'] + changed = False + session = result.get('session', dict()) + kwargs = { + "changed": changed, + "session": session, + "msg": "Action was successful." if not module.check_mode else result.get( + "msg", "No action performed in check mode." + ) + } + result_keys = [result_key for result_key in result if result_key not in kwargs] + for result_key in result_keys: + kwargs[result_key] = result[result_key] + module.exit_json(**kwargs) + + +if __name__ == '__main__': + main() diff --git a/tests/unit/plugins/module_utils/test_ocapi_utils.py b/tests/unit/plugins/module_utils/test_ocapi_utils.py new file mode 100644 index 0000000000..3c939b5586 --- /dev/null +++ b/tests/unit/plugins/module_utils/test_ocapi_utils.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Ansible project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import re +import shutil +import tempfile + +from ansible_collections.community.general.tests.unit.compat import unittest +from ansible_collections.community.general.plugins.module_utils.ocapi_utils import OcapiUtils + + +class TestOcapiUtils(unittest.TestCase): + def setUp(self): + self.tempdir = tempfile.mkdtemp() + self.utils = OcapiUtils(creds={"user": "a_user", "pswd": "a_password"}, + base_uri="fakeUri", + proxy_slot_number=None, + timeout=30, + module=None) + + def tearDown(self): + shutil.rmtree(self.tempdir) + + def test_prepare_multipart_firmware_upload(self): + # Generate a binary file and save it + filename = "fake_firmware.bin" + filepath = os.path.join(self.tempdir, filename) + file_contents = b'\x00\x01\x02\x03\x04' + with open(filepath, 'wb+') as f: + f.write(file_contents) + + # Call prepare_mutipart_firmware_upload + content_type, b_form_data = self.utils.prepare_multipart_firmware_upload(filepath) + + # Check the returned content-type + content_type_pattern = r"multipart/form-data; boundary=(.*)" + m = re.match(content_type_pattern, content_type) + self.assertIsNotNone(m) + + # Check the returned binary data + boundary = m.group(1) + expected_content_text = '--%s\r\n' % boundary + expected_content_text += 'Content-Disposition: form-data; name="FirmwareFile"; filename="%s"\r\n' % filename + expected_content_text += 'Content-Type: application/octet-stream\r\n\r\n' + expected_content_bytes = bytearray(expected_content_text, 'utf-8') + expected_content_bytes += file_contents + expected_content_bytes += bytearray('\r\n--%s--' % boundary, 'utf-8') + self.assertEqual(expected_content_bytes, b_form_data) diff --git a/tests/unit/plugins/modules/test_ocapi_command.py b/tests/unit/plugins/modules/test_ocapi_command.py new file mode 100644 index 0000000000..031fb9dd09 --- /dev/null +++ b/tests/unit/plugins/modules/test_ocapi_command.py @@ -0,0 +1,639 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Ansible project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import shutil +import tempfile + +from ansible_collections.community.general.tests.unit.compat.mock import patch +from ansible_collections.community.general.tests.unit.compat import unittest +from ansible.module_utils import basic +import ansible_collections.community.general.plugins.modules.ocapi_command as module +from ansible_collections.community.general.tests.unit.plugins.modules.utils import AnsibleExitJson, AnsibleFailJson +from ansible_collections.community.general.tests.unit.plugins.modules.utils import set_module_args, exit_json, fail_json +from ansible.module_utils.six.moves.urllib.parse import quote_plus, urljoin + + +MOCK_BASE_URI = "mockBaseUri/" +OPERATING_SYSTEM_URI = "OperatingSystem" +MOCK_JOB_NAME = "MockJob" + +ACTION_WAS_SUCCESSFUL = "Action was successful." +UPDATE_NOT_PERFORMED_IN_CHECK_MODE = "Update not performed in check mode." +NO_ACTION_PERFORMED_IN_CHECK_MODE = "No action performed in check mode." + +MOCK_SUCCESSFUL_HTTP_RESPONSE_LED_INDICATOR_OFF_WITH_ETAG = { + "ret": True, + "data": { + "IndicatorLED": { + "ID": 4, + "Name": "Off" + }, + "PowerState": { + "ID": 2, + "Name": "On" + } + }, + "headers": {"etag": "MockETag"} +} + +MOCK_SUCCESSFUL_HTTP_RESPONSE = { + "ret": True, + "data": {} +} + +MOCK_404_RESPONSE = { + "ret": False, + "status": 404 +} + +MOCK_SUCCESSFUL_HTTP_RESPONSE_WITH_LOCATION_HEADER = { + "ret": True, + "data": {}, + "headers": {"location": "mock_location"} +} + +MOCK_HTTP_RESPONSE_CONFLICT = { + "ret": False, + "msg": "Conflict", + "status": 409 +} + +MOCK_HTTP_RESPONSE_JOB_IN_PROGRESS = { + "ret": True, + "data": { + "PercentComplete": 99 + }, + "headers": { + "etag": "12345" + } +} + +MOCK_HTTP_RESPONSE_JOB_COMPLETE = { + "ret": True, + "data": { + "PercentComplete": 100 + }, + "headers": { + "etag": "12345" + } +} + + +def get_bin_path(self, arg, required=False): + """Mock AnsibleModule.get_bin_path""" + return arg + + +def get_exception_message(ansible_exit_json): + """From an AnsibleExitJson exception, get the message string.""" + return ansible_exit_json.exception.args[0]["msg"] + + +def is_changed(ansible_exit_json): + """From an AnsibleExitJson exception, return the value of the changed flag""" + return ansible_exit_json.exception.args[0]["changed"] + + +def mock_get_request(*args, **kwargs): + """Mock for get_request.""" + url = args[1] + if url == 'https://' + MOCK_BASE_URI: + return MOCK_SUCCESSFUL_HTTP_RESPONSE_LED_INDICATOR_OFF_WITH_ETAG + elif url == "mock_location": + return MOCK_SUCCESSFUL_HTTP_RESPONSE + raise RuntimeError("Illegal call to get_request in test: " + args[1]) + + +def mock_get_request_job_does_not_exist(*args, **kwargs): + """Mock for get_request.""" + url = args[1] + if url == 'https://' + MOCK_BASE_URI: + return MOCK_SUCCESSFUL_HTTP_RESPONSE_LED_INDICATOR_OFF_WITH_ETAG + elif url == urljoin('https://' + MOCK_BASE_URI, "Jobs/" + MOCK_JOB_NAME): + return MOCK_404_RESPONSE + raise RuntimeError("Illegal call to get_request in test: " + args[1]) + + +def mock_get_request_job_in_progress(*args, **kwargs): + url = args[1] + if url == 'https://' + MOCK_BASE_URI: + return MOCK_SUCCESSFUL_HTTP_RESPONSE_LED_INDICATOR_OFF_WITH_ETAG + elif url == urljoin('https://' + MOCK_BASE_URI, "Jobs/" + MOCK_JOB_NAME): + return MOCK_HTTP_RESPONSE_JOB_IN_PROGRESS + raise RuntimeError("Illegal call to get_request in test: " + args[1]) + + +def mock_get_request_job_complete(*args, **kwargs): + url = args[1] + if url == 'https://' + MOCK_BASE_URI: + return MOCK_SUCCESSFUL_HTTP_RESPONSE_LED_INDICATOR_OFF_WITH_ETAG + elif url == urljoin('https://' + MOCK_BASE_URI, "Jobs/" + MOCK_JOB_NAME): + return MOCK_HTTP_RESPONSE_JOB_COMPLETE + raise RuntimeError("Illegal call to get_request in test: " + args[1]) + + +def mock_put_request(*args, **kwargs): + """Mock put_request.""" + url = args[1] + if url == 'https://' + MOCK_BASE_URI: + return MOCK_SUCCESSFUL_HTTP_RESPONSE_WITH_LOCATION_HEADER + raise RuntimeError("Illegal PUT call to: " + args[1]) + + +def mock_delete_request(*args, **kwargs): + """Mock delete request.""" + url = args[1] + if url == urljoin('https://' + MOCK_BASE_URI, 'Jobs/' + MOCK_JOB_NAME): + return MOCK_SUCCESSFUL_HTTP_RESPONSE + raise RuntimeError("Illegal DELETE call to: " + args[1]) + + +def mock_post_request(*args, **kwargs): + """Mock post_request.""" + url = args[1] + if url == urljoin('https://' + MOCK_BASE_URI, OPERATING_SYSTEM_URI): + return MOCK_SUCCESSFUL_HTTP_RESPONSE + raise RuntimeError("Illegal POST call to: " + args[1]) + + +def mock_http_request_conflict(*args, **kwargs): + """Mock to make an HTTP request return 409 Conflict""" + return MOCK_HTTP_RESPONSE_CONFLICT + + +def mock_invalid_http_request(*args, **kwargs): + """Mock to make an HTTP request invalid. Raises an exception.""" + raise RuntimeError("Illegal HTTP call to " + args[1]) + + +class TestOcapiCommand(unittest.TestCase): + + def setUp(self): + self.mock_module_helper = patch.multiple(basic.AnsibleModule, + exit_json=exit_json, + fail_json=fail_json, + get_bin_path=get_bin_path) + self.mock_module_helper.start() + self.addCleanup(self.mock_module_helper.stop) + self.tempdir = tempfile.mkdtemp() + + def tearDown(self): + shutil.rmtree(self.tempdir) + + def test_module_fail_when_required_args_missing(self): + with self.assertRaises(AnsibleFailJson) as ansible_fail_json: + set_module_args({}) + module.main() + self.assertIn("missing required arguments:", get_exception_message(ansible_fail_json)) + + def test_module_fail_when_unknown_category(self): + with self.assertRaises(AnsibleFailJson) as ansible_fail_json: + set_module_args({ + 'category': 'unknown', + 'command': 'IndicatorLedOn', + 'username': 'USERID', + 'password': 'PASSW0RD=21', + 'baseuri': MOCK_BASE_URI + }) + module.main() + self.assertIn("Invalid Category 'unknown", get_exception_message(ansible_fail_json)) + + def test_set_power_mode(self): + """Test that we can set chassis power mode""" + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_put_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Chassis', + 'command': 'PowerModeLow', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual(ACTION_WAS_SUCCESSFUL, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_set_chassis_led_indicator(self): + """Test that we can set chassis LED indicator.""" + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_put_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Chassis', + 'command': 'IndicatorLedOn', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual(ACTION_WAS_SUCCESSFUL, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_set_power_mode_already_set(self): + """Test that if we set Power Mode to normal when it's already normal, we get changed=False.""" + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Chassis', + 'command': 'PowerModeNormal', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual(ACTION_WAS_SUCCESSFUL, get_exception_message(ansible_exit_json)) + self.assertFalse(is_changed(ansible_exit_json)) + + def test_set_power_mode_check_mode(self): + """Test check mode when setting chassis Power Mode.""" + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Chassis', + 'command': 'IndicatorLedOn', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21', + '_ansible_check_mode': True + }) + module.main() + self.assertEqual(UPDATE_NOT_PERFORMED_IN_CHECK_MODE, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_set_chassis_led_indicator_check_mode(self): + """Test check mode when setting chassis LED indicator""" + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Chassis', + 'command': 'IndicatorLedOn', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21', + '_ansible_check_mode': True + }) + module.main() + self.assertEqual(UPDATE_NOT_PERFORMED_IN_CHECK_MODE, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_set_chassis_led_indicator_already_set(self): + """Test that if we set LED Indicator to off when it's already off, we get changed=False.""" + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Chassis', + 'command': 'IndicatorLedOff', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual(ACTION_WAS_SUCCESSFUL, get_exception_message(ansible_exit_json)) + self.assertFalse(is_changed(ansible_exit_json)) + + def test_set_chassis_led_indicator_already_set_check_mode(self): + """Test that if we set LED Indicator to off when it's already off, we get changed=False even in check mode.""" + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Chassis', + 'command': 'IndicatorLedOff', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21', + "_ansible_check_mode": True + }) + module.main() + self.assertEqual(NO_ACTION_PERFORMED_IN_CHECK_MODE, get_exception_message(ansible_exit_json)) + self.assertFalse(is_changed(ansible_exit_json)) + + def test_set_chassis_invalid_indicator_command(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_put_request): + with self.assertRaises(AnsibleFailJson) as ansible_fail_json: + set_module_args({ + 'category': 'Chassis', + 'command': 'IndicatorLedBright', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertIn("Invalid Command", get_exception_message(ansible_fail_json)) + + def test_reset_enclosure(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_put_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Systems', + 'command': 'PowerGracefulRestart', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual(ACTION_WAS_SUCCESSFUL, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_reset_enclosure_check_mode(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Systems', + 'command': 'PowerGracefulRestart', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21', + "_ansible_check_mode": True + }) + module.main() + self.assertEqual(UPDATE_NOT_PERFORMED_IN_CHECK_MODE, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_firmware_upload_missing_update_image_path(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_put_request): + with self.assertRaises(AnsibleFailJson) as ansible_fail_json: + set_module_args({ + 'category': 'Update', + 'command': 'FWUpload', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual("Missing update_image_path.", get_exception_message(ansible_fail_json)) + + def test_firmware_upload_file_not_found(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_invalid_http_request): + with self.assertRaises(AnsibleFailJson) as ansible_fail_json: + set_module_args({ + 'category': 'Update', + 'command': 'FWUpload', + 'update_image_path': 'nonexistentfile.bin', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual("File does not exist.", get_exception_message(ansible_fail_json)) + + def test_firmware_upload(self): + filename = "fake_firmware.bin" + filepath = os.path.join(self.tempdir, filename) + file_contents = b'\x00\x01\x02\x03\x04' + with open(filepath, 'wb+') as f: + f.write(file_contents) + + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_put_request, + post_request=mock_post_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Update', + 'command': 'FWUpload', + 'update_image_path': filepath, + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual(ACTION_WAS_SUCCESSFUL, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_firmware_upload_check_mode(self): + filename = "fake_firmware.bin" + filepath = os.path.join(self.tempdir, filename) + file_contents = b'\x00\x01\x02\x03\x04' + with open(filepath, 'wb+') as f: + f.write(file_contents) + + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_put_request, + post_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Update', + 'command': 'FWUpload', + 'update_image_path': filepath, + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21', + "_ansible_check_mode": True + }) + module.main() + self.assertEqual(UPDATE_NOT_PERFORMED_IN_CHECK_MODE, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_firmware_update(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_put_request, + post_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Update', + 'command': 'FWUpdate', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual(ACTION_WAS_SUCCESSFUL, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_firmware_update_check_mode(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_invalid_http_request, + post_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Update', + 'command': 'FWUpdate', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21', + "_ansible_check_mode": True + }) + module.main() + self.assertEqual(UPDATE_NOT_PERFORMED_IN_CHECK_MODE, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_firmware_activate(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_put_request, + post_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Update', + 'command': 'FWActivate', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual(ACTION_WAS_SUCCESSFUL, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_firmware_activate_check_mode(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_invalid_http_request, + post_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Update', + 'command': 'FWActivate', + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21', + "_ansible_check_mode": True + }) + module.main() + self.assertEqual(UPDATE_NOT_PERFORMED_IN_CHECK_MODE, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_delete_job(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request_job_complete, + delete_request=mock_delete_request, + put_request=mock_invalid_http_request, + post_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Jobs', + 'command': 'DeleteJob', + 'baseuri': MOCK_BASE_URI, + 'job_name': MOCK_JOB_NAME, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual(ACTION_WAS_SUCCESSFUL, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_delete_job_in_progress(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request_job_in_progress, + delete_request=mock_invalid_http_request, + put_request=mock_invalid_http_request, + post_request=mock_invalid_http_request): + with self.assertRaises(AnsibleFailJson) as ansible_fail_json: + set_module_args({ + 'category': 'Jobs', + 'command': 'DeleteJob', + 'baseuri': MOCK_BASE_URI, + 'job_name': MOCK_JOB_NAME, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual("Cannot delete job because it is in progress.", get_exception_message(ansible_fail_json)) + + def test_delete_job_in_progress_only_on_delete(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request_job_complete, + delete_request=mock_http_request_conflict, + put_request=mock_invalid_http_request, + post_request=mock_invalid_http_request): + with self.assertRaises(AnsibleFailJson) as ansible_fail_json: + set_module_args({ + 'category': 'Jobs', + 'command': 'DeleteJob', + 'baseuri': MOCK_BASE_URI, + 'job_name': MOCK_JOB_NAME, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual("Cannot delete job because it is in progress.", get_exception_message(ansible_fail_json)) + + def test_delete_job_check_mode(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request_job_complete, + delete_request=mock_delete_request, + put_request=mock_invalid_http_request, + post_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Jobs', + 'command': 'DeleteJob', + 'baseuri': MOCK_BASE_URI, + 'job_name': MOCK_JOB_NAME, + 'username': 'USERID', + 'password': 'PASSWORD=21', + '_ansible_check_mode': True + }) + module.main() + self.assertEqual(UPDATE_NOT_PERFORMED_IN_CHECK_MODE, get_exception_message(ansible_exit_json)) + self.assertTrue(is_changed(ansible_exit_json)) + + def test_delete_job_check_mode_job_not_found(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request_job_does_not_exist, + delete_request=mock_delete_request, + put_request=mock_invalid_http_request, + post_request=mock_invalid_http_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Jobs', + 'command': 'DeleteJob', + 'baseuri': MOCK_BASE_URI, + 'job_name': MOCK_JOB_NAME, + 'username': 'USERID', + 'password': 'PASSWORD=21', + '_ansible_check_mode': True + }) + module.main() + self.assertEqual("Job already deleted.", get_exception_message(ansible_exit_json)) + self.assertFalse(is_changed(ansible_exit_json)) + + def test_delete_job_check_mode_job_in_progress(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request_job_in_progress, + delete_request=mock_delete_request, + put_request=mock_invalid_http_request, + post_request=mock_invalid_http_request): + with self.assertRaises(AnsibleFailJson) as ansible_fail_json: + set_module_args({ + 'category': 'Jobs', + 'command': 'DeleteJob', + 'baseuri': MOCK_BASE_URI, + 'job_name': MOCK_JOB_NAME, + 'username': 'USERID', + 'password': 'PASSWORD=21', + '_ansible_check_mode': True + }) + module.main() + self.assertEqual("Cannot delete job because it is in progress.", get_exception_message(ansible_fail_json)) diff --git a/tests/unit/plugins/modules/test_ocapi_info.py b/tests/unit/plugins/modules/test_ocapi_info.py new file mode 100644 index 0000000000..5010b328f8 --- /dev/null +++ b/tests/unit/plugins/modules/test_ocapi_info.py @@ -0,0 +1,240 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Ansible project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible_collections.community.general.tests.unit.compat.mock import patch +from ansible_collections.community.general.tests.unit.compat import unittest +from ansible.module_utils import basic +import ansible_collections.community.general.plugins.modules.ocapi_info as module +from ansible_collections.community.general.tests.unit.plugins.modules.utils import AnsibleExitJson, AnsibleFailJson +from ansible_collections.community.general.tests.unit.plugins.modules.utils import set_module_args, exit_json, fail_json + +MOCK_BASE_URI = "mockBaseUri" +MOCK_JOB_NAME_IN_PROGRESS = "MockJobInProgress" +MOCK_JOB_NAME_COMPLETE = "MockJobComplete" +MOCK_JOB_NAME_DOES_NOT_EXIST = "MockJobDoesNotExist" + +ACTION_WAS_SUCCESSFUL = "Action was successful." + +MOCK_SUCCESSFUL_HTTP_RESPONSE = { + "ret": True, + "data": {} +} + +MOCK_404_RESPONSE = { + "ret": False, + "status": 404 +} + +MOCK_HTTP_RESPONSE_JOB_IN_PROGRESS = { + "ret": True, + "data": { + "Self": "https://openflex-data24-usalp02120qo0012-iomb:443/Storage/Devices/openflex-data24-usalp02120qo0012/Jobs/FirmwareUpdate/", + "ID": MOCK_JOB_NAME_IN_PROGRESS, + "PercentComplete": 10, + "Status": { + "State": { + "ID": 16, + "Name": "In service" + }, + "Health": [ + { + "ID": 5, + "Name": "OK" + } + ] + } + } +} + +MOCK_HTTP_RESPONSE_JOB_COMPLETE = { + "ret": True, + "data": { + "Self": "https://openflex-data24-usalp02120qo0012-iomb:443/Storage/Devices/openflex-data24-usalp02120qo0012/Jobs/FirmwareUpdate/", + "ID": MOCK_JOB_NAME_COMPLETE, + "PercentComplete": 100, + "Status": { + "State": { + "ID": 65540, + "Name": "Activate needed" + }, + "Health": [ + { + "ID": 5, + "Name": "OK" + } + ], + "Details": [ + "Completed." + ] + } + } +} + + +def get_bin_path(self, arg, required=False): + """Mock AnsibleModule.get_bin_path""" + return arg + + +def get_exception_message(ansible_exit_json): + """From an AnsibleExitJson exception, get the message string.""" + return ansible_exit_json.exception.args[0]["msg"] + + +def mock_get_request(*args, **kwargs): + """Mock for get_request.""" + url = args[1] + if url == "https://" + MOCK_BASE_URI: + return MOCK_SUCCESSFUL_HTTP_RESPONSE + elif url == "https://" + MOCK_BASE_URI + '/Jobs/' + MOCK_JOB_NAME_IN_PROGRESS: + return MOCK_HTTP_RESPONSE_JOB_IN_PROGRESS + elif url == "https://" + MOCK_BASE_URI + '/Jobs/' + MOCK_JOB_NAME_COMPLETE: + return MOCK_HTTP_RESPONSE_JOB_COMPLETE + elif url == "https://" + MOCK_BASE_URI + '/Jobs/' + MOCK_JOB_NAME_DOES_NOT_EXIST: + return MOCK_404_RESPONSE + else: + raise RuntimeError("Illegal GET call to: " + args[1]) + + +def mock_put_request(*args, **kwargs): + """Mock put_request. PUT should never happen so it will raise an error.""" + raise RuntimeError("Illegal PUT call to: " + args[1]) + + +def mock_delete_request(*args, **kwargs): + """Mock delete request. DELETE should never happen so it will raise an error.""" + raise RuntimeError("Illegal DELETE call to: " + args[1]) + + +def mock_post_request(*args, **kwargs): + """Mock post_request. POST should never happen so it will raise an error.""" + raise RuntimeError("Illegal POST call to: " + args[1]) + + +class TestOcapiInfo(unittest.TestCase): + def setUp(self): + self.mock_module_helper = patch.multiple(basic.AnsibleModule, + exit_json=exit_json, + fail_json=fail_json, + get_bin_path=get_bin_path) + self.mock_module_helper.start() + self.addCleanup(self.mock_module_helper.stop) + + def test_module_fail_when_required_args_missing(self): + with self.assertRaises(AnsibleFailJson) as ansible_fail_json: + set_module_args({}) + module.main() + self.assertIn("missing required arguments:", get_exception_message(ansible_fail_json)) + + def test_module_fail_when_unknown_category(self): + with self.assertRaises(AnsibleFailJson) as ansible_fail_json: + set_module_args({ + 'category': 'unknown', + 'command': 'JobStatus', + 'username': 'USERID', + 'password': 'PASSW0RD=21', + 'baseuri': MOCK_BASE_URI + }) + module.main() + self.assertIn("Invalid Category 'unknown", get_exception_message(ansible_fail_json)) + + def test_module_fail_when_unknown_command(self): + with self.assertRaises(AnsibleFailJson) as ansible_fail_json: + set_module_args({ + 'category': 'Jobs', + 'command': 'unknown', + 'username': 'USERID', + 'password': 'PASSW0RD=21', + 'baseuri': MOCK_BASE_URI + }) + module.main() + self.assertIn("Invalid Command 'unknown", get_exception_message(ansible_fail_json)) + + def test_job_status_in_progress(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_put_request, + delete_request=mock_delete_request, + post_request=mock_post_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Jobs', + 'command': 'JobStatus', + 'job_name': MOCK_JOB_NAME_IN_PROGRESS, + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual(ACTION_WAS_SUCCESSFUL, get_exception_message(ansible_exit_json)) + response_data = ansible_exit_json.exception.args[0] + self.assertEqual(MOCK_HTTP_RESPONSE_JOB_IN_PROGRESS["data"]["PercentComplete"], response_data["percentComplete"]) + self.assertEqual(MOCK_HTTP_RESPONSE_JOB_IN_PROGRESS["data"]["Status"]["State"]["ID"], response_data["operationStatusId"]) + self.assertEqual(MOCK_HTTP_RESPONSE_JOB_IN_PROGRESS["data"]["Status"]["State"]["Name"], response_data["operationStatus"]) + self.assertEqual(MOCK_HTTP_RESPONSE_JOB_IN_PROGRESS["data"]["Status"]["Health"][0]["Name"], response_data["operationHealth"]) + self.assertEqual(MOCK_HTTP_RESPONSE_JOB_IN_PROGRESS["data"]["Status"]["Health"][0]["ID"], response_data["operationHealthId"]) + self.assertTrue(response_data["jobExists"]) + self.assertFalse(response_data["changed"]) + self.assertEqual(ACTION_WAS_SUCCESSFUL, response_data["msg"]) + self.assertIsNone(response_data["details"]) + + def test_job_status_complete(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_put_request, + delete_request=mock_delete_request, + post_request=mock_post_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Jobs', + 'command': 'JobStatus', + 'job_name': MOCK_JOB_NAME_COMPLETE, + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual(ACTION_WAS_SUCCESSFUL, get_exception_message(ansible_exit_json)) + response_data = ansible_exit_json.exception.args[0] + self.assertEqual(MOCK_HTTP_RESPONSE_JOB_COMPLETE["data"]["PercentComplete"], response_data["percentComplete"]) + self.assertEqual(MOCK_HTTP_RESPONSE_JOB_COMPLETE["data"]["Status"]["State"]["ID"], response_data["operationStatusId"]) + self.assertEqual(MOCK_HTTP_RESPONSE_JOB_COMPLETE["data"]["Status"]["State"]["Name"], response_data["operationStatus"]) + self.assertEqual(MOCK_HTTP_RESPONSE_JOB_COMPLETE["data"]["Status"]["Health"][0]["Name"], response_data["operationHealth"]) + self.assertEqual(MOCK_HTTP_RESPONSE_JOB_COMPLETE["data"]["Status"]["Health"][0]["ID"], response_data["operationHealthId"]) + self.assertTrue(response_data["jobExists"]) + self.assertFalse(response_data["changed"]) + self.assertEqual(ACTION_WAS_SUCCESSFUL, response_data["msg"]) + self.assertEqual(["Completed."], response_data["details"]) + + def test_job_status_not_found(self): + with patch.multiple("ansible_collections.community.general.plugins.module_utils.ocapi_utils.OcapiUtils", + get_request=mock_get_request, + put_request=mock_put_request, + delete_request=mock_delete_request, + post_request=mock_post_request): + with self.assertRaises(AnsibleExitJson) as ansible_exit_json: + set_module_args({ + 'category': 'Jobs', + 'command': 'JobStatus', + 'job_name': MOCK_JOB_NAME_DOES_NOT_EXIST, + 'baseuri': MOCK_BASE_URI, + 'username': 'USERID', + 'password': 'PASSWORD=21' + }) + module.main() + self.assertEqual(ACTION_WAS_SUCCESSFUL, get_exception_message(ansible_exit_json)) + response_data = ansible_exit_json.exception.args[0] + self.assertFalse(response_data["jobExists"]) + self.assertEqual(0, response_data["percentComplete"]) + self.assertEqual(1, response_data["operationStatusId"]) + self.assertEqual("Not Available", response_data["operationStatus"]) + self.assertIsNone(response_data["operationHealth"]) + self.assertIsNone(response_data["operationHealthId"]) + self.assertFalse(response_data["changed"]) + self.assertEqual(ACTION_WAS_SUCCESSFUL, response_data["msg"]) + self.assertEqual("Job does not exist.", response_data["details"]) From afd215167230a97ad5cc01d6b983904d03e74455 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 22 Jan 2023 17:44:42 +0100 Subject: [PATCH 117/134] [PR #5732/0ca41ded backport][stable-6] Bugfix/keycloak userfed idempotency (#5874) Bugfix/keycloak userfed idempotency (#5732) * fix(modules/keycloak_user_federation): fixes ... ... federation read call not finding already existing federations properly because of bad parametrisation * fix(modules/keycloak_user_federation): added ... ... new integration test for module idempotency bugfix * added changelog fragment for pr Co-authored-by: Mirko Wilhelmi (cherry picked from commit 0ca41dedce083b34fe06faa84eb001c1d1f5a8bd) Co-authored-by: morco --- ...32-bugfix-keycloak-userfed-idempotency.yml | 6 + plugins/modules/keycloak_user_federation.py | 4 +- .../keycloak_user_federation/tasks/main.yml | 108 ++++++++++++++++++ 3 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/5732-bugfix-keycloak-userfed-idempotency.yml diff --git a/changelogs/fragments/5732-bugfix-keycloak-userfed-idempotency.yml b/changelogs/fragments/5732-bugfix-keycloak-userfed-idempotency.yml new file mode 100644 index 0000000000..c50a105c3f --- /dev/null +++ b/changelogs/fragments/5732-bugfix-keycloak-userfed-idempotency.yml @@ -0,0 +1,6 @@ +bugfixes: + - > + keycloak_user_federation - fixes idempotency detection issues. In some + cases the module could fail to properly detect already existing user + federations because of a buggy seemingly superflous extra query parameter + (https://github.com/ansible-collections/community.general/pull/5732). diff --git a/plugins/modules/keycloak_user_federation.py b/plugins/modules/keycloak_user_federation.py index 3e66c577ec..3659d757ac 100644 --- a/plugins/modules/keycloak_user_federation.py +++ b/plugins/modules/keycloak_user_federation.py @@ -24,7 +24,7 @@ description: to your needs and a user having the expected roles. - The names of module options are snake_cased versions of the camelCase ones found in the - Keycloak API and its documentation at U(https://www.keycloak.org/docs-api/15.0/rest-api/index.html). + Keycloak API and its documentation at U(https://www.keycloak.org/docs-api/20.0.2/rest-api/index.html). options: @@ -835,7 +835,7 @@ def main(): # See if it already exists in Keycloak if cid is None: - found = kc.get_components(urlencode(dict(type='org.keycloak.storage.UserStorageProvider', parent=realm, name=name)), realm) + found = kc.get_components(urlencode(dict(type='org.keycloak.storage.UserStorageProvider', name=name)), realm) if len(found) > 1: module.fail_json(msg='No ID given and found multiple user federations with name `{name}`. Cannot continue.'.format(name=name)) before_comp = next(iter(found), None) diff --git a/tests/integration/targets/keycloak_user_federation/tasks/main.yml b/tests/integration/targets/keycloak_user_federation/tasks/main.yml index 79e21dae03..139d6ee2be 100644 --- a/tests/integration/targets/keycloak_user_federation/tasks/main.yml +++ b/tests/integration/targets/keycloak_user_federation/tasks/main.yml @@ -66,6 +66,59 @@ - result.existing == {} - result.end_state.name == "{{ federation }}" +- name: Create new user federation in admin realm + community.general.keycloak_user_federation: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ admin_realm }}" + name: "{{ federation }}" + state: present + provider_id: ldap + provider_type: org.keycloak.storage.UserStorageProvider + config: + enabled: true + priority: 0 + fullSyncPeriod: -1 + changedSyncPeriod: -1 + cachePolicy: DEFAULT + batchSizeForSync: 1000 + editMode: READ_ONLY + importEnabled: true + syncRegistrations: false + vendor: other + usernameLDAPAttribute: uid + rdnLDAPAttribute: uid + uuidLDAPAttribute: entryUUID + userObjectClasses: "inetOrgPerson, organizationalPerson" + connectionUrl: "ldaps://ldap.example.com:636" + usersDn: "ou=Users,dc=example,dc=com" + authType: simple + bindDn: cn=directory reader + bindCredential: secret + searchScope: 1 + validatePasswordPolicy: false + trustEmail: false + useTruststoreSpi: "ldapsOnly" + connectionPooling: true + pagination: true + allowKerberosAuthentication: false + useKerberosForPasswordAuthentication: false + debug: false + register: result + +- name: Debug + debug: + var: result + +- name: Assert user federation created (admin realm) + assert: + that: + - result is changed + - result.existing == {} + - result.end_state.name == "{{ federation }}" + - name: Update existing user federation (no change) community.general.keycloak_user_federation: auth_keycloak_url: "{{ url }}" @@ -121,6 +174,61 @@ - result.end_state != {} - result.end_state.name == "{{ federation }}" +- name: Update existing user federation (no change, admin realm) + community.general.keycloak_user_federation: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ admin_realm }}" + name: "{{ federation }}" + state: present + provider_id: ldap + provider_type: org.keycloak.storage.UserStorageProvider + config: + enabled: true + priority: 0 + fullSyncPeriod: -1 + changedSyncPeriod: -1 + cachePolicy: DEFAULT + batchSizeForSync: 1000 + editMode: READ_ONLY + importEnabled: true + syncRegistrations: false + vendor: other + usernameLDAPAttribute: uid + rdnLDAPAttribute: uid + uuidLDAPAttribute: entryUUID + userObjectClasses: "inetOrgPerson, organizationalPerson" + connectionUrl: "ldaps://ldap.example.com:636" + usersDn: "ou=Users,dc=example,dc=com" + authType: simple + bindDn: cn=directory reader + bindCredential: "**********" + searchScope: 1 + validatePasswordPolicy: false + trustEmail: false + useTruststoreSpi: "ldapsOnly" + connectionPooling: true + pagination: true + allowKerberosAuthentication: false + useKerberosForPasswordAuthentication: false + debug: false + register: result + +- name: Debug + debug: + var: result + +- name: Assert user federation unchanged (admin realm) + assert: + that: + - result is not changed + - result.existing != {} + - result.existing.name == "{{ federation }}" + - result.end_state != {} + - result.end_state.name == "{{ federation }}" + - name: Update existing user federation (with change) community.general.keycloak_user_federation: auth_keycloak_url: "{{ url }}" From 57cd48f3cfa479f728ecd9cbdac754fe94b366d2 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 22 Jan 2023 17:44:52 +0100 Subject: [PATCH 118/134] [PR #5750/6781dd19 backport][stable-6] bugfixing keycloak user federation failing when updating default mapper simultaneously (#5876) bugfixing keycloak user federation failing when updating default mapper simultaneously (#5750) * fix(modules/keycloak_user_federation): fixes ... ... user federation creation failing when also updating/changing default mappers at the same time * add changelog fragment for pr Co-authored-by: Mirko Wilhelmi (cherry picked from commit 6781dd19183a6c9322242461c1f6a585cca717fa) Co-authored-by: morco --- ...n-update-default-mapper-simultaneously.yml | 7 ++ plugins/modules/keycloak_user_federation.py | 2 + .../keycloak_user_federation/tasks/main.yml | 88 +++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 changelogs/fragments/5750-bugfixing-keycloak-usrfed-fail-when-update-default-mapper-simultaneously.yml diff --git a/changelogs/fragments/5750-bugfixing-keycloak-usrfed-fail-when-update-default-mapper-simultaneously.yml b/changelogs/fragments/5750-bugfixing-keycloak-usrfed-fail-when-update-default-mapper-simultaneously.yml new file mode 100644 index 0000000000..93cfc3adcb --- /dev/null +++ b/changelogs/fragments/5750-bugfixing-keycloak-usrfed-fail-when-update-default-mapper-simultaneously.yml @@ -0,0 +1,7 @@ +bugfixes: + - >- + keycloak_user_federation - fixes federation creation issue. When a new + federation was created and at the same time a default / standard mapper + was also changed / updated the creation process failed as a bad None + set variable led to a bad malformed url request + (https://github.com/ansible-collections/community.general/pull/5750). diff --git a/plugins/modules/keycloak_user_federation.py b/plugins/modules/keycloak_user_federation.py index 3659d757ac..fbb31e695d 100644 --- a/plugins/modules/keycloak_user_federation.py +++ b/plugins/modules/keycloak_user_federation.py @@ -923,6 +923,8 @@ def main(): updated_mappers = desired_comp.pop('mappers', []) after_comp = kc.create_component(desired_comp, realm) + cid = after_comp['id'] + for mapper in updated_mappers: found = kc.get_components(urlencode(dict(parent=cid, name=mapper['name'])), realm) if len(found) > 1: diff --git a/tests/integration/targets/keycloak_user_federation/tasks/main.yml b/tests/integration/targets/keycloak_user_federation/tasks/main.yml index 139d6ee2be..ae0b4bf162 100644 --- a/tests/integration/targets/keycloak_user_federation/tasks/main.yml +++ b/tests/integration/targets/keycloak_user_federation/tasks/main.yml @@ -270,6 +270,14 @@ useKerberosForPasswordAuthentication: false debug: false mappers: + # overwrite / update pre existing default mapper + - name: "username" + providerId: "user-attribute-ldap-mapper" + config: + ldap.attribute: ldap_user + user.model.attribute: usr + read.only: true + # create new mapper - name: "full name" providerId: "full-name-ldap-mapper" providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" @@ -335,3 +343,83 @@ - result is not changed - result.existing == {} - result.end_state == {} + +- name: Create new user federation together with mappers + community.general.keycloak_user_federation: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + name: "{{ federation }}" + state: present + provider_id: ldap + provider_type: org.keycloak.storage.UserStorageProvider + config: + enabled: true + priority: 0 + fullSyncPeriod: -1 + changedSyncPeriod: -1 + cachePolicy: DEFAULT + batchSizeForSync: 1000 + editMode: READ_ONLY + importEnabled: true + syncRegistrations: false + vendor: other + usernameLDAPAttribute: uid + rdnLDAPAttribute: uid + uuidLDAPAttribute: entryUUID + userObjectClasses: "inetOrgPerson, organizationalPerson" + connectionUrl: "ldaps://ldap.example.com:636" + usersDn: "ou=Users,dc=example,dc=com" + authType: simple + bindDn: cn=directory reader + bindCredential: secret + searchScope: 1 + validatePasswordPolicy: false + trustEmail: false + useTruststoreSpi: "ldapsOnly" + connectionPooling: true + pagination: true + allowKerberosAuthentication: false + useKerberosForPasswordAuthentication: false + debug: false + mappers: + # overwrite / update pre existing default mapper + - name: "username" + providerId: "user-attribute-ldap-mapper" + config: + ldap.attribute: ldap_user + user.model.attribute: usr + read.only: true + # create new mapper + - name: "full name" + providerId: "full-name-ldap-mapper" + providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" + config: + ldap.full.name.attribute: cn + read.only: true + write.only: false + register: result + +- name: Debug + debug: + var: result + +- name: Assert user federation created + assert: + that: + - result is changed + - result.existing == {} + - result.end_state.name == "{{ federation }}" + +## no point in retesting this, just doing it to clean up introduced server changes +- name: Delete absent user federation + community.general.keycloak_user_federation: + auth_keycloak_url: "{{ url }}" + auth_realm: "{{ admin_realm }}" + auth_username: "{{ admin_user }}" + auth_password: "{{ admin_password }}" + realm: "{{ realm }}" + name: "{{ federation }}" + state: absent From 0729f0c2622cef46e20c0730b59037b461a69450 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 22 Jan 2023 17:46:44 +0100 Subject: [PATCH 119/134] [PR #5811/bf117c83 backport][stable-6] Clarify Error message when bitwarden vault not unlocked (#5878) Clarify Error message when bitwarden vault not unlocked (#5811) * Clarify Error message when vault not unlocked You can be logged into the Bitwarden-CLI, but it can still be locked. This took me several hours to debug, since every time I ran 'bw login' it told me, that I am already logged in. If you run 'bw unlock' without being logged in, you are prompted to log in. This clarifies the Error occurring and can drastically reduce debugging time, since you don't have to look into the source code to get an understanding of whats wrong. * RM: negation Nobody needs negation * Update function name * FIX: tests * ADD: changelog * Update changelogs/fragments/5811-clarify-bitwarden-error.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit bf117c839cdfbf5d6fd398df6750b53c71f8e16b) Co-authored-by: Christoph <29735603+Chr1s70ph@users.noreply.github.com> --- changelogs/fragments/5811-clarify-bitwarden-error.yml | 2 ++ plugins/lookup/bitwarden.py | 6 +++--- tests/unit/plugins/lookup/test_bitwarden.py | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/5811-clarify-bitwarden-error.yml diff --git a/changelogs/fragments/5811-clarify-bitwarden-error.yml b/changelogs/fragments/5811-clarify-bitwarden-error.yml new file mode 100644 index 0000000000..343faba478 --- /dev/null +++ b/changelogs/fragments/5811-clarify-bitwarden-error.yml @@ -0,0 +1,2 @@ +minor_changes: + - bitwarden lookup plugin - clarify what to do, if the bitwarden vault is not unlocked (https://github.com/ansible-collections/community.general/pull/5811). diff --git a/plugins/lookup/bitwarden.py b/plugins/lookup/bitwarden.py index dbcb88d456..344f960b0a 100644 --- a/plugins/lookup/bitwarden.py +++ b/plugins/lookup/bitwarden.py @@ -83,7 +83,7 @@ class Bitwarden(object): return self._cli_path @property - def logged_in(self): + def unlocked(self): out, err = self._run(['status'], stdin="") decoded = AnsibleJSONDecoder().raw_decode(out)[0] return decoded['status'] == 'unlocked' @@ -135,8 +135,8 @@ class LookupModule(LookupBase): self.set_options(var_options=variables, direct=kwargs) field = self.get_option('field') search_field = self.get_option('search') - if not _bitwarden.logged_in: - raise AnsibleError("Not logged into Bitwarden. Run 'bw login'.") + if not _bitwarden.unlocked: + raise AnsibleError("Bitwarden Vault locked. Run 'bw unlock'.") return [_bitwarden.get_field(field, term, search_field) for term in terms] diff --git a/tests/unit/plugins/lookup/test_bitwarden.py b/tests/unit/plugins/lookup/test_bitwarden.py index 7f86c39697..90f3ff7751 100644 --- a/tests/unit/plugins/lookup/test_bitwarden.py +++ b/tests/unit/plugins/lookup/test_bitwarden.py @@ -111,7 +111,7 @@ MOCK_RECORDS = [ class MockBitwarden(Bitwarden): - logged_in = True + unlocked = True def _get_matches(self, search_value, search_field="name"): return list(filter(lambda record: record[search_field] == search_value, MOCK_RECORDS)) @@ -119,7 +119,7 @@ class MockBitwarden(Bitwarden): class LoggedOutMockBitwarden(MockBitwarden): - logged_in = False + unlocked = False class TestLookupModule(unittest.TestCase): @@ -155,7 +155,7 @@ class TestLookupModule(unittest.TestCase): self.lookup.run(['a_test'])[0]) @patch('ansible_collections.community.general.plugins.lookup.bitwarden._bitwarden', LoggedOutMockBitwarden()) - def test_bitwarden_plugin_logged_out(self): + def test_bitwarden_plugin_unlocked(self): record = MOCK_RECORDS[0] record_name = record['name'] with self.assertRaises(AnsibleError): From ee07d8320a2ab89bda20eb42cb4315c3a5a3f715 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 22 Jan 2023 18:16:53 +0100 Subject: [PATCH 120/134] [PR #5868/098912c2 backport][stable-6] stormssh tests: do not install newer cryptography (#5872) stormssh tests: do not install newer cryptography (#5868) Do not install newer cryptography. ci_complete (cherry picked from commit 098912c2293febb91cfca14631784ccb72c4b774) Co-authored-by: Felix Fontein --- tests/integration/targets/ssh_config/tasks/main.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/integration/targets/ssh_config/tasks/main.yml b/tests/integration/targets/ssh_config/tasks/main.yml index ce57493b84..d0b088302c 100644 --- a/tests/integration/targets/ssh_config/tasks/main.yml +++ b/tests/integration/targets/ssh_config/tasks/main.yml @@ -5,7 +5,9 @@ - name: Install required libs pip: - name: stormssh + name: + - stormssh + - 'paramiko<3.0.0' state: present extra_args: "-c {{ remote_constraints }}" From 54099d77ff0a26087b19055cd507224f1d792e44 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 23 Jan 2023 23:16:01 +0100 Subject: [PATCH 121/134] [PR #5803/f38bfadd backport][stable-6] Bugfix: proxmox_disk - read time out on import (#5881) Bugfix: proxmox_disk - read time out on import (#5803) * Use async calls and fix docs * Add changelog fragment (cherry picked from commit f38bfaddf0d9cb63e028a4bc14d732bc35039492) Co-authored-by: castorsky --- .../fragments/5803-proxmox-read-timeout.yml | 2 + plugins/modules/proxmox_disk.py | 61 ++++++++++++------- 2 files changed, 41 insertions(+), 22 deletions(-) create mode 100644 changelogs/fragments/5803-proxmox-read-timeout.yml diff --git a/changelogs/fragments/5803-proxmox-read-timeout.yml b/changelogs/fragments/5803-proxmox-read-timeout.yml new file mode 100644 index 0000000000..fc29605e4f --- /dev/null +++ b/changelogs/fragments/5803-proxmox-read-timeout.yml @@ -0,0 +1,2 @@ +bugfixes: + - proxmox_disk - fixed issue with read timeout on import action (https://github.com/ansible-collections/community.general/pull/5803). diff --git a/plugins/modules/proxmox_disk.py b/plugins/modules/proxmox_disk.py index 8a81f18a3f..8292b1de50 100644 --- a/plugins/modules/proxmox_disk.py +++ b/plugins/modules/proxmox_disk.py @@ -104,6 +104,7 @@ options: - Move the disk to this storage when I(state=moved). - You can move between storages only in scope of one VM. - Mutually exclusive with I(target_vmid). + - Consider increasing I(timeout) in case of large disk images or slow storage backend. type: str target_vmid: description: @@ -113,8 +114,8 @@ options: type: int timeout: description: - - Timeout in seconds to wait when moving disk. - - Used only when I(state=moved). + - Timeout in seconds to wait for slow operations such as importing disk or moving disk between storages. + - Used only when I(state) is C(present) or C(moved). type: int default: 600 aio: @@ -172,6 +173,7 @@ options: - C(:/) or C(/) - Attention! Only root can use absolute paths. - This parameter is mutually exclusive with I(size). + - Increase I(timeout) parameter when importing large disk images or using slow storage. type: str iops: description: @@ -471,6 +473,16 @@ class ProxmoxDiskAnsible(ProxmoxAnsible): params.update(dict((k, int(v)) for k, v in params.items() if isinstance(v, bool))) return params + def wait_till_complete_or_timeout(self, node_name, task_id): + timeout = self.module.params['timeout'] + while timeout: + if self.api_task_ok(node_name, task_id): + return True + timeout -= 1 + if timeout <= 0: + return False + sleep(1) + def create_disk(self, disk, vmid, vm, vm_config): create = self.module.params['create'] if create == 'disabled' and disk not in vm_config: @@ -484,20 +496,23 @@ class ProxmoxDiskAnsible(ProxmoxAnsible): if import_string: config_str = "%s:%s,import-from=%s" % (self.module.params["storage"], "0", import_string) + timeout_str = "Reached timeout while importing VM disk. Last line in task before timeout: %s" + ok_str = "Disk %s imported into VM %s" else: config_str = "%s:%s" % (self.module.params["storage"], self.module.params["size"]) + ok_str = "Disk %s created in VM %s" + timeout_str = "Reached timeout while creating VM disk. Last line in task before timeout: %s" for k, v in attributes.items(): config_str += ',%s=%s' % (k, v) - create_disk = {self.module.params["disk"]: config_str} - self.proxmox_api.nodes(vm['node']).qemu(vmid).config.set(**create_disk) - return True, "Disk %s created in VM %s" % (disk, vmid) + disk_config_to_apply = {self.module.params["disk"]: config_str} if create in ['disabled', 'regular'] and disk in vm_config: # UPDATE disk_config = disk_conf_str_to_dict(vm_config[disk]) config_str = disk_config["volume"] + ok_str = "Disk %s updated in VM %s" attributes = self.get_create_attributes() # 'import_from' fails on disk updates attributes.pop('import_from', None) @@ -513,9 +528,16 @@ class ProxmoxDiskAnsible(ProxmoxAnsible): if disk_config == attributes: return False, "Disk %s is up to date in VM %s" % (disk, vmid) - update_disk = {self.module.params["disk"]: config_str} - self.proxmox_api.nodes(vm['node']).qemu(vmid).config.set(**update_disk) - return True, "Disk %s updated in VM %s" % (disk, vmid) + disk_config_to_apply = {self.module.params["disk"]: config_str} + + current_task_id = self.proxmox_api.nodes(vm['node']).qemu(vmid).config.post(**disk_config_to_apply) + task_success = self.wait_till_complete_or_timeout(vm['node'], current_task_id) + if task_success: + return True, ok_str % (disk, vmid) + else: + self.module.fail_json( + msg=timeout_str % self.proxmox_api.nodes(vm['node']).tasks(current_task_id).log.get()[:1] + ) def move_disk(self, disk, vmid, vm, vm_config): params = dict() @@ -535,20 +557,15 @@ class ProxmoxDiskAnsible(ProxmoxAnsible): if params['storage'] == disk_config['storage_name']: return False - taskid = self.proxmox_api.nodes(vm['node']).qemu(vmid).move_disk.post(**params) - timeout = self.module.params['timeout'] - while timeout: - status_data = self.proxmox_api.nodes(vm['node']).tasks(taskid).status.get() - if status_data['status'] == 'stopped' and status_data['exitstatus'] == 'OK': - return True - if timeout <= 0: - self.module.fail_json( - msg='Reached timeout while waiting for moving VM disk. Last line in task before timeout: %s' % - self.proxmox_api.nodes(vm['node']).tasks(taskid).log.get()[:1]) - - sleep(1) - timeout -= 1 - return True + task_id = self.proxmox_api.nodes(vm['node']).qemu(vmid).move_disk.post(**params) + task_success = self.wait_till_complete_or_timeout(vm['node'], task_id) + if task_success: + return True + else: + self.module.fail_json( + msg='Reached timeout while waiting for moving VM disk. Last line in task before timeout: %s' % + self.proxmox_api.nodes(vm['node']).tasks(task_id).log.get()[:1] + ) def main(): From c7f7bd60508b40d6de7ffa3bcf4f5ee789d955ef Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 24 Jan 2023 20:06:16 +0100 Subject: [PATCH 122/134] [PR #5822/fe520a6b backport][stable-6] Gem: Support force flag when uninstalling (#5884) Gem: Support force flag when uninstalling (#5822) * Gem: Support force flag when uninstalling * Improve docs' syntax * Add changelog fragment (cherry picked from commit fe520a6b09aeab283f1477556b49cb64386a8e10) Co-authored-by: Juan Vela --- changelogs/fragments/5822-gem-uninstall-force.yml | 2 ++ plugins/modules/gem.py | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5822-gem-uninstall-force.yml diff --git a/changelogs/fragments/5822-gem-uninstall-force.yml b/changelogs/fragments/5822-gem-uninstall-force.yml new file mode 100644 index 0000000000..7b8a0efbda --- /dev/null +++ b/changelogs/fragments/5822-gem-uninstall-force.yml @@ -0,0 +1,2 @@ +bugfixes: + - gem - fix force parameter not being passed to gem command when uninstalling (https://github.com/ansible-collections/community.general/pull/5822). diff --git a/plugins/modules/gem.py b/plugins/modules/gem.py index 21e9efea58..a44683c786 100644 --- a/plugins/modules/gem.py +++ b/plugins/modules/gem.py @@ -105,7 +105,7 @@ options: required: false force: description: - - Force gem to install, bypassing dependency checks. + - Force gem to (un-)install, bypassing dependency checks. required: false default: false type: bool @@ -235,6 +235,8 @@ def uninstall(module): else: cmd.append('--all') cmd.append('--executable') + if module.params['force']: + cmd.append('--force') cmd.append(module.params['name']) module.run_command(cmd, environ_update=environ, check_rc=True) From a146eb3118dbc0cad3361a0fac00921c0bbac264 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 26 Jan 2023 06:23:51 +0100 Subject: [PATCH 123/134] [PR #5888/855cbd67 backport][stable-6] Update gitlab_deploy_key.py (#5896) Update gitlab_deploy_key.py (#5888) * Update gitlab_deploy_key.py Change key title on key update * Create 5888-update-key-title Add changelog fragment for key title change * Update changelogs/fragments/5888-update-key-title Co-authored-by: Felix Fontein * Rename 5888-update-key-title to 5888-update-key-title.yml Co-authored-by: Felix Fontein (cherry picked from commit 855cbd67aed46e9cae30fda61535fa21183a40bb) Co-authored-by: lapete --- changelogs/fragments/5888-update-key-title.yml | 2 ++ plugins/modules/gitlab_deploy_key.py | 1 + 2 files changed, 3 insertions(+) create mode 100644 changelogs/fragments/5888-update-key-title.yml diff --git a/changelogs/fragments/5888-update-key-title.yml b/changelogs/fragments/5888-update-key-title.yml new file mode 100644 index 0000000000..e620ad3d79 --- /dev/null +++ b/changelogs/fragments/5888-update-key-title.yml @@ -0,0 +1,2 @@ +minor_changes: + - gitlab_deploy_key - also update ``title`` and not just ``can_push`` (https://github.com/ansible-collections/community.general/pull/5888). diff --git a/plugins/modules/gitlab_deploy_key.py b/plugins/modules/gitlab_deploy_key.py index 3ed2b2d7a5..f4a9fb29fa 100644 --- a/plugins/modules/gitlab_deploy_key.py +++ b/plugins/modules/gitlab_deploy_key.py @@ -151,6 +151,7 @@ class GitLabDeployKey(object): changed = True else: changed, deploy_key = self.update_deploy_key(self.deploy_key_object, { + 'title': key_title, 'can_push': options['can_push']}) self.deploy_key_object = deploy_key From 9d99ccef2d62bba8b59735c813fa11f9e7818757 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 28 Jan 2023 11:52:14 +0100 Subject: [PATCH 124/134] [PR #5851/7b8b73f1 backport][stable-6] Add support to Bitwarden Lookup for filtering results by collection (#5849) (#5904) Add support to Bitwarden Lookup for filtering results by collection (#5849) (#5851) * Add support to Bitwarden Lookup for filtering results by collection id (#5849) * Debug * Add support to Bitwarden Lookup for filtering results by collection id (#5849) * Update comments * Fix blank line issue * Fix unit tests for bitwarden lookup plugin. Add changelog fragment file. * Change collectionId to collection_id parameter on bitwarden plugin * Fix collection id parameter name when used in bw cli (cherry picked from commit 7b8b73f17faee9f76b9cd62b770b277a5e752905) Co-authored-by: Piotr --- ...-add-filter-by-collection-id-parameter.yml | 2 ++ plugins/lookup/bitwarden.py | 32 +++++++++++++++---- tests/unit/plugins/lookup/test_bitwarden.py | 2 +- 3 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 changelogs/fragments/5851-lookup-bitwarden-add-filter-by-collection-id-parameter.yml diff --git a/changelogs/fragments/5851-lookup-bitwarden-add-filter-by-collection-id-parameter.yml b/changelogs/fragments/5851-lookup-bitwarden-add-filter-by-collection-id-parameter.yml new file mode 100644 index 0000000000..28b878a5b0 --- /dev/null +++ b/changelogs/fragments/5851-lookup-bitwarden-add-filter-by-collection-id-parameter.yml @@ -0,0 +1,2 @@ +minor_changes: + - bitwarden lookup plugin - implement filtering results by ``collection_id`` parameter (https://github.com/ansible-collections/community.general/issues/5849). \ No newline at end of file diff --git a/plugins/lookup/bitwarden.py b/plugins/lookup/bitwarden.py index 344f960b0a..389fa475bd 100644 --- a/plugins/lookup/bitwarden.py +++ b/plugins/lookup/bitwarden.py @@ -28,8 +28,12 @@ DOCUMENTATION = """ default: name version_added: 5.7.0 field: - description: Field to fetch; leave unset to fetch whole response. + description: Field to fetch. Leave unset to fetch whole response. type: str + collection_id: + description: Collection ID to filter results by collection. Leave unset to skip filtering. + type: str + version_added: 6.3.0 """ EXAMPLES = """ @@ -43,6 +47,11 @@ EXAMPLES = """ msg: >- {{ lookup('community.general.bitwarden', 'bafba515-af11-47e6-abe3-af1200cd18b2', search='id', field='password') }} +- name: "Get 'password' from Bitwarden record named 'a_test' from collection" + ansible.builtin.debug: + msg: >- + {{ lookup('community.general.bitwarden', 'a_test', field='password', collection_id='bafba515-af11-47e6-abe3-af1200cd18b2') }} + - name: "Get full Bitwarden record named 'a_test'" ansible.builtin.debug: msg: >- @@ -96,10 +105,17 @@ class Bitwarden(object): raise BitwardenException(err) return to_text(out, errors='surrogate_or_strict'), to_text(err, errors='surrogate_or_strict') - def _get_matches(self, search_value, search_field): + def _get_matches(self, search_value, search_field, collection_id): """Return matching records whose search_field is equal to key. """ - out, err = self._run(['list', 'items', '--search', search_value]) + + # Prepare set of params for Bitwarden CLI + params = ['list', 'items', '--search', search_value] + + if collection_id: + params.extend(['--collectionid', collection_id]) + + out, err = self._run(params) # This includes things that matched in different fields. initial_matches = AnsibleJSONDecoder().raw_decode(out)[0] @@ -107,12 +123,13 @@ class Bitwarden(object): # Filter to only include results from the right field. return [item for item in initial_matches if item[search_field] == search_value] - def get_field(self, field, search_value, search_field="name"): - """Return a list of the specified field for records whose search_field match search_value. + def get_field(self, field, search_value, search_field="name", collection_id=None): + """Return a list of the specified field for records whose search_field match search_value + and filtered by collection if collection has been provided. If field is None, return the whole record for each match. """ - matches = self._get_matches(search_value, search_field) + matches = self._get_matches(search_value, search_field, collection_id) if field in ['autofillOnPageLoad', 'password', 'passwordRevisionDate', 'totp', 'uris', 'username']: return [match['login'][field] for match in matches] @@ -135,10 +152,11 @@ class LookupModule(LookupBase): self.set_options(var_options=variables, direct=kwargs) field = self.get_option('field') search_field = self.get_option('search') + collection_id = self.get_option('collection_id') if not _bitwarden.unlocked: raise AnsibleError("Bitwarden Vault locked. Run 'bw unlock'.") - return [_bitwarden.get_field(field, term, search_field) for term in terms] + return [_bitwarden.get_field(field, term, search_field, collection_id) for term in terms] _bitwarden = Bitwarden() diff --git a/tests/unit/plugins/lookup/test_bitwarden.py b/tests/unit/plugins/lookup/test_bitwarden.py index 90f3ff7751..ac0242737e 100644 --- a/tests/unit/plugins/lookup/test_bitwarden.py +++ b/tests/unit/plugins/lookup/test_bitwarden.py @@ -113,7 +113,7 @@ class MockBitwarden(Bitwarden): unlocked = True - def _get_matches(self, search_value, search_field="name"): + def _get_matches(self, search_value, search_field="name", collection_id=None): return list(filter(lambda record: record[search_field] == search_value, MOCK_RECORDS)) From 99336ba5fe9a5369b716d1d7a5ba932c435180f4 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 28 Jan 2023 11:52:27 +0100 Subject: [PATCH 125/134] [PR #5812/8818a6f2 backport][stable-6] OpenNebula/one_vm implement the one.vm.updateconf API call (#5905) OpenNebula/one_vm implement the one.vm.updateconf API call (#5812) * opennebula: Add template manipulation helpers * one_vm: Use 'updateconf' API call to modify running VMs * one_vm: Emulate 'updateconf' API call for newly created VMs * opennebula/one_vm: Satisfy linter checks * opennebula/one_vm: Apply suggestions from code review Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> * opennebula/one_vm: Drop 'extend' function, use 'dict_merge' instead * Add changelog fragment * one_vm: Refactor 'parse_updateconf' function * opennebula/one_vm: Apply suggestions from code review Co-authored-by: Felix Fontein * one_vm: Allow for using updateconf in all scenarios --------- Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> Co-authored-by: Felix Fontein (cherry picked from commit 8818a6f2421d50980229db464a710a84e4748eff) Co-authored-by: Michal Opala --- .../5812-implement-updateconf-api-call.yml | 2 + plugins/module_utils/opennebula.py | 30 ++ plugins/modules/one_vm.py | 259 ++++++++++++------ .../plugins/module_utils/test_opennebula.py | 91 ++++++ tests/unit/plugins/modules/test_one_vm.py | 62 +++++ 5 files changed, 364 insertions(+), 80 deletions(-) create mode 100644 changelogs/fragments/5812-implement-updateconf-api-call.yml create mode 100644 tests/unit/plugins/module_utils/test_opennebula.py create mode 100644 tests/unit/plugins/modules/test_one_vm.py diff --git a/changelogs/fragments/5812-implement-updateconf-api-call.yml b/changelogs/fragments/5812-implement-updateconf-api-call.yml new file mode 100644 index 0000000000..09058f044e --- /dev/null +++ b/changelogs/fragments/5812-implement-updateconf-api-call.yml @@ -0,0 +1,2 @@ +minor_changes: + - one_vm - add a new ``updateconf`` option which implements the ``one.vm.updateconf`` API call (https://github.com/ansible-collections/community.general/pull/5812). diff --git a/plugins/module_utils/opennebula.py b/plugins/module_utils/opennebula.py index b27ec229bf..0fe649ba5c 100644 --- a/plugins/module_utils/opennebula.py +++ b/plugins/module_utils/opennebula.py @@ -26,6 +26,36 @@ except ImportError: HAS_PYONE = False +# A helper function to mitigate https://github.com/OpenNebula/one/issues/6064. +# It allows for easily handling lists like "NIC" or "DISK" in the JSON-like template representation. +# There are either lists of dictionaries (length > 1) or just dictionaries. +def flatten(to_flatten, extract=False): + """Flattens nested lists (with optional value extraction).""" + def recurse(to_flatten): + return sum(map(recurse, to_flatten), []) if isinstance(to_flatten, list) else [to_flatten] + value = recurse(to_flatten) + if extract and len(value) == 1: + return value[0] + return value + + +# A helper function to mitigate https://github.com/OpenNebula/one/issues/6064. +# It renders JSON-like template representation into OpenNebula's template syntax (string). +def render(to_render): + """Converts dictionary to OpenNebula template.""" + def recurse(to_render): + for key, value in sorted(to_render.items()): + if isinstance(value, dict): + yield '{0:}=[{1:}]'.format(key, ','.join(recurse(value))) + continue + if isinstance(value, list): + for item in value: + yield '{0:}=[{1:}]'.format(key, ','.join(recurse(item))) + continue + yield '{0:}="{1:}"'.format(key, value) + return '\n'.join(recurse(to_render)) + + class OpenNebulaModule: """ Base class for all OpenNebula Ansible Modules. diff --git a/plugins/modules/one_vm.py b/plugins/modules/one_vm.py index 7122907d38..3724d9433d 100644 --- a/plugins/modules/one_vm.py +++ b/plugins/modules/one_vm.py @@ -196,6 +196,13 @@ options: - Name of Datastore to use to create a new instace version_added: '0.2.0' type: str + updateconf: + description: + - When I(instance_ids) is provided, updates running VMs with the C(updateconf) API call. + - When new VMs are being created, emulates the C(updateconf) API call via direct template merge. + - Allows for complete modifications of the C(CONTEXT) attribute. + type: dict + version_added: 6.3.0 author: - "Milan Ilic (@ilicmilan)" - "Jan Meerkamp (@meerkampdvv)" @@ -403,6 +410,30 @@ EXAMPLES = ''' disk_saveas: name: bar-image disk_id: 1 + +- name: "Deploy 2 new instances with a custom 'start script'" + community.general.one_vm: + template_name: app_template + count: 2 + updateconf: + CONTEXT: + START_SCRIPT: ip r r 169.254.16.86/32 dev eth0 + +- name: "Add a custom 'start script' to a running VM" + community.general.one_vm: + instance_ids: 351 + updateconf: + CONTEXT: + START_SCRIPT: ip r r 169.254.16.86/32 dev eth0 + +- name: "Update SSH public keys inside the VM's context" + community.general.one_vm: + instance_ids: 351 + updateconf: + CONTEXT: + SSH_PUBLIC_KEY: |- + ssh-rsa ... + ssh-ed25519 ... ''' RETURN = ''' @@ -510,6 +541,17 @@ instances: "TE_GALAXY": "bar", "USER_INPUTS": null } + updateconf: + description: A dictionary of key/values attributes that are set with the updateconf API call. + type: dict + version_added: 6.3.0 + sample: { + "OS": { "ARCH": "x86_64" }, + "CONTEXT": { + "START_SCRIPT": "ip r r 169.254.16.86/32 dev eth0", + "SSH_PUBLIC_KEY": "ssh-rsa ...\\nssh-ed25519 ..." + } + } tagged_instances: description: - A list of instances info based on a specific attributes and/or @@ -615,6 +657,17 @@ tagged_instances: "TE_GALAXY": "bar", "USER_INPUTS": null } + updateconf: + description: A dictionary of key/values attributes that are set with the updateconf API call + type: dict + version_added: 6.3.0 + sample: { + "OS": { "ARCH": "x86_64" }, + "CONTEXT": { + "START_SCRIPT": "ip r r 169.254.16.86/32 dev eth0", + "SSH_PUBLIC_KEY": "ssh-rsa ...\\nssh-ed25519 ..." + } + } ''' try: @@ -623,9 +676,52 @@ try: except ImportError: HAS_PYONE = False -from ansible.module_utils.basic import AnsibleModule + import os +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.common.dict_transformations import dict_merge + +from ansible_collections.community.general.plugins.module_utils.opennebula import flatten, render + + +UPDATECONF_ATTRIBUTES = { + "OS": ["ARCH", "MACHINE", "KERNEL", "INITRD", "BOOTLOADER", "BOOT", "SD_DISK_BUS", "UUID"], + "FEATURES": ["ACPI", "PAE", "APIC", "LOCALTIME", "HYPERV", "GUEST_AGENT"], + "INPUT": ["TYPE", "BUS"], + "GRAPHICS": ["TYPE", "LISTEN", "PASSWD", "KEYMAP"], + "RAW": ["DATA", "DATA_VMX", "TYPE"], + "CONTEXT": [], +} + + +def check_updateconf(module, to_check): + '''Checks if attributes are compatible with one.vm.updateconf API call.''' + for attr, subattributes in to_check.items(): + if attr not in UPDATECONF_ATTRIBUTES: + module.fail_json(msg="'{0:}' is not a valid VM attribute.".format(attr)) + if not UPDATECONF_ATTRIBUTES[attr]: + continue + for subattr in subattributes: + if subattr not in UPDATECONF_ATTRIBUTES[attr]: + module.fail_json(msg="'{0:}' is not a valid VM subattribute of '{1:}'".format(subattr, attr)) + + +def parse_updateconf(vm_template): + '''Extracts 'updateconf' attributes from a VM template.''' + updateconf = {} + for attr, subattributes in vm_template.items(): + if attr not in UPDATECONF_ATTRIBUTES: + continue + tmp = {} + for subattr, value in subattributes.items(): + if UPDATECONF_ATTRIBUTES[attr] and subattr not in UPDATECONF_ATTRIBUTES[attr]: + continue + tmp[subattr] = value + if tmp: + updateconf[attr] = tmp + return updateconf + def get_template(module, client, predicate): @@ -767,6 +863,8 @@ def get_vm_info(client, vm): vm_labels, vm_attributes = get_vm_labels_and_attributes_dict(client, vm.ID) + updateconf = parse_updateconf(vm.TEMPLATE) + info = { 'template_id': int(vm.TEMPLATE['TEMPLATE_ID']), 'vm_id': vm.ID, @@ -785,7 +883,8 @@ def get_vm_info(client, vm): 'uptime_h': int(vm_uptime), 'attributes': vm_attributes, 'mode': permissions_str, - 'labels': vm_labels + 'labels': vm_labels, + 'updateconf': updateconf, } return info @@ -844,6 +943,28 @@ def set_vm_ownership(module, client, vms, owner_id, group_id): return changed +def update_vm(module, client, vm, updateconf_dict): + changed = False + if not updateconf_dict: + return changed + + before = client.vm.info(vm.ID).TEMPLATE + + client.vm.updateconf(vm.ID, render(updateconf_dict), 1) # 1: Merge new template with the existing one. + + after = client.vm.info(vm.ID).TEMPLATE + + changed = before != after + return changed + + +def update_vms(module, client, vms, *args): + changed = False + for vm in vms: + changed = update_vm(module, client, vm, *args) or changed + return changed + + def get_size_in_MB(module, size_str): SYMBOLS = ['B', 'KB', 'MB', 'GB', 'TB'] @@ -871,81 +992,46 @@ def get_size_in_MB(module, size_str): return size_in_MB -def create_disk_str(module, client, template_id, disk_size_list): - - if not disk_size_list: - return '' - - template = client.template.info(template_id) - if isinstance(template.TEMPLATE['DISK'], list): - # check if the number of disks is correct - if len(template.TEMPLATE['DISK']) != len(disk_size_list): - module.fail_json(msg='This template has ' + str(len(template.TEMPLATE['DISK'])) + ' disks but you defined ' + str(len(disk_size_list))) - result = '' - index = 0 - for DISKS in template.TEMPLATE['DISK']: - disk = {} - diskresult = '' - # Get all info about existed disk e.g. IMAGE_ID,... - for key, value in DISKS.items(): - disk[key] = value - # copy disk attributes if it is not the size attribute - diskresult += 'DISK = [' + ','.join('{key}="{val}"'.format(key=key, val=val) for key, val in disk.items() if key != 'SIZE') - # Set the Disk Size - diskresult += ', SIZE=' + str(int(get_size_in_MB(module, disk_size_list[index]))) + ']\n' - result += diskresult - index += 1 - else: - if len(disk_size_list) > 1: - module.fail_json(msg='This template has one disk but you defined ' + str(len(disk_size_list))) - disk = {} - # Get all info about existed disk e.g. IMAGE_ID,... - for key, value in template.TEMPLATE['DISK'].items(): - disk[key] = value - # copy disk attributes if it is not the size attribute - result = 'DISK = [' + ','.join('{key}="{val}"'.format(key=key, val=val) for key, val in disk.items() if key != 'SIZE') - # Set the Disk Size - result += ', SIZE=' + str(int(get_size_in_MB(module, disk_size_list[0]))) + ']\n' - - return result - - -def create_attributes_str(attributes_dict, labels_list): - - attributes_str = '' - - if labels_list: - attributes_str += 'LABELS="' + ','.join('{label}'.format(label=label) for label in labels_list) + '"\n' - if attributes_dict: - attributes_str += '\n'.join('{key}="{val}"'.format(key=key.upper(), val=val) for key, val in attributes_dict.items()) + '\n' - - return attributes_str - - -def create_nics_str(network_attrs_list): - nics_str = '' - - for network in network_attrs_list: - # Packing key-value dict in string with format key="value", key="value" - network_str = ','.join('{key}="{val}"'.format(key=key, val=val) for key, val in network.items()) - nics_str = nics_str + 'NIC = [' + network_str + ']\n' - - return nics_str - - -def create_vm(module, client, template_id, attributes_dict, labels_list, disk_size, network_attrs_list, vm_start_on_hold, vm_persistent): - +def create_vm(module, client, template_id, attributes_dict, labels_list, disk_size, network_attrs_list, vm_start_on_hold, vm_persistent, updateconf_dict): if attributes_dict: vm_name = attributes_dict.get('NAME', '') - disk_str = create_disk_str(module, client, template_id, disk_size) - vm_extra_template_str = create_attributes_str(attributes_dict, labels_list) + create_nics_str(network_attrs_list) + disk_str + template = client.template.info(template_id).TEMPLATE + + disk_count = len(flatten(template.get('DISK', []))) + if disk_size: + size_count = len(flatten(disk_size)) + # check if the number of disks is correct + if disk_count != size_count: + module.fail_json(msg='This template has ' + str(disk_count) + ' disks but you defined ' + str(size_count)) + + vm_extra_template = dict_merge(template or {}, attributes_dict or {}) + vm_extra_template = dict_merge(vm_extra_template, { + 'LABELS': ','.join(labels_list), + 'NIC': flatten(network_attrs_list, extract=True), + 'DISK': flatten([ + disk if not size else dict_merge(disk, { + 'SIZE': str(int(get_size_in_MB(module, size))), + }) + for disk, size in zip( + flatten(template.get('DISK', [])), + flatten(disk_size or [None] * disk_count), + ) + if disk is not None + ], extract=True) + }) + vm_extra_template = dict_merge(vm_extra_template, updateconf_dict or {}) + try: - vm_id = client.template.instantiate(template_id, vm_name, vm_start_on_hold, vm_extra_template_str, vm_persistent) + vm_id = client.template.instantiate(template_id, + vm_name, + vm_start_on_hold, + render(vm_extra_template), + vm_persistent) except pyone.OneException as e: module.fail_json(msg=str(e)) - vm = get_vm_by_id(client, vm_id) + vm = get_vm_by_id(client, vm_id) return get_vm_info(client, vm) @@ -1028,8 +1114,10 @@ def get_all_vms_by_attributes(client, attributes_dict, labels_list): return vm_list -def create_count_of_vms( - module, client, template_id, count, attributes_dict, labels_list, disk_size, network_attrs_list, wait, wait_timeout, vm_start_on_hold, vm_persistent): +def create_count_of_vms(module, client, + template_id, count, + attributes_dict, labels_list, disk_size, network_attrs_list, + wait, wait_timeout, vm_start_on_hold, vm_persistent, updateconf_dict): new_vms_list = [] vm_name = '' @@ -1058,7 +1146,9 @@ def create_count_of_vms( new_vm_name += next_index # Update NAME value in the attributes in case there is index attributes_dict['NAME'] = new_vm_name - new_vm_dict = create_vm(module, client, template_id, attributes_dict, labels_list, disk_size, network_attrs_list, vm_start_on_hold, vm_persistent) + new_vm_dict = create_vm(module, client, + template_id, attributes_dict, labels_list, disk_size, network_attrs_list, + vm_start_on_hold, vm_persistent, updateconf_dict) new_vm_id = new_vm_dict.get('vm_id') new_vm = get_vm_by_id(client, new_vm_id) new_vms_list.append(new_vm) @@ -1076,9 +1166,10 @@ def create_count_of_vms( return True, new_vms_list, [] -def create_exact_count_of_vms(module, client, template_id, exact_count, attributes_dict, count_attributes_dict, - labels_list, count_labels_list, disk_size, network_attrs_list, hard, wait, wait_timeout, vm_start_on_hold, vm_persistent): - +def create_exact_count_of_vms(module, client, + template_id, exact_count, attributes_dict, count_attributes_dict, + labels_list, count_labels_list, disk_size, network_attrs_list, + hard, wait, wait_timeout, vm_start_on_hold, vm_persistent, updateconf_dict): vm_list = get_all_vms_by_attributes(client, count_attributes_dict, count_labels_list) vm_count_diff = exact_count - len(vm_list) @@ -1095,7 +1186,7 @@ def create_exact_count_of_vms(module, client, template_id, exact_count, attribut # Add more VMs changed, instances_list, tagged_instances = create_count_of_vms(module, client, template_id, vm_count_diff, attributes_dict, labels_list, disk_size, network_attrs_list, wait, wait_timeout, - vm_start_on_hold, vm_persistent) + vm_start_on_hold, vm_persistent, updateconf_dict) tagged_instances_list += instances_list elif vm_count_diff < 0: @@ -1398,7 +1489,8 @@ def main(): "labels": {"default": [], "type": "list", "elements": "str"}, "count_labels": {"required": False, "type": "list", "elements": "str"}, "disk_saveas": {"type": "dict"}, - "persistent": {"default": False, "type": "bool"} + "persistent": {"default": False, "type": "bool"}, + "updateconf": {"type": "dict"}, } module = AnsibleModule(argument_spec=fields, @@ -1452,6 +1544,7 @@ def main(): count_labels = params.get('count_labels') disk_saveas = params.get('disk_saveas') persistent = params.get('persistent') + updateconf = params.get('updateconf') if not (auth.username and auth.password): module.warn("Credentials missing") @@ -1470,6 +1563,9 @@ def main(): attributes = copy.copy(count_attributes) check_attributes(module, count_attributes) + if updateconf: + check_updateconf(module, updateconf) + if count_labels and not labels: module.warn('When you pass `count_labels` without `labels` option when deploying, `labels` option will have same values implicitly.') labels = count_labels @@ -1529,13 +1625,13 @@ def main(): # Deploy an exact count of VMs changed, instances_list, tagged_instances_list = create_exact_count_of_vms(module, one_client, template_id, exact_count, attributes, count_attributes, labels, count_labels, disk_size, - networks, hard, wait, wait_timeout, put_vm_on_hold, persistent) + networks, hard, wait, wait_timeout, put_vm_on_hold, persistent, updateconf) vms = tagged_instances_list elif template_id is not None and state == 'present': # Deploy count VMs changed, instances_list, tagged_instances_list = create_count_of_vms(module, one_client, template_id, count, attributes, labels, disk_size, networks, wait, wait_timeout, - put_vm_on_hold, persistent) + put_vm_on_hold, persistent, updateconf) # instances_list - new instances # tagged_instances_list - all instances with specified `count_attributes` and `count_labels` vms = instances_list @@ -1587,6 +1683,9 @@ def main(): if owner_id is not None or group_id is not None: changed = set_vm_ownership(module, one_client, vms, owner_id, group_id) or changed + if template_id is None and updateconf is not None: + changed = update_vms(module, one_client, vms, updateconf) or changed + if wait and not module.check_mode and state != 'present': wait_for = { 'absent': wait_for_done, diff --git a/tests/unit/plugins/module_utils/test_opennebula.py b/tests/unit/plugins/module_utils/test_opennebula.py new file mode 100644 index 0000000000..3dd2e91876 --- /dev/null +++ b/tests/unit/plugins/module_utils/test_opennebula.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2023, Michal Opala +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import textwrap + +import pytest + +from ansible_collections.community.general.plugins.module_utils.opennebula import flatten, render + + +FLATTEN_VALID = [ + ( + [[[1]], [2], 3], + False, + [1, 2, 3] + ), + ( + [[[1]], [2], 3], + True, + [1, 2, 3] + ), + ( + [[1]], + False, + [1] + ), + ( + [[1]], + True, + 1 + ), + ( + 1, + False, + [1] + ), + ( + 1, + True, + 1 + ), +] + +RENDER_VALID = [ + ( + { + "NIC": {"NAME": "NIC0", "NETWORK_ID": 0}, + "CPU": 1, + "MEMORY": 1024, + }, + textwrap.dedent(''' + CPU="1" + MEMORY="1024" + NIC=[NAME="NIC0",NETWORK_ID="0"] + ''').strip() + ), + ( + { + "NIC": [ + {"NAME": "NIC0", "NETWORK_ID": 0}, + {"NAME": "NIC1", "NETWORK_ID": 1}, + ], + "CPU": 1, + "MEMORY": 1024, + }, + textwrap.dedent(''' + CPU="1" + MEMORY="1024" + NIC=[NAME="NIC0",NETWORK_ID="0"] + NIC=[NAME="NIC1",NETWORK_ID="1"] + ''').strip() + ), +] + + +@pytest.mark.parametrize('to_flatten,extract,expected_result', FLATTEN_VALID) +def test_flatten(to_flatten, extract, expected_result): + result = flatten(to_flatten, extract) + assert result == expected_result, repr(result) + + +@pytest.mark.parametrize('to_render,expected_result', RENDER_VALID) +def test_render(to_render, expected_result): + result = render(to_render) + assert result == expected_result, repr(result) diff --git a/tests/unit/plugins/modules/test_one_vm.py b/tests/unit/plugins/modules/test_one_vm.py new file mode 100644 index 0000000000..f89a0c63df --- /dev/null +++ b/tests/unit/plugins/modules/test_one_vm.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2023, Michal Opala +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os + +import pytest + +from ansible_collections.community.general.plugins.modules.one_vm import parse_updateconf + + +PARSE_UPDATECONF_VALID = [ + ( + { + "CPU": 1, + "OS": {"ARCH": 2}, + }, + { + "OS": {"ARCH": 2}, + } + ), + ( + { + "OS": {"ARCH": 1, "ASD": 2}, # "ASD" is an invalid attribute, we ignore it + }, + { + "OS": {"ARCH": 1}, + } + ), + ( + { + "OS": {"ASD": 1}, # "ASD" is an invalid attribute, we ignore it + }, + { + } + ), + ( + { + "MEMORY": 1, + "CONTEXT": { + "PASSWORD": 2, + "SSH_PUBLIC_KEY": 3, + }, + }, + { + "CONTEXT": { + "PASSWORD": 2, + "SSH_PUBLIC_KEY": 3, + }, + } + ), +] + + +@pytest.mark.parametrize('vm_template,expected_result', PARSE_UPDATECONF_VALID) +def test_parse_updateconf(vm_template, expected_result): + result = parse_updateconf(vm_template) + assert result == expected_result, repr(result) From 61324ed9eb2e683975b89e1269a643fc798a1a42 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 29 Jan 2023 15:33:30 +0100 Subject: [PATCH 126/134] [PR #5897/6c6de8fb backport][stable-6] add external user support to ipa_group module (#5912) add external user support to ipa_group module (#5897) * add external user support to ipa_group module * add changelog * fix style errors * remove trailing whitespace * Update plugins/modules/ipa_group.py Co-authored-by: Felix Fontein * Update plugins/modules/ipa_group.py Co-authored-by: Felix Fontein * Update plugins/modules/ipa_group.py Co-authored-by: Felix Fontein * Update plugins/modules/ipa_group.py Co-authored-by: Felix Fontein * Update changelogs/fragments/5897-ipa_group-add-external-users.yml Co-authored-by: Felix Fontein * Update plugins/modules/ipa_group.py Co-authored-by: Felix Fontein * Update plugins/modules/ipa_group.py Co-authored-by: Felix Fontein --------- Co-authored-by: Yuriy Halytskyy Co-authored-by: Felix Fontein (cherry picked from commit 6c6de8fb90cb273250517a603d61eb49bd2603ee) Co-authored-by: yhal003 --- .../5897-ipa_group-add-external-users.yml | 2 + plugins/modules/ipa_group.py | 56 ++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/5897-ipa_group-add-external-users.yml diff --git a/changelogs/fragments/5897-ipa_group-add-external-users.yml b/changelogs/fragments/5897-ipa_group-add-external-users.yml new file mode 100644 index 0000000000..e41ea7a97c --- /dev/null +++ b/changelogs/fragments/5897-ipa_group-add-external-users.yml @@ -0,0 +1,2 @@ +minor_changes: + - ipa_group - allow to add and remove external users with the ``external_user`` option (https://github.com/ansible-collections/community.general/pull/5897). \ No newline at end of file diff --git a/plugins/modules/ipa_group.py b/plugins/modules/ipa_group.py index fa3c610d90..89cc806d2d 100644 --- a/plugins/modules/ipa_group.py +++ b/plugins/modules/ipa_group.py @@ -64,6 +64,17 @@ options: - If option is omitted assigned users will not be checked or changed. type: list elements: str + external_user: + description: + - List of external users assigned to this group. + - Behaves identically to I(user) with respect to I(append) attribute. + - List entries can be in C(DOMAIN\\username) or SID format. + - Unless SIDs are provided, the module will always attempt to make changes even if the group already has all the users. + This is because only SIDs are returned by IPA query. + - I(external=true) is needed for this option to work. + type: list + elements: str + version_added: 6.3.0 state: description: - State to ensure @@ -116,6 +127,28 @@ EXAMPLES = r''' ipa_user: admin ipa_pass: topsecret +- name: Add external user to a group + community.general.ipa_group: + name: developers + external: true + append: true + external_user: + - S-1-5-21-123-1234-12345-63421 + ipa_host: ipa.example.com + ipa_user: admin + ipa_pass: topsecret + +- name: Add a user from MYDOMAIN + community.general.ipa_group: + name: developers + external: true + append: true + external_user: + - MYDOMAIN\\john + ipa_host: ipa.example.com + ipa_user: admin + ipa_pass: topsecret + - name: Ensure group is absent community.general.ipa_group: name: sysops @@ -164,6 +197,9 @@ class GroupIPAClient(IPAClient): def group_add_member_user(self, name, item): return self.group_add_member(name=name, item={'user': item}) + def group_add_member_externaluser(self, name, item): + return self.group_add_member(name=name, item={'ipaexternalmember': item}) + def group_remove_member(self, name, item): return self._post_json(method='group_remove_member', name=name, item=item) @@ -173,6 +209,9 @@ class GroupIPAClient(IPAClient): def group_remove_member_user(self, name, item): return self.group_remove_member(name=name, item={'user': item}) + def group_remove_member_externaluser(self, name, item): + return self.group_remove_member(name=name, item={'ipaexternalmember': item}) + def get_group_dict(description=None, external=None, gid=None, nonposix=None): group = {} @@ -208,12 +247,19 @@ def ensure(module, client): name = module.params['cn'] group = module.params['group'] user = module.params['user'] + external = module.params['external'] + external_user = module.params['external_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']) + module_group = get_group_dict(description=module.params['description'], + external=external, + gid=module.params['gidnumber'], + nonposix=module.params['nonposix']) ipa_group = client.group_find(name=name) + if (not (external or external_user is None)): + module.fail_json("external_user can only be set if external = True") + changed = False if state == 'present': if not ipa_group: @@ -242,6 +288,11 @@ def ensure(module, client): client.group_remove_member_user, append=append) or changed + if external_user is not None: + changed = client.modify_if_diff(name, ipa_group.get('ipaexternalmember', []), external_user, + client.group_add_member_externaluser, + client.group_remove_member_externaluser, + append=append) or changed else: if ipa_group: changed = True @@ -256,6 +307,7 @@ def main(): argument_spec.update(cn=dict(type='str', required=True, aliases=['name']), description=dict(type='str'), external=dict(type='bool'), + external_user=dict(type='list', elements='str'), gidnumber=dict(type='str', aliases=['gid']), group=dict(type='list', elements='str'), nonposix=dict(type='bool'), From 24cf56113580baac924529a5bd1993d501d891b5 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 29 Jan 2023 18:37:18 +0100 Subject: [PATCH 127/134] [PR #5913/451c9025 backport][stable-6] dig lookup: support CAA record type (#5917) dig lookup: support CAA record type (#5913) * Support CAA record type. * Update return docs. (cherry picked from commit 451c90251ad4b41e2f3b9a2c7e8bb557a1d5733f) Co-authored-by: Felix Fontein --- changelogs/fragments/5913-dig-caa.yml | 2 ++ plugins/lookup/dig.py | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/5913-dig-caa.yml diff --git a/changelogs/fragments/5913-dig-caa.yml b/changelogs/fragments/5913-dig-caa.yml new file mode 100644 index 0000000000..62ff698737 --- /dev/null +++ b/changelogs/fragments/5913-dig-caa.yml @@ -0,0 +1,2 @@ +minor_changes: + - "dig lookup plugin - support CAA record type (https://github.com/ansible-collections/community.general/pull/5913)." diff --git a/plugins/lookup/dig.py b/plugins/lookup/dig.py index ceaff15e9f..c3c209d303 100644 --- a/plugins/lookup/dig.py +++ b/plugins/lookup/dig.py @@ -35,9 +35,10 @@ DOCUMENTATION = ''' description: - Record type to query. - C(DLV) has been removed in community.general 6.0.0. + - C(CAA) has been added in community.general 6.3.0. type: str default: 'A' - choices: [A, ALL, AAAA, CNAME, DNAME, DNSKEY, DS, HINFO, LOC, MX, NAPTR, NS, NSEC3PARAM, PTR, RP, RRSIG, SOA, SPF, SRV, SSHFP, TLSA, TXT] + choices: [A, ALL, AAAA, CAA, CNAME, DNAME, DNSKEY, DS, HINFO, LOC, MX, NAPTR, NS, NSEC3PARAM, PTR, RP, RRSIG, SOA, SPF, SRV, SSHFP, TLSA, TXT] flat: description: If 0 each record is returned as a dictionary, otherwise a string. type: int @@ -129,6 +130,12 @@ RETURN = """ AAAA: description: - address + CAA: + description: + - flags + - tag + - value + version_added: 6.3.0 CNAME: description: - target @@ -198,7 +205,7 @@ try: import dns.resolver import dns.reversename import dns.rdataclass - from dns.rdatatype import (A, AAAA, CNAME, DNAME, DNSKEY, DS, HINFO, LOC, + from dns.rdatatype import (A, AAAA, CAA, CNAME, DNAME, DNSKEY, DS, HINFO, LOC, MX, NAPTR, NS, NSEC3PARAM, PTR, RP, SOA, SPF, SRV, SSHFP, TLSA, TXT) HAVE_DNS = True except ImportError: @@ -218,6 +225,7 @@ def make_rdata_dict(rdata): supported_types = { A: ['address'], AAAA: ['address'], + CAA: ['flags', 'tag', 'value'], CNAME: ['target'], DNAME: ['target'], DNSKEY: ['flags', 'algorithm', 'protocol', 'key'], From 9740b76f3c5d0017b4857bcf68f0e37943bc4402 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 29 Jan 2023 18:37:27 +0100 Subject: [PATCH 128/134] [PR #5914/3da24d50 backport][stable-6] dig lookup: fix DNSKEY's algorithm handling (#5916) dig lookup: fix DNSKEY's algorithm handling (#5914) Fix DNSKEY's algorithm handling. (cherry picked from commit 3da24d50cdadfd4aa383800f72ca6dab22ee93f2) Co-authored-by: Felix Fontein --- changelogs/fragments/5914-dig-dnskey.yml | 2 ++ plugins/lookup/dig.py | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/5914-dig-dnskey.yml diff --git a/changelogs/fragments/5914-dig-dnskey.yml b/changelogs/fragments/5914-dig-dnskey.yml new file mode 100644 index 0000000000..d6a26388d2 --- /dev/null +++ b/changelogs/fragments/5914-dig-dnskey.yml @@ -0,0 +1,2 @@ +bugfixes: + - "dig lookup plugin - correctly handle DNSKEY record type's ``algorithm`` field (https://github.com/ansible-collections/community.general/pull/5914)." diff --git a/plugins/lookup/dig.py b/plugins/lookup/dig.py index c3c209d303..d0d94e988a 100644 --- a/plugins/lookup/dig.py +++ b/plugins/lookup/dig.py @@ -238,7 +238,7 @@ def make_rdata_dict(rdata): NSEC3PARAM: ['algorithm', 'flags', 'iterations', 'salt'], PTR: ['target'], RP: ['mbox', 'txt'], - # RRSIG: ['algorithm', 'labels', 'original_ttl', 'expiration', 'inception', 'signature'], + # RRSIG: ['type_covered', 'algorithm', 'labels', 'original_ttl', 'expiration', 'inception', 'key_tag', 'signer', 'signature'], SOA: ['mname', 'rname', 'serial', 'refresh', 'retry', 'expire', 'minimum'], SPF: ['strings'], SRV: ['priority', 'weight', 'port', 'target'], @@ -259,6 +259,8 @@ def make_rdata_dict(rdata): if rdata.rdtype == DS and f == 'digest': val = dns.rdata._hexify(rdata.digest).replace(' ', '') + if rdata.rdtype == DNSKEY and f == 'algorithm': + val = int(val) if rdata.rdtype == DNSKEY and f == 'key': val = dns.rdata._base64ify(rdata.key).replace(' ', '') if rdata.rdtype == NSEC3PARAM and f == 'salt': From 48bfba435f3b9568c368ba8c5625644bcf6c94c5 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 29 Jan 2023 22:28:51 +0100 Subject: [PATCH 129/134] [PR #5918/393f2d61 backport][stable-6] Fix PLATFORM attributes docs fragment (#5919) Fix PLATFORM attributes docs fragment (#5918) Fix PLATFORM attributes docs fragment. (cherry picked from commit 393f2d615383e384002dd38cb123f423a6975907) Co-authored-by: Felix Fontein --- plugins/doc_fragments/attributes.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/doc_fragments/attributes.py b/plugins/doc_fragments/attributes.py index e7ab495916..9b8488e0a5 100644 --- a/plugins/doc_fragments/attributes.py +++ b/plugins/doc_fragments/attributes.py @@ -21,6 +21,8 @@ attributes: ''' PLATFORM = r''' +options: {} +attributes: platform: description: Target OS/families that can be operated against. support: N/A From e5930aabcb9ed16453c4fcb2202450e6ec1e0ca2 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 30 Jan 2023 05:57:28 +0000 Subject: [PATCH 130/134] [PR #5883/dcc3d4f5 backport][stable-6] Add support for setenv parameters (#5920) Add support for setenv parameters (#5883) (cherry picked from commit dcc3d4f50843b54aee82a44b059466149d692fa5) Co-authored-by: Renaud <33203203+redat00@users.noreply.github.com> --- ...doers-add-support-for-setenv-parameter.yml | 2 ++ plugins/modules/sudoers.py | 22 ++++++++++++++++++- .../targets/sudoers/tasks/main.yml | 16 +++++++++++++- 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/5883-sudoers-add-support-for-setenv-parameter.yml diff --git a/changelogs/fragments/5883-sudoers-add-support-for-setenv-parameter.yml b/changelogs/fragments/5883-sudoers-add-support-for-setenv-parameter.yml new file mode 100644 index 0000000000..f713428136 --- /dev/null +++ b/changelogs/fragments/5883-sudoers-add-support-for-setenv-parameter.yml @@ -0,0 +1,2 @@ +minor_changes: + - sudoers - add ``setenv`` parameters to support passing environment variables via sudo. (https://github.com/ansible-collections/community.general/pull/5883) diff --git a/plugins/modules/sudoers.py b/plugins/modules/sudoers.py index f2bcb20b75..fd29b189f0 100644 --- a/plugins/modules/sudoers.py +++ b/plugins/modules/sudoers.py @@ -43,6 +43,12 @@ options: - Whether a password will be required to run the sudo'd command. default: true type: bool + setenv: + description: + - Whether to allow keeping the environment when command is run with sudo. + default: false + type: bool + version_added: 6.3.0 host: description: - Specify the host the rule is for. @@ -123,6 +129,13 @@ EXAMPLES = ''' community.general.sudoers: name: alice-service state: absent + +- name: Allow alice to sudo /usr/local/bin/upload and keep env variables + community.general.sudoers: + name: allow-alice-upload + user: alice + commands: /usr/local/bin/upload + setenv: true ''' import os @@ -143,6 +156,7 @@ class Sudoers(object): self.group = module.params['group'] self.state = module.params['state'] self.nopassword = module.params['nopassword'] + self.setenv = module.params['setenv'] self.host = module.params['host'] self.runas = module.params['runas'] self.sudoers_path = module.params['sudoers_path'] @@ -185,12 +199,14 @@ class Sudoers(object): commands_str = ', '.join(self.commands) nopasswd_str = 'NOPASSWD:' if self.nopassword else '' + setenv_str = 'SETENV:' if self.setenv else '' runas_str = '({runas})'.format(runas=self.runas) if self.runas is not None else '' - return "{owner} {host}={runas}{nopasswd} {commands}\n".format( + return "{owner} {host}={runas}{nopasswd}{setenv} {commands}\n".format( owner=owner, host=self.host, runas=runas_str, nopasswd=nopasswd_str, + setenv=setenv_str, commands=commands_str ) @@ -239,6 +255,10 @@ def main(): 'type': 'bool', 'default': True, }, + 'setenv': { + 'type': 'bool', + 'default': False, + }, 'host': { 'type': 'str', 'default': 'ALL', diff --git a/tests/integration/targets/sudoers/tasks/main.yml b/tests/integration/targets/sudoers/tasks/main.yml index a44307ad9e..dd62025d5e 100644 --- a/tests/integration/targets/sudoers/tasks/main.yml +++ b/tests/integration/targets/sudoers/tasks/main.yml @@ -145,6 +145,20 @@ src: "{{ sudoers_path }}/my-sudo-rule-7" register: rule_7_contents +- name: Create rule with setenv parameters + community.general.sudoers: + name: my-sudo-rule-8 + state: present + user: alice + commands: /usr/local/bin/command + setenv: true + register: rule_8 + +- name: Grab contents of my-sudo-rule-8 + ansible.builtin.slurp: + src: "{{ sudoers_path }}/my-sudo-rule-8" + register: rule_8_contents + - name: Revoke rule 1 community.general.sudoers: name: my-sudo-rule-1 @@ -202,7 +216,6 @@ when: ansible_os_family != 'Darwin' register: edge_case_3 - - name: Revoke non-existing rule community.general.sudoers: name: non-existing-rule @@ -243,6 +256,7 @@ - "rule_5_contents['content'] | b64decode == 'alice ALL=NOPASSWD: /usr/local/bin/command\n'" - "rule_6_contents['content'] | b64decode == 'alice ALL=(bob)NOPASSWD: /usr/local/bin/command\n'" - "rule_7_contents['content'] | b64decode == 'alice host-1=NOPASSWD: /usr/local/bin/command\n'" + - "rule_8_contents['content'] | b64decode == 'alice ALL=NOPASSWD:SETENV: /usr/local/bin/command\n'" - name: Check revocation stat ansible.builtin.assert: From 7def57a71f68dc550c348b00c76a3ff2c9347b49 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 30 Jan 2023 21:16:57 +0100 Subject: [PATCH 131/134] [PR #5908/31ff3f66 backport][stable-6] Fixes #5907: gitlab_runner is not idempotent on first run after runner creation (#5922) Fixes #5907: gitlab_runner is not idempotent on first run after runner creation (#5908) This fix introduces the new boolean option 'access_level_on_creation'. It controls, whether the value of 'access_level' is used for runner registration or not. The option 'access_level' has been ignored on registration so far and was only used on updates. The user is informed by a deprecation warning, if the option is unspecified. For reasons of compatibility 'false' is assumed in that case. The option 'access_level_on_creation' will switch to 'true' for the next major release (community.general 7.0.0) Signed-off-by: Christoph Fiehe Co-authored-by: Christoph Fiehe (cherry picked from commit 31ff3f662d91fc36e453415ccb229282b479f96c) Co-authored-by: cfiehe --- .../5907-fix-gitlab_runner-not-idempotent.yml | 4 ++ plugins/modules/gitlab_runner.py | 53 +++++++++++++------ 2 files changed, 40 insertions(+), 17 deletions(-) create mode 100644 changelogs/fragments/5907-fix-gitlab_runner-not-idempotent.yml diff --git a/changelogs/fragments/5907-fix-gitlab_runner-not-idempotent.yml b/changelogs/fragments/5907-fix-gitlab_runner-not-idempotent.yml new file mode 100644 index 0000000000..a7386b8c73 --- /dev/null +++ b/changelogs/fragments/5907-fix-gitlab_runner-not-idempotent.yml @@ -0,0 +1,4 @@ +minor_changes: + - gitlab_runner - add new boolean option ``access_level_on_creation``. It controls, whether the value of ``access_level`` is used for runner registration or not. The option ``access_level`` has been ignored on registration so far and was only used on updates (https://github.com/ansible-collections/community.general/issues/5907, https://github.com/ansible-collections/community.general/pull/5908). +deprecated_features: + - gitlab_runner - the default of the new option ``access_level_on_creation`` will change from ``false`` to ``true`` in community.general 7.0.0. This will cause ``access_level`` to be used during runner registration as well, and not only during updates (https://github.com/ansible-collections/community.general/pull/5908). diff --git a/plugins/modules/gitlab_runner.py b/plugins/modules/gitlab_runner.py index 1094df9424..9d7c900cc5 100644 --- a/plugins/modules/gitlab_runner.py +++ b/plugins/modules/gitlab_runner.py @@ -84,12 +84,23 @@ options: access_level: description: - Determines if a runner can pick up jobs only from protected branches. + - If I(access_level_on_creation) is not explicitly set to C(true), this option is ignored on registration and + is only applied on updates. - If set to C(ref_protected), runner can pick up jobs only from protected branches. - If set to C(not_protected), runner can pick up jobs from both protected and unprotected branches. required: false default: ref_protected choices: ["ref_protected", "not_protected"] type: str + access_level_on_creation: + description: + - Whether the runner should be registered with an access level or not. + - If set to C(true), the value of I(access_level) is used for runner registration. + - If set to C(false), GitLab registers the runner with the default access level. + - The current default of this option is C(false). This default is deprecated and will change to C(true) in commuinty.general 7.0.0. + required: false + type: bool + version_added: 6.3.0 maximum_timeout: description: - The maximum time that a runner has to complete a specific job. @@ -207,27 +218,34 @@ class GitLabRunner(object): def create_or_update_runner(self, description, options): changed = False + arguments = { + 'active': options['active'], + 'locked': options['locked'], + 'run_untagged': options['run_untagged'], + 'maximum_timeout': options['maximum_timeout'], + 'tag_list': options['tag_list'], + } # Because we have already call userExists in main() if self.runner_object is None: - runner = self.create_runner({ - 'description': description, - 'active': options['active'], - 'token': options['registration_token'], - 'locked': options['locked'], - 'run_untagged': options['run_untagged'], - 'maximum_timeout': options['maximum_timeout'], - 'tag_list': options['tag_list'], - }) + arguments['description'] = description + arguments['token'] = options['registration_token'] + + access_level_on_creation = self._module.params['access_level_on_creation'] + if access_level_on_creation is None: + message = "The option 'access_level_on_creation' is unspecified, so 'false' is assumed. "\ + "That means any value of 'access_level' is ignored and GitLab registers the runner with its default value. "\ + "The option 'access_level_on_creation' will switch to 'true' in community.general 7.0.0" + self._module.deprecate(message, version='7.0.0', collection_name='community.general') + access_level_on_creation = False + + if access_level_on_creation: + arguments['access_level'] = options['access_level'] + + runner = self.create_runner(arguments) changed = True else: - changed, runner = self.update_runner(self.runner_object, { - 'active': options['active'], - 'locked': options['locked'], - 'run_untagged': options['run_untagged'], - 'maximum_timeout': options['maximum_timeout'], - 'access_level': options['access_level'], - 'tag_list': options['tag_list'], - }) + arguments['access_level'] = options['access_level'] + changed, runner = self.update_runner(self.runner_object, arguments) self.runner_object = runner if changed: @@ -328,6 +346,7 @@ def main(): run_untagged=dict(type='bool', default=True), locked=dict(type='bool', default=False), access_level=dict(type='str', default='ref_protected', choices=["not_protected", "ref_protected"]), + access_level_on_creation=dict(type='bool'), maximum_timeout=dict(type='int', default=3600), registration_token=dict(type='str', no_log=True), project=dict(type='str'), From 3c5c3a01131c27049b48ed5da03d409a50a1c9b2 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 30 Jan 2023 21:17:09 +0100 Subject: [PATCH 132/134] [PR #5903/ea5cbe25 backport][stable-6] Redfish: Removed basic auth header when performing a GET on the service root and POST to the session collection (#5924) Redfish: Removed basic auth header when performing a GET on the service root and POST to the session collection (#5903) * Redfish: Removed basic auth header when performing a GET on the service root and POST to the session collection * Update changelogs/fragments/5886-redfish-correct-basic-auth-usage-on-session-creation.yml Co-authored-by: Felix Fontein --------- Co-authored-by: Felix Fontein (cherry picked from commit ea5cbe2553716192c9a15f93532c286d1ddec1d1) Co-authored-by: Mike Raineri --- ...t-basic-auth-usage-on-session-creation.yml | 2 ++ plugins/module_utils/redfish_utils.py | 35 ++++++++++++------- 2 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 changelogs/fragments/5886-redfish-correct-basic-auth-usage-on-session-creation.yml diff --git a/changelogs/fragments/5886-redfish-correct-basic-auth-usage-on-session-creation.yml b/changelogs/fragments/5886-redfish-correct-basic-auth-usage-on-session-creation.yml new file mode 100644 index 0000000000..25ec0746a6 --- /dev/null +++ b/changelogs/fragments/5886-redfish-correct-basic-auth-usage-on-session-creation.yml @@ -0,0 +1,2 @@ +bugfixes: + - redfish_utils - removed basic auth HTTP header when performing a GET on the service root resource and when performing a POST to the session collection (https://github.com/ansible-collections/community.general/issues/5886). diff --git a/plugins/module_utils/redfish_utils.py b/plugins/module_utils/redfish_utils.py index 4a56346c3f..eadca28205 100644 --- a/plugins/module_utils/redfish_utils.py +++ b/plugins/module_utils/redfish_utils.py @@ -38,6 +38,8 @@ class RedfishUtils(object): self.timeout = timeout self.module = module self.service_root = '/redfish/v1/' + self.session_service_uri = '/redfish/v1/SessionService' + self.sessions_uri = '/redfish/v1/SessionService/Sessions' self.resource_id = resource_id self.data_modification = data_modification self.strip_etag_quotes = strip_etag_quotes @@ -125,6 +127,10 @@ class RedfishUtils(object): req_headers = dict(GET_HEADERS) username, password, basic_auth = self._auth_params(req_headers) try: + # Service root is an unauthenticated resource; remove credentials + # in case the caller will be using sessions later. + if uri == (self.root_uri + self.service_root): + basic_auth = False resp = open_url(uri, method="GET", headers=req_headers, url_username=username, url_password=password, force_basic_auth=basic_auth, validate_certs=False, @@ -151,6 +157,11 @@ class RedfishUtils(object): req_headers = dict(POST_HEADERS) username, password, basic_auth = self._auth_params(req_headers) try: + # When performing a POST to the session collection, credentials are + # provided in the request body. Do not provide the basic auth + # header since this can cause conflicts with some services + if self.sessions_uri is not None and uri == (self.root_uri + self.sessions_uri): + basic_auth = False resp = open_url(uri, data=json.dumps(pyld), headers=req_headers, method="POST", url_username=username, url_password=password, @@ -363,23 +374,23 @@ class RedfishUtils(object): return {'ret': True} def _find_sessionservice_resource(self): + # Get the service root response = self.get_request(self.root_uri + self.service_root) if response['ret'] is False: return response data = response['data'] - if 'SessionService' not in data: + + # Check for the session service and session collection. Well-known + # defaults are provided in the constructor, but services that predate + # Redfish 1.6.0 might contain different values. + self.session_service_uri = data.get('SessionService', {}).get('@odata.id') + self.sessions_uri = data.get('Links', {}).get('Sessions', {}).get('@odata.id') + + # If one isn't found, return an error + if self.session_service_uri is None: return {'ret': False, 'msg': "SessionService resource not found"} - else: - session_service = data["SessionService"]["@odata.id"] - self.session_service_uri = session_service - response = self.get_request(self.root_uri + session_service) - if response['ret'] is False: - return response - data = response['data'] - sessions = data['Sessions']['@odata.id'] - if sessions[-1:] == '/': - sessions = sessions[:-1] - self.sessions_uri = sessions + if self.sessions_uri is None: + return {'ret': False, 'msg': "SessionCollection resource not found"} return {'ret': True} def _get_resource_uri_by_id(self, uris, id_prop): From 8da9cf3276d24382079b13c65b2296c34d9eec4b Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 31 Jan 2023 07:15:12 +0100 Subject: [PATCH 133/134] Fix changelog fragment types. (cherry picked from commit 84dbb286ebc26fcda1155eac5ca690faed7a5b56) --- changelogs/fragments/5811-clarify-bitwarden-error.yml | 2 +- changelogs/fragments/5888-update-key-title.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/changelogs/fragments/5811-clarify-bitwarden-error.yml b/changelogs/fragments/5811-clarify-bitwarden-error.yml index 343faba478..ee9a3c72b1 100644 --- a/changelogs/fragments/5811-clarify-bitwarden-error.yml +++ b/changelogs/fragments/5811-clarify-bitwarden-error.yml @@ -1,2 +1,2 @@ -minor_changes: +bugfixes: - bitwarden lookup plugin - clarify what to do, if the bitwarden vault is not unlocked (https://github.com/ansible-collections/community.general/pull/5811). diff --git a/changelogs/fragments/5888-update-key-title.yml b/changelogs/fragments/5888-update-key-title.yml index e620ad3d79..d98dcc4c17 100644 --- a/changelogs/fragments/5888-update-key-title.yml +++ b/changelogs/fragments/5888-update-key-title.yml @@ -1,2 +1,2 @@ -minor_changes: +bugfixes: - gitlab_deploy_key - also update ``title`` and not just ``can_push`` (https://github.com/ansible-collections/community.general/pull/5888). From d483fd94824e142db622c50e510879aca6cd4c63 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 31 Jan 2023 07:17:03 +0100 Subject: [PATCH 134/134] Release 6.3.0. --- CHANGELOG.rst | 70 +++++++++ changelogs/changelog.yaml | 141 ++++++++++++++++++ .../fragments/5486-snap-alias-cmd-runner.yml | 2 - .../5694-add-custom-fields-to-bitwarden.yml | 2 - ...06-add-builds-forks-container-registry.yml | 2 - changelogs/fragments/5718-opkg-refactor.yaml | 2 - ...hat_subscription-add-red-hat-api-token.yml | 2 - ...32-bugfix-keycloak-userfed-idempotency.yml | 6 - ...-when-default-workspace-doesnt-exists.yaml | 3 - ...n-update-default-mapper-simultaneously.yml | 7 - .../fragments/5751-gem-fix-uninstall-hang.yml | 2 - .../fragments/5755-mh-fix-output-conflict.yml | 2 - changelogs/fragments/5761-callback-types.yml | 7 - .../fragments/5765-mh-lax-output-conflict.yml | 9 -- ...72-consul-deprecate-params-when-absent.yml | 2 - changelogs/fragments/5773-snap-mh-execute.yml | 2 - .../5793-apache2-module-npm-warnings.yml | 2 - .../fragments/5794-alternatives-fedora37.yml | 2 - .../fragments/5803-proxmox-read-timeout.yml | 2 - ...04-minor-changes-to-hpe-ilo-collection.yml | 2 - ...-xml-children-parameter-does-not-exist.yml | 2 - .../5811-clarify-bitwarden-error.yml | 2 - .../5812-implement-updateconf-api-call.yml | 2 - .../5818-nsupdate-fix-zone-lookup.yml | 2 - .../fragments/5822-gem-uninstall-force.yml | 2 - .../5843-terraform-validate-no-color.yml | 2 - .../5844-iptables-state-refactor.yml | 2 - ...-add-filter-by-collection-id-parameter.yml | 2 - ...doers-add-support-for-setenv-parameter.yml | 2 - ...t-basic-auth-usage-on-session-creation.yml | 2 - .../fragments/5888-update-key-title.yml | 2 - .../5897-ipa_group-add-external-users.yml | 2 - .../5907-fix-gitlab_runner-not-idempotent.yml | 4 - changelogs/fragments/5913-dig-caa.yml | 2 - changelogs/fragments/5914-dig-dnskey.yml | 2 - changelogs/fragments/6.3.0.yml | 1 - 36 files changed, 211 insertions(+), 91 deletions(-) delete mode 100644 changelogs/fragments/5486-snap-alias-cmd-runner.yml delete mode 100644 changelogs/fragments/5694-add-custom-fields-to-bitwarden.yml delete mode 100644 changelogs/fragments/5706-add-builds-forks-container-registry.yml delete mode 100644 changelogs/fragments/5718-opkg-refactor.yaml delete mode 100644 changelogs/fragments/5725-redhat_subscription-add-red-hat-api-token.yml delete mode 100644 changelogs/fragments/5732-bugfix-keycloak-userfed-idempotency.yml delete mode 100644 changelogs/fragments/5735-terraform-init-fix-when-default-workspace-doesnt-exists.yaml delete mode 100644 changelogs/fragments/5750-bugfixing-keycloak-usrfed-fail-when-update-default-mapper-simultaneously.yml delete mode 100644 changelogs/fragments/5751-gem-fix-uninstall-hang.yml delete mode 100644 changelogs/fragments/5755-mh-fix-output-conflict.yml delete mode 100644 changelogs/fragments/5761-callback-types.yml delete mode 100644 changelogs/fragments/5765-mh-lax-output-conflict.yml delete mode 100644 changelogs/fragments/5772-consul-deprecate-params-when-absent.yml delete mode 100644 changelogs/fragments/5773-snap-mh-execute.yml delete mode 100644 changelogs/fragments/5793-apache2-module-npm-warnings.yml delete mode 100644 changelogs/fragments/5794-alternatives-fedora37.yml delete mode 100644 changelogs/fragments/5803-proxmox-read-timeout.yml delete mode 100644 changelogs/fragments/5804-minor-changes-to-hpe-ilo-collection.yml delete mode 100644 changelogs/fragments/5808-xml-children-parameter-does-not-exist.yml delete mode 100644 changelogs/fragments/5811-clarify-bitwarden-error.yml delete mode 100644 changelogs/fragments/5812-implement-updateconf-api-call.yml delete mode 100644 changelogs/fragments/5818-nsupdate-fix-zone-lookup.yml delete mode 100644 changelogs/fragments/5822-gem-uninstall-force.yml delete mode 100644 changelogs/fragments/5843-terraform-validate-no-color.yml delete mode 100644 changelogs/fragments/5844-iptables-state-refactor.yml delete mode 100644 changelogs/fragments/5851-lookup-bitwarden-add-filter-by-collection-id-parameter.yml delete mode 100644 changelogs/fragments/5883-sudoers-add-support-for-setenv-parameter.yml delete mode 100644 changelogs/fragments/5886-redfish-correct-basic-auth-usage-on-session-creation.yml delete mode 100644 changelogs/fragments/5888-update-key-title.yml delete mode 100644 changelogs/fragments/5897-ipa_group-add-external-users.yml delete mode 100644 changelogs/fragments/5907-fix-gitlab_runner-not-idempotent.yml delete mode 100644 changelogs/fragments/5913-dig-caa.yml delete mode 100644 changelogs/fragments/5914-dig-dnskey.yml delete mode 100644 changelogs/fragments/6.3.0.yml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b74e399820..b41f75654b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,76 @@ Community General Release Notes This changelog describes changes after version 5.0.0. +v6.3.0 +====== + +Release Summary +--------------- + +Regular bugfix and feature release. + +Minor Changes +------------- + +- apache2_module - add module argument ``warn_mpm_absent`` to control whether warning are raised in some edge cases (https://github.com/ansible-collections/community.general/pull/5793). +- bitwarden lookup plugin - can now retrieve secrets from custom fields (https://github.com/ansible-collections/community.general/pull/5694). +- bitwarden lookup plugin - implement filtering results by ``collection_id`` parameter (https://github.com/ansible-collections/community.general/issues/5849). +- dig lookup plugin - support CAA record type (https://github.com/ansible-collections/community.general/pull/5913). +- gitlab_project - add ``builds_access_level``, ``container_registry_access_level`` and ``forking_access_level`` options (https://github.com/ansible-collections/community.general/pull/5706). +- gitlab_runner - add new boolean option ``access_level_on_creation``. It controls, whether the value of ``access_level`` is used for runner registration or not. The option ``access_level`` has been ignored on registration so far and was only used on updates (https://github.com/ansible-collections/community.general/issues/5907, https://github.com/ansible-collections/community.general/pull/5908). +- ilo_redfish_utils module utils - change implementation of DNS Server IP and NTP Server IP update (https://github.com/ansible-collections/community.general/pull/5804). +- ipa_group - allow to add and remove external users with the ``external_user`` option (https://github.com/ansible-collections/community.general/pull/5897). +- iptables_state - minor refactoring within the module (https://github.com/ansible-collections/community.general/pull/5844). +- one_vm - add a new ``updateconf`` option which implements the ``one.vm.updateconf`` API call (https://github.com/ansible-collections/community.general/pull/5812). +- opkg - refactored module to use ``CmdRunner`` for executing ``opkg`` (https://github.com/ansible-collections/community.general/pull/5718). +- redhat_subscription - adds ``token`` parameter for subscription-manager authentication using Red Hat API token (https://github.com/ansible-collections/community.general/pull/5725). +- snap - minor refactor when executing module (https://github.com/ansible-collections/community.general/pull/5773). +- snap_alias - refactored module to use ``CmdRunner`` to execute ``snap`` (https://github.com/ansible-collections/community.general/pull/5486). +- sudoers - add ``setenv`` parameters to support passing environment variables via sudo. (https://github.com/ansible-collections/community.general/pull/5883) + +Breaking Changes / Porting Guide +-------------------------------- + +- ModuleHelper module utils - when the module sets output variables named ``msg``, ``exception``, ``output``, ``vars``, or ``changed``, the actual output will prefix those names with ``_`` (underscore symbol) only when they clash with output variables generated by ModuleHelper itself, which only occurs when handling exceptions. Please note that this breaking change does not require a new major release since before this release, it was not possible to add such variables to the output `due to a bug `__ (https://github.com/ansible-collections/community.general/pull/5765). + +Deprecated Features +------------------- + +- consul - deprecate using parameters unused for ``state=absent`` (https://github.com/ansible-collections/community.general/pull/5772). +- gitlab_runner - the default of the new option ``access_level_on_creation`` will change from ``false`` to ``true`` in community.general 7.0.0. This will cause ``access_level`` to be used during runner registration as well, and not only during updates (https://github.com/ansible-collections/community.general/pull/5908). + +Bugfixes +-------- + +- ModuleHelper - fix bug when adjusting the name of reserved output variables (https://github.com/ansible-collections/community.general/pull/5755). +- alternatives - support subcommands on Fedora 37, which uses ``follower`` instead of ``slave`` (https://github.com/ansible-collections/community.general/pull/5794). +- bitwarden lookup plugin - clarify what to do, if the bitwarden vault is not unlocked (https://github.com/ansible-collections/community.general/pull/5811). +- dig lookup plugin - correctly handle DNSKEY record type's ``algorithm`` field (https://github.com/ansible-collections/community.general/pull/5914). +- gem - fix force parameter not being passed to gem command when uninstalling (https://github.com/ansible-collections/community.general/pull/5822). +- gem - fix hang due to interactive prompt for confirmation on specific version uninstall (https://github.com/ansible-collections/community.general/pull/5751). +- gitlab_deploy_key - also update ``title`` and not just ``can_push`` (https://github.com/ansible-collections/community.general/pull/5888). +- keycloak_user_federation - fixes federation creation issue. When a new federation was created and at the same time a default / standard mapper was also changed / updated the creation process failed as a bad None set variable led to a bad malformed url request (https://github.com/ansible-collections/community.general/pull/5750). +- keycloak_user_federation - fixes idempotency detection issues. In some cases the module could fail to properly detect already existing user federations because of a buggy seemingly superflous extra query parameter (https://github.com/ansible-collections/community.general/pull/5732). +- loganalytics callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761). +- logdna callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761). +- logstash callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761). +- nsupdate - fix zone lookup. The SOA record for an existing zone is returned as an answer RR and not as an authority RR (https://github.com/ansible-collections/community.general/issues/5817, https://github.com/ansible-collections/community.general/pull/5818). +- proxmox_disk - fixed issue with read timeout on import action (https://github.com/ansible-collections/community.general/pull/5803). +- redfish_utils - removed basic auth HTTP header when performing a GET on the service root resource and when performing a POST to the session collection (https://github.com/ansible-collections/community.general/issues/5886). +- splunk callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761). +- sumologic callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761). +- syslog_json callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761). +- terraform - fix ``current`` workspace never getting appended to the ``all`` key in the ``workspace_ctf`` object (https://github.com/ansible-collections/community.general/pull/5735). +- terraform - fix ``terraform init`` failure when there are multiple workspaces on the remote backend and when ``default`` workspace is missing by setting ``TF_WORKSPACE`` environmental variable to the value of ``workspace`` when used (https://github.com/ansible-collections/community.general/pull/5735). +- terraform module - disable ANSI escape sequences during validation phase (https://github.com/ansible-collections/community.general/pull/5843). +- xml - fixed a bug where empty ``children`` list would not be set (https://github.com/ansible-collections/community.general/pull/5808). + +New Modules +----------- + +- ocapi_command - Manages Out-Of-Band controllers using Open Composable API (OCAPI) +- ocapi_info - Manages Out-Of-Band controllers using Open Composable API (OCAPI) + v6.2.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 5d45cc7534..e5d5ec8120 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -883,3 +883,144 @@ releases: - 5744-unixy-callback-fix-config-manager-typo.yml - 6.2.0.yml release_date: '2023-01-04' + 6.3.0: + changes: + breaking_changes: + - 'ModuleHelper module utils - when the module sets output variables named ``msg``, + ``exception``, ``output``, ``vars``, or ``changed``, the actual output will + prefix those names with ``_`` (underscore symbol) only when they clash with + output variables generated by ModuleHelper itself, which only occurs when + handling exceptions. Please note that this breaking change does not require + a new major release since before this release, it was not possible to add + such variables to the output `due to a bug `__ + (https://github.com/ansible-collections/community.general/pull/5765). + + ' + bugfixes: + - ModuleHelper - fix bug when adjusting the name of reserved output variables + (https://github.com/ansible-collections/community.general/pull/5755). + - alternatives - support subcommands on Fedora 37, which uses ``follower`` instead + of ``slave`` (https://github.com/ansible-collections/community.general/pull/5794). + - bitwarden lookup plugin - clarify what to do, if the bitwarden vault is not + unlocked (https://github.com/ansible-collections/community.general/pull/5811). + - dig lookup plugin - correctly handle DNSKEY record type's ``algorithm`` field + (https://github.com/ansible-collections/community.general/pull/5914). + - gem - fix force parameter not being passed to gem command when uninstalling + (https://github.com/ansible-collections/community.general/pull/5822). + - gem - fix hang due to interactive prompt for confirmation on specific version + uninstall (https://github.com/ansible-collections/community.general/pull/5751). + - gitlab_deploy_key - also update ``title`` and not just ``can_push`` (https://github.com/ansible-collections/community.general/pull/5888). + - keycloak_user_federation - fixes federation creation issue. When a new federation + was created and at the same time a default / standard mapper was also changed + / updated the creation process failed as a bad None set variable led to a + bad malformed url request (https://github.com/ansible-collections/community.general/pull/5750). + - 'keycloak_user_federation - fixes idempotency detection issues. In some cases + the module could fail to properly detect already existing user federations + because of a buggy seemingly superflous extra query parameter (https://github.com/ansible-collections/community.general/pull/5732). + + ' + - loganalytics callback plugin - adjust type of callback to ``notification``, + it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761). + - logdna callback plugin - adjust type of callback to ``notification``, it was + incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761). + - logstash callback plugin - adjust type of callback to ``notification``, it + was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761). + - nsupdate - fix zone lookup. The SOA record for an existing zone is returned + as an answer RR and not as an authority RR (https://github.com/ansible-collections/community.general/issues/5817, + https://github.com/ansible-collections/community.general/pull/5818). + - proxmox_disk - fixed issue with read timeout on import action (https://github.com/ansible-collections/community.general/pull/5803). + - redfish_utils - removed basic auth HTTP header when performing a GET on the + service root resource and when performing a POST to the session collection + (https://github.com/ansible-collections/community.general/issues/5886). + - splunk callback plugin - adjust type of callback to ``notification``, it was + incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761). + - sumologic callback plugin - adjust type of callback to ``notification``, it + was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761). + - syslog_json callback plugin - adjust type of callback to ``notification``, + it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761). + - terraform - fix ``current`` workspace never getting appended to the ``all`` + key in the ``workspace_ctf`` object (https://github.com/ansible-collections/community.general/pull/5735). + - terraform - fix ``terraform init`` failure when there are multiple workspaces + on the remote backend and when ``default`` workspace is missing by setting + ``TF_WORKSPACE`` environmental variable to the value of ``workspace`` when + used (https://github.com/ansible-collections/community.general/pull/5735). + - terraform module - disable ANSI escape sequences during validation phase (https://github.com/ansible-collections/community.general/pull/5843). + - xml - fixed a bug where empty ``children`` list would not be set (https://github.com/ansible-collections/community.general/pull/5808). + deprecated_features: + - consul - deprecate using parameters unused for ``state=absent`` (https://github.com/ansible-collections/community.general/pull/5772). + - gitlab_runner - the default of the new option ``access_level_on_creation`` + will change from ``false`` to ``true`` in community.general 7.0.0. This will + cause ``access_level`` to be used during runner registration as well, and + not only during updates (https://github.com/ansible-collections/community.general/pull/5908). + minor_changes: + - apache2_module - add module argument ``warn_mpm_absent`` to control whether + warning are raised in some edge cases (https://github.com/ansible-collections/community.general/pull/5793). + - bitwarden lookup plugin - can now retrieve secrets from custom fields (https://github.com/ansible-collections/community.general/pull/5694). + - bitwarden lookup plugin - implement filtering results by ``collection_id`` + parameter (https://github.com/ansible-collections/community.general/issues/5849). + - dig lookup plugin - support CAA record type (https://github.com/ansible-collections/community.general/pull/5913). + - gitlab_project - add ``builds_access_level``, ``container_registry_access_level`` + and ``forking_access_level`` options (https://github.com/ansible-collections/community.general/pull/5706). + - gitlab_runner - add new boolean option ``access_level_on_creation``. It controls, + whether the value of ``access_level`` is used for runner registration or not. + The option ``access_level`` has been ignored on registration so far and was + only used on updates (https://github.com/ansible-collections/community.general/issues/5907, + https://github.com/ansible-collections/community.general/pull/5908). + - ilo_redfish_utils module utils - change implementation of DNS Server IP and + NTP Server IP update (https://github.com/ansible-collections/community.general/pull/5804). + - ipa_group - allow to add and remove external users with the ``external_user`` + option (https://github.com/ansible-collections/community.general/pull/5897). + - iptables_state - minor refactoring within the module (https://github.com/ansible-collections/community.general/pull/5844). + - one_vm - add a new ``updateconf`` option which implements the ``one.vm.updateconf`` + API call (https://github.com/ansible-collections/community.general/pull/5812). + - opkg - refactored module to use ``CmdRunner`` for executing ``opkg`` (https://github.com/ansible-collections/community.general/pull/5718). + - redhat_subscription - adds ``token`` parameter for subscription-manager authentication + using Red Hat API token (https://github.com/ansible-collections/community.general/pull/5725). + - snap - minor refactor when executing module (https://github.com/ansible-collections/community.general/pull/5773). + - snap_alias - refactored module to use ``CmdRunner`` to execute ``snap`` (https://github.com/ansible-collections/community.general/pull/5486). + - sudoers - add ``setenv`` parameters to support passing environment variables + via sudo. (https://github.com/ansible-collections/community.general/pull/5883) + release_summary: Regular bugfix and feature release. + fragments: + - 5486-snap-alias-cmd-runner.yml + - 5694-add-custom-fields-to-bitwarden.yml + - 5706-add-builds-forks-container-registry.yml + - 5718-opkg-refactor.yaml + - 5725-redhat_subscription-add-red-hat-api-token.yml + - 5732-bugfix-keycloak-userfed-idempotency.yml + - 5735-terraform-init-fix-when-default-workspace-doesnt-exists.yaml + - 5750-bugfixing-keycloak-usrfed-fail-when-update-default-mapper-simultaneously.yml + - 5751-gem-fix-uninstall-hang.yml + - 5755-mh-fix-output-conflict.yml + - 5761-callback-types.yml + - 5765-mh-lax-output-conflict.yml + - 5772-consul-deprecate-params-when-absent.yml + - 5773-snap-mh-execute.yml + - 5793-apache2-module-npm-warnings.yml + - 5794-alternatives-fedora37.yml + - 5803-proxmox-read-timeout.yml + - 5804-minor-changes-to-hpe-ilo-collection.yml + - 5808-xml-children-parameter-does-not-exist.yml + - 5811-clarify-bitwarden-error.yml + - 5812-implement-updateconf-api-call.yml + - 5818-nsupdate-fix-zone-lookup.yml + - 5822-gem-uninstall-force.yml + - 5843-terraform-validate-no-color.yml + - 5844-iptables-state-refactor.yml + - 5851-lookup-bitwarden-add-filter-by-collection-id-parameter.yml + - 5883-sudoers-add-support-for-setenv-parameter.yml + - 5886-redfish-correct-basic-auth-usage-on-session-creation.yml + - 5888-update-key-title.yml + - 5897-ipa_group-add-external-users.yml + - 5907-fix-gitlab_runner-not-idempotent.yml + - 5913-dig-caa.yml + - 5914-dig-dnskey.yml + - 6.3.0.yml + modules: + - description: Manages Out-Of-Band controllers using Open Composable API (OCAPI) + name: ocapi_command + namespace: '' + - description: Manages Out-Of-Band controllers using Open Composable API (OCAPI) + name: ocapi_info + namespace: '' + release_date: '2023-01-31' diff --git a/changelogs/fragments/5486-snap-alias-cmd-runner.yml b/changelogs/fragments/5486-snap-alias-cmd-runner.yml deleted file mode 100644 index 59ae0c5abf..0000000000 --- a/changelogs/fragments/5486-snap-alias-cmd-runner.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - snap_alias - refactored module to use ``CmdRunner`` to execute ``snap`` (https://github.com/ansible-collections/community.general/pull/5486). diff --git a/changelogs/fragments/5694-add-custom-fields-to-bitwarden.yml b/changelogs/fragments/5694-add-custom-fields-to-bitwarden.yml deleted file mode 100644 index 55006f06a9..0000000000 --- a/changelogs/fragments/5694-add-custom-fields-to-bitwarden.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - bitwarden lookup plugin - can now retrieve secrets from custom fields (https://github.com/ansible-collections/community.general/pull/5694). diff --git a/changelogs/fragments/5706-add-builds-forks-container-registry.yml b/changelogs/fragments/5706-add-builds-forks-container-registry.yml deleted file mode 100644 index 5635241b64..0000000000 --- a/changelogs/fragments/5706-add-builds-forks-container-registry.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - gitlab_project - add ``builds_access_level``, ``container_registry_access_level`` and ``forking_access_level`` options (https://github.com/ansible-collections/community.general/pull/5706). diff --git a/changelogs/fragments/5718-opkg-refactor.yaml b/changelogs/fragments/5718-opkg-refactor.yaml deleted file mode 100644 index fb8b5680da..0000000000 --- a/changelogs/fragments/5718-opkg-refactor.yaml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - opkg - refactored module to use ``CmdRunner`` for executing ``opkg`` (https://github.com/ansible-collections/community.general/pull/5718). diff --git a/changelogs/fragments/5725-redhat_subscription-add-red-hat-api-token.yml b/changelogs/fragments/5725-redhat_subscription-add-red-hat-api-token.yml deleted file mode 100644 index 980e91ceb2..0000000000 --- a/changelogs/fragments/5725-redhat_subscription-add-red-hat-api-token.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - redhat_subscription - adds ``token`` parameter for subscription-manager authentication using Red Hat API token (https://github.com/ansible-collections/community.general/pull/5725). diff --git a/changelogs/fragments/5732-bugfix-keycloak-userfed-idempotency.yml b/changelogs/fragments/5732-bugfix-keycloak-userfed-idempotency.yml deleted file mode 100644 index c50a105c3f..0000000000 --- a/changelogs/fragments/5732-bugfix-keycloak-userfed-idempotency.yml +++ /dev/null @@ -1,6 +0,0 @@ -bugfixes: - - > - keycloak_user_federation - fixes idempotency detection issues. In some - cases the module could fail to properly detect already existing user - federations because of a buggy seemingly superflous extra query parameter - (https://github.com/ansible-collections/community.general/pull/5732). diff --git a/changelogs/fragments/5735-terraform-init-fix-when-default-workspace-doesnt-exists.yaml b/changelogs/fragments/5735-terraform-init-fix-when-default-workspace-doesnt-exists.yaml deleted file mode 100644 index 3ec348aed9..0000000000 --- a/changelogs/fragments/5735-terraform-init-fix-when-default-workspace-doesnt-exists.yaml +++ /dev/null @@ -1,3 +0,0 @@ -bugfixes: - - terraform - fix ``current`` workspace never getting appended to the ``all`` key in the ``workspace_ctf`` object (https://github.com/ansible-collections/community.general/pull/5735). - - terraform - fix ``terraform init`` failure when there are multiple workspaces on the remote backend and when ``default`` workspace is missing by setting ``TF_WORKSPACE`` environmental variable to the value of ``workspace`` when used (https://github.com/ansible-collections/community.general/pull/5735). diff --git a/changelogs/fragments/5750-bugfixing-keycloak-usrfed-fail-when-update-default-mapper-simultaneously.yml b/changelogs/fragments/5750-bugfixing-keycloak-usrfed-fail-when-update-default-mapper-simultaneously.yml deleted file mode 100644 index 93cfc3adcb..0000000000 --- a/changelogs/fragments/5750-bugfixing-keycloak-usrfed-fail-when-update-default-mapper-simultaneously.yml +++ /dev/null @@ -1,7 +0,0 @@ -bugfixes: - - >- - keycloak_user_federation - fixes federation creation issue. When a new - federation was created and at the same time a default / standard mapper - was also changed / updated the creation process failed as a bad None - set variable led to a bad malformed url request - (https://github.com/ansible-collections/community.general/pull/5750). diff --git a/changelogs/fragments/5751-gem-fix-uninstall-hang.yml b/changelogs/fragments/5751-gem-fix-uninstall-hang.yml deleted file mode 100644 index 3fdd0056de..0000000000 --- a/changelogs/fragments/5751-gem-fix-uninstall-hang.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - gem - fix hang due to interactive prompt for confirmation on specific version uninstall (https://github.com/ansible-collections/community.general/pull/5751). diff --git a/changelogs/fragments/5755-mh-fix-output-conflict.yml b/changelogs/fragments/5755-mh-fix-output-conflict.yml deleted file mode 100644 index f433cc0290..0000000000 --- a/changelogs/fragments/5755-mh-fix-output-conflict.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - ModuleHelper - fix bug when adjusting the name of reserved output variables (https://github.com/ansible-collections/community.general/pull/5755). diff --git a/changelogs/fragments/5761-callback-types.yml b/changelogs/fragments/5761-callback-types.yml deleted file mode 100644 index 62466f46a5..0000000000 --- a/changelogs/fragments/5761-callback-types.yml +++ /dev/null @@ -1,7 +0,0 @@ -bugfixes: - - "loganalytics callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761)." - - "logdna callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761)." - - "logstash callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761)." - - "splunk callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761)." - - "sumologic callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761)." - - "syslog_json callback plugin - adjust type of callback to ``notification``, it was incorrectly classified as ``aggregate`` before (https://github.com/ansible-collections/community.general/pull/5761)." diff --git a/changelogs/fragments/5765-mh-lax-output-conflict.yml b/changelogs/fragments/5765-mh-lax-output-conflict.yml deleted file mode 100644 index 2e8cc292bd..0000000000 --- a/changelogs/fragments/5765-mh-lax-output-conflict.yml +++ /dev/null @@ -1,9 +0,0 @@ -breaking_changes: - - > - ModuleHelper module utils - when the module sets output variables named ``msg``, ``exception``, ``output``, ``vars``, or ``changed``, - the actual output will prefix those names with ``_`` (underscore symbol) only when they clash with output variables generated by ModuleHelper - itself, which only occurs when handling exceptions. Please note that this breaking - change does not require a new major release since before this release, it was not possible - to add such variables to the output - `due to a bug `__ - (https://github.com/ansible-collections/community.general/pull/5765). diff --git a/changelogs/fragments/5772-consul-deprecate-params-when-absent.yml b/changelogs/fragments/5772-consul-deprecate-params-when-absent.yml deleted file mode 100644 index 44d681765f..0000000000 --- a/changelogs/fragments/5772-consul-deprecate-params-when-absent.yml +++ /dev/null @@ -1,2 +0,0 @@ -deprecated_features: - - consul - deprecate using parameters unused for ``state=absent`` (https://github.com/ansible-collections/community.general/pull/5772). diff --git a/changelogs/fragments/5773-snap-mh-execute.yml b/changelogs/fragments/5773-snap-mh-execute.yml deleted file mode 100644 index 43b9b6a1ac..0000000000 --- a/changelogs/fragments/5773-snap-mh-execute.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - snap - minor refactor when executing module (https://github.com/ansible-collections/community.general/pull/5773). diff --git a/changelogs/fragments/5793-apache2-module-npm-warnings.yml b/changelogs/fragments/5793-apache2-module-npm-warnings.yml deleted file mode 100644 index a4750790a4..0000000000 --- a/changelogs/fragments/5793-apache2-module-npm-warnings.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - apache2_module - add module argument ``warn_mpm_absent`` to control whether warning are raised in some edge cases (https://github.com/ansible-collections/community.general/pull/5793). \ No newline at end of file diff --git a/changelogs/fragments/5794-alternatives-fedora37.yml b/changelogs/fragments/5794-alternatives-fedora37.yml deleted file mode 100644 index bfb77142cc..0000000000 --- a/changelogs/fragments/5794-alternatives-fedora37.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - "alternatives - support subcommands on Fedora 37, which uses ``follower`` instead of ``slave`` (https://github.com/ansible-collections/community.general/pull/5794)." diff --git a/changelogs/fragments/5803-proxmox-read-timeout.yml b/changelogs/fragments/5803-proxmox-read-timeout.yml deleted file mode 100644 index fc29605e4f..0000000000 --- a/changelogs/fragments/5803-proxmox-read-timeout.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - proxmox_disk - fixed issue with read timeout on import action (https://github.com/ansible-collections/community.general/pull/5803). diff --git a/changelogs/fragments/5804-minor-changes-to-hpe-ilo-collection.yml b/changelogs/fragments/5804-minor-changes-to-hpe-ilo-collection.yml deleted file mode 100644 index b53bd9eecf..0000000000 --- a/changelogs/fragments/5804-minor-changes-to-hpe-ilo-collection.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - ilo_redfish_utils module utils - change implementation of DNS Server IP and NTP Server IP update (https://github.com/ansible-collections/community.general/pull/5804). diff --git a/changelogs/fragments/5808-xml-children-parameter-does-not-exist.yml b/changelogs/fragments/5808-xml-children-parameter-does-not-exist.yml deleted file mode 100644 index 2bad2c9886..0000000000 --- a/changelogs/fragments/5808-xml-children-parameter-does-not-exist.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- xml - fixed a bug where empty ``children`` list would not be set (https://github.com/ansible-collections/community.general/pull/5808). \ No newline at end of file diff --git a/changelogs/fragments/5811-clarify-bitwarden-error.yml b/changelogs/fragments/5811-clarify-bitwarden-error.yml deleted file mode 100644 index ee9a3c72b1..0000000000 --- a/changelogs/fragments/5811-clarify-bitwarden-error.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - bitwarden lookup plugin - clarify what to do, if the bitwarden vault is not unlocked (https://github.com/ansible-collections/community.general/pull/5811). diff --git a/changelogs/fragments/5812-implement-updateconf-api-call.yml b/changelogs/fragments/5812-implement-updateconf-api-call.yml deleted file mode 100644 index 09058f044e..0000000000 --- a/changelogs/fragments/5812-implement-updateconf-api-call.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - one_vm - add a new ``updateconf`` option which implements the ``one.vm.updateconf`` API call (https://github.com/ansible-collections/community.general/pull/5812). diff --git a/changelogs/fragments/5818-nsupdate-fix-zone-lookup.yml b/changelogs/fragments/5818-nsupdate-fix-zone-lookup.yml deleted file mode 100644 index 4f6ed6a125..0000000000 --- a/changelogs/fragments/5818-nsupdate-fix-zone-lookup.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - nsupdate - fix zone lookup. The SOA record for an existing zone is returned as an answer RR and not as an authority RR (https://github.com/ansible-collections/community.general/issues/5817, https://github.com/ansible-collections/community.general/pull/5818). diff --git a/changelogs/fragments/5822-gem-uninstall-force.yml b/changelogs/fragments/5822-gem-uninstall-force.yml deleted file mode 100644 index 7b8a0efbda..0000000000 --- a/changelogs/fragments/5822-gem-uninstall-force.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - gem - fix force parameter not being passed to gem command when uninstalling (https://github.com/ansible-collections/community.general/pull/5822). diff --git a/changelogs/fragments/5843-terraform-validate-no-color.yml b/changelogs/fragments/5843-terraform-validate-no-color.yml deleted file mode 100644 index 25cc6045ad..0000000000 --- a/changelogs/fragments/5843-terraform-validate-no-color.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- terraform module - disable ANSI escape sequences during validation phase (https://github.com/ansible-collections/community.general/pull/5843). \ No newline at end of file diff --git a/changelogs/fragments/5844-iptables-state-refactor.yml b/changelogs/fragments/5844-iptables-state-refactor.yml deleted file mode 100644 index a69b88de24..0000000000 --- a/changelogs/fragments/5844-iptables-state-refactor.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - iptables_state - minor refactoring within the module (https://github.com/ansible-collections/community.general/pull/5844). diff --git a/changelogs/fragments/5851-lookup-bitwarden-add-filter-by-collection-id-parameter.yml b/changelogs/fragments/5851-lookup-bitwarden-add-filter-by-collection-id-parameter.yml deleted file mode 100644 index 28b878a5b0..0000000000 --- a/changelogs/fragments/5851-lookup-bitwarden-add-filter-by-collection-id-parameter.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - bitwarden lookup plugin - implement filtering results by ``collection_id`` parameter (https://github.com/ansible-collections/community.general/issues/5849). \ No newline at end of file diff --git a/changelogs/fragments/5883-sudoers-add-support-for-setenv-parameter.yml b/changelogs/fragments/5883-sudoers-add-support-for-setenv-parameter.yml deleted file mode 100644 index f713428136..0000000000 --- a/changelogs/fragments/5883-sudoers-add-support-for-setenv-parameter.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - sudoers - add ``setenv`` parameters to support passing environment variables via sudo. (https://github.com/ansible-collections/community.general/pull/5883) diff --git a/changelogs/fragments/5886-redfish-correct-basic-auth-usage-on-session-creation.yml b/changelogs/fragments/5886-redfish-correct-basic-auth-usage-on-session-creation.yml deleted file mode 100644 index 25ec0746a6..0000000000 --- a/changelogs/fragments/5886-redfish-correct-basic-auth-usage-on-session-creation.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - redfish_utils - removed basic auth HTTP header when performing a GET on the service root resource and when performing a POST to the session collection (https://github.com/ansible-collections/community.general/issues/5886). diff --git a/changelogs/fragments/5888-update-key-title.yml b/changelogs/fragments/5888-update-key-title.yml deleted file mode 100644 index d98dcc4c17..0000000000 --- a/changelogs/fragments/5888-update-key-title.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - gitlab_deploy_key - also update ``title`` and not just ``can_push`` (https://github.com/ansible-collections/community.general/pull/5888). diff --git a/changelogs/fragments/5897-ipa_group-add-external-users.yml b/changelogs/fragments/5897-ipa_group-add-external-users.yml deleted file mode 100644 index e41ea7a97c..0000000000 --- a/changelogs/fragments/5897-ipa_group-add-external-users.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - ipa_group - allow to add and remove external users with the ``external_user`` option (https://github.com/ansible-collections/community.general/pull/5897). \ No newline at end of file diff --git a/changelogs/fragments/5907-fix-gitlab_runner-not-idempotent.yml b/changelogs/fragments/5907-fix-gitlab_runner-not-idempotent.yml deleted file mode 100644 index a7386b8c73..0000000000 --- a/changelogs/fragments/5907-fix-gitlab_runner-not-idempotent.yml +++ /dev/null @@ -1,4 +0,0 @@ -minor_changes: - - gitlab_runner - add new boolean option ``access_level_on_creation``. It controls, whether the value of ``access_level`` is used for runner registration or not. The option ``access_level`` has been ignored on registration so far and was only used on updates (https://github.com/ansible-collections/community.general/issues/5907, https://github.com/ansible-collections/community.general/pull/5908). -deprecated_features: - - gitlab_runner - the default of the new option ``access_level_on_creation`` will change from ``false`` to ``true`` in community.general 7.0.0. This will cause ``access_level`` to be used during runner registration as well, and not only during updates (https://github.com/ansible-collections/community.general/pull/5908). diff --git a/changelogs/fragments/5913-dig-caa.yml b/changelogs/fragments/5913-dig-caa.yml deleted file mode 100644 index 62ff698737..0000000000 --- a/changelogs/fragments/5913-dig-caa.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - "dig lookup plugin - support CAA record type (https://github.com/ansible-collections/community.general/pull/5913)." diff --git a/changelogs/fragments/5914-dig-dnskey.yml b/changelogs/fragments/5914-dig-dnskey.yml deleted file mode 100644 index d6a26388d2..0000000000 --- a/changelogs/fragments/5914-dig-dnskey.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - "dig lookup plugin - correctly handle DNSKEY record type's ``algorithm`` field (https://github.com/ansible-collections/community.general/pull/5914)." diff --git a/changelogs/fragments/6.3.0.yml b/changelogs/fragments/6.3.0.yml deleted file mode 100644 index 4b1469c9fe..0000000000 --- a/changelogs/fragments/6.3.0.yml +++ /dev/null @@ -1 +0,0 @@ -release_summary: Regular bugfix and feature release.