From d5e1edd28471a6f38ea1b9cc769c92eba4ba1141 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 26 Apr 2021 18:36:49 +0200 Subject: [PATCH 001/139] Add release summary. --- changelogs/fragments/3.0.0.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/fragments/3.0.0.yml diff --git a/changelogs/fragments/3.0.0.yml b/changelogs/fragments/3.0.0.yml new file mode 100644 index 0000000000..e4dc558962 --- /dev/null +++ b/changelogs/fragments/3.0.0.yml @@ -0,0 +1 @@ +release_summary: This is release 3.0.0 of ``community.general``, released on 2021-04-26. From e784254679660c78d46fabfb5e7599d4ecd7674b Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 26 Apr 2021 18:40:14 +0200 Subject: [PATCH 002/139] Release 3.0.0. --- CHANGELOG.rst | 531 ++++++++++ README.md | 4 +- changelogs/changelog.yaml | 975 +++++++++++++++++- changelogs/fragments/1475-xfconf-facts.yml | 4 - ...lesystem-fix-1457-resizefs-idempotency.yml | 5 - ...n_projects_not_initialized_has_changed.yml | 3 - .../1661-gitlab-deploy-key-update-pubkey.yml | 5 - ...d-id-props-to-redfish-inventory-output.yml | 2 - .../fragments/1695-parted-updatedregex.yaml | 4 - changelogs/fragments/1702_homebrew_tap.yml | 2 - .../1703-sensu_silence-fix_json_parsing.yml | 2 - .../1714-gitlab_runner-required-reg-token.yml | 2 - .../1715-proxmox_kvm-add-vmid-to-returns.yml | 2 - ...721-fix-nomad_job_info-no-jobs-failure.yml | 2 - changelogs/fragments/1722_timezone.yml | 2 - ...adog_monitor-add-missing-monitor-types.yml | 2 - ...ixes-for-updating-existing-gitlab-user.yml | 2 - changelogs/fragments/1735-imc-sessions.yml | 2 - .../fragments/1740-aerospike_migration.yml | 2 - .../fragments/1741-use-path-argspec.yml | 4 - ...ase-insensitive-hostname-fqdn-matching.yml | 2 - ...document-fstypes-supported-by-resizefs.yml | 3 - .../1761-redfish-tidy-up-validation.yml | 2 - changelogs/fragments/1765-proxmox-params.yml | 2 - .../fragments/1766-zfs-fixed-sanity.yml | 2 - .../1771-centurylink-validation-elements.yml | 2 - .../fragments/1776-git_config-tilde_value.yml | 2 - .../1783-proxmox-kvm-fix-args-500-error.yaml | 3 - ...ease-nios_host_record-dns-bypass-check.yml | 3 - .../fragments/1795-list-elements-batch1.yml | 27 - .../1813-lxd_profile-merge-profiles.yml | 2 - ...4-dnsimple-add-support-for-caa-records.yml | 2 - .../1819-tidyup-pylint-blacklistnames.yml | 17 - .../1830-valmod_docmissingtype_batch1.yml | 7 - .../1833-zfs-creation-only-properties.yaml | 2 - .../1838-runit-deprecate-param-dist.yml | 2 - .../fragments/1847-proxmox-kvm-fix-status.yml | 2 - ...er-fix-state-is-clean-without-release.yaml | 2 - changelogs/fragments/1861-python3-keys.yml | 22 - .../1867-modhelper-cmdmixin-dict-params.yml | 2 - .../fragments/1871-infoblox-inventory.yml | 2 - .../fragments/1880-fix_cobbler_system_ssl.yml | 2 - ...nmcli-ensure-slave-type-for-bond-slave.yml | 2 - .../1885-sanity-check-fixes-batch3.yml | 18 - ...894-feat-nmcli-add-method4-and-method6.yml | 2 - .../1895-proxmox-kvm-fix-issue-1875.yml | 3 - ...m_versionlock-lock_unlock_concurrently.yml | 3 - .../1914-add-sanitization-to-url.yml | 3 - .../1916-add-version-sort-filter.yml | 3 - .../1927-removed-parameter-invalid.yml | 12 - .../fragments/1928-bigpanda-message.yml | 2 - changelogs/fragments/1929-grove-message.yml | 4 - .../fragments/1949-proxmox-inventory-tags.yml | 5 - changelogs/fragments/1970-valmod-batch7.yml | 18 - .../1972-ini_file-empty-str-value.yml | 2 - .../1977-jenkinsjob-validate-certs.yml | 2 - .../fragments/1978-jira-transition-logic.yml | 4 - ...proxmox-inventory-fix-template-in-pool.yml | 3 - .../fragments/1993-haproxy-fix-draining.yml | 3 - .../fragments/1999-proxmox-fix-issue-1955.yml | 3 - .../2000-proxmox_kvm-tag-support.yml | 3 - changelogs/fragments/2001-no_log-false.yml | 2 - changelogs/fragments/2006-valmod-batch8.yml | 4 - ...te-java-cert-replace-cert-when-changed.yml | 7 - .../2013-proxmox-purge-parameter.yml | 3 - .../2014-allow-root-for-kibana-plugin.yaml | 2 - .../2020-remove-unused-param-in-rax.yml | 2 - .../fragments/2024-module-helper-fixes.yml | 4 - ...ish-session-create-delete-authenticate.yml | 2 - .../2031-ipa_sudorule_add_runasextusers.yml | 3 - changelogs/fragments/2032-one_image-pyone.yml | 2 - .../fragments/2036-scaleway-inventory.yml | 3 - .../fragments/2037-add-from-csv-filter.yml | 7 - ...index-error-in-redfish-set-manager-nic.yml | 2 - changelogs/fragments/2057-nios-devel.yml | 2 - .../fragments/2061-archive-refactor1.yml | 2 - .../fragments/2065-snmp-facts-timeout.yml | 2 - .../2072-stacki-host-params-fallback.yml | 2 - ...t-PATH-env-variable-in-zypper-modules.yaml | 2 - .../fragments/2110-vdo-add_force_option.yaml | 3 - .../2116-add-fields-to-ipa-config-module.yml | 2 - .../fragments/2125-git-config-scope-file.yml | 2 - .../2135-vmadm-resolvers-type-fix.yml | 2 - .../2139-dimensiondata_network-str-format.yml | 2 - .../2142-apache2_mod_proxy-cleanup.yml | 2 - ...143-kibana_plugin-fixed-function-calls.yml | 2 - .../fragments/2144-atomic_get_bin_path.yml | 4 - .../2146-npm-add_no_bin_links_option.yaml | 3 - ...148-proxmox-inventory-agent-interfaces.yml | 3 - .../fragments/2157-unreachable-code.yml | 4 - ...pa-user-sshpubkey-multi-word-comments.yaml | 2 - changelogs/fragments/2160-list-literals.yml | 11 - .../fragments/2161-pkgutil-list-extend.yml | 2 - .../fragments/2162-modhelper-variables.yml | 2 - .../fragments/2162-proxmox-constructable.yml | 3 - ...ystore_1667_improve_temp_files_storage.yml | 5 - ...2174-ipa-user-userauthtype-multiselect.yml | 2 - ...re_1668_dont_expose_secrets_on_cmdline.yml | 4 - ...3-java_keystore_improve_error_handling.yml | 6 - .../2185-xfconf-absent-check-mode.yml | 2 - .../2188-xfconf-modhelper-variables.yml | 3 - changelogs/fragments/2192-add-jira-attach.yml | 2 - .../2203-modhelper-cause-changes-deco.yml | 2 - .../2204-github_repo-fix-baseurl_port.yml | 2 - changelogs/fragments/2208-jira-revamp.yml | 2 - changelogs/fragments/2218-cpanm-revamp.yml | 5 - .../fragments/2220_nmcli_wifi_support.yaml | 3 - .../2223_nmcli_no_IP_config_on_slave.yaml | 3 - .../2224_nmcli_allow_MAC_overwrite.yaml | 3 - ..._keystore-1669-ssl-input-files-by-path.yml | 6 - changelogs/fragments/2236-jira-isinstance.yml | 2 - changelogs/fragments/2244-hashids-filters.yml | 6 - ...2245-proxmox_fix_agent_string_handling.yml | 3 - changelogs/fragments/2246-terraform.yaml | 4 - ...9-linode_v4-support-private_ip-option.yaml | 2 - ...eycloak-modules-to-take-token-as-param.yml | 5 - .../fragments/2257-ldap_entry-params.yml | 2 - ...2259-proxmox-multi-nic-and-unsupported.yml | 5 - .../2262-java_keystore-passphrase.yml | 8 - ...vol_size_addition-subtraction_support.yaml | 5 - .../fragments/2268-validation-univetion.yml | 4 - .../2280-pids-new-pattern-option.yml | 3 - .../fragments/2282-nmap-fix-cache-support.yml | 2 - ...-influxdb_retention_policy-idempotence.yml | 4 - ...-terraform-add-plugin_paths-parameter.yaml | 3 - .../2329-hiera-lookup-plugin-return-type.yaml | 2 - .../fragments/2340-jenkins_plugin-py2.yml | 2 - .../fragments/2349-jira-bugfix-b64decode.yml | 2 - changelogs/fragments/3.0.0.yml | 1 - ...620-consul_io-env-variables-conf-based.yml | 5 - .../fragments/719-manageiq-resource_id.yml | 2 - .../fragments/720-cloudforms_inventory.yml | 2 - ...-invocate-feature-when-variable-is-set.yml | 2 - .../948-dellemc-migration-removal.yml | 13 - .../fragments/CVE-2021-20191_no_log.yml | 4 - changelogs/fragments/allow_funcd_to_load.yml | 2 - changelogs/fragments/dict-filter.yml | 3 - .../fragments/meta-runtime-deprecations.yml | 2 - changelogs/fragments/no_log-fixes.yml | 25 - .../fragments/path_join-shim-filter.yml | 3 - .../fragments/remove-deprecated-features.yml | 16 - .../fragments/remove-deprecated-modules.yml | 66 -- changelogs/fragments/selective-core-2.11.yml | 2 - 143 files changed, 1507 insertions(+), 621 deletions(-) delete mode 100644 changelogs/fragments/1475-xfconf-facts.yml delete mode 100644 changelogs/fragments/1478-filesystem-fix-1457-resizefs-idempotency.yml delete mode 100644 changelogs/fragments/1596-xfs_quota-feedback_on_projects_not_initialized_has_changed.yml delete mode 100644 changelogs/fragments/1661-gitlab-deploy-key-update-pubkey.yml delete mode 100644 changelogs/fragments/1691-add-name-and-id-props-to-redfish-inventory-output.yml delete mode 100644 changelogs/fragments/1695-parted-updatedregex.yaml delete mode 100644 changelogs/fragments/1702_homebrew_tap.yml delete mode 100644 changelogs/fragments/1703-sensu_silence-fix_json_parsing.yml delete mode 100644 changelogs/fragments/1714-gitlab_runner-required-reg-token.yml delete mode 100644 changelogs/fragments/1715-proxmox_kvm-add-vmid-to-returns.yml delete mode 100644 changelogs/fragments/1721-fix-nomad_job_info-no-jobs-failure.yml delete mode 100644 changelogs/fragments/1722_timezone.yml delete mode 100644 changelogs/fragments/1723-datadog_monitor-add-missing-monitor-types.yml delete mode 100644 changelogs/fragments/1724-various-fixes-for-updating-existing-gitlab-user.yml delete mode 100644 changelogs/fragments/1735-imc-sessions.yml delete mode 100644 changelogs/fragments/1740-aerospike_migration.yml delete mode 100644 changelogs/fragments/1741-use-path-argspec.yml delete mode 100644 changelogs/fragments/1744-case-insensitive-hostname-fqdn-matching.yml delete mode 100644 changelogs/fragments/1753-document-fstypes-supported-by-resizefs.yml delete mode 100644 changelogs/fragments/1761-redfish-tidy-up-validation.yml delete mode 100644 changelogs/fragments/1765-proxmox-params.yml delete mode 100644 changelogs/fragments/1766-zfs-fixed-sanity.yml delete mode 100644 changelogs/fragments/1771-centurylink-validation-elements.yml delete mode 100644 changelogs/fragments/1776-git_config-tilde_value.yml delete mode 100644 changelogs/fragments/1783-proxmox-kvm-fix-args-500-error.yaml delete mode 100644 changelogs/fragments/1788-ease-nios_host_record-dns-bypass-check.yml delete mode 100644 changelogs/fragments/1795-list-elements-batch1.yml delete mode 100644 changelogs/fragments/1813-lxd_profile-merge-profiles.yml delete mode 100644 changelogs/fragments/1814-dnsimple-add-support-for-caa-records.yml delete mode 100644 changelogs/fragments/1819-tidyup-pylint-blacklistnames.yml delete mode 100644 changelogs/fragments/1830-valmod_docmissingtype_batch1.yml delete mode 100644 changelogs/fragments/1833-zfs-creation-only-properties.yaml delete mode 100644 changelogs/fragments/1838-runit-deprecate-param-dist.yml delete mode 100644 changelogs/fragments/1847-proxmox-kvm-fix-status.yml delete mode 100644 changelogs/fragments/1852-deploy-helper-fix-state-is-clean-without-release.yaml delete mode 100644 changelogs/fragments/1861-python3-keys.yml delete mode 100644 changelogs/fragments/1867-modhelper-cmdmixin-dict-params.yml delete mode 100644 changelogs/fragments/1871-infoblox-inventory.yml delete mode 100644 changelogs/fragments/1880-fix_cobbler_system_ssl.yml delete mode 100644 changelogs/fragments/1882-fix-nmcli-ensure-slave-type-for-bond-slave.yml delete mode 100644 changelogs/fragments/1885-sanity-check-fixes-batch3.yml delete mode 100644 changelogs/fragments/1894-feat-nmcli-add-method4-and-method6.yml delete mode 100644 changelogs/fragments/1895-proxmox-kvm-fix-issue-1875.yml delete mode 100644 changelogs/fragments/1912-yum_versionlock-lock_unlock_concurrently.yml delete mode 100644 changelogs/fragments/1914-add-sanitization-to-url.yml delete mode 100644 changelogs/fragments/1916-add-version-sort-filter.yml delete mode 100644 changelogs/fragments/1927-removed-parameter-invalid.yml delete mode 100644 changelogs/fragments/1928-bigpanda-message.yml delete mode 100644 changelogs/fragments/1929-grove-message.yml delete mode 100644 changelogs/fragments/1949-proxmox-inventory-tags.yml delete mode 100644 changelogs/fragments/1970-valmod-batch7.yml delete mode 100644 changelogs/fragments/1972-ini_file-empty-str-value.yml delete mode 100644 changelogs/fragments/1977-jenkinsjob-validate-certs.yml delete mode 100644 changelogs/fragments/1978-jira-transition-logic.yml delete mode 100644 changelogs/fragments/1991-proxmox-inventory-fix-template-in-pool.yml delete mode 100644 changelogs/fragments/1993-haproxy-fix-draining.yml delete mode 100644 changelogs/fragments/1999-proxmox-fix-issue-1955.yml delete mode 100644 changelogs/fragments/2000-proxmox_kvm-tag-support.yml delete mode 100644 changelogs/fragments/2001-no_log-false.yml delete mode 100644 changelogs/fragments/2006-valmod-batch8.yml delete mode 100644 changelogs/fragments/2008-update-java-cert-replace-cert-when-changed.yml delete mode 100644 changelogs/fragments/2013-proxmox-purge-parameter.yml delete mode 100644 changelogs/fragments/2014-allow-root-for-kibana-plugin.yaml delete mode 100644 changelogs/fragments/2020-remove-unused-param-in-rax.yml delete mode 100644 changelogs/fragments/2024-module-helper-fixes.yml delete mode 100644 changelogs/fragments/2027-add-redfish-session-create-delete-authenticate.yml delete mode 100644 changelogs/fragments/2031-ipa_sudorule_add_runasextusers.yml delete mode 100644 changelogs/fragments/2032-one_image-pyone.yml delete mode 100644 changelogs/fragments/2036-scaleway-inventory.yml delete mode 100644 changelogs/fragments/2037-add-from-csv-filter.yml delete mode 100644 changelogs/fragments/2040-fix-index-error-in-redfish-set-manager-nic.yml delete mode 100644 changelogs/fragments/2057-nios-devel.yml delete mode 100644 changelogs/fragments/2061-archive-refactor1.yml delete mode 100644 changelogs/fragments/2065-snmp-facts-timeout.yml delete mode 100644 changelogs/fragments/2072-stacki-host-params-fallback.yml delete mode 100644 changelogs/fragments/2094-bugfix-respect-PATH-env-variable-in-zypper-modules.yaml delete mode 100644 changelogs/fragments/2110-vdo-add_force_option.yaml delete mode 100644 changelogs/fragments/2116-add-fields-to-ipa-config-module.yml delete mode 100644 changelogs/fragments/2125-git-config-scope-file.yml delete mode 100644 changelogs/fragments/2135-vmadm-resolvers-type-fix.yml delete mode 100644 changelogs/fragments/2139-dimensiondata_network-str-format.yml delete mode 100644 changelogs/fragments/2142-apache2_mod_proxy-cleanup.yml delete mode 100644 changelogs/fragments/2143-kibana_plugin-fixed-function-calls.yml delete mode 100644 changelogs/fragments/2144-atomic_get_bin_path.yml delete mode 100644 changelogs/fragments/2146-npm-add_no_bin_links_option.yaml delete mode 100644 changelogs/fragments/2148-proxmox-inventory-agent-interfaces.yml delete mode 100644 changelogs/fragments/2157-unreachable-code.yml delete mode 100644 changelogs/fragments/2159-ipa-user-sshpubkey-multi-word-comments.yaml delete mode 100644 changelogs/fragments/2160-list-literals.yml delete mode 100644 changelogs/fragments/2161-pkgutil-list-extend.yml delete mode 100644 changelogs/fragments/2162-modhelper-variables.yml delete mode 100644 changelogs/fragments/2162-proxmox-constructable.yml delete mode 100644 changelogs/fragments/2163-java_keystore_1667_improve_temp_files_storage.yml delete mode 100644 changelogs/fragments/2174-ipa-user-userauthtype-multiselect.yml delete mode 100644 changelogs/fragments/2177-java_keystore_1668_dont_expose_secrets_on_cmdline.yml delete mode 100644 changelogs/fragments/2183-java_keystore_improve_error_handling.yml delete mode 100644 changelogs/fragments/2185-xfconf-absent-check-mode.yml delete mode 100644 changelogs/fragments/2188-xfconf-modhelper-variables.yml delete mode 100644 changelogs/fragments/2192-add-jira-attach.yml delete mode 100644 changelogs/fragments/2203-modhelper-cause-changes-deco.yml delete mode 100644 changelogs/fragments/2204-github_repo-fix-baseurl_port.yml delete mode 100644 changelogs/fragments/2208-jira-revamp.yml delete mode 100644 changelogs/fragments/2218-cpanm-revamp.yml delete mode 100644 changelogs/fragments/2220_nmcli_wifi_support.yaml delete mode 100644 changelogs/fragments/2223_nmcli_no_IP_config_on_slave.yaml delete mode 100644 changelogs/fragments/2224_nmcli_allow_MAC_overwrite.yaml delete mode 100644 changelogs/fragments/2230-java_keystore-1669-ssl-input-files-by-path.yml delete mode 100644 changelogs/fragments/2236-jira-isinstance.yml delete mode 100644 changelogs/fragments/2244-hashids-filters.yml delete mode 100644 changelogs/fragments/2245-proxmox_fix_agent_string_handling.yml delete mode 100644 changelogs/fragments/2246-terraform.yaml delete mode 100644 changelogs/fragments/2249-linode_v4-support-private_ip-option.yaml delete mode 100644 changelogs/fragments/2250-allow-keycloak-modules-to-take-token-as-param.yml delete mode 100644 changelogs/fragments/2257-ldap_entry-params.yml delete mode 100644 changelogs/fragments/2259-proxmox-multi-nic-and-unsupported.yml delete mode 100644 changelogs/fragments/2262-java_keystore-passphrase.yml delete mode 100644 changelogs/fragments/2267-lvol_size_addition-subtraction_support.yaml delete mode 100644 changelogs/fragments/2268-validation-univetion.yml delete mode 100644 changelogs/fragments/2280-pids-new-pattern-option.yml delete mode 100644 changelogs/fragments/2282-nmap-fix-cache-support.yml delete mode 100644 changelogs/fragments/2284-influxdb_retention_policy-idempotence.yml delete mode 100644 changelogs/fragments/2308-terraform-add-plugin_paths-parameter.yaml delete mode 100644 changelogs/fragments/2329-hiera-lookup-plugin-return-type.yaml delete mode 100644 changelogs/fragments/2340-jenkins_plugin-py2.yml delete mode 100644 changelogs/fragments/2349-jira-bugfix-b64decode.yml delete mode 100644 changelogs/fragments/3.0.0.yml delete mode 100644 changelogs/fragments/620-consul_io-env-variables-conf-based.yml delete mode 100644 changelogs/fragments/719-manageiq-resource_id.yml delete mode 100644 changelogs/fragments/720-cloudforms_inventory.yml delete mode 100644 changelogs/fragments/816-only-invocate-feature-when-variable-is-set.yml delete mode 100644 changelogs/fragments/948-dellemc-migration-removal.yml delete mode 100644 changelogs/fragments/CVE-2021-20191_no_log.yml delete mode 100644 changelogs/fragments/allow_funcd_to_load.yml delete mode 100644 changelogs/fragments/dict-filter.yml delete mode 100644 changelogs/fragments/meta-runtime-deprecations.yml delete mode 100644 changelogs/fragments/no_log-fixes.yml delete mode 100644 changelogs/fragments/path_join-shim-filter.yml delete mode 100644 changelogs/fragments/remove-deprecated-features.yml delete mode 100644 changelogs/fragments/remove-deprecated-modules.yml delete mode 100644 changelogs/fragments/selective-core-2.11.yml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7b796ddb34..9c6cf15746 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,3 +3,534 @@ Community General Release Notes =============================== .. contents:: Topics + +This changelog describes changes after version 2.0.0. + +v3.0.0 +====== + +Release Summary +--------------- + +This is release 3.0.0 of ``community.general``, released on 2021-04-26. + +Minor Changes +------------- + +- apache2_mod_proxy - refactored/cleaned-up part of the code (https://github.com/ansible-collections/community.general/pull/2142). +- archive - refactored some reused code out into a couple of functions (https://github.com/ansible-collections/community.general/pull/2061). +- atomic_container - using ``get_bin_path()`` before calling ``run_command()`` (https://github.com/ansible-collections/community.general/pull/2144). +- atomic_host - using ``get_bin_path()`` before calling ``run_command()`` (https://github.com/ansible-collections/community.general/pull/2144). +- atomic_image - using ``get_bin_path()`` before calling ``run_command()`` (https://github.com/ansible-collections/community.general/pull/2144). +- beadm - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). +- bitbucket_pipeline_variable - removed unreachable code (https://github.com/ansible-collections/community.general/pull/2157). +- bundler - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- clc_* modules - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1771). +- consul - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- consul_acl - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- consul_io inventory script - conf options - allow custom configuration options via env variables (https://github.com/ansible-collections/community.general/pull/620). +- consul_session - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- cpanm - honor and install specified version when running in ``new`` mode; that feature is not available in ``compatibility`` mode (https://github.com/ansible-collections/community.general/issues/208). +- cpanm - rewritten using ``ModuleHelper`` (https://github.com/ansible-collections/community.general/pull/2218). +- csv module utils - new module_utils for shared functions between ``from_csv`` filter and ``read_csv`` module (https://github.com/ansible-collections/community.general/pull/2037). +- datadog_monitor - add missing monitor types ``query alert``, ``trace-analytics alert``, ``rum alert`` (https://github.com/ansible-collections/community.general/pull/1723). +- datadog_monitor - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- dnsimple - add CAA records to the whitelist of valid record types (https://github.com/ansible-collections/community.general/pull/1814). +- dnsimple - elements of list parameters ``record_ids`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- gitlab_deploy_key - when the given key title already exists but has a different public key, the public key will now be updated to given value (https://github.com/ansible-collections/community.general/pull/1661). +- gitlab_runner - elements of list parameters ``tag_list`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- grove - the option ``message`` has been renamed to ``message_content``. The old name ``message`` is kept as an alias and will be removed for community.general 4.0.0. This was done because ``message`` is used internally by Ansible (https://github.com/ansible-collections/community.general/pull/1929). +- heroku_collaborator - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- hiera lookup - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). +- homebrew_tap - add support to specify search path for ``brew`` executable (https://github.com/ansible-collections/community.general/issues/1702). +- ipa_config - add new options ``ipaconfigstring``, ``ipadefaultprimarygroup``, ``ipagroupsearchfields``, ``ipahomesrootdir``, ``ipabrkauthzdata``, ``ipamaxusernamelength``, ``ipapwdexpadvnotify``, ``ipasearchrecordslimit``, ``ipasearchtimelimit``, ``ipauserauthtype``, and ``ipausersearchfields`` (https://github.com/ansible-collections/community.general/pull/2116). +- ipa_sudorule - add support for setting sudo runasuser (https://github.com/ansible-collections/community.general/pull/2031). +- ipa_user - fix ``userauthtype`` option to take in list of strings for the multi-select field instead of single string (https://github.com/ansible-collections/community.general/pull/2174). +- ipwcli_dns - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). +- java_cert - change ``state: present`` to check certificates by hash, not just alias name (https://github.com/ansible/ansible/issues/43249). +- java_keystore - add options ``certificate_path`` and ``private_key_path``, mutually exclusive with ``certificate`` and ``private_key`` respectively, and targetting files on remote hosts rather than their contents on the controller. (https://github.com/ansible-collections/community.general/issues/1669). +- jenkins_job - add a ``validate_certs`` parameter that allows disabling TLS/SSL certificate validation (https://github.com/ansible-collections/community.general/issues/255). +- jira - added ``attach`` operation, which allows a user to attach a file to an issue (https://github.com/ansible-collections/community.general/pull/2192). +- jira - added parameter ``account_id`` for compatibility with recent versions of JIRA (https://github.com/ansible-collections/community.general/issues/818, https://github.com/ansible-collections/community.general/pull/1978). +- jira - revamped the module as a class using ``ModuleHelper`` (https://github.com/ansible-collections/community.general/pull/2208). +- keycloak_* modules - allow the keycloak modules to use a token for the authentication, the modules can take either a token or the credentials (https://github.com/ansible-collections/community.general/pull/2250). +- keycloak_client - elements of list parameters ``default_roles``, ``redirect_uris``, ``web_origins`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- kibana_plugin - add parameter for passing ``--allow-root`` flag to kibana and kibana-plugin commands (https://github.com/ansible-collections/community.general/pull/2014). +- known_hosts module utils - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). +- librato_annotation - elements of list parameters ``links`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- linode_v4 - add support for ``private_ip`` option (https://github.com/ansible-collections/community.general/pull/2249). +- linode_v4 - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- lvol - added proper support for ``+-`` options when extending or reducing the logical volume (https://github.com/ansible-collections/community.general/issues/1988). +- lxd_container - ``client_key`` and ``client_cert`` are now of type ``path`` and no longer ``str``. A side effect is that certain expansions are made, like ``~`` is replaced by the user's home directory, and environment variables like ``$HOME`` or ``$TEMP`` are evaluated (https://github.com/ansible-collections/community.general/pull/1741). +- lxd_container - elements of list parameter ``profiles`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- lxd_profile - ``client_key`` and ``client_cert`` are now of type ``path`` and no longer ``str``. A side effect is that certain expansions are made, like ``~`` is replaced by the user's home directory, and environment variables like ``$HOME`` or ``$TEMP`` are evaluated (https://github.com/ansible-collections/community.general/pull/1741). +- lxd_profile - added ``merge_profile`` parameter to merge configurations from the play to an existing profile (https://github.com/ansible-collections/community.general/pull/1813). +- mail - elements of list parameters ``to``, ``cc``, ``bcc``, ``attach``, ``headers`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- manageiq_alert_profiles - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- manageiq_policies - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- manageiq_tags - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- manageiq_tags and manageiq_policies - added new parameter ``resource_id``. This parameter can be used instead of parameter ``resource_name`` (https://github.com/ansible-collections/community.general/pull/719). +- module_helper module utils - ``CmdMixin.run_command()`` now accepts ``dict`` command arguments, providing the parameter and its value (https://github.com/ansible-collections/community.general/pull/1867). +- module_helper module utils - added management of facts and adhoc setting of the initial value for variables (https://github.com/ansible-collections/community.general/pull/2188). +- module_helper module utils - added mechanism to manage variables, providing automatic output of variables, change status and diff information (https://github.com/ansible-collections/community.general/pull/2162). +- na_ontap_gather_facts - elements of list parameters ``gather_subset`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- nexmo - elements of list parameters ``dest`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- nictagadm - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). +- nmcli - add ability to connect to a Wifi network and also to attach it to a master (bond) (https://github.com/ansible-collections/community.general/pull/2220). +- nmcli - do not set IP configuration on slave connection (https://github.com/ansible-collections/community.general/pull/2223). +- nmcli - don't restrict the ability to manually set the MAC address to the bridge (https://github.com/ansible-collections/community.general/pull/2224). +- npm - add ``no_bin_links`` option (https://github.com/ansible-collections/community.general/issues/2128). +- nsupdate - elements of list parameters ``value`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- oci_vcn - ``api_user_key_file`` is now of type ``path`` and no longer ``str``. A side effect is that certain expansions are made, like ``~`` is replaced by the user's home directory, and environment variables like ``$HOME`` or ``$TEMP`` are evaluated (https://github.com/ansible-collections/community.general/pull/1741). +- omapi_host - elements of list parameters ``statements`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- one_host - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- one_image_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- one_vm - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- oneandone_firewall_policy - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- oneandone_load_balancer - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- oneandone_monitoring_policy - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- oneandone_private_network - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- oneandone_server - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- onepassword_info - elements of list parameters ``search_terms`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- oneview_datacenter_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- oneview_enclosure_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- oneview_ethernet_network_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- oneview_network_set_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- ovh_ip_failover - removed unreachable code (https://github.com/ansible-collections/community.general/pull/2157). +- packet_device - elements of list parameters ``device_ids``, ``hostnames`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- pagerduty - elements of list parameters ``service`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- pids - new options ``pattern`` and `ignore_case`` for retrieving PIDs of processes matching a supplied pattern (https://github.com/ansible-collections/community.general/pull/2280). +- plugins/module_utils/oracle/oci_utils.py - elements of list parameter ``key_by`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- profitbricks - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- profitbricks_volume - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- proxmox - added ``purge`` module parameter for use when deleting lxc's with HA options (https://github.com/ansible-collections/community.general/pull/2013). +- proxmox inventory plugin - added ``Constructable`` class to the inventory to provide options ``strict``, ``keyed_groups``, ``groups``, and ``compose`` (https://github.com/ansible-collections/community.general/pull/2180). +- proxmox inventory plugin - added ``proxmox_agent_interfaces`` fact describing network interfaces returned from a QEMU guest agent (https://github.com/ansible-collections/community.general/pull/2148). +- proxmox inventory plugin - added ``tags_parsed`` fact containing tags parsed as a list (https://github.com/ansible-collections/community.general/pull/1949). +- proxmox inventory plugin - allow to select whether ``ansible_host`` should be set for the proxmox nodes (https://github.com/ansible-collections/community.general/pull/2263). +- proxmox_kvm - added new module parameter ``tags`` for use with PVE 6+ (https://github.com/ansible-collections/community.general/pull/2000). +- proxmox_kvm module - actually implemented ``vmid`` and ``status`` return values. Updated documentation to reflect current situation (https://github.com/ansible-collections/community.general/issues/1410, https://github.com/ansible-collections/community.general/pull/1715). +- pubnub_blocks - elements of list parameters ``event_handlers`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- rax - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2006). +- rax_cdb_user - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2006). +- rax_scaling_group - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2006). +- read_csv - refactored read_csv module to use shared csv functions from csv module_utils (https://github.com/ansible-collections/community.general/pull/2037). +- redfish modules - explicitly setting lists' elements to ``str`` (https://github.com/ansible-collections/community.general/pull/1761). +- redfish_* modules, redfish_utils module utils - add support for Redfish session create, delete, and authenticate (https://github.com/ansible-collections/community.general/issues/1975). +- redfish_config - case insensitive search for situations where the hostname/FQDN case on iLO doesn't match variable's case (https://github.com/ansible-collections/community.general/pull/1744). +- redhat_subscription - elements of list parameters ``pool_ids``, ``addons`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- rhevm - removed unreachable code (https://github.com/ansible-collections/community.general/pull/2157). +- rocketchat - elements of list parameters ``attachments`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- scaleway_compute - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- scaleway_lb - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). +- sendgrid - elements of list parameters ``to_addresses``, ``cc``, ``bcc``, ``attachments`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- sensu_check - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- sensu_client - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- sensu_handler - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- sl_vm - elements of list parameters ``disks``, ``ssh_keys`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- slack - elements of list parameters ``attachments`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- smartos_image_info - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). +- snmp_facts - added parameters ``timeout`` and ``retries`` to module (https://github.com/ansible-collections/community.general/issues/980). +- statusio_maintenance - elements of list parameters ``components``, ``containers`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- svr4pkg - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). +- terraform - add ``plugin_paths`` parameter which allows disabling Terraform from performing plugin discovery and auto-download (https://github.com/ansible-collections/community.general/pull/2308). +- timezone - add Gentoo and Alpine Linux support (https://github.com/ansible-collections/community.general/issues/781). +- twilio - elements of list parameters ``to_numbers`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- udm_dns_zone - elements of list parameters ``nameserver``, ``interfaces``, and ``mx`` are now validated (https://github.com/ansible-collections/community.general/pull/2268). +- vdo - add ``force`` option (https://github.com/ansible-collections/community.general/issues/2101). +- vmadm - elements of list parameters ``disks``, ``nics``, ``resolvers``, ``filesystems`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- webfaction_domain - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- webfaction_site - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). +- xattr - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). +- xfconf - added option ``disable_facts`` to disable facts and its associated deprecation warning (https://github.com/ansible-collections/community.general/issues/1475). +- xfconf - changed implementation to use ``ModuleHelper`` new features (https://github.com/ansible-collections/community.general/pull/2188). +- xml - elements of list parameters ``add_children``, ``set_children`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). +- yum_versionlock - Do the lock/unlock concurrently to speed up (https://github.com/ansible-collections/community.general/pull/1912). +- zfs_facts - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). +- zpool_facts - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). + +Breaking Changes / Porting Guide +-------------------------------- + +- If you use Ansible 2.9 and these plugins or modules from this collection, community.general 3.0.0 results in errors when trying to use the DellEMC content by FQCN, like ``community.general.idrac_firmware``. + Since Ansible 2.9 is not able to use redirections, you will have to adjust your playbooks and roles manually to use the new FQCNs (``dellemc.openmanage.idrac_firmware`` for the previous example) and to make sure that you have ``dellemc.openmanage`` installed. + + If you use ansible-base 2.10 or newer and did not install Ansible 4.0.0, but installed (and/or upgraded) community.general manually, you need to make sure to also install the ``dellemc.openmanage`` collection if you are using any of these plugins or modules. + While ansible-base 2.10 or newer can use the redirects that community.general 3.0.0 adds, the collection they point to (such as dellemc.openmanage) must be installed for them to work. +- gitlab_deploy_key - if for an already existing key title a different public key was given as parameter nothing happened, now this changed so that the public key is updated to the new value (https://github.com/ansible-collections/community.general/pull/1661). +- java_keystore - instead of failing, now overwrites keystore if the alias (name) is changed. This was originally the intended behavior, but did not work due to a logic error. Make sure that your playbooks and roles do not depend on the old behavior of failing instead of overwriting (https://github.com/ansible-collections/community.general/issues/1671). +- java_keystore - instead of failing, now overwrites keystore if the passphrase is changed. Make sure that your playbooks and roles do not depend on the old behavior of failing instead of overwriting (https://github.com/ansible-collections/community.general/issues/1671). +- one_image - use pyone instead of python-oca (https://github.com/ansible-collections/community.general/pull/2032). +- utm_proxy_auth_profile - the ``frontend_cookie_secret`` return value now contains a placeholder string instead of the module's ``frontend_cookie_secret`` parameter (https://github.com/ansible-collections/community.general/pull/1736). + +Deprecated Features +------------------- + +- apt_rpm - deprecated invalid parameter alias ``update-cache``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). +- composer - deprecated invalid parameter aliases ``working-dir``, ``global-command``, ``prefer-source``, ``prefer-dist``, ``no-dev``, ``no-scripts``, ``no-plugins``, ``optimize-autoloader``, ``classmap-authoritative``, ``apcu-autoloader``, ``ignore-platform-reqs``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). +- cpanm - parameter ``system_lib`` deprecated in favor of using ``become`` (https://github.com/ansible-collections/community.general/pull/2218). +- github_deploy_key - deprecated invalid parameter alias ``2fa_token``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). +- grove - the option ``message`` will be removed in community.general 4.0.0. Use the new option ``message_content`` instead (https://github.com/ansible-collections/community.general/pull/1929). +- homebrew - deprecated invalid parameter alias ``update-brew``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). +- homebrew_cask - deprecated invalid parameter alias ``update-brew``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). +- opkg - deprecated invalid parameter alias ``update-cache``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). +- pacman - deprecated invalid parameter alias ``update-cache``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). +- puppet - deprecated undocumented parameter ``show_diff``, will be removed in 7.0.0. (https://github.com/ansible-collections/community.general/pull/1927). +- runit - unused parameter ``dist`` marked for deprecation (https://github.com/ansible-collections/community.general/pull/1830). +- slackpkg - deprecated invalid parameter alias ``update-cache``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). +- urmpi - deprecated invalid parameter aliases ``update-cache`` and ``no-recommends``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). +- xbps - deprecated invalid parameter alias ``update-cache``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). +- xfconf - returning output as facts is deprecated, this will be removed in community.general 4.0.0. Please register the task output in a variable and use it instead. You can already switch to the new behavior now by using the new ``disable_facts`` option (https://github.com/ansible-collections/community.general/pull/1747). + +Removed Features (previously deprecated) +---------------------------------------- + +- The ``ome_device_info``, ``idrac_firmware`` and ``idrac_server_config_profile`` modules have now been migrated from community.general to the `dellemc.openmanage `_ Ansible collection. + If you use ansible-base 2.10 or newer, redirections have been provided. + + If you use Ansible 2.9 and installed this collection, you need to adjust the FQCNs (``community.general.idrac_firmware`` → ``dellemc.openmanage.idrac_firmware``) and make sure to install the dellemc.openmanage collection. +- The deprecated ali_instance_facts module has been removed. Use ali_instance_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated gluster_heal_info module has been removed. Use gluster.gluster.gluster_heal_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated gluster_peer module has been removed. Use gluster.gluster.gluster_peer instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated gluster_volume module has been removed. Use gluster.gluster.gluster_volume instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated helm module has been removed. Use community.kubernetes.helm instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated hpilo_facts module has been removed. Use hpilo_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated idrac_redfish_facts module has been removed. Use idrac_redfish_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated jenkins_job_facts module has been removed. Use jenkins_job_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ldap_attr module has been removed. Use ldap_attrs instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated memset_memstore_facts module has been removed. Use memset_memstore_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated memset_server_facts module has been removed. Use memset_server_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated na_ontap_gather_facts module has been removed. Use netapp.ontap.na_ontap_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated nginx_status_facts module has been removed. Use nginx_status_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated one_image_facts module has been removed. Use one_image_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated onepassword_facts module has been removed. Use onepassword_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated oneview_datacenter_facts module has been removed. Use oneview_datacenter_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated oneview_enclosure_facts module has been removed. Use oneview_enclosure_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated oneview_ethernet_network_facts module has been removed. Use oneview_ethernet_network_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated oneview_fc_network_facts module has been removed. Use oneview_fc_network_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated oneview_fcoe_network_facts module has been removed. Use oneview_fcoe_network_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated oneview_logical_interconnect_group_facts module has been removed. Use oneview_logical_interconnect_group_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated oneview_network_set_facts module has been removed. Use oneview_network_set_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated oneview_san_manager_facts module has been removed. Use oneview_san_manager_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated online_server_facts module has been removed. Use online_server_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated online_user_facts module has been removed. Use online_user_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt module has been removed. Use ovirt.ovirt.ovirt_vm instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_affinity_label_facts module has been removed. Use ovirt.ovirt.ovirt_affinity_label_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_api_facts module has been removed. Use ovirt.ovirt.ovirt_api_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_cluster_facts module has been removed. Use ovirt.ovirt.ovirt_cluster_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_datacenter_facts module has been removed. Use ovirt.ovirt.ovirt_datacenter_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_disk_facts module has been removed. Use ovirt.ovirt.ovirt_disk_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_event_facts module has been removed. Use ovirt.ovirt.ovirt_event_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_external_provider_facts module has been removed. Use ovirt.ovirt.ovirt_external_provider_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_group_facts module has been removed. Use ovirt.ovirt.ovirt_group_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_host_facts module has been removed. Use ovirt.ovirt.ovirt_host_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_host_storage_facts module has been removed. Use ovirt.ovirt.ovirt_host_storage_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_network_facts module has been removed. Use ovirt.ovirt.ovirt_network_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_nic_facts module has been removed. Use ovirt.ovirt.ovirt_nic_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_permission_facts module has been removed. Use ovirt.ovirt.ovirt_permission_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_quota_facts module has been removed. Use ovirt.ovirt.ovirt_quota_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_scheduling_policy_facts module has been removed. Use ovirt.ovirt.ovirt_scheduling_policy_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_snapshot_facts module has been removed. Use ovirt.ovirt.ovirt_snapshot_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_storage_domain_facts module has been removed. Use ovirt.ovirt.ovirt_storage_domain_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_storage_template_facts module has been removed. Use ovirt.ovirt.ovirt_storage_template_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_storage_vm_facts module has been removed. Use ovirt.ovirt.ovirt_storage_vm_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_tag_facts module has been removed. Use ovirt.ovirt.ovirt_tag_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_template_facts module has been removed. Use ovirt.ovirt.ovirt_template_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_user_facts module has been removed. Use ovirt.ovirt.ovirt_user_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_vm_facts module has been removed. Use ovirt.ovirt.ovirt_vm_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated ovirt_vmpool_facts module has been removed. Use ovirt.ovirt.ovirt_vmpool_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated purefa_facts module has been removed. Use purestorage.flasharray.purefa_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated purefb_facts module has been removed. Use purestorage.flasharray.purefb_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated python_requirements_facts module has been removed. Use python_requirements_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated redfish_facts module has been removed. Use redfish_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated scaleway_image_facts module has been removed. Use scaleway_image_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated scaleway_ip_facts module has been removed. Use scaleway_ip_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated scaleway_organization_facts module has been removed. Use scaleway_organization_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated scaleway_security_group_facts module has been removed. Use scaleway_security_group_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated scaleway_server_facts module has been removed. Use scaleway_server_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated scaleway_snapshot_facts module has been removed. Use scaleway_snapshot_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated scaleway_volume_facts module has been removed. Use scaleway_volume_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated smartos_image_facts module has been removed. Use smartos_image_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated vertica_facts module has been removed. Use vertica_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The deprecated xenserver_guest_facts module has been removed. Use xenserver_guest_info instead (https://github.com/ansible-collections/community.general/pull/1924). +- The ovirt_facts docs fragment has been removed (https://github.com/ansible-collections/community.general/pull/1924). +- airbrake_deployment - removed deprecated ``token`` parameter. Use ``project_id`` and ``project_key`` instead (https://github.com/ansible-collections/community.general/pull/1926). +- bigpanda - the alias ``message`` has been removed. Use ``deployment_message`` instead (https://github.com/ansible-collections/community.general/pull/1926). +- cisco_spark, cisco_webex - the alias ``message`` has been removed. Use ``msg`` instead (https://github.com/ansible-collections/community.general/pull/1926). +- clc_aa_policy - the ``wait`` parameter has been removed. It did not have any effect (https://github.com/ansible-collections/community.general/pull/1926). +- datadog_monitor - the alias ``message`` has been removed. Use ``notification_message`` instead (https://github.com/ansible-collections/community.general/pull/1926). +- django_manage - the parameter ``liveserver`` has been removed (https://github.com/ansible-collections/community.general/pull/1926). +- idrac_redfish_config - the parameters ``manager_attribute_name`` and ``manager_attribute_value`` have been removed. Use ``manager_attributes`` instead (https://github.com/ansible-collections/community.general/pull/1926). +- iso_extract - the alias ``thirsty`` has been removed. Use ``force`` instead (https://github.com/ansible-collections/community.general/pull/1926). +- ldap_entry - the ``params`` parameter is now completely removed. Using it already triggered an error since community.general 0.1.2 (https://github.com/ansible-collections/community.general/pull/2257). +- pulp_repo - the ``feed_client_cert`` parameter no longer defaults to the value of the ``client_cert`` parameter (https://github.com/ansible-collections/community.general/pull/1926). +- pulp_repo - the ``feed_client_key`` parameter no longer defaults to the value of the ``client_key`` parameter (https://github.com/ansible-collections/community.general/pull/1926). +- pulp_repo - the alias ``ca_cert`` has been removed. Use ``feed_ca_cert`` instead (https://github.com/ansible-collections/community.general/pull/1926). +- rax - unused parameter ``service`` removed (https://github.com/ansible-collections/community.general/pull/2020). +- redfish modules - issuing a data modification command without specifying the ID of the target System, Chassis or Manager resource when there is more than one is no longer allowed. Use the ``resource_id`` option to specify the target ID (https://github.com/ansible-collections/community.general/pull/1926). +- redfish_config - the parameters ``bios_attribute_name`` and ``bios_attribute_value`` have been removed. Use ``bios_attributes`` instead (https://github.com/ansible-collections/community.general/pull/1926). +- syspatch - the ``apply`` parameter has been removed. This is the default mode, so simply removing it will not change the behavior (https://github.com/ansible-collections/community.general/pull/1926). +- xbps - the ``force`` parameter has been removed. It did not have any effect (https://github.com/ansible-collections/community.general/pull/1926). + +Security Fixes +-------------- + +- dnsmadeeasy - mark the ``account_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- gitlab_runner - mark the ``registration_token`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- hwc_ecs_instance - mark the ``admin_pass`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- ibm_sa_host - mark the ``iscsi_chap_secret`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- java_cert - remove password from ``run_command`` arguments (https://github.com/ansible-collections/community.general/pull/2008). +- java_keystore - pass secret to keytool through an environment variable to not expose it as a commandline argument (https://github.com/ansible-collections/community.general/issues/1668). +- keycloak_* modules - mark the ``auth_client_secret`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- keycloak_client - mark the ``registration_access_token`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- librato_annotation - mark the ``api_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- logentries_msg - mark the ``token`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- module_utils/_netapp, na_ontap_gather_facts - enabled ``no_log`` for the options ``api_key`` and ``secret_key`` to prevent accidental disclosure (CVE-2021-20191, https://github.com/ansible-collections/community.general/pull/1725). +- module_utils/identity/keycloak, keycloak_client, keycloak_clienttemplate, keycloak_group - enabled ``no_log`` for the option ``auth_client_secret`` to prevent accidental disclosure (CVE-2021-20191, https://github.com/ansible-collections/community.general/pull/1725). +- nios_nsgroup - mark the ``tsig_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- oneandone_firewall_policy, oneandone_load_balancer, oneandone_monitoring_policy, oneandone_private_network, oneandone_public_ip - mark the ``auth_token`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- ovirt - mark the ``instance_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- ovirt - mark the ``instance_rootpw`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- pagerduty_alert - mark the ``api_key``, ``service_key`` and ``integration_key`` parameters as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- pagerduty_change - mark the ``integration_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- pingdom - mark the ``key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- pulp_repo - mark the ``feed_client_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- rax_clb_ssl - mark the ``private_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- redfish_command - mark the ``update_creds.password`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- rollbar_deployment - mark the ``token`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- spotinst_aws_elastigroup - mark the ``multai_token`` and ``token`` parameters as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- stackdriver - mark the ``key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). +- utm_proxy_auth_profile - enabled ``no_log`` for the option ``frontend_cookie_secret`` to prevent accidental disclosure (CVE-2021-20191, https://github.com/ansible-collections/community.general/pull/1725). +- utm_proxy_auth_profile - mark the ``frontend_cookie_secret`` parameter as ``no_log`` to avoid leakage of secrets. This causes the ``utm_proxy_auth_profile`` return value to no longer containing the correct value, but a placeholder (https://github.com/ansible-collections/community.general/pull/1736). + +Bugfixes +-------- + +- Mark various module options with ``no_log=False`` which have a name that potentially could leak secrets, but which do not (https://github.com/ansible-collections/community.general/pull/2001). +- aerospike_migration - fix typo that caused ``migrate_tx_key`` instead of ``migrate_rx_key`` being used (https://github.com/ansible-collections/community.general/pull/1739). +- alternatives - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- beadm - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- bigpanda - actually use the ``deployment_message`` option (https://github.com/ansible-collections/community.general/pull/1928). +- chef_databag lookup plugin - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- cloudforms inventory - fixed issue that non-existing (archived) VMs were synced (https://github.com/ansible-collections/community.general/pull/720). +- cobbler_sync, cobbler_system - fix SSL/TLS certificate check when ``validate_certs`` set to ``false`` (https://github.com/ansible-collections/community.general/pull/1880). +- consul_io inventory script - kv_groups - fix byte chain decoding for Python 3 (https://github.com/ansible-collections/community.general/pull/620). +- cronvar - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- dconf - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- deploy_helper - allow ``state=clean`` to be used without defining a ``release`` (https://github.com/ansible-collections/community.general/issues/1852). +- dimensiondata_network - bug when formatting message, instead of % a simple comma was used (https://github.com/ansible-collections/community.general/pull/2139). +- diy callback plugin - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- elasticsearch_plugin - ``state`` parameter choices must use ``list()`` in python3 (https://github.com/ansible-collections/community.general/pull/1830). +- filesystem - do not fail when ``resizefs=yes`` and ``fstype=xfs`` if there is nothing to do, even if the filesystem is not mounted. This only covers systems supporting access to unmounted XFS filesystems. Others will still fail (https://github.com/ansible-collections/community.general/issues/1457, https://github.com/ansible-collections/community.general/pull/1478). +- filesystem - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- filesystem - remove ``swap`` from list of FS supported by ``resizefs=yes`` (https://github.com/ansible-collections/community.general/issues/790). +- funcd connection plugin - can now load (https://github.com/ansible-collections/community.general/pull/2235). +- git_config - fixed scope ``file`` behaviour and added integraton test for it (https://github.com/ansible-collections/community.general/issues/2117). +- git_config - prevent ``run_command`` from expanding values (https://github.com/ansible-collections/community.general/issues/1776). +- github_repo - PyGithub bug does not allow explicit port in ``base_url``. Specifying port is not required (https://github.com/PyGithub/PyGithub/issues/1913). +- gitlab_runner - parameter ``registration_token`` was required but is used only when ``state`` is ``present`` (https://github.com/ansible-collections/community.general/issues/1714). +- gitlab_user - make updates to the ``isadmin``, ``password`` and ``confirm`` options of an already existing GitLab user work (https://github.com/ansible-collections/community.general/pull/1724). +- haproxy - fix a bug preventing haproxy from properly entering ``DRAIN`` mode (https://github.com/ansible-collections/community.general/issues/1913). +- hiera lookup plugin - converts the return type of plugin to unicode string (https://github.com/ansible-collections/community.general/pull/2329). +- hipchat - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- idrac_redfish_command - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- idrac_redfish_config - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- idrac_redfish_info - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- imc_rest - explicitly logging out instead of registering the call in ```atexit``` (https://github.com/ansible-collections/community.general/issues/1735). +- influxdb_retention_policy - ensure idempotent module execution with different duration and shard duration parameter values (https://github.com/ansible-collections/community.general/issues/2281). +- infoblox inventory script - make sure that the script also works with Ansible 2.9, and returns a more helpful error when community.general is not installed as part of Ansible 2.10/3 (https://github.com/ansible-collections/community.general/pull/1871). +- ini_file - allows an empty string as a value for an option (https://github.com/ansible-collections/community.general/pull/1972). +- interfaces_file - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- ipa_user - allow ``sshpubkey`` to permit multiple word comments (https://github.com/ansible-collections/community.general/pull/2159). +- iso_extract - use proper alias deprecation mechanism for ``thirsty`` alias of ``force`` (https://github.com/ansible-collections/community.general/pull/1830). +- java_cert - allow setting ``state: absent`` by providing just the ``cert_alias`` (https://github.com/ansible/ansible/issues/27982). +- java_cert - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- java_cert - properly handle proxy arguments when the scheme is provided (https://github.com/ansible/ansible/issues/54481). +- java_keystore - improve error handling and return ``cmd`` as documented. Force ``LANG``, ``LC_ALL`` and ``LC_MESSAGES`` environment variables to ``C`` to rely on ``keytool`` output parsing. Fix pylint's ``unused-variable`` and ``no-else-return`` hints (https://github.com/ansible-collections/community.general/pull/2183). +- java_keystore - use tempfile lib to create temporary files with randomized names, and remove the temporary PKCS#12 keystore as well as other materials (https://github.com/ansible-collections/community.general/issues/1667). +- jenkins_plugin - fixes Python 2 compatibility issue (https://github.com/ansible-collections/community.general/pull/2340). +- jira - fixed calling of ``isinstance`` (https://github.com/ansible-collections/community.general/issues/2234). +- jira - fixed error when loading base64-encoded content as attachment (https://github.com/ansible-collections/community.general/pull/2349). +- jira - fixed fields' update in ticket transitions (https://github.com/ansible-collections/community.general/issues/818). +- kibana_plugin - ``state`` parameter choices must use ``list()`` in python3 (https://github.com/ansible-collections/community.general/pull/1830). +- kibana_plugin - added missing parameters to ``remove_plugin`` when using ``state=present force=true``, and fix potential quoting errors when invoking ``kibana`` (https://github.com/ansible-collections/community.general/pull/2143). +- logstash_plugin - wrapped ``dict.keys()`` with ``list`` for use in ``choices`` setting (https://github.com/ansible-collections/community.general/pull/1830). +- lvg - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- lvol - fixed sizing calculation rounding to match the underlying tools (https://github.com/ansible-collections/community.general/issues/1988). +- lvol - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- lxc - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- lxc_container - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- lxc_container - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- lxd_container - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- manageiq_provider - wrapped ``dict.keys()`` with ``list`` for use in ``choices`` setting (https://github.com/ansible-collections/community.general/pull/1970). +- memcached cache plugin - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- meta/runtime.yml - improve deprecation messages (https://github.com/ansible-collections/community.general/pull/1918). +- module_helper module utils - actually ignoring formatting of parameters with value ``None`` (https://github.com/ansible-collections/community.general/pull/2024). +- module_helper module utils - fixed decorator ``cause_changes`` (https://github.com/ansible-collections/community.general/pull/2203). +- module_helper module utils - handling ``ModuleHelperException`` now properly calls ``fail_json()`` (https://github.com/ansible-collections/community.general/pull/2024). +- module_helper module utils - use the command name as-is in ``CmdMixin`` if it fails ``get_bin_path()`` - allowing full path names to be passed (https://github.com/ansible-collections/community.general/pull/2024). +- net_tools.nios.api module_utils - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- nios* modules - fix modules to work with ansible-core 2.11 (https://github.com/ansible-collections/community.general/pull/2057). +- nios_host_record - allow DNS Bypass for views other than default (https://github.com/ansible-collections/community.general/issues/1786). +- nmap inventory plugin - fix cache and constructed group support (https://github.com/ansible-collections/community.general/issues/2242). +- nmcli - add ``method4`` and ``method6`` options (https://github.com/ansible-collections/community.general/pull/1894). +- nmcli - ensure the ``slave-type`` option is passed to ``nmcli`` for type ``bond-slave`` (https://github.com/ansible-collections/community.general/pull/1882). +- nomad_job_info - fix module failure when nomad client returns no jobs (https://github.com/ansible-collections/community.general/pull/1721). +- nsot inventory script - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- oci_vcn - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- oneandone_monitoring_policy - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- packet_volume_attachment - removed extraneous ``print`` call - old debug? (https://github.com/ansible-collections/community.general/pull/1970). +- parted - change the regex that decodes the partition size to better support different formats that parted uses. Change the regex that validates parted's version string (https://github.com/ansible-collections/community.general/pull/1695). +- parted - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- pkgutil - fixed calls to ``list.extend()`` (https://github.com/ansible-collections/community.general/pull/2161). +- proxmox - removed requirement that root password is provided when containter state is ``present`` (https://github.com/ansible-collections/community.general/pull/1999). +- proxmox inventory - added handling of commas in KVM agent configuration string (https://github.com/ansible-collections/community.general/pull/2245). +- proxmox inventory - added handling of extra trailing slashes in the URL (https://github.com/ansible-collections/community.general/pull/1914). +- proxmox inventory - exclude qemu templates from inclusion to the inventory via pools (https://github.com/ansible-collections/community.general/issues/1986, https://github.com/ansible-collections/community.general/pull/1991). +- proxmox inventory plugin - allowed proxomox tag string to contain commas when returned as fact (https://github.com/ansible-collections/community.general/pull/1949). +- proxmox inventory plugin - support network interfaces without IP addresses, multiple network interfaces and unsupported/commanddisabled guest error (https://github.com/ansible-collections/community.general/pull/2263). +- proxmox lxc - only add the features flag when module parameter ``features`` is set. Before an empty string was send to proxmox in case the parameter was not used, which required to use ``root@pam`` for module execution (https://github.com/ansible-collections/community.general/pull/1763). +- proxmox* modules - refactored some parameter validation code into use of ``env_fallback``, ``required_if``, ``required_together``, ``required_one_of`` (https://github.com/ansible-collections/community.general/pull/1765). +- proxmox_kvm - do not add ``args`` if ``proxmox_default_behavior`` is set to no_defaults (https://github.com/ansible-collections/community.general/issues/1641). +- proxmox_kvm - fix parameter ``vmid`` passed twice to ``exit_json`` while creating a virtual machine without cloning (https://github.com/ansible-collections/community.general/issues/1875, https://github.com/ansible-collections/community.general/pull/1895). +- proxmox_kvm - fix undefined local variable ``status`` when the parameter ``state`` is either ``stopped``, ``started``, ``restarted`` or ``absent`` (https://github.com/ansible-collections/community.general/pull/1847). +- proxmox_kvm - stop implicitly adding ``force`` equal to ``false``. Proxmox API requires not implemented parameters otherwise, and assumes ``force`` to be ``false`` by default anyways (https://github.com/ansible-collections/community.general/pull/1783). +- redfish_command - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- redfish_config - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- redfish_config module, redfish_utils module utils - fix IndexError in ``SetManagerNic`` command (https://github.com/ansible-collections/community.general/issues/1692). +- redfish_info module, redfish_utils module utils - add ``Name`` and ``Id`` properties to output of Redfish inventory commands (https://github.com/ansible-collections/community.general/issues/1650). +- redhat_subscription - ``mutually_exclusive`` was referring to parameter alias instead of name (https://github.com/ansible-collections/community.general/pull/1795). +- redhat_subscription - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- redis cache plugin - wrapped usages of ``keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- riak - parameters ``wait_for_handoffs`` and ``wait_for_ring`` are ``int`` but the default value was ``false`` (https://github.com/ansible-collections/community.general/pull/1830). +- rundeck_acl_policy - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- runit - removed unused code, and passing command as ``list`` instead of ``str`` to ``run_command()`` (https://github.com/ansible-collections/community.general/pull/1830). +- scaleway inventory plugin - fix pagination on scaleway inventory plugin (https://github.com/ansible-collections/community.general/pull/2036). +- selective callback plugin - adjust import so that the plugin also works with ansible-core 2.11 (https://github.com/ansible-collections/community.general/pull/1807). +- selective callback plugin - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- sensu-silence module - fix json parsing of sensu API responses on Python 3.5 (https://github.com/ansible-collections/community.general/pull/1703). +- sensu_check - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- spotinst_aws_elastigroup - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- stacki_host - replaced ``default`` to environment variables with ``fallback`` to them (https://github.com/ansible-collections/community.general/pull/2072). +- statusio_maintenance - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- terraform - fix issue that cause the destroy to fail because from Terraform 0.15 on, the ``terraform destroy -force`` option is replaced with ``terraform destroy -auto-approve`` (https://github.com/ansible-collections/community.general/issues/2247). +- terraform - fix issue that cause the execution fail because from Terraform 0.15 on, the ``-var`` and ``-var-file`` options are no longer available on ``terraform validate`` (https://github.com/ansible-collections/community.general/pull/2246). +- terraform - remove uses of ``use_unsafe_shell=True`` (https://github.com/ansible-collections/community.general/pull/2246). +- timezone - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819). +- udm_dns_record - fixed default value of parameter ``data`` to match its type (https://github.com/ansible-collections/community.general/pull/2268). +- utm_utils module_utils - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- vdo - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). +- vmadm - correct type of list elements in ``resolvers`` parameter (https://github.com/ansible-collections/community.general/issues/2135). +- xfconf - module was not honoring check mode when ``state`` was ``absent`` (https://github.com/ansible-collections/community.general/pull/2185). +- xfs_quota - the feedback for initializing project quota using xfs_quota binary from ``xfsprogs`` has changed since the version it was written for (https://github.com/ansible-collections/community.general/pull/1596). +- zfs - some ZFS properties could be passed when the dataset/volume did not exist, but would fail if the dataset already existed, even if the property matched what was specified in the ansible task (https://github.com/ansible-collections/community.general/issues/868, https://github.com/ansible-collections/community.general/pull/1833). +- zfs_delegate_admin - the elements of ``users``, ``groups`` and ``permissions`` are now enforced to be strings (https://github.com/ansible-collections/community.general/pull/1766). +- zypper, zypper_repository - respect ``PATH`` environment variable when resolving zypper executable path (https://github.com/ansible-collections/community.general/pull/2094). + +New Plugins +----------- + +Become +~~~~~~ + +- sudosu - Run tasks using sudo su - + +Callback +~~~~~~~~ + +- loganalytics - Posts task results to Azure Log Analytics + +Filter +~~~~~~ + +- dict - The ``dict`` function as a filter: converts a list of tuples to a dictionary +- from_csv - Converts CSV text input into list of dicts +- hashids_decode - Decodes a sequence of numbers from a YouTube-like hash +- hashids_encode - Encodes YouTube-like hashes from a sequence of integers +- path_join - Redirects to ansible.builtin.path_join for ansible-base 2.10 or newer, and provides a compatible implementation for Ansible 2.9 +- version_sort - Sort a list according to version order instead of pure alphabetical one + +Inventory +~~~~~~~~~ + +- lxd - Returns Ansible inventory from lxd host + +New Modules +----------- + +Cloud +~~~~~ + +misc +^^^^ + +- proxmox_storage_info - Retrieve information about one or more Proxmox VE storages + +opennebula +^^^^^^^^^^ + +- one_template - Manages OpenNebula templates + +Files +~~~~~ + +- filesize - Create a file with a given size, or resize it if it exists + +Identity +~~~~~~~~ + +ipa +^^^ + +- ipa_otpconfig - Manage FreeIPA OTP Configuration Settings +- ipa_otptoken - Manage FreeIPA OTPs + +keycloak +^^^^^^^^ + +- keycloak_realm - Allows administration of Keycloak realm via Keycloak API + +Monitoring +~~~~~~~~~~ + +- spectrum_model_attrs - Enforce a model's attributes in CA Spectrum. +- statsd - Send metrics to StatsD + +Net Tools +~~~~~~~~~ + +- gandi_livedns - Manage Gandi LiveDNS records + +pritunl +^^^^^^^ + +- pritunl_org - Manages Pritunl Organizations using the Pritunl API +- pritunl_org_info - List Pritunl Organizations using the Pritunl API +- pritunl_user - Manage Pritunl Users using the Pritunl API +- pritunl_user_info - List Pritunl Users using the Pritunl API + +Remote Management +~~~~~~~~~~~~~~~~~ + +lenovoxcc +^^^^^^^^^ + +- xcc_redfish_command - Manages Lenovo Out-Of-Band controllers using Redfish APIs + +Source Control +~~~~~~~~~~~~~~ + +github +^^^^^^ + +- github_repo - Manage your repositories on Github + +gitlab +^^^^^^ + +- gitlab_project_members - Manage project members on GitLab Server + +Web Infrastructure +~~~~~~~~~~~~~~~~~~ + +- jenkins_build - Manage jenkins builds diff --git a/README.md b/README.md index 935f0ecabd..aba74a6853 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 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-3)](https://dev.azure.com/ansible/community.general/_build?definitionId=31) [![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.general)](https://codecov.io/gh/ansible-collections/community.general) This repo contains the `community.general` Ansible Collection. The collection includes many modules and plugins supported by Ansible community which are not part of more specialized community collections. @@ -76,7 +76,7 @@ Basic instructions without release branches: ## 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-3/CHANGELOG.rst). ## Roadmap diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index e78468a3ca..344ddea77c 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -1,2 +1,975 @@ ancestor: 2.0.0 -releases: {} +releases: + 3.0.0: + changes: + breaking_changes: + - 'If you use Ansible 2.9 and these plugins or modules from this collection, + community.general 3.0.0 results in errors when trying to use the DellEMC content + by FQCN, like ``community.general.idrac_firmware``. + + Since Ansible 2.9 is not able to use redirections, you will have to adjust + your playbooks and roles manually to use the new FQCNs (``dellemc.openmanage.idrac_firmware`` + for the previous example) and to make sure that you have ``dellemc.openmanage`` + installed. + + + If you use ansible-base 2.10 or newer and did not install Ansible 4.0.0, but + installed (and/or upgraded) community.general manually, you need to make sure + to also install the ``dellemc.openmanage`` collection if you are using any + of these plugins or modules. + + While ansible-base 2.10 or newer can use the redirects that community.general + 3.0.0 adds, the collection they point to (such as dellemc.openmanage) must + be installed for them to work. + + ' + - gitlab_deploy_key - if for an already existing key title a different public + key was given as parameter nothing happened, now this changed so that the + public key is updated to the new value (https://github.com/ansible-collections/community.general/pull/1661). + - java_keystore - instead of failing, now overwrites keystore if the alias (name) + is changed. This was originally the intended behavior, but did not work due + to a logic error. Make sure that your playbooks and roles do not depend on + the old behavior of failing instead of overwriting (https://github.com/ansible-collections/community.general/issues/1671). + - java_keystore - instead of failing, now overwrites keystore if the passphrase + is changed. Make sure that your playbooks and roles do not depend on the old + behavior of failing instead of overwriting (https://github.com/ansible-collections/community.general/issues/1671). + - one_image - use pyone instead of python-oca (https://github.com/ansible-collections/community.general/pull/2032). + - utm_proxy_auth_profile - the ``frontend_cookie_secret`` return value now contains + a placeholder string instead of the module's ``frontend_cookie_secret`` parameter + (https://github.com/ansible-collections/community.general/pull/1736). + bugfixes: + - Mark various module options with ``no_log=False`` which have a name that potentially + could leak secrets, but which do not (https://github.com/ansible-collections/community.general/pull/2001). + - aerospike_migration - fix typo that caused ``migrate_tx_key`` instead of ``migrate_rx_key`` + being used (https://github.com/ansible-collections/community.general/pull/1739). + - 'alternatives - internal refactoring: replaced uses of ``_`` with ``dummy`` + (https://github.com/ansible-collections/community.general/pull/1819).' + - 'beadm - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819).' + - bigpanda - actually use the ``deployment_message`` option (https://github.com/ansible-collections/community.general/pull/1928). + - chef_databag lookup plugin - wrapped usages of ``dict.keys()`` in ``list()`` + for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - cloudforms inventory - fixed issue that non-existing (archived) VMs were synced + (https://github.com/ansible-collections/community.general/pull/720). + - cobbler_sync, cobbler_system - fix SSL/TLS certificate check when ``validate_certs`` + set to ``false`` (https://github.com/ansible-collections/community.general/pull/1880). + - consul_io inventory script - kv_groups - fix byte chain decoding for Python + 3 (https://github.com/ansible-collections/community.general/pull/620). + - 'cronvar - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819).' + - 'dconf - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819).' + - deploy_helper - allow ``state=clean`` to be used without defining a ``release`` + (https://github.com/ansible-collections/community.general/issues/1852). + - dimensiondata_network - bug when formatting message, instead of % a simple + comma was used (https://github.com/ansible-collections/community.general/pull/2139). + - diy callback plugin - wrapped usages of ``dict.keys()`` in ``list()`` for + Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - elasticsearch_plugin - ``state`` parameter choices must use ``list()`` in + python3 (https://github.com/ansible-collections/community.general/pull/1830). + - filesystem - do not fail when ``resizefs=yes`` and ``fstype=xfs`` if there + is nothing to do, even if the filesystem is not mounted. This only covers + systems supporting access to unmounted XFS filesystems. Others will still + fail (https://github.com/ansible-collections/community.general/issues/1457, + https://github.com/ansible-collections/community.general/pull/1478). + - 'filesystem - internal refactoring: replaced uses of ``_`` with ``dummy`` + (https://github.com/ansible-collections/community.general/pull/1819).' + - filesystem - remove ``swap`` from list of FS supported by ``resizefs=yes`` + (https://github.com/ansible-collections/community.general/issues/790). + - funcd connection plugin - can now load (https://github.com/ansible-collections/community.general/pull/2235). + - git_config - fixed scope ``file`` behaviour and added integraton test for + it (https://github.com/ansible-collections/community.general/issues/2117). + - git_config - prevent ``run_command`` from expanding values (https://github.com/ansible-collections/community.general/issues/1776). + - github_repo - PyGithub bug does not allow explicit port in ``base_url``. Specifying + port is not required (https://github.com/PyGithub/PyGithub/issues/1913). + - gitlab_runner - parameter ``registration_token`` was required but is used + only when ``state`` is ``present`` (https://github.com/ansible-collections/community.general/issues/1714). + - gitlab_user - make updates to the ``isadmin``, ``password`` and ``confirm`` + options of an already existing GitLab user work (https://github.com/ansible-collections/community.general/pull/1724). + - haproxy - fix a bug preventing haproxy from properly entering ``DRAIN`` mode + (https://github.com/ansible-collections/community.general/issues/1913). + - hiera lookup plugin - converts the return type of plugin to unicode string + (https://github.com/ansible-collections/community.general/pull/2329). + - 'hipchat - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819).' + - idrac_redfish_command - wrapped usages of ``dict.keys()`` in ``list()`` for + Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - idrac_redfish_config - wrapped usages of ``dict.keys()`` in ``list()`` for + Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - idrac_redfish_info - wrapped usages of ``dict.keys()`` in ``list()`` for Python + 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - imc_rest - explicitly logging out instead of registering the call in ```atexit``` + (https://github.com/ansible-collections/community.general/issues/1735). + - influxdb_retention_policy - ensure idempotent module execution with different + duration and shard duration parameter values (https://github.com/ansible-collections/community.general/issues/2281). + - infoblox inventory script - make sure that the script also works with Ansible + 2.9, and returns a more helpful error when community.general is not installed + as part of Ansible 2.10/3 (https://github.com/ansible-collections/community.general/pull/1871). + - ini_file - allows an empty string as a value for an option (https://github.com/ansible-collections/community.general/pull/1972). + - 'interfaces_file - internal refactoring: replaced uses of ``_`` with ``dummy`` + (https://github.com/ansible-collections/community.general/pull/1819).' + - ipa_user - allow ``sshpubkey`` to permit multiple word comments (https://github.com/ansible-collections/community.general/pull/2159). + - iso_extract - use proper alias deprecation mechanism for ``thirsty`` alias + of ``force`` (https://github.com/ansible-collections/community.general/pull/1830). + - 'java_cert - allow setting ``state: absent`` by providing just the ``cert_alias`` + (https://github.com/ansible/ansible/issues/27982).' + - 'java_cert - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819).' + - java_cert - properly handle proxy arguments when the scheme is provided (https://github.com/ansible/ansible/issues/54481). + - java_keystore - improve error handling and return ``cmd`` as documented. Force + ``LANG``, ``LC_ALL`` and ``LC_MESSAGES`` environment variables to ``C`` to + rely on ``keytool`` output parsing. Fix pylint's ``unused-variable`` and ``no-else-return`` + hints (https://github.com/ansible-collections/community.general/pull/2183). + - java_keystore - use tempfile lib to create temporary files with randomized + names, and remove the temporary PKCS#12 keystore as well as other materials + (https://github.com/ansible-collections/community.general/issues/1667). + - jenkins_plugin - fixes Python 2 compatibility issue (https://github.com/ansible-collections/community.general/pull/2340). + - jira - fixed calling of ``isinstance`` (https://github.com/ansible-collections/community.general/issues/2234). + - jira - fixed error when loading base64-encoded content as attachment (https://github.com/ansible-collections/community.general/pull/2349). + - jira - fixed fields' update in ticket transitions (https://github.com/ansible-collections/community.general/issues/818). + - kibana_plugin - ``state`` parameter choices must use ``list()`` in python3 + (https://github.com/ansible-collections/community.general/pull/1830). + - kibana_plugin - added missing parameters to ``remove_plugin`` when using ``state=present + force=true``, and fix potential quoting errors when invoking ``kibana`` (https://github.com/ansible-collections/community.general/pull/2143). + - logstash_plugin - wrapped ``dict.keys()`` with ``list`` for use in ``choices`` + setting (https://github.com/ansible-collections/community.general/pull/1830). + - 'lvg - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819).' + - lvol - fixed sizing calculation rounding to match the underlying tools (https://github.com/ansible-collections/community.general/issues/1988). + - 'lvol - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819).' + - 'lxc - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819).' + - 'lxc_container - internal refactoring: replaced uses of ``_`` with ``dummy`` + (https://github.com/ansible-collections/community.general/pull/1819).' + - lxc_container - wrapped usages of ``dict.keys()`` in ``list()`` for Python + 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - lxd_container - wrapped usages of ``dict.keys()`` in ``list()`` for Python + 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - manageiq_provider - wrapped ``dict.keys()`` with ``list`` for use in ``choices`` + setting (https://github.com/ansible-collections/community.general/pull/1970). + - memcached cache plugin - wrapped usages of ``dict.keys()`` in ``list()`` for + Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - meta/runtime.yml - improve deprecation messages (https://github.com/ansible-collections/community.general/pull/1918). + - module_helper module utils - actually ignoring formatting of parameters with + value ``None`` (https://github.com/ansible-collections/community.general/pull/2024). + - module_helper module utils - fixed decorator ``cause_changes`` (https://github.com/ansible-collections/community.general/pull/2203). + - module_helper module utils - handling ``ModuleHelperException`` now properly + calls ``fail_json()`` (https://github.com/ansible-collections/community.general/pull/2024). + - module_helper module utils - use the command name as-is in ``CmdMixin`` if + it fails ``get_bin_path()`` - allowing full path names to be passed (https://github.com/ansible-collections/community.general/pull/2024). + - net_tools.nios.api module_utils - wrapped usages of ``dict.keys()`` in ``list()`` + for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - nios* modules - fix modules to work with ansible-core 2.11 (https://github.com/ansible-collections/community.general/pull/2057). + - nios_host_record - allow DNS Bypass for views other than default (https://github.com/ansible-collections/community.general/issues/1786). + - nmap inventory plugin - fix cache and constructed group support (https://github.com/ansible-collections/community.general/issues/2242). + - nmcli - add ``method4`` and ``method6`` options (https://github.com/ansible-collections/community.general/pull/1894). + - nmcli - ensure the ``slave-type`` option is passed to ``nmcli`` for type ``bond-slave`` + (https://github.com/ansible-collections/community.general/pull/1882). + - nomad_job_info - fix module failure when nomad client returns no jobs (https://github.com/ansible-collections/community.general/pull/1721). + - nsot inventory script - wrapped usages of ``dict.keys()`` in ``list()`` for + Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - oci_vcn - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility + (https://github.com/ansible-collections/community.general/pull/1861). + - oneandone_monitoring_policy - wrapped usages of ``dict.keys()`` in ``list()`` + for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - packet_volume_attachment - removed extraneous ``print`` call - old debug? + (https://github.com/ansible-collections/community.general/pull/1970). + - parted - change the regex that decodes the partition size to better support + different formats that parted uses. Change the regex that validates parted's + version string (https://github.com/ansible-collections/community.general/pull/1695). + - 'parted - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819).' + - pkgutil - fixed calls to ``list.extend()`` (https://github.com/ansible-collections/community.general/pull/2161). + - proxmox - removed requirement that root password is provided when containter + state is ``present`` (https://github.com/ansible-collections/community.general/pull/1999). + - proxmox inventory - added handling of commas in KVM agent configuration string + (https://github.com/ansible-collections/community.general/pull/2245). + - proxmox inventory - added handling of extra trailing slashes in the URL (https://github.com/ansible-collections/community.general/pull/1914). + - proxmox inventory - exclude qemu templates from inclusion to the inventory + via pools (https://github.com/ansible-collections/community.general/issues/1986, + https://github.com/ansible-collections/community.general/pull/1991). + - proxmox inventory plugin - allowed proxomox tag string to contain commas when + returned as fact (https://github.com/ansible-collections/community.general/pull/1949). + - proxmox inventory plugin - support network interfaces without IP addresses, + multiple network interfaces and unsupported/commanddisabled guest error (https://github.com/ansible-collections/community.general/pull/2263). + - proxmox lxc - only add the features flag when module parameter ``features`` + is set. Before an empty string was send to proxmox in case the parameter was + not used, which required to use ``root@pam`` for module execution (https://github.com/ansible-collections/community.general/pull/1763). + - proxmox* modules - refactored some parameter validation code into use of ``env_fallback``, + ``required_if``, ``required_together``, ``required_one_of`` (https://github.com/ansible-collections/community.general/pull/1765). + - proxmox_kvm - do not add ``args`` if ``proxmox_default_behavior`` is set to + no_defaults (https://github.com/ansible-collections/community.general/issues/1641). + - proxmox_kvm - fix parameter ``vmid`` passed twice to ``exit_json`` while creating + a virtual machine without cloning (https://github.com/ansible-collections/community.general/issues/1875, + https://github.com/ansible-collections/community.general/pull/1895). + - proxmox_kvm - fix undefined local variable ``status`` when the parameter ``state`` + is either ``stopped``, ``started``, ``restarted`` or ``absent`` (https://github.com/ansible-collections/community.general/pull/1847). + - proxmox_kvm - stop implicitly adding ``force`` equal to ``false``. Proxmox + API requires not implemented parameters otherwise, and assumes ``force`` to + be ``false`` by default anyways (https://github.com/ansible-collections/community.general/pull/1783). + - redfish_command - wrapped usages of ``dict.keys()`` in ``list()`` for Python + 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - redfish_config - wrapped usages of ``dict.keys()`` in ``list()`` for Python + 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - redfish_config module, redfish_utils module utils - fix IndexError in ``SetManagerNic`` + command (https://github.com/ansible-collections/community.general/issues/1692). + - redfish_info module, redfish_utils module utils - add ``Name`` and ``Id`` + properties to output of Redfish inventory commands (https://github.com/ansible-collections/community.general/issues/1650). + - redhat_subscription - ``mutually_exclusive`` was referring to parameter alias + instead of name (https://github.com/ansible-collections/community.general/pull/1795). + - redhat_subscription - wrapped usages of ``dict.keys()`` in ``list()`` for + Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - redis cache plugin - wrapped usages of ``keys()`` in ``list()`` for Python + 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - riak - parameters ``wait_for_handoffs`` and ``wait_for_ring`` are ``int`` + but the default value was ``false`` (https://github.com/ansible-collections/community.general/pull/1830). + - 'rundeck_acl_policy - internal refactoring: replaced uses of ``_`` with ``dummy`` + (https://github.com/ansible-collections/community.general/pull/1819).' + - runit - removed unused code, and passing command as ``list`` instead of ``str`` + to ``run_command()`` (https://github.com/ansible-collections/community.general/pull/1830). + - scaleway inventory plugin - fix pagination on scaleway inventory plugin (https://github.com/ansible-collections/community.general/pull/2036). + - selective callback plugin - adjust import so that the plugin also works with + ansible-core 2.11 (https://github.com/ansible-collections/community.general/pull/1807). + - selective callback plugin - wrapped usages of ``dict.keys()`` in ``list()`` + for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - sensu-silence module - fix json parsing of sensu API responses on Python 3.5 + (https://github.com/ansible-collections/community.general/pull/1703). + - sensu_check - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 + compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - spotinst_aws_elastigroup - wrapped usages of ``dict.keys()`` in ``list()`` + for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - stacki_host - replaced ``default`` to environment variables with ``fallback`` + to them (https://github.com/ansible-collections/community.general/pull/2072). + - 'statusio_maintenance - internal refactoring: replaced uses of ``_`` with + ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819).' + - terraform - fix issue that cause the destroy to fail because from Terraform + 0.15 on, the ``terraform destroy -force`` option is replaced with ``terraform + destroy -auto-approve`` (https://github.com/ansible-collections/community.general/issues/2247). + - terraform - fix issue that cause the execution fail because from Terraform + 0.15 on, the ``-var`` and ``-var-file`` options are no longer available on + ``terraform validate`` (https://github.com/ansible-collections/community.general/pull/2246). + - terraform - remove uses of ``use_unsafe_shell=True`` (https://github.com/ansible-collections/community.general/pull/2246). + - 'timezone - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819).' + - udm_dns_record - fixed default value of parameter ``data`` to match its type + (https://github.com/ansible-collections/community.general/pull/2268). + - utm_utils module_utils - wrapped usages of ``dict.keys()`` in ``list()`` for + Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). + - vdo - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility + (https://github.com/ansible-collections/community.general/pull/1861). + - vmadm - correct type of list elements in ``resolvers`` parameter (https://github.com/ansible-collections/community.general/issues/2135). + - xfconf - module was not honoring check mode when ``state`` was ``absent`` + (https://github.com/ansible-collections/community.general/pull/2185). + - xfs_quota - the feedback for initializing project quota using xfs_quota binary + from ``xfsprogs`` has changed since the version it was written for (https://github.com/ansible-collections/community.general/pull/1596). + - zfs - some ZFS properties could be passed when the dataset/volume did not + exist, but would fail if the dataset already existed, even if the property + matched what was specified in the ansible task (https://github.com/ansible-collections/community.general/issues/868, + https://github.com/ansible-collections/community.general/pull/1833). + - zfs_delegate_admin - the elements of ``users``, ``groups`` and ``permissions`` + are now enforced to be strings (https://github.com/ansible-collections/community.general/pull/1766). + - zypper, zypper_repository - respect ``PATH`` environment variable when resolving + zypper executable path (https://github.com/ansible-collections/community.general/pull/2094). + deprecated_features: + - apt_rpm - deprecated invalid parameter alias ``update-cache``, will be removed + in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). + - composer - deprecated invalid parameter aliases ``working-dir``, ``global-command``, + ``prefer-source``, ``prefer-dist``, ``no-dev``, ``no-scripts``, ``no-plugins``, + ``optimize-autoloader``, ``classmap-authoritative``, ``apcu-autoloader``, + ``ignore-platform-reqs``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). + - cpanm - parameter ``system_lib`` deprecated in favor of using ``become`` (https://github.com/ansible-collections/community.general/pull/2218). + - github_deploy_key - deprecated invalid parameter alias ``2fa_token``, will + be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). + - grove - the option ``message`` will be removed in community.general 4.0.0. + Use the new option ``message_content`` instead (https://github.com/ansible-collections/community.general/pull/1929). + - homebrew - deprecated invalid parameter alias ``update-brew``, will be removed + in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). + - homebrew_cask - deprecated invalid parameter alias ``update-brew``, will be + removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). + - opkg - deprecated invalid parameter alias ``update-cache``, will be removed + in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). + - pacman - deprecated invalid parameter alias ``update-cache``, will be removed + in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). + - puppet - deprecated undocumented parameter ``show_diff``, will be removed + in 7.0.0. (https://github.com/ansible-collections/community.general/pull/1927). + - runit - unused parameter ``dist`` marked for deprecation (https://github.com/ansible-collections/community.general/pull/1830). + - slackpkg - deprecated invalid parameter alias ``update-cache``, will be removed + in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). + - urmpi - deprecated invalid parameter aliases ``update-cache`` and ``no-recommends``, + will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). + - xbps - deprecated invalid parameter alias ``update-cache``, will be removed + in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). + - xfconf - returning output as facts is deprecated, this will be removed in + community.general 4.0.0. Please register the task output in a variable and + use it instead. You can already switch to the new behavior now by using the + new ``disable_facts`` option (https://github.com/ansible-collections/community.general/pull/1747). + minor_changes: + - apache2_mod_proxy - refactored/cleaned-up part of the code (https://github.com/ansible-collections/community.general/pull/2142). + - archive - refactored some reused code out into a couple of functions (https://github.com/ansible-collections/community.general/pull/2061). + - atomic_container - using ``get_bin_path()`` before calling ``run_command()`` + (https://github.com/ansible-collections/community.general/pull/2144). + - atomic_host - using ``get_bin_path()`` before calling ``run_command()`` (https://github.com/ansible-collections/community.general/pull/2144). + - atomic_image - using ``get_bin_path()`` before calling ``run_command()`` (https://github.com/ansible-collections/community.general/pull/2144). + - beadm - minor refactor converting multiple statements to a single list literal + (https://github.com/ansible-collections/community.general/pull/2160). + - bitbucket_pipeline_variable - removed unreachable code (https://github.com/ansible-collections/community.general/pull/2157). + - bundler - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - clc_* modules - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1771). + - consul - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - consul_acl - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - consul_io inventory script - conf options - allow custom configuration options + via env variables (https://github.com/ansible-collections/community.general/pull/620). + - consul_session - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - cpanm - honor and install specified version when running in ``new`` mode; + that feature is not available in ``compatibility`` mode (https://github.com/ansible-collections/community.general/issues/208). + - cpanm - rewritten using ``ModuleHelper`` (https://github.com/ansible-collections/community.general/pull/2218). + - csv module utils - new module_utils for shared functions between ``from_csv`` + filter and ``read_csv`` module (https://github.com/ansible-collections/community.general/pull/2037). + - datadog_monitor - add missing monitor types ``query alert``, ``trace-analytics + alert``, ``rum alert`` (https://github.com/ansible-collections/community.general/pull/1723). + - datadog_monitor - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - dnsimple - add CAA records to the whitelist of valid record types (https://github.com/ansible-collections/community.general/pull/1814). + - dnsimple - elements of list parameters ``record_ids`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - gitlab_deploy_key - when the given key title already exists but has a different + public key, the public key will now be updated to given value (https://github.com/ansible-collections/community.general/pull/1661). + - gitlab_runner - elements of list parameters ``tag_list`` are now validated + (https://github.com/ansible-collections/community.general/pull/1795). + - grove - the option ``message`` has been renamed to ``message_content``. The + old name ``message`` is kept as an alias and will be removed for community.general + 4.0.0. This was done because ``message`` is used internally by Ansible (https://github.com/ansible-collections/community.general/pull/1929). + - heroku_collaborator - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). + - hiera lookup - minor refactor converting multiple statements to a single list + literal (https://github.com/ansible-collections/community.general/pull/2160). + - homebrew_tap - add support to specify search path for ``brew`` executable + (https://github.com/ansible-collections/community.general/issues/1702). + - ipa_config - add new options ``ipaconfigstring``, ``ipadefaultprimarygroup``, + ``ipagroupsearchfields``, ``ipahomesrootdir``, ``ipabrkauthzdata``, ``ipamaxusernamelength``, + ``ipapwdexpadvnotify``, ``ipasearchrecordslimit``, ``ipasearchtimelimit``, + ``ipauserauthtype``, and ``ipausersearchfields`` (https://github.com/ansible-collections/community.general/pull/2116). + - ipa_sudorule - add support for setting sudo runasuser (https://github.com/ansible-collections/community.general/pull/2031). + - ipa_user - fix ``userauthtype`` option to take in list of strings for the + multi-select field instead of single string (https://github.com/ansible-collections/community.general/pull/2174). + - ipwcli_dns - minor refactor converting multiple statements to a single list + literal (https://github.com/ansible-collections/community.general/pull/2160). + - 'java_cert - change ``state: present`` to check certificates by hash, not + just alias name (https://github.com/ansible/ansible/issues/43249).' + - java_keystore - add options ``certificate_path`` and ``private_key_path``, + mutually exclusive with ``certificate`` and ``private_key`` respectively, + and targetting files on remote hosts rather than their contents on the controller. + (https://github.com/ansible-collections/community.general/issues/1669). + - jenkins_job - add a ``validate_certs`` parameter that allows disabling TLS/SSL + certificate validation (https://github.com/ansible-collections/community.general/issues/255). + - jira - added ``attach`` operation, which allows a user to attach a file to + an issue (https://github.com/ansible-collections/community.general/pull/2192). + - jira - added parameter ``account_id`` for compatibility with recent versions + of JIRA (https://github.com/ansible-collections/community.general/issues/818, + https://github.com/ansible-collections/community.general/pull/1978). + - jira - revamped the module as a class using ``ModuleHelper`` (https://github.com/ansible-collections/community.general/pull/2208). + - keycloak_* modules - allow the keycloak modules to use a token for the authentication, + the modules can take either a token or the credentials (https://github.com/ansible-collections/community.general/pull/2250). + - keycloak_client - elements of list parameters ``default_roles``, ``redirect_uris``, + ``web_origins`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - kibana_plugin - add parameter for passing ``--allow-root`` flag to kibana + and kibana-plugin commands (https://github.com/ansible-collections/community.general/pull/2014). + - known_hosts module utils - minor refactor converting multiple statements to + a single list literal (https://github.com/ansible-collections/community.general/pull/2160). + - librato_annotation - elements of list parameters ``links`` are now validated + (https://github.com/ansible-collections/community.general/pull/1795). + - linode_v4 - add support for ``private_ip`` option (https://github.com/ansible-collections/community.general/pull/2249). + - linode_v4 - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). + - lvol - added proper support for ``+-`` options when extending or reducing + the logical volume (https://github.com/ansible-collections/community.general/issues/1988). + - lxd_container - ``client_key`` and ``client_cert`` are now of type ``path`` + and no longer ``str``. A side effect is that certain expansions are made, + like ``~`` is replaced by the user's home directory, and environment variables + like ``$HOME`` or ``$TEMP`` are evaluated (https://github.com/ansible-collections/community.general/pull/1741). + - lxd_container - elements of list parameter ``profiles`` are now validated + (https://github.com/ansible-collections/community.general/pull/1795). + - lxd_profile - ``client_key`` and ``client_cert`` are now of type ``path`` + and no longer ``str``. A side effect is that certain expansions are made, + like ``~`` is replaced by the user's home directory, and environment variables + like ``$HOME`` or ``$TEMP`` are evaluated (https://github.com/ansible-collections/community.general/pull/1741). + - lxd_profile - added ``merge_profile`` parameter to merge configurations from + the play to an existing profile (https://github.com/ansible-collections/community.general/pull/1813). + - mail - elements of list parameters ``to``, ``cc``, ``bcc``, ``attach``, ``headers`` + are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - manageiq_alert_profiles - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). + - manageiq_policies - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). + - manageiq_tags - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). + - manageiq_tags and manageiq_policies - added new parameter ``resource_id``. + This parameter can be used instead of parameter ``resource_name`` (https://github.com/ansible-collections/community.general/pull/719). + - module_helper module utils - ``CmdMixin.run_command()`` now accepts ``dict`` + command arguments, providing the parameter and its value (https://github.com/ansible-collections/community.general/pull/1867). + - module_helper module utils - added management of facts and adhoc setting of + the initial value for variables (https://github.com/ansible-collections/community.general/pull/2188). + - module_helper module utils - added mechanism to manage variables, providing + automatic output of variables, change status and diff information (https://github.com/ansible-collections/community.general/pull/2162). + - na_ontap_gather_facts - elements of list parameters ``gather_subset`` are + now validated (https://github.com/ansible-collections/community.general/pull/1795). + - nexmo - elements of list parameters ``dest`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - nictagadm - minor refactor converting multiple statements to a single list + literal (https://github.com/ansible-collections/community.general/pull/2160). + - nmcli - add ability to connect to a Wifi network and also to attach it to + a master (bond) (https://github.com/ansible-collections/community.general/pull/2220). + - nmcli - do not set IP configuration on slave connection (https://github.com/ansible-collections/community.general/pull/2223). + - nmcli - don't restrict the ability to manually set the MAC address to the + bridge (https://github.com/ansible-collections/community.general/pull/2224). + - npm - add ``no_bin_links`` option (https://github.com/ansible-collections/community.general/issues/2128). + - nsupdate - elements of list parameters ``value`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - oci_vcn - ``api_user_key_file`` is now of type ``path`` and no longer ``str``. + A side effect is that certain expansions are made, like ``~`` is replaced + by the user's home directory, and environment variables like ``$HOME`` or + ``$TEMP`` are evaluated (https://github.com/ansible-collections/community.general/pull/1741). + - omapi_host - elements of list parameters ``statements`` are now validated + (https://github.com/ansible-collections/community.general/pull/1795). + - one_host - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). + - one_image_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). + - one_vm - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). + - oneandone_firewall_policy - elements of list parameters are now validated + (https://github.com/ansible-collections/community.general/pull/1885). + - oneandone_load_balancer - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - oneandone_monitoring_policy - elements of list parameters are now validated + (https://github.com/ansible-collections/community.general/pull/1885). + - oneandone_private_network - elements of list parameters are now validated + (https://github.com/ansible-collections/community.general/pull/1885). + - oneandone_server - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - onepassword_info - elements of list parameters ``search_terms`` are now validated + (https://github.com/ansible-collections/community.general/pull/1795). + - oneview_datacenter_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). + - oneview_enclosure_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). + - oneview_ethernet_network_info - elements of list parameters are now validated + (https://github.com/ansible-collections/community.general/pull/1970). + - oneview_network_set_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). + - ovh_ip_failover - removed unreachable code (https://github.com/ansible-collections/community.general/pull/2157). + - packet_device - elements of list parameters ``device_ids``, ``hostnames`` + are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - pagerduty - elements of list parameters ``service`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - pids - new options ``pattern`` and `ignore_case`` for retrieving PIDs of + processes matching a supplied pattern (https://github.com/ansible-collections/community.general/pull/2280). + - plugins/module_utils/oracle/oci_utils.py - elements of list parameter ``key_by`` + are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - profitbricks - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - profitbricks_volume - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - proxmox - added ``purge`` module parameter for use when deleting lxc's with + HA options (https://github.com/ansible-collections/community.general/pull/2013). + - proxmox inventory plugin - added ``Constructable`` class to the inventory + to provide options ``strict``, ``keyed_groups``, ``groups``, and ``compose`` + (https://github.com/ansible-collections/community.general/pull/2180). + - proxmox inventory plugin - added ``proxmox_agent_interfaces`` fact describing + network interfaces returned from a QEMU guest agent (https://github.com/ansible-collections/community.general/pull/2148). + - proxmox inventory plugin - added ``tags_parsed`` fact containing tags parsed + as a list (https://github.com/ansible-collections/community.general/pull/1949). + - proxmox inventory plugin - allow to select whether ``ansible_host`` should + be set for the proxmox nodes (https://github.com/ansible-collections/community.general/pull/2263). + - proxmox_kvm - added new module parameter ``tags`` for use with PVE 6+ (https://github.com/ansible-collections/community.general/pull/2000). + - proxmox_kvm module - actually implemented ``vmid`` and ``status`` return values. + Updated documentation to reflect current situation (https://github.com/ansible-collections/community.general/issues/1410, + https://github.com/ansible-collections/community.general/pull/1715). + - pubnub_blocks - elements of list parameters ``event_handlers`` are now validated + (https://github.com/ansible-collections/community.general/pull/1795). + - rax - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2006). + - rax_cdb_user - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2006). + - rax_scaling_group - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2006). + - read_csv - refactored read_csv module to use shared csv functions from csv + module_utils (https://github.com/ansible-collections/community.general/pull/2037). + - redfish modules - explicitly setting lists' elements to ``str`` (https://github.com/ansible-collections/community.general/pull/1761). + - redfish_* modules, redfish_utils module utils - add support for Redfish session + create, delete, and authenticate (https://github.com/ansible-collections/community.general/issues/1975). + - redfish_config - case insensitive search for situations where the hostname/FQDN + case on iLO doesn't match variable's case (https://github.com/ansible-collections/community.general/pull/1744). + - redhat_subscription - elements of list parameters ``pool_ids``, ``addons`` + are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - rhevm - removed unreachable code (https://github.com/ansible-collections/community.general/pull/2157). + - rocketchat - elements of list parameters ``attachments`` are now validated + (https://github.com/ansible-collections/community.general/pull/1795). + - scaleway_compute - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). + - scaleway_lb - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). + - sendgrid - elements of list parameters ``to_addresses``, ``cc``, ``bcc``, + ``attachments`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - sensu_check - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - sensu_client - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - sensu_handler - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - sl_vm - elements of list parameters ``disks``, ``ssh_keys`` are now validated + (https://github.com/ansible-collections/community.general/pull/1795). + - slack - elements of list parameters ``attachments`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - smartos_image_info - minor refactor converting multiple statements to a single + list literal (https://github.com/ansible-collections/community.general/pull/2160). + - snmp_facts - added parameters ``timeout`` and ``retries`` to module (https://github.com/ansible-collections/community.general/issues/980). + - statusio_maintenance - elements of list parameters ``components``, ``containers`` + are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - svr4pkg - minor refactor converting multiple statements to a single list literal + (https://github.com/ansible-collections/community.general/pull/2160). + - terraform - add ``plugin_paths`` parameter which allows disabling Terraform + from performing plugin discovery and auto-download (https://github.com/ansible-collections/community.general/pull/2308). + - timezone - add Gentoo and Alpine Linux support (https://github.com/ansible-collections/community.general/issues/781). + - twilio - elements of list parameters ``to_numbers`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - udm_dns_zone - elements of list parameters ``nameserver``, ``interfaces``, + and ``mx`` are now validated (https://github.com/ansible-collections/community.general/pull/2268). + - vdo - add ``force`` option (https://github.com/ansible-collections/community.general/issues/2101). + - vmadm - elements of list parameters ``disks``, ``nics``, ``resolvers``, ``filesystems`` + are now validated (https://github.com/ansible-collections/community.general/pull/1795). + - webfaction_domain - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - webfaction_site - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). + - xattr - minor refactor converting multiple statements to a single list literal + (https://github.com/ansible-collections/community.general/pull/2160). + - xfconf - added option ``disable_facts`` to disable facts and its associated + deprecation warning (https://github.com/ansible-collections/community.general/issues/1475). + - xfconf - changed implementation to use ``ModuleHelper`` new features (https://github.com/ansible-collections/community.general/pull/2188). + - xml - elements of list parameters ``add_children``, ``set_children`` are now + validated (https://github.com/ansible-collections/community.general/pull/1795). + - yum_versionlock - Do the lock/unlock concurrently to speed up (https://github.com/ansible-collections/community.general/pull/1912). + - zfs_facts - minor refactor converting multiple statements to a single list + literal (https://github.com/ansible-collections/community.general/pull/2160). + - zpool_facts - minor refactor converting multiple statements to a single list + literal (https://github.com/ansible-collections/community.general/pull/2160). + release_summary: This is release 3.0.0 of ``community.general``, released on + 2021-04-26. + removed_features: + - "The ``ome_device_info``, ``idrac_firmware`` and ``idrac_server_config_profile`` + \ modules have now been migrated from community.general to the `dellemc.openmanage + `_ Ansible collection.\nIf + you use ansible-base 2.10 or newer, redirections have been provided.\n\nIf + you use Ansible 2.9 and installed this collection, you need to adjust the + FQCNs (``community.general.idrac_firmware`` \u2192 ``dellemc.openmanage.idrac_firmware``) + and make sure to install the dellemc.openmanage collection.\n" + - The deprecated ali_instance_facts module has been removed. Use ali_instance_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated gluster_heal_info module has been removed. Use gluster.gluster.gluster_heal_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated gluster_peer module has been removed. Use gluster.gluster.gluster_peer + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated gluster_volume module has been removed. Use gluster.gluster.gluster_volume + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated helm module has been removed. Use community.kubernetes.helm + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated hpilo_facts module has been removed. Use hpilo_info instead + (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated idrac_redfish_facts module has been removed. Use idrac_redfish_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated jenkins_job_facts module has been removed. Use jenkins_job_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ldap_attr module has been removed. Use ldap_attrs instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated memset_memstore_facts module has been removed. Use memset_memstore_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated memset_server_facts module has been removed. Use memset_server_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated na_ontap_gather_facts module has been removed. Use netapp.ontap.na_ontap_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated nginx_status_facts module has been removed. Use nginx_status_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated one_image_facts module has been removed. Use one_image_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated onepassword_facts module has been removed. Use onepassword_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated oneview_datacenter_facts module has been removed. Use oneview_datacenter_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated oneview_enclosure_facts module has been removed. Use oneview_enclosure_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated oneview_ethernet_network_facts module has been removed. Use + oneview_ethernet_network_info instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated oneview_fc_network_facts module has been removed. Use oneview_fc_network_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated oneview_fcoe_network_facts module has been removed. Use oneview_fcoe_network_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated oneview_logical_interconnect_group_facts module has been removed. + Use oneview_logical_interconnect_group_info instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated oneview_network_set_facts module has been removed. Use oneview_network_set_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated oneview_san_manager_facts module has been removed. Use oneview_san_manager_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated online_server_facts module has been removed. Use online_server_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated online_user_facts module has been removed. Use online_user_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt module has been removed. Use ovirt.ovirt.ovirt_vm instead + (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_affinity_label_facts module has been removed. Use ovirt.ovirt.ovirt_affinity_label_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_api_facts module has been removed. Use ovirt.ovirt.ovirt_api_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_cluster_facts module has been removed. Use ovirt.ovirt.ovirt_cluster_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_datacenter_facts module has been removed. Use ovirt.ovirt.ovirt_datacenter_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_disk_facts module has been removed. Use ovirt.ovirt.ovirt_disk_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_event_facts module has been removed. Use ovirt.ovirt.ovirt_event_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_external_provider_facts module has been removed. Use + ovirt.ovirt.ovirt_external_provider_info instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_group_facts module has been removed. Use ovirt.ovirt.ovirt_group_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_host_facts module has been removed. Use ovirt.ovirt.ovirt_host_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_host_storage_facts module has been removed. Use ovirt.ovirt.ovirt_host_storage_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_network_facts module has been removed. Use ovirt.ovirt.ovirt_network_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_nic_facts module has been removed. Use ovirt.ovirt.ovirt_nic_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_permission_facts module has been removed. Use ovirt.ovirt.ovirt_permission_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_quota_facts module has been removed. Use ovirt.ovirt.ovirt_quota_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_scheduling_policy_facts module has been removed. Use + ovirt.ovirt.ovirt_scheduling_policy_info instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_snapshot_facts module has been removed. Use ovirt.ovirt.ovirt_snapshot_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_storage_domain_facts module has been removed. Use ovirt.ovirt.ovirt_storage_domain_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_storage_template_facts module has been removed. Use ovirt.ovirt.ovirt_storage_template_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_storage_vm_facts module has been removed. Use ovirt.ovirt.ovirt_storage_vm_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_tag_facts module has been removed. Use ovirt.ovirt.ovirt_tag_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_template_facts module has been removed. Use ovirt.ovirt.ovirt_template_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_user_facts module has been removed. Use ovirt.ovirt.ovirt_user_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_vm_facts module has been removed. Use ovirt.ovirt.ovirt_vm_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated ovirt_vmpool_facts module has been removed. Use ovirt.ovirt.ovirt_vmpool_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated purefa_facts module has been removed. Use purestorage.flasharray.purefa_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated purefb_facts module has been removed. Use purestorage.flasharray.purefb_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated python_requirements_facts module has been removed. Use python_requirements_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated redfish_facts module has been removed. Use redfish_info instead + (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated scaleway_image_facts module has been removed. Use scaleway_image_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated scaleway_ip_facts module has been removed. Use scaleway_ip_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated scaleway_organization_facts module has been removed. Use scaleway_organization_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated scaleway_security_group_facts module has been removed. Use + scaleway_security_group_info instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated scaleway_server_facts module has been removed. Use scaleway_server_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated scaleway_snapshot_facts module has been removed. Use scaleway_snapshot_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated scaleway_volume_facts module has been removed. Use scaleway_volume_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated smartos_image_facts module has been removed. Use smartos_image_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated vertica_facts module has been removed. Use vertica_info instead + (https://github.com/ansible-collections/community.general/pull/1924). + - The deprecated xenserver_guest_facts module has been removed. Use xenserver_guest_info + instead (https://github.com/ansible-collections/community.general/pull/1924). + - The ovirt_facts docs fragment has been removed (https://github.com/ansible-collections/community.general/pull/1924). + - airbrake_deployment - removed deprecated ``token`` parameter. Use ``project_id`` + and ``project_key`` instead (https://github.com/ansible-collections/community.general/pull/1926). + - bigpanda - the alias ``message`` has been removed. Use ``deployment_message`` + instead (https://github.com/ansible-collections/community.general/pull/1926). + - cisco_spark, cisco_webex - the alias ``message`` has been removed. Use ``msg`` + instead (https://github.com/ansible-collections/community.general/pull/1926). + - clc_aa_policy - the ``wait`` parameter has been removed. It did not have any + effect (https://github.com/ansible-collections/community.general/pull/1926). + - datadog_monitor - the alias ``message`` has been removed. Use ``notification_message`` + instead (https://github.com/ansible-collections/community.general/pull/1926). + - django_manage - the parameter ``liveserver`` has been removed (https://github.com/ansible-collections/community.general/pull/1926). + - idrac_redfish_config - the parameters ``manager_attribute_name`` and ``manager_attribute_value`` + have been removed. Use ``manager_attributes`` instead (https://github.com/ansible-collections/community.general/pull/1926). + - iso_extract - the alias ``thirsty`` has been removed. Use ``force`` instead + (https://github.com/ansible-collections/community.general/pull/1926). + - ldap_entry - the ``params`` parameter is now completely removed. Using it + already triggered an error since community.general 0.1.2 (https://github.com/ansible-collections/community.general/pull/2257). + - pulp_repo - the ``feed_client_cert`` parameter no longer defaults to the value + of the ``client_cert`` parameter (https://github.com/ansible-collections/community.general/pull/1926). + - pulp_repo - the ``feed_client_key`` parameter no longer defaults to the value + of the ``client_key`` parameter (https://github.com/ansible-collections/community.general/pull/1926). + - pulp_repo - the alias ``ca_cert`` has been removed. Use ``feed_ca_cert`` instead + (https://github.com/ansible-collections/community.general/pull/1926). + - rax - unused parameter ``service`` removed (https://github.com/ansible-collections/community.general/pull/2020). + - redfish modules - issuing a data modification command without specifying the + ID of the target System, Chassis or Manager resource when there is more than + one is no longer allowed. Use the ``resource_id`` option to specify the target + ID (https://github.com/ansible-collections/community.general/pull/1926). + - redfish_config - the parameters ``bios_attribute_name`` and ``bios_attribute_value`` + have been removed. Use ``bios_attributes`` instead (https://github.com/ansible-collections/community.general/pull/1926). + - syspatch - the ``apply`` parameter has been removed. This is the default mode, + so simply removing it will not change the behavior (https://github.com/ansible-collections/community.general/pull/1926). + - xbps - the ``force`` parameter has been removed. It did not have any effect + (https://github.com/ansible-collections/community.general/pull/1926). + security_fixes: + - dnsmadeeasy - mark the ``account_key`` parameter as ``no_log`` to avoid leakage + of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - gitlab_runner - mark the ``registration_token`` parameter as ``no_log`` to + avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - hwc_ecs_instance - mark the ``admin_pass`` parameter as ``no_log`` to avoid + leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - ibm_sa_host - mark the ``iscsi_chap_secret`` parameter as ``no_log`` to avoid + leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - java_cert - remove password from ``run_command`` arguments (https://github.com/ansible-collections/community.general/pull/2008). + - java_keystore - pass secret to keytool through an environment variable to + not expose it as a commandline argument (https://github.com/ansible-collections/community.general/issues/1668). + - keycloak_* modules - mark the ``auth_client_secret`` parameter as ``no_log`` + to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - keycloak_client - mark the ``registration_access_token`` parameter as ``no_log`` + to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - librato_annotation - mark the ``api_key`` parameter as ``no_log`` to avoid + leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - logentries_msg - mark the ``token`` parameter as ``no_log`` to avoid leakage + of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - module_utils/_netapp, na_ontap_gather_facts - enabled ``no_log`` for the options + ``api_key`` and ``secret_key`` to prevent accidental disclosure (CVE-2021-20191, + https://github.com/ansible-collections/community.general/pull/1725). + - module_utils/identity/keycloak, keycloak_client, keycloak_clienttemplate, + keycloak_group - enabled ``no_log`` for the option ``auth_client_secret`` + to prevent accidental disclosure (CVE-2021-20191, https://github.com/ansible-collections/community.general/pull/1725). + - nios_nsgroup - mark the ``tsig_key`` parameter as ``no_log`` to avoid leakage + of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - oneandone_firewall_policy, oneandone_load_balancer, oneandone_monitoring_policy, + oneandone_private_network, oneandone_public_ip - mark the ``auth_token`` parameter + as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - ovirt - mark the ``instance_key`` parameter as ``no_log`` to avoid leakage + of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - ovirt - mark the ``instance_rootpw`` parameter as ``no_log`` to avoid leakage + of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - pagerduty_alert - mark the ``api_key``, ``service_key`` and ``integration_key`` + parameters as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - pagerduty_change - mark the ``integration_key`` parameter as ``no_log`` to + avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - pingdom - mark the ``key`` parameter as ``no_log`` to avoid leakage of secrets + (https://github.com/ansible-collections/community.general/pull/1736). + - pulp_repo - mark the ``feed_client_key`` parameter as ``no_log`` to avoid + leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - rax_clb_ssl - mark the ``private_key`` parameter as ``no_log`` to avoid leakage + of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - redfish_command - mark the ``update_creds.password`` parameter as ``no_log`` + to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - rollbar_deployment - mark the ``token`` parameter as ``no_log`` to avoid leakage + of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - spotinst_aws_elastigroup - mark the ``multai_token`` and ``token`` parameters + as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736). + - stackdriver - mark the ``key`` parameter as ``no_log`` to avoid leakage of + secrets (https://github.com/ansible-collections/community.general/pull/1736). + - utm_proxy_auth_profile - enabled ``no_log`` for the option ``frontend_cookie_secret`` + to prevent accidental disclosure (CVE-2021-20191, https://github.com/ansible-collections/community.general/pull/1725). + - utm_proxy_auth_profile - mark the ``frontend_cookie_secret`` parameter as + ``no_log`` to avoid leakage of secrets. This causes the ``utm_proxy_auth_profile`` + return value to no longer containing the correct value, but a placeholder + (https://github.com/ansible-collections/community.general/pull/1736). + fragments: + - 1475-xfconf-facts.yml + - 1478-filesystem-fix-1457-resizefs-idempotency.yml + - 1596-xfs_quota-feedback_on_projects_not_initialized_has_changed.yml + - 1661-gitlab-deploy-key-update-pubkey.yml + - 1691-add-name-and-id-props-to-redfish-inventory-output.yml + - 1695-parted-updatedregex.yaml + - 1702_homebrew_tap.yml + - 1703-sensu_silence-fix_json_parsing.yml + - 1714-gitlab_runner-required-reg-token.yml + - 1715-proxmox_kvm-add-vmid-to-returns.yml + - 1721-fix-nomad_job_info-no-jobs-failure.yml + - 1722_timezone.yml + - 1723-datadog_monitor-add-missing-monitor-types.yml + - 1724-various-fixes-for-updating-existing-gitlab-user.yml + - 1735-imc-sessions.yml + - 1740-aerospike_migration.yml + - 1741-use-path-argspec.yml + - 1744-case-insensitive-hostname-fqdn-matching.yml + - 1753-document-fstypes-supported-by-resizefs.yml + - 1761-redfish-tidy-up-validation.yml + - 1765-proxmox-params.yml + - 1766-zfs-fixed-sanity.yml + - 1771-centurylink-validation-elements.yml + - 1776-git_config-tilde_value.yml + - 1783-proxmox-kvm-fix-args-500-error.yaml + - 1788-ease-nios_host_record-dns-bypass-check.yml + - 1795-list-elements-batch1.yml + - 1813-lxd_profile-merge-profiles.yml + - 1814-dnsimple-add-support-for-caa-records.yml + - 1819-tidyup-pylint-blacklistnames.yml + - 1830-valmod_docmissingtype_batch1.yml + - 1833-zfs-creation-only-properties.yaml + - 1838-runit-deprecate-param-dist.yml + - 1847-proxmox-kvm-fix-status.yml + - 1852-deploy-helper-fix-state-is-clean-without-release.yaml + - 1861-python3-keys.yml + - 1867-modhelper-cmdmixin-dict-params.yml + - 1871-infoblox-inventory.yml + - 1880-fix_cobbler_system_ssl.yml + - 1882-fix-nmcli-ensure-slave-type-for-bond-slave.yml + - 1885-sanity-check-fixes-batch3.yml + - 1894-feat-nmcli-add-method4-and-method6.yml + - 1895-proxmox-kvm-fix-issue-1875.yml + - 1912-yum_versionlock-lock_unlock_concurrently.yml + - 1914-add-sanitization-to-url.yml + - 1916-add-version-sort-filter.yml + - 1927-removed-parameter-invalid.yml + - 1928-bigpanda-message.yml + - 1929-grove-message.yml + - 1949-proxmox-inventory-tags.yml + - 1970-valmod-batch7.yml + - 1972-ini_file-empty-str-value.yml + - 1977-jenkinsjob-validate-certs.yml + - 1978-jira-transition-logic.yml + - 1991-proxmox-inventory-fix-template-in-pool.yml + - 1993-haproxy-fix-draining.yml + - 1999-proxmox-fix-issue-1955.yml + - 2000-proxmox_kvm-tag-support.yml + - 2001-no_log-false.yml + - 2006-valmod-batch8.yml + - 2008-update-java-cert-replace-cert-when-changed.yml + - 2013-proxmox-purge-parameter.yml + - 2014-allow-root-for-kibana-plugin.yaml + - 2020-remove-unused-param-in-rax.yml + - 2024-module-helper-fixes.yml + - 2027-add-redfish-session-create-delete-authenticate.yml + - 2031-ipa_sudorule_add_runasextusers.yml + - 2032-one_image-pyone.yml + - 2036-scaleway-inventory.yml + - 2037-add-from-csv-filter.yml + - 2040-fix-index-error-in-redfish-set-manager-nic.yml + - 2057-nios-devel.yml + - 2061-archive-refactor1.yml + - 2065-snmp-facts-timeout.yml + - 2072-stacki-host-params-fallback.yml + - 2094-bugfix-respect-PATH-env-variable-in-zypper-modules.yaml + - 2110-vdo-add_force_option.yaml + - 2116-add-fields-to-ipa-config-module.yml + - 2125-git-config-scope-file.yml + - 2135-vmadm-resolvers-type-fix.yml + - 2139-dimensiondata_network-str-format.yml + - 2142-apache2_mod_proxy-cleanup.yml + - 2143-kibana_plugin-fixed-function-calls.yml + - 2144-atomic_get_bin_path.yml + - 2146-npm-add_no_bin_links_option.yaml + - 2148-proxmox-inventory-agent-interfaces.yml + - 2157-unreachable-code.yml + - 2159-ipa-user-sshpubkey-multi-word-comments.yaml + - 2160-list-literals.yml + - 2161-pkgutil-list-extend.yml + - 2162-modhelper-variables.yml + - 2162-proxmox-constructable.yml + - 2163-java_keystore_1667_improve_temp_files_storage.yml + - 2174-ipa-user-userauthtype-multiselect.yml + - 2177-java_keystore_1668_dont_expose_secrets_on_cmdline.yml + - 2183-java_keystore_improve_error_handling.yml + - 2185-xfconf-absent-check-mode.yml + - 2188-xfconf-modhelper-variables.yml + - 2192-add-jira-attach.yml + - 2203-modhelper-cause-changes-deco.yml + - 2204-github_repo-fix-baseurl_port.yml + - 2208-jira-revamp.yml + - 2218-cpanm-revamp.yml + - 2220_nmcli_wifi_support.yaml + - 2223_nmcli_no_IP_config_on_slave.yaml + - 2224_nmcli_allow_MAC_overwrite.yaml + - 2230-java_keystore-1669-ssl-input-files-by-path.yml + - 2236-jira-isinstance.yml + - 2244-hashids-filters.yml + - 2245-proxmox_fix_agent_string_handling.yml + - 2246-terraform.yaml + - 2249-linode_v4-support-private_ip-option.yaml + - 2250-allow-keycloak-modules-to-take-token-as-param.yml + - 2257-ldap_entry-params.yml + - 2259-proxmox-multi-nic-and-unsupported.yml + - 2262-java_keystore-passphrase.yml + - 2267-lvol_size_addition-subtraction_support.yaml + - 2268-validation-univetion.yml + - 2280-pids-new-pattern-option.yml + - 2282-nmap-fix-cache-support.yml + - 2284-influxdb_retention_policy-idempotence.yml + - 2308-terraform-add-plugin_paths-parameter.yaml + - 2329-hiera-lookup-plugin-return-type.yaml + - 2340-jenkins_plugin-py2.yml + - 2349-jira-bugfix-b64decode.yml + - 3.0.0.yml + - 620-consul_io-env-variables-conf-based.yml + - 719-manageiq-resource_id.yml + - 720-cloudforms_inventory.yml + - 816-only-invocate-feature-when-variable-is-set.yml + - 948-dellemc-migration-removal.yml + - CVE-2021-20191_no_log.yml + - allow_funcd_to_load.yml + - dict-filter.yml + - meta-runtime-deprecations.yml + - no_log-fixes.yml + - path_join-shim-filter.yml + - remove-deprecated-features.yml + - remove-deprecated-modules.yml + - selective-core-2.11.yml + modules: + - description: Create a file with a given size, or resize it if it exists + name: filesize + namespace: files + - description: Manage Gandi LiveDNS records + name: gandi_livedns + namespace: net_tools + - description: Manage your repositories on Github + name: github_repo + namespace: source_control.github + - description: Manage project members on GitLab Server + name: gitlab_project_members + namespace: source_control.gitlab + - description: Manage FreeIPA OTP Configuration Settings + name: ipa_otpconfig + namespace: identity.ipa + - description: Manage FreeIPA OTPs + name: ipa_otptoken + namespace: identity.ipa + - description: Manage jenkins builds + name: jenkins_build + namespace: web_infrastructure + - description: Allows administration of Keycloak realm via Keycloak API + name: keycloak_realm + namespace: identity.keycloak + - description: Manages OpenNebula templates + name: one_template + namespace: cloud.opennebula + - description: Manages Pritunl Organizations using the Pritunl API + name: pritunl_org + namespace: net_tools.pritunl + - description: List Pritunl Organizations using the Pritunl API + name: pritunl_org_info + namespace: net_tools.pritunl + - description: Manage Pritunl Users using the Pritunl API + name: pritunl_user + namespace: net_tools.pritunl + - description: List Pritunl Users using the Pritunl API + name: pritunl_user_info + namespace: net_tools.pritunl + - description: Retrieve information about one or more Proxmox VE storages + name: proxmox_storage_info + namespace: cloud.misc + - description: Enforce a model's attributes in CA Spectrum. + name: spectrum_model_attrs + namespace: monitoring + - description: Send metrics to StatsD + name: statsd + namespace: monitoring + - description: Manages Lenovo Out-Of-Band controllers using Redfish APIs + name: xcc_redfish_command + namespace: remote_management.lenovoxcc + plugins: + become: + - description: Run tasks using sudo su - + name: sudosu + namespace: null + callback: + - description: Posts task results to Azure Log Analytics + name: loganalytics + namespace: null + filter: + - description: 'The ``dict`` function as a filter: converts a list of tuples + to a dictionary' + name: dict + namespace: null + - description: Converts CSV text input into list of dicts + name: from_csv + namespace: null + - description: Decodes a sequence of numbers from a YouTube-like hash + name: hashids_decode + namespace: null + - description: Encodes YouTube-like hashes from a sequence of integers + name: hashids_encode + namespace: null + - description: Redirects to ansible.builtin.path_join for ansible-base 2.10 + or newer, and provides a compatible implementation for Ansible 2.9 + name: path_join + namespace: null + - description: Sort a list according to version order instead of pure alphabetical + one + name: version_sort + namespace: null + inventory: + - description: Returns Ansible inventory from lxd host + name: lxd + namespace: null + release_date: '2021-04-26' diff --git a/changelogs/fragments/1475-xfconf-facts.yml b/changelogs/fragments/1475-xfconf-facts.yml deleted file mode 100644 index cffc6f023e..0000000000 --- a/changelogs/fragments/1475-xfconf-facts.yml +++ /dev/null @@ -1,4 +0,0 @@ -minor_changes: - - xfconf - added option ``disable_facts`` to disable facts and its associated deprecation warning (https://github.com/ansible-collections/community.general/issues/1475). -deprecated_features: - - xfconf - returning output as facts is deprecated, this will be removed in community.general 4.0.0. Please register the task output in a variable and use it instead. You can already switch to the new behavior now by using the new ``disable_facts`` option (https://github.com/ansible-collections/community.general/pull/1747). diff --git a/changelogs/fragments/1478-filesystem-fix-1457-resizefs-idempotency.yml b/changelogs/fragments/1478-filesystem-fix-1457-resizefs-idempotency.yml deleted file mode 100644 index a90444308e..0000000000 --- a/changelogs/fragments/1478-filesystem-fix-1457-resizefs-idempotency.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -bugfixes: - - filesystem - do not fail when ``resizefs=yes`` and ``fstype=xfs`` if there is nothing to do, even if - the filesystem is not mounted. This only covers systems supporting access to unmounted XFS filesystems. - Others will still fail (https://github.com/ansible-collections/community.general/issues/1457, https://github.com/ansible-collections/community.general/pull/1478). diff --git a/changelogs/fragments/1596-xfs_quota-feedback_on_projects_not_initialized_has_changed.yml b/changelogs/fragments/1596-xfs_quota-feedback_on_projects_not_initialized_has_changed.yml deleted file mode 100644 index ba75a86a62..0000000000 --- a/changelogs/fragments/1596-xfs_quota-feedback_on_projects_not_initialized_has_changed.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - xfs_quota - the feedback for initializing project quota using xfs_quota binary from ``xfsprogs`` has changed since the version it was written for (https://github.com/ansible-collections/community.general/pull/1596). diff --git a/changelogs/fragments/1661-gitlab-deploy-key-update-pubkey.yml b/changelogs/fragments/1661-gitlab-deploy-key-update-pubkey.yml deleted file mode 100644 index f6edfc6f53..0000000000 --- a/changelogs/fragments/1661-gitlab-deploy-key-update-pubkey.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -minor_changes: - - gitlab_deploy_key - when the given key title already exists but has a different public key, the public key will now be updated to given value (https://github.com/ansible-collections/community.general/pull/1661). -breaking_changes: - - gitlab_deploy_key - if for an already existing key title a different public key was given as parameter nothing happened, now this changed so that the public key is updated to the new value (https://github.com/ansible-collections/community.general/pull/1661). diff --git a/changelogs/fragments/1691-add-name-and-id-props-to-redfish-inventory-output.yml b/changelogs/fragments/1691-add-name-and-id-props-to-redfish-inventory-output.yml deleted file mode 100644 index 1cf8897018..0000000000 --- a/changelogs/fragments/1691-add-name-and-id-props-to-redfish-inventory-output.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - redfish_info module, redfish_utils module utils - add ``Name`` and ``Id`` properties to output of Redfish inventory commands (https://github.com/ansible-collections/community.general/issues/1650). diff --git a/changelogs/fragments/1695-parted-updatedregex.yaml b/changelogs/fragments/1695-parted-updatedregex.yaml deleted file mode 100644 index fb3a5a5eaa..0000000000 --- a/changelogs/fragments/1695-parted-updatedregex.yaml +++ /dev/null @@ -1,4 +0,0 @@ -bugfixes: - - parted - change the regex that decodes the partition size to better support different formats that parted uses. - Change the regex that validates parted's version string - (https://github.com/ansible-collections/community.general/pull/1695). diff --git a/changelogs/fragments/1702_homebrew_tap.yml b/changelogs/fragments/1702_homebrew_tap.yml deleted file mode 100644 index 7eabc45a9b..0000000000 --- a/changelogs/fragments/1702_homebrew_tap.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: -- homebrew_tap - add support to specify search path for ``brew`` executable (https://github.com/ansible-collections/community.general/issues/1702). diff --git a/changelogs/fragments/1703-sensu_silence-fix_json_parsing.yml b/changelogs/fragments/1703-sensu_silence-fix_json_parsing.yml deleted file mode 100644 index 18d39b5674..0000000000 --- a/changelogs/fragments/1703-sensu_silence-fix_json_parsing.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - sensu-silence module - fix json parsing of sensu API responses on Python 3.5 (https://github.com/ansible-collections/community.general/pull/1703). diff --git a/changelogs/fragments/1714-gitlab_runner-required-reg-token.yml b/changelogs/fragments/1714-gitlab_runner-required-reg-token.yml deleted file mode 100644 index ec73bf422c..0000000000 --- a/changelogs/fragments/1714-gitlab_runner-required-reg-token.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - gitlab_runner - parameter ``registration_token`` was required but is used only when ``state`` is ``present`` (https://github.com/ansible-collections/community.general/issues/1714). diff --git a/changelogs/fragments/1715-proxmox_kvm-add-vmid-to-returns.yml b/changelogs/fragments/1715-proxmox_kvm-add-vmid-to-returns.yml deleted file mode 100644 index b4561f5145..0000000000 --- a/changelogs/fragments/1715-proxmox_kvm-add-vmid-to-returns.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - proxmox_kvm module - actually implemented ``vmid`` and ``status`` return values. Updated documentation to reflect current situation (https://github.com/ansible-collections/community.general/issues/1410, https://github.com/ansible-collections/community.general/pull/1715). diff --git a/changelogs/fragments/1721-fix-nomad_job_info-no-jobs-failure.yml b/changelogs/fragments/1721-fix-nomad_job_info-no-jobs-failure.yml deleted file mode 100644 index c3c3d804e3..0000000000 --- a/changelogs/fragments/1721-fix-nomad_job_info-no-jobs-failure.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - nomad_job_info - fix module failure when nomad client returns no jobs (https://github.com/ansible-collections/community.general/pull/1721). diff --git a/changelogs/fragments/1722_timezone.yml b/changelogs/fragments/1722_timezone.yml deleted file mode 100644 index cae337effd..0000000000 --- a/changelogs/fragments/1722_timezone.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: -- timezone - add Gentoo and Alpine Linux support (https://github.com/ansible-collections/community.general/issues/781). diff --git a/changelogs/fragments/1723-datadog_monitor-add-missing-monitor-types.yml b/changelogs/fragments/1723-datadog_monitor-add-missing-monitor-types.yml deleted file mode 100644 index 8b01717897..0000000000 --- a/changelogs/fragments/1723-datadog_monitor-add-missing-monitor-types.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - datadog_monitor - add missing monitor types ``query alert``, ``trace-analytics alert``, ``rum alert`` (https://github.com/ansible-collections/community.general/pull/1723). diff --git a/changelogs/fragments/1724-various-fixes-for-updating-existing-gitlab-user.yml b/changelogs/fragments/1724-various-fixes-for-updating-existing-gitlab-user.yml deleted file mode 100644 index eab67e0f47..0000000000 --- a/changelogs/fragments/1724-various-fixes-for-updating-existing-gitlab-user.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - gitlab_user - make updates to the ``isadmin``, ``password`` and ``confirm`` options of an already existing GitLab user work (https://github.com/ansible-collections/community.general/pull/1724). diff --git a/changelogs/fragments/1735-imc-sessions.yml b/changelogs/fragments/1735-imc-sessions.yml deleted file mode 100644 index 057393d06c..0000000000 --- a/changelogs/fragments/1735-imc-sessions.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - imc_rest - explicitly logging out instead of registering the call in ```atexit``` (https://github.com/ansible-collections/community.general/issues/1735). diff --git a/changelogs/fragments/1740-aerospike_migration.yml b/changelogs/fragments/1740-aerospike_migration.yml deleted file mode 100644 index e66963aae7..0000000000 --- a/changelogs/fragments/1740-aerospike_migration.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- "aerospike_migration - fix typo that caused ``migrate_tx_key`` instead of ``migrate_rx_key`` being used (https://github.com/ansible-collections/community.general/pull/1739)." diff --git a/changelogs/fragments/1741-use-path-argspec.yml b/changelogs/fragments/1741-use-path-argspec.yml deleted file mode 100644 index ed05fee16a..0000000000 --- a/changelogs/fragments/1741-use-path-argspec.yml +++ /dev/null @@ -1,4 +0,0 @@ -minor_changes: -- "oci_vcn - ``api_user_key_file`` is now of type ``path`` and no longer ``str``. A side effect is that certain expansions are made, like ``~`` is replaced by the user's home directory, and environment variables like ``$HOME`` or ``$TEMP`` are evaluated (https://github.com/ansible-collections/community.general/pull/1741)." -- "lxd_container - ``client_key`` and ``client_cert`` are now of type ``path`` and no longer ``str``. A side effect is that certain expansions are made, like ``~`` is replaced by the user's home directory, and environment variables like ``$HOME`` or ``$TEMP`` are evaluated (https://github.com/ansible-collections/community.general/pull/1741)." -- "lxd_profile - ``client_key`` and ``client_cert`` are now of type ``path`` and no longer ``str``. A side effect is that certain expansions are made, like ``~`` is replaced by the user's home directory, and environment variables like ``$HOME`` or ``$TEMP`` are evaluated (https://github.com/ansible-collections/community.general/pull/1741)." diff --git a/changelogs/fragments/1744-case-insensitive-hostname-fqdn-matching.yml b/changelogs/fragments/1744-case-insensitive-hostname-fqdn-matching.yml deleted file mode 100644 index 0e9c086b96..0000000000 --- a/changelogs/fragments/1744-case-insensitive-hostname-fqdn-matching.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - redfish_config - case insensitive search for situations where the hostname/FQDN case on iLO doesn't match variable's case (https://github.com/ansible-collections/community.general/pull/1744). diff --git a/changelogs/fragments/1753-document-fstypes-supported-by-resizefs.yml b/changelogs/fragments/1753-document-fstypes-supported-by-resizefs.yml deleted file mode 100644 index 9b1329412c..0000000000 --- a/changelogs/fragments/1753-document-fstypes-supported-by-resizefs.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - filesystem - remove ``swap`` from list of FS supported by ``resizefs=yes`` (https://github.com/ansible-collections/community.general/issues/790). diff --git a/changelogs/fragments/1761-redfish-tidy-up-validation.yml b/changelogs/fragments/1761-redfish-tidy-up-validation.yml deleted file mode 100644 index 751c7ca30d..0000000000 --- a/changelogs/fragments/1761-redfish-tidy-up-validation.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - redfish modules - explicitly setting lists' elements to ``str`` (https://github.com/ansible-collections/community.general/pull/1761). diff --git a/changelogs/fragments/1765-proxmox-params.yml b/changelogs/fragments/1765-proxmox-params.yml deleted file mode 100644 index fd6d63c788..0000000000 --- a/changelogs/fragments/1765-proxmox-params.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - proxmox* modules - refactored some parameter validation code into use of ``env_fallback``, ``required_if``, ``required_together``, ``required_one_of`` (https://github.com/ansible-collections/community.general/pull/1765). diff --git a/changelogs/fragments/1766-zfs-fixed-sanity.yml b/changelogs/fragments/1766-zfs-fixed-sanity.yml deleted file mode 100644 index ac31084e2c..0000000000 --- a/changelogs/fragments/1766-zfs-fixed-sanity.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - zfs_delegate_admin - the elements of ``users``, ``groups`` and ``permissions`` are now enforced to be strings (https://github.com/ansible-collections/community.general/pull/1766). diff --git a/changelogs/fragments/1771-centurylink-validation-elements.yml b/changelogs/fragments/1771-centurylink-validation-elements.yml deleted file mode 100644 index 4c7a9bbbe4..0000000000 --- a/changelogs/fragments/1771-centurylink-validation-elements.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - clc_* modules - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1771). diff --git a/changelogs/fragments/1776-git_config-tilde_value.yml b/changelogs/fragments/1776-git_config-tilde_value.yml deleted file mode 100644 index c98912a24d..0000000000 --- a/changelogs/fragments/1776-git_config-tilde_value.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - git_config - prevent ``run_command`` from expanding values (https://github.com/ansible-collections/community.general/issues/1776). diff --git a/changelogs/fragments/1783-proxmox-kvm-fix-args-500-error.yaml b/changelogs/fragments/1783-proxmox-kvm-fix-args-500-error.yaml deleted file mode 100644 index 5e46b066a8..0000000000 --- a/changelogs/fragments/1783-proxmox-kvm-fix-args-500-error.yaml +++ /dev/null @@ -1,3 +0,0 @@ -bugfixes: - - proxmox_kvm - do not add ``args`` if ``proxmox_default_behavior`` is set to no_defaults (https://github.com/ansible-collections/community.general/issues/1641). - - proxmox_kvm - stop implicitly adding ``force`` equal to ``false``. Proxmox API requires not implemented parameters otherwise, and assumes ``force`` to be ``false`` by default anyways (https://github.com/ansible-collections/community.general/pull/1783). diff --git a/changelogs/fragments/1788-ease-nios_host_record-dns-bypass-check.yml b/changelogs/fragments/1788-ease-nios_host_record-dns-bypass-check.yml deleted file mode 100644 index 6b1a43cc25..0000000000 --- a/changelogs/fragments/1788-ease-nios_host_record-dns-bypass-check.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - nios_host_record - allow DNS Bypass for views other than default (https://github.com/ansible-collections/community.general/issues/1786). diff --git a/changelogs/fragments/1795-list-elements-batch1.yml b/changelogs/fragments/1795-list-elements-batch1.yml deleted file mode 100644 index 9b057c7712..0000000000 --- a/changelogs/fragments/1795-list-elements-batch1.yml +++ /dev/null @@ -1,27 +0,0 @@ -minor_changes: - - plugins/module_utils/oracle/oci_utils.py - elements of list parameter ``key_by`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - lxd_container - elements of list parameter ``profiles`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - packet_device - elements of list parameters ``device_ids``, ``hostnames`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - pubnub_blocks - elements of list parameters ``event_handlers`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - vmadm - elements of list parameters ``disks``, ``nics``, ``resolvers``, ``filesystems`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - sl_vm - elements of list parameters ``disks``, ``ssh_keys`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - xml - elements of list parameters ``add_children``, ``set_children`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - keycloak_client - elements of list parameters ``default_roles``, ``redirect_uris``, ``web_origins`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - onepassword_info - elements of list parameters ``search_terms`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - librato_annotation - elements of list parameters ``links`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - pagerduty - elements of list parameters ``service`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - statusio_maintenance - elements of list parameters ``components``, ``containers`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - dnsimple - elements of list parameters ``record_ids`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - nsupdate - elements of list parameters ``value`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - omapi_host - elements of list parameters ``statements`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - mail - elements of list parameters ``to``, ``cc``, ``bcc``, ``attach``, ``headers`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - nexmo - elements of list parameters ``dest`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - rocketchat - elements of list parameters ``attachments`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - sendgrid - elements of list parameters ``to_addresses``, ``cc``, ``bcc``, ``attachments`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - slack - elements of list parameters ``attachments`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - twilio - elements of list parameters ``to_numbers`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - redhat_subscription - elements of list parameters ``pool_ids``, ``addons`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - gitlab_runner - elements of list parameters ``tag_list`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). - - na_ontap_gather_facts - elements of list parameters ``gather_subset`` are now validated (https://github.com/ansible-collections/community.general/pull/1795). -bugfixes: - - redhat_subscription - ``mutually_exclusive`` was referring to parameter alias instead of name (https://github.com/ansible-collections/community.general/pull/1795). diff --git a/changelogs/fragments/1813-lxd_profile-merge-profiles.yml b/changelogs/fragments/1813-lxd_profile-merge-profiles.yml deleted file mode 100644 index d374347a5e..0000000000 --- a/changelogs/fragments/1813-lxd_profile-merge-profiles.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: -- lxd_profile - added ``merge_profile`` parameter to merge configurations from the play to an existing profile (https://github.com/ansible-collections/community.general/pull/1813). diff --git a/changelogs/fragments/1814-dnsimple-add-support-for-caa-records.yml b/changelogs/fragments/1814-dnsimple-add-support-for-caa-records.yml deleted file mode 100644 index bc4915b7b9..0000000000 --- a/changelogs/fragments/1814-dnsimple-add-support-for-caa-records.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - dnsimple - add CAA records to the whitelist of valid record types (https://github.com/ansible-collections/community.general/pull/1814). diff --git a/changelogs/fragments/1819-tidyup-pylint-blacklistnames.yml b/changelogs/fragments/1819-tidyup-pylint-blacklistnames.yml deleted file mode 100644 index fdbc850528..0000000000 --- a/changelogs/fragments/1819-tidyup-pylint-blacklistnames.yml +++ /dev/null @@ -1,17 +0,0 @@ -bugfixes: - - "alternatives - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "beadm - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "cronvar - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "dconf - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "filesystem - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "hipchat - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "interfaces_file - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "java_cert - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "lvg - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "lvol - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "lxc - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "lxc_container - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "parted - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "rundeck_acl_policy - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "statusio_maintenance - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." - - "timezone - internal refactoring: replaced uses of ``_`` with ``dummy`` (https://github.com/ansible-collections/community.general/pull/1819)." diff --git a/changelogs/fragments/1830-valmod_docmissingtype_batch1.yml b/changelogs/fragments/1830-valmod_docmissingtype_batch1.yml deleted file mode 100644 index 83a27f7e77..0000000000 --- a/changelogs/fragments/1830-valmod_docmissingtype_batch1.yml +++ /dev/null @@ -1,7 +0,0 @@ -bugfixes: - - kibana_plugin - ``state`` parameter choices must use ``list()`` in python3 (https://github.com/ansible-collections/community.general/pull/1830). - - elasticsearch_plugin - ``state`` parameter choices must use ``list()`` in python3 (https://github.com/ansible-collections/community.general/pull/1830). - - riak - parameters ``wait_for_handoffs`` and ``wait_for_ring`` are ``int`` but the default value was ``false`` (https://github.com/ansible-collections/community.general/pull/1830). - - logstash_plugin - wrapped ``dict.keys()`` with ``list`` for use in ``choices`` setting (https://github.com/ansible-collections/community.general/pull/1830). - - iso_extract - use proper alias deprecation mechanism for ``thirsty`` alias of ``force`` (https://github.com/ansible-collections/community.general/pull/1830). - - runit - removed unused code, and passing command as ``list`` instead of ``str`` to ``run_command()`` (https://github.com/ansible-collections/community.general/pull/1830). diff --git a/changelogs/fragments/1833-zfs-creation-only-properties.yaml b/changelogs/fragments/1833-zfs-creation-only-properties.yaml deleted file mode 100644 index deb972a6d2..0000000000 --- a/changelogs/fragments/1833-zfs-creation-only-properties.yaml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - zfs - some ZFS properties could be passed when the dataset/volume did not exist, but would fail if the dataset already existed, even if the property matched what was specified in the ansible task (https://github.com/ansible-collections/community.general/issues/868, https://github.com/ansible-collections/community.general/pull/1833). diff --git a/changelogs/fragments/1838-runit-deprecate-param-dist.yml b/changelogs/fragments/1838-runit-deprecate-param-dist.yml deleted file mode 100644 index 5d133c074e..0000000000 --- a/changelogs/fragments/1838-runit-deprecate-param-dist.yml +++ /dev/null @@ -1,2 +0,0 @@ -deprecated_features: - - runit - unused parameter ``dist`` marked for deprecation (https://github.com/ansible-collections/community.general/pull/1830). diff --git a/changelogs/fragments/1847-proxmox-kvm-fix-status.yml b/changelogs/fragments/1847-proxmox-kvm-fix-status.yml deleted file mode 100644 index 0863f1bed2..0000000000 --- a/changelogs/fragments/1847-proxmox-kvm-fix-status.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - proxmox_kvm - fix undefined local variable ``status`` when the parameter ``state`` is either ``stopped``, ``started``, ``restarted`` or ``absent`` (https://github.com/ansible-collections/community.general/pull/1847). diff --git a/changelogs/fragments/1852-deploy-helper-fix-state-is-clean-without-release.yaml b/changelogs/fragments/1852-deploy-helper-fix-state-is-clean-without-release.yaml deleted file mode 100644 index 0946a4f38f..0000000000 --- a/changelogs/fragments/1852-deploy-helper-fix-state-is-clean-without-release.yaml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - deploy_helper - allow ``state=clean`` to be used without defining a ``release`` (https://github.com/ansible-collections/community.general/issues/1852). \ No newline at end of file diff --git a/changelogs/fragments/1861-python3-keys.yml b/changelogs/fragments/1861-python3-keys.yml deleted file mode 100644 index 029ed93575..0000000000 --- a/changelogs/fragments/1861-python3-keys.yml +++ /dev/null @@ -1,22 +0,0 @@ -bugfixes: - - redis cache plugin - wrapped usages of ``keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - memcached cache plugin - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - diy callback plugin - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - selective callback plugin - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - chef_databag lookup plugin - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - net_tools.nios.api module_utils - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - utm_utils module_utils - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - lxc_container - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - lxd_container - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - oneandone_monitoring_policy - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - oci_vcn - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - spotinst_aws_elastigroup - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - sensu_check - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - redhat_subscription - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - idrac_redfish_command - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - idrac_redfish_config - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - idrac_redfish_info - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - redfish_command - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - redfish_config - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - vdo - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). - - nsot inventory script - wrapped usages of ``dict.keys()`` in ``list()`` for Python 3 compatibility (https://github.com/ansible-collections/community.general/pull/1861). diff --git a/changelogs/fragments/1867-modhelper-cmdmixin-dict-params.yml b/changelogs/fragments/1867-modhelper-cmdmixin-dict-params.yml deleted file mode 100644 index 3f757b233a..0000000000 --- a/changelogs/fragments/1867-modhelper-cmdmixin-dict-params.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - module_helper module utils - ``CmdMixin.run_command()`` now accepts ``dict`` command arguments, providing the parameter and its value (https://github.com/ansible-collections/community.general/pull/1867). diff --git a/changelogs/fragments/1871-infoblox-inventory.yml b/changelogs/fragments/1871-infoblox-inventory.yml deleted file mode 100644 index d49d176f1b..0000000000 --- a/changelogs/fragments/1871-infoblox-inventory.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- "infoblox inventory script - make sure that the script also works with Ansible 2.9, and returns a more helpful error when community.general is not installed as part of Ansible 2.10/3 (https://github.com/ansible-collections/community.general/pull/1871)." diff --git a/changelogs/fragments/1880-fix_cobbler_system_ssl.yml b/changelogs/fragments/1880-fix_cobbler_system_ssl.yml deleted file mode 100644 index 849f703130..0000000000 --- a/changelogs/fragments/1880-fix_cobbler_system_ssl.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - cobbler_sync, cobbler_system - fix SSL/TLS certificate check when ``validate_certs`` set to ``false`` (https://github.com/ansible-collections/community.general/pull/1880). diff --git a/changelogs/fragments/1882-fix-nmcli-ensure-slave-type-for-bond-slave.yml b/changelogs/fragments/1882-fix-nmcli-ensure-slave-type-for-bond-slave.yml deleted file mode 100644 index 47569b6a24..0000000000 --- a/changelogs/fragments/1882-fix-nmcli-ensure-slave-type-for-bond-slave.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - nmcli - ensure the ``slave-type`` option is passed to ``nmcli`` for type ``bond-slave`` (https://github.com/ansible-collections/community.general/pull/1882). diff --git a/changelogs/fragments/1885-sanity-check-fixes-batch3.yml b/changelogs/fragments/1885-sanity-check-fixes-batch3.yml deleted file mode 100644 index bf819a6e21..0000000000 --- a/changelogs/fragments/1885-sanity-check-fixes-batch3.yml +++ /dev/null @@ -1,18 +0,0 @@ -minor_changes: - - oneandone_firewall_policy - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - oneandone_load_balancer - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - oneandone_monitoring_policy - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - oneandone_private_network - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - oneandone_server - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - profitbricks - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - profitbricks_volume - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - webfaction_domain - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - webfaction_site - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - consul - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - consul_acl - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - consul_session - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - datadog_monitor - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - sensu_check - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - sensu_client - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - sensu_handler - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). - - bundler - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1885). diff --git a/changelogs/fragments/1894-feat-nmcli-add-method4-and-method6.yml b/changelogs/fragments/1894-feat-nmcli-add-method4-and-method6.yml deleted file mode 100644 index 05daac483c..0000000000 --- a/changelogs/fragments/1894-feat-nmcli-add-method4-and-method6.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - nmcli - add ``method4`` and ``method6`` options (https://github.com/ansible-collections/community.general/pull/1894). diff --git a/changelogs/fragments/1895-proxmox-kvm-fix-issue-1875.yml b/changelogs/fragments/1895-proxmox-kvm-fix-issue-1875.yml deleted file mode 100644 index 73d908cfa8..0000000000 --- a/changelogs/fragments/1895-proxmox-kvm-fix-issue-1875.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - proxmox_kvm - fix parameter ``vmid`` passed twice to ``exit_json`` while creating a virtual machine without cloning (https://github.com/ansible-collections/community.general/issues/1875, https://github.com/ansible-collections/community.general/pull/1895). diff --git a/changelogs/fragments/1912-yum_versionlock-lock_unlock_concurrently.yml b/changelogs/fragments/1912-yum_versionlock-lock_unlock_concurrently.yml deleted file mode 100644 index 36f40da0fe..0000000000 --- a/changelogs/fragments/1912-yum_versionlock-lock_unlock_concurrently.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: - - yum_versionlock - Do the lock/unlock concurrently to speed up (https://github.com/ansible-collections/community.general/pull/1912). diff --git a/changelogs/fragments/1914-add-sanitization-to-url.yml b/changelogs/fragments/1914-add-sanitization-to-url.yml deleted file mode 100644 index 3b41bcb7af..0000000000 --- a/changelogs/fragments/1914-add-sanitization-to-url.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - proxmox inventory - added handling of extra trailing slashes in the URL (https://github.com/ansible-collections/community.general/pull/1914). diff --git a/changelogs/fragments/1916-add-version-sort-filter.yml b/changelogs/fragments/1916-add-version-sort-filter.yml deleted file mode 100644 index a06b464e55..0000000000 --- a/changelogs/fragments/1916-add-version-sort-filter.yml +++ /dev/null @@ -1,3 +0,0 @@ -add plugin.filter: - - name: version_sort - description: Sort a list according to version order instead of pure alphabetical one diff --git a/changelogs/fragments/1927-removed-parameter-invalid.yml b/changelogs/fragments/1927-removed-parameter-invalid.yml deleted file mode 100644 index 6dbc2e187b..0000000000 --- a/changelogs/fragments/1927-removed-parameter-invalid.yml +++ /dev/null @@ -1,12 +0,0 @@ -deprecated_features: - - composer - deprecated invalid parameter aliases ``working-dir``, ``global-command``, ``prefer-source``, ``prefer-dist``, ``no-dev``, ``no-scripts``, ``no-plugins``, ``optimize-autoloader``, ``classmap-authoritative``, ``apcu-autoloader``, ``ignore-platform-reqs``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). - - apt_rpm - deprecated invalid parameter alias ``update-cache``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). - - homebrew - deprecated invalid parameter alias ``update-brew``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). - - homebrew_cask - deprecated invalid parameter alias ``update-brew``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). - - opkg - deprecated invalid parameter alias ``update-cache``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). - - pacman - deprecated invalid parameter alias ``update-cache``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). - - slackpkg - deprecated invalid parameter alias ``update-cache``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). - - urmpi - deprecated invalid parameter aliases ``update-cache`` and ``no-recommends``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). - - xbps - deprecated invalid parameter alias ``update-cache``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). - - github_deploy_key - deprecated invalid parameter alias ``2fa_token``, will be removed in 5.0.0 (https://github.com/ansible-collections/community.general/pull/1927). - - puppet - deprecated undocumented parameter ``show_diff``, will be removed in 7.0.0. (https://github.com/ansible-collections/community.general/pull/1927). diff --git a/changelogs/fragments/1928-bigpanda-message.yml b/changelogs/fragments/1928-bigpanda-message.yml deleted file mode 100644 index 081b51cc0f..0000000000 --- a/changelogs/fragments/1928-bigpanda-message.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- "bigpanda - actually use the ``deployment_message`` option (https://github.com/ansible-collections/community.general/pull/1928)." diff --git a/changelogs/fragments/1929-grove-message.yml b/changelogs/fragments/1929-grove-message.yml deleted file mode 100644 index 402aa24639..0000000000 --- a/changelogs/fragments/1929-grove-message.yml +++ /dev/null @@ -1,4 +0,0 @@ -minor_changes: -- "grove - the option ``message`` has been renamed to ``message_content``. The old name ``message`` is kept as an alias and will be removed for community.general 4.0.0. This was done because ``message`` is used internally by Ansible (https://github.com/ansible-collections/community.general/pull/1929)." -deprecated_features: -- "grove - the option ``message`` will be removed in community.general 4.0.0. Use the new option ``message_content`` instead (https://github.com/ansible-collections/community.general/pull/1929)." diff --git a/changelogs/fragments/1949-proxmox-inventory-tags.yml b/changelogs/fragments/1949-proxmox-inventory-tags.yml deleted file mode 100644 index 073428c2e6..0000000000 --- a/changelogs/fragments/1949-proxmox-inventory-tags.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -bugfixes: -- proxmox inventory plugin - allowed proxomox tag string to contain commas when returned as fact (https://github.com/ansible-collections/community.general/pull/1949). -minor_changes: -- proxmox inventory plugin - added ``tags_parsed`` fact containing tags parsed as a list (https://github.com/ansible-collections/community.general/pull/1949). diff --git a/changelogs/fragments/1970-valmod-batch7.yml b/changelogs/fragments/1970-valmod-batch7.yml deleted file mode 100644 index cd577d4578..0000000000 --- a/changelogs/fragments/1970-valmod-batch7.yml +++ /dev/null @@ -1,18 +0,0 @@ -minor_changes: - - heroku_collaborator - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). - - linode_v4 - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). - - one_host - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). - - one_image_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). - - one_vm - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). - - scaleway_compute - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). - - scaleway_lb - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). - - manageiq_alert_profiles - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). - - manageiq_policies - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). - - manageiq_tags - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). - - oneview_datacenter_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). - - oneview_enclosure_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). - - oneview_ethernet_network_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). - - oneview_network_set_info - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/1970). -bugfixes: - - manageiq_provider - wrapped ``dict.keys()`` with ``list`` for use in ``choices`` setting (https://github.com/ansible-collections/community.general/pull/1970). - - packet_volume_attachment - removed extraneous ``print`` call - old debug? (https://github.com/ansible-collections/community.general/pull/1970). diff --git a/changelogs/fragments/1972-ini_file-empty-str-value.yml b/changelogs/fragments/1972-ini_file-empty-str-value.yml deleted file mode 100644 index 7beba5ac4c..0000000000 --- a/changelogs/fragments/1972-ini_file-empty-str-value.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - ini_file - allows an empty string as a value for an option (https://github.com/ansible-collections/community.general/pull/1972). diff --git a/changelogs/fragments/1977-jenkinsjob-validate-certs.yml b/changelogs/fragments/1977-jenkinsjob-validate-certs.yml deleted file mode 100644 index b4f7b2f938..0000000000 --- a/changelogs/fragments/1977-jenkinsjob-validate-certs.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - jenkins_job - add a ``validate_certs`` parameter that allows disabling TLS/SSL certificate validation (https://github.com/ansible-collections/community.general/issues/255). diff --git a/changelogs/fragments/1978-jira-transition-logic.yml b/changelogs/fragments/1978-jira-transition-logic.yml deleted file mode 100644 index 12b4adc56d..0000000000 --- a/changelogs/fragments/1978-jira-transition-logic.yml +++ /dev/null @@ -1,4 +0,0 @@ -bugfixes: - - jira - fixed fields' update in ticket transitions (https://github.com/ansible-collections/community.general/issues/818). -minor_changes: - - jira - added parameter ``account_id`` for compatibility with recent versions of JIRA (https://github.com/ansible-collections/community.general/issues/818, https://github.com/ansible-collections/community.general/pull/1978). diff --git a/changelogs/fragments/1991-proxmox-inventory-fix-template-in-pool.yml b/changelogs/fragments/1991-proxmox-inventory-fix-template-in-pool.yml deleted file mode 100644 index 90a438dddf..0000000000 --- a/changelogs/fragments/1991-proxmox-inventory-fix-template-in-pool.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - proxmox inventory - exclude qemu templates from inclusion to the inventory via pools (https://github.com/ansible-collections/community.general/issues/1986, https://github.com/ansible-collections/community.general/pull/1991). diff --git a/changelogs/fragments/1993-haproxy-fix-draining.yml b/changelogs/fragments/1993-haproxy-fix-draining.yml deleted file mode 100644 index fd5c77f573..0000000000 --- a/changelogs/fragments/1993-haproxy-fix-draining.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - haproxy - fix a bug preventing haproxy from properly entering ``DRAIN`` mode (https://github.com/ansible-collections/community.general/issues/1913). diff --git a/changelogs/fragments/1999-proxmox-fix-issue-1955.yml b/changelogs/fragments/1999-proxmox-fix-issue-1955.yml deleted file mode 100644 index 274e70fb0f..0000000000 --- a/changelogs/fragments/1999-proxmox-fix-issue-1955.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: -- proxmox - removed requirement that root password is provided when containter state is ``present`` (https://github.com/ansible-collections/community.general/pull/1999). diff --git a/changelogs/fragments/2000-proxmox_kvm-tag-support.yml b/changelogs/fragments/2000-proxmox_kvm-tag-support.yml deleted file mode 100644 index d4084ecd67..0000000000 --- a/changelogs/fragments/2000-proxmox_kvm-tag-support.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: -- proxmox_kvm - added new module parameter ``tags`` for use with PVE 6+ (https://github.com/ansible-collections/community.general/pull/2000). diff --git a/changelogs/fragments/2001-no_log-false.yml b/changelogs/fragments/2001-no_log-false.yml deleted file mode 100644 index 82d9ba0bb0..0000000000 --- a/changelogs/fragments/2001-no_log-false.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- "Mark various module options with ``no_log=False`` which have a name that potentially could leak secrets, but which do not (https://github.com/ansible-collections/community.general/pull/2001)." diff --git a/changelogs/fragments/2006-valmod-batch8.yml b/changelogs/fragments/2006-valmod-batch8.yml deleted file mode 100644 index 30be5e16b2..0000000000 --- a/changelogs/fragments/2006-valmod-batch8.yml +++ /dev/null @@ -1,4 +0,0 @@ -minor_changes: - - rax - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2006). - - rax_cdb_user - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2006). - - rax_scaling_group - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2006). diff --git a/changelogs/fragments/2008-update-java-cert-replace-cert-when-changed.yml b/changelogs/fragments/2008-update-java-cert-replace-cert-when-changed.yml deleted file mode 100644 index 8cfda91016..0000000000 --- a/changelogs/fragments/2008-update-java-cert-replace-cert-when-changed.yml +++ /dev/null @@ -1,7 +0,0 @@ -minor_changes: - - "java_cert - change ``state: present`` to check certificates by hash, not just alias name (https://github.com/ansible/ansible/issues/43249)." -bugfixes: - - "java_cert - allow setting ``state: absent`` by providing just the ``cert_alias`` (https://github.com/ansible/ansible/issues/27982)." - - "java_cert - properly handle proxy arguments when the scheme is provided (https://github.com/ansible/ansible/issues/54481)." -security_fixes: - - "java_cert - remove password from ``run_command`` arguments (https://github.com/ansible-collections/community.general/pull/2008)." diff --git a/changelogs/fragments/2013-proxmox-purge-parameter.yml b/changelogs/fragments/2013-proxmox-purge-parameter.yml deleted file mode 100644 index 6c681e5a19..0000000000 --- a/changelogs/fragments/2013-proxmox-purge-parameter.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: -- proxmox - added ``purge`` module parameter for use when deleting lxc's with HA options (https://github.com/ansible-collections/community.general/pull/2013). diff --git a/changelogs/fragments/2014-allow-root-for-kibana-plugin.yaml b/changelogs/fragments/2014-allow-root-for-kibana-plugin.yaml deleted file mode 100644 index 6420203888..0000000000 --- a/changelogs/fragments/2014-allow-root-for-kibana-plugin.yaml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - kibana_plugin - add parameter for passing ``--allow-root`` flag to kibana and kibana-plugin commands (https://github.com/ansible-collections/community.general/pull/2014). diff --git a/changelogs/fragments/2020-remove-unused-param-in-rax.yml b/changelogs/fragments/2020-remove-unused-param-in-rax.yml deleted file mode 100644 index 333548f0b9..0000000000 --- a/changelogs/fragments/2020-remove-unused-param-in-rax.yml +++ /dev/null @@ -1,2 +0,0 @@ -removed_features: - - rax - unused parameter ``service`` removed (https://github.com/ansible-collections/community.general/pull/2020). diff --git a/changelogs/fragments/2024-module-helper-fixes.yml b/changelogs/fragments/2024-module-helper-fixes.yml deleted file mode 100644 index 3ce3cc71dc..0000000000 --- a/changelogs/fragments/2024-module-helper-fixes.yml +++ /dev/null @@ -1,4 +0,0 @@ -bugfixes: - - module_helper module utils - actually ignoring formatting of parameters with value ``None`` (https://github.com/ansible-collections/community.general/pull/2024). - - module_helper module utils - handling ``ModuleHelperException`` now properly calls ``fail_json()`` (https://github.com/ansible-collections/community.general/pull/2024). - - module_helper module utils - use the command name as-is in ``CmdMixin`` if it fails ``get_bin_path()`` - allowing full path names to be passed (https://github.com/ansible-collections/community.general/pull/2024). diff --git a/changelogs/fragments/2027-add-redfish-session-create-delete-authenticate.yml b/changelogs/fragments/2027-add-redfish-session-create-delete-authenticate.yml deleted file mode 100644 index b5c22b9502..0000000000 --- a/changelogs/fragments/2027-add-redfish-session-create-delete-authenticate.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - redfish_* modules, redfish_utils module utils - add support for Redfish session create, delete, and authenticate (https://github.com/ansible-collections/community.general/issues/1975). diff --git a/changelogs/fragments/2031-ipa_sudorule_add_runasextusers.yml b/changelogs/fragments/2031-ipa_sudorule_add_runasextusers.yml deleted file mode 100644 index 9e70a16d80..0000000000 --- a/changelogs/fragments/2031-ipa_sudorule_add_runasextusers.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: -- ipa_sudorule - add support for setting sudo runasuser (https://github.com/ansible-collections/community.general/pull/2031). diff --git a/changelogs/fragments/2032-one_image-pyone.yml b/changelogs/fragments/2032-one_image-pyone.yml deleted file mode 100644 index 4975cb73ad..0000000000 --- a/changelogs/fragments/2032-one_image-pyone.yml +++ /dev/null @@ -1,2 +0,0 @@ -breaking_changes: - - one_image - use pyone instead of python-oca (https://github.com/ansible-collections/community.general/pull/2032). diff --git a/changelogs/fragments/2036-scaleway-inventory.yml b/changelogs/fragments/2036-scaleway-inventory.yml deleted file mode 100644 index 44161306ac..0000000000 --- a/changelogs/fragments/2036-scaleway-inventory.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - scaleway inventory plugin - fix pagination on scaleway inventory plugin (https://github.com/ansible-collections/community.general/pull/2036). diff --git a/changelogs/fragments/2037-add-from-csv-filter.yml b/changelogs/fragments/2037-add-from-csv-filter.yml deleted file mode 100644 index d99c4cd0a8..0000000000 --- a/changelogs/fragments/2037-add-from-csv-filter.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -add plugin.filter: - - name: from_csv - description: Converts CSV text input into list of dicts -minor_changes: - - csv module utils - new module_utils for shared functions between ``from_csv`` filter and ``read_csv`` module (https://github.com/ansible-collections/community.general/pull/2037). - - read_csv - refactored read_csv module to use shared csv functions from csv module_utils (https://github.com/ansible-collections/community.general/pull/2037). diff --git a/changelogs/fragments/2040-fix-index-error-in-redfish-set-manager-nic.yml b/changelogs/fragments/2040-fix-index-error-in-redfish-set-manager-nic.yml deleted file mode 100644 index 04d9a11101..0000000000 --- a/changelogs/fragments/2040-fix-index-error-in-redfish-set-manager-nic.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - redfish_config module, redfish_utils module utils - fix IndexError in ``SetManagerNic`` command (https://github.com/ansible-collections/community.general/issues/1692). diff --git a/changelogs/fragments/2057-nios-devel.yml b/changelogs/fragments/2057-nios-devel.yml deleted file mode 100644 index be9f8a970f..0000000000 --- a/changelogs/fragments/2057-nios-devel.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- "nios* modules - fix modules to work with ansible-core 2.11 (https://github.com/ansible-collections/community.general/pull/2057)." diff --git a/changelogs/fragments/2061-archive-refactor1.yml b/changelogs/fragments/2061-archive-refactor1.yml deleted file mode 100644 index a7189a2f59..0000000000 --- a/changelogs/fragments/2061-archive-refactor1.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - archive - refactored some reused code out into a couple of functions (https://github.com/ansible-collections/community.general/pull/2061). diff --git a/changelogs/fragments/2065-snmp-facts-timeout.yml b/changelogs/fragments/2065-snmp-facts-timeout.yml deleted file mode 100644 index 0e6a4e54fa..0000000000 --- a/changelogs/fragments/2065-snmp-facts-timeout.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - snmp_facts - added parameters ``timeout`` and ``retries`` to module (https://github.com/ansible-collections/community.general/issues/980). diff --git a/changelogs/fragments/2072-stacki-host-params-fallback.yml b/changelogs/fragments/2072-stacki-host-params-fallback.yml deleted file mode 100644 index f586a6eb0c..0000000000 --- a/changelogs/fragments/2072-stacki-host-params-fallback.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - stacki_host - replaced ``default`` to environment variables with ``fallback`` to them (https://github.com/ansible-collections/community.general/pull/2072). diff --git a/changelogs/fragments/2094-bugfix-respect-PATH-env-variable-in-zypper-modules.yaml b/changelogs/fragments/2094-bugfix-respect-PATH-env-variable-in-zypper-modules.yaml deleted file mode 100644 index e0addce2fc..0000000000 --- a/changelogs/fragments/2094-bugfix-respect-PATH-env-variable-in-zypper-modules.yaml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - zypper, zypper_repository - respect ``PATH`` environment variable when resolving zypper executable path (https://github.com/ansible-collections/community.general/pull/2094). diff --git a/changelogs/fragments/2110-vdo-add_force_option.yaml b/changelogs/fragments/2110-vdo-add_force_option.yaml deleted file mode 100644 index 9e93a919a2..0000000000 --- a/changelogs/fragments/2110-vdo-add_force_option.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: - - vdo - add ``force`` option (https://github.com/ansible-collections/community.general/issues/2101). diff --git a/changelogs/fragments/2116-add-fields-to-ipa-config-module.yml b/changelogs/fragments/2116-add-fields-to-ipa-config-module.yml deleted file mode 100644 index d1e1dc3180..0000000000 --- a/changelogs/fragments/2116-add-fields-to-ipa-config-module.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - ipa_config - add new options ``ipaconfigstring``, ``ipadefaultprimarygroup``, ``ipagroupsearchfields``, ``ipahomesrootdir``, ``ipabrkauthzdata``, ``ipamaxusernamelength``, ``ipapwdexpadvnotify``, ``ipasearchrecordslimit``, ``ipasearchtimelimit``, ``ipauserauthtype``, and ``ipausersearchfields`` (https://github.com/ansible-collections/community.general/pull/2116). diff --git a/changelogs/fragments/2125-git-config-scope-file.yml b/changelogs/fragments/2125-git-config-scope-file.yml deleted file mode 100644 index 75862e0333..0000000000 --- a/changelogs/fragments/2125-git-config-scope-file.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - git_config - fixed scope ``file`` behaviour and added integraton test for it (https://github.com/ansible-collections/community.general/issues/2117). diff --git a/changelogs/fragments/2135-vmadm-resolvers-type-fix.yml b/changelogs/fragments/2135-vmadm-resolvers-type-fix.yml deleted file mode 100644 index fcce6e12e1..0000000000 --- a/changelogs/fragments/2135-vmadm-resolvers-type-fix.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - vmadm - correct type of list elements in ``resolvers`` parameter (https://github.com/ansible-collections/community.general/issues/2135). diff --git a/changelogs/fragments/2139-dimensiondata_network-str-format.yml b/changelogs/fragments/2139-dimensiondata_network-str-format.yml deleted file mode 100644 index 115b04f045..0000000000 --- a/changelogs/fragments/2139-dimensiondata_network-str-format.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - dimensiondata_network - bug when formatting message, instead of % a simple comma was used (https://github.com/ansible-collections/community.general/pull/2139). diff --git a/changelogs/fragments/2142-apache2_mod_proxy-cleanup.yml b/changelogs/fragments/2142-apache2_mod_proxy-cleanup.yml deleted file mode 100644 index 6a24f1afc3..0000000000 --- a/changelogs/fragments/2142-apache2_mod_proxy-cleanup.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - apache2_mod_proxy - refactored/cleaned-up part of the code (https://github.com/ansible-collections/community.general/pull/2142). diff --git a/changelogs/fragments/2143-kibana_plugin-fixed-function-calls.yml b/changelogs/fragments/2143-kibana_plugin-fixed-function-calls.yml deleted file mode 100644 index 54a41cd237..0000000000 --- a/changelogs/fragments/2143-kibana_plugin-fixed-function-calls.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - kibana_plugin - added missing parameters to ``remove_plugin`` when using ``state=present force=true``, and fix potential quoting errors when invoking ``kibana`` (https://github.com/ansible-collections/community.general/pull/2143). diff --git a/changelogs/fragments/2144-atomic_get_bin_path.yml b/changelogs/fragments/2144-atomic_get_bin_path.yml deleted file mode 100644 index eeb55114d2..0000000000 --- a/changelogs/fragments/2144-atomic_get_bin_path.yml +++ /dev/null @@ -1,4 +0,0 @@ -minor_changes: - - atomic_container - using ``get_bin_path()`` before calling ``run_command()`` (https://github.com/ansible-collections/community.general/pull/2144). - - atomic_host - using ``get_bin_path()`` before calling ``run_command()`` (https://github.com/ansible-collections/community.general/pull/2144). - - atomic_image - using ``get_bin_path()`` before calling ``run_command()`` (https://github.com/ansible-collections/community.general/pull/2144). diff --git a/changelogs/fragments/2146-npm-add_no_bin_links_option.yaml b/changelogs/fragments/2146-npm-add_no_bin_links_option.yaml deleted file mode 100644 index 651af80186..0000000000 --- a/changelogs/fragments/2146-npm-add_no_bin_links_option.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: - - npm - add ``no_bin_links`` option (https://github.com/ansible-collections/community.general/issues/2128). diff --git a/changelogs/fragments/2148-proxmox-inventory-agent-interfaces.yml b/changelogs/fragments/2148-proxmox-inventory-agent-interfaces.yml deleted file mode 100644 index 0ef97f20ed..0000000000 --- a/changelogs/fragments/2148-proxmox-inventory-agent-interfaces.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: -- proxmox inventory plugin - added ``proxmox_agent_interfaces`` fact describing network interfaces returned from a QEMU guest agent (https://github.com/ansible-collections/community.general/pull/2148). diff --git a/changelogs/fragments/2157-unreachable-code.yml b/changelogs/fragments/2157-unreachable-code.yml deleted file mode 100644 index 7cb84b4db9..0000000000 --- a/changelogs/fragments/2157-unreachable-code.yml +++ /dev/null @@ -1,4 +0,0 @@ -minor_changes: - - rhevm - removed unreachable code (https://github.com/ansible-collections/community.general/pull/2157). - - ovh_ip_failover - removed unreachable code (https://github.com/ansible-collections/community.general/pull/2157). - - bitbucket_pipeline_variable - removed unreachable code (https://github.com/ansible-collections/community.general/pull/2157). diff --git a/changelogs/fragments/2159-ipa-user-sshpubkey-multi-word-comments.yaml b/changelogs/fragments/2159-ipa-user-sshpubkey-multi-word-comments.yaml deleted file mode 100644 index 10547bb71b..0000000000 --- a/changelogs/fragments/2159-ipa-user-sshpubkey-multi-word-comments.yaml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - ipa_user - allow ``sshpubkey`` to permit multiple word comments (https://github.com/ansible-collections/community.general/pull/2159). diff --git a/changelogs/fragments/2160-list-literals.yml b/changelogs/fragments/2160-list-literals.yml deleted file mode 100644 index 661b1e322e..0000000000 --- a/changelogs/fragments/2160-list-literals.yml +++ /dev/null @@ -1,11 +0,0 @@ -minor_changes: - - hiera lookup - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). - - known_hosts module utils - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). - - nictagadm - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). - - smartos_image_info - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). - - xattr - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). - - ipwcli_dns - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). - - svr4pkg - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). - - zfs_facts - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). - - zpool_facts - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). - - beadm - minor refactor converting multiple statements to a single list literal (https://github.com/ansible-collections/community.general/pull/2160). diff --git a/changelogs/fragments/2161-pkgutil-list-extend.yml b/changelogs/fragments/2161-pkgutil-list-extend.yml deleted file mode 100644 index 9af970afd8..0000000000 --- a/changelogs/fragments/2161-pkgutil-list-extend.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - pkgutil - fixed calls to ``list.extend()`` (https://github.com/ansible-collections/community.general/pull/2161). diff --git a/changelogs/fragments/2162-modhelper-variables.yml b/changelogs/fragments/2162-modhelper-variables.yml deleted file mode 100644 index 68b0edc37e..0000000000 --- a/changelogs/fragments/2162-modhelper-variables.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - module_helper module utils - added mechanism to manage variables, providing automatic output of variables, change status and diff information (https://github.com/ansible-collections/community.general/pull/2162). diff --git a/changelogs/fragments/2162-proxmox-constructable.yml b/changelogs/fragments/2162-proxmox-constructable.yml deleted file mode 100644 index dfcb1e3495..0000000000 --- a/changelogs/fragments/2162-proxmox-constructable.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: -- proxmox inventory plugin - added ``Constructable`` class to the inventory to provide options ``strict``, ``keyed_groups``, ``groups``, and ``compose`` (https://github.com/ansible-collections/community.general/pull/2180). diff --git a/changelogs/fragments/2163-java_keystore_1667_improve_temp_files_storage.yml b/changelogs/fragments/2163-java_keystore_1667_improve_temp_files_storage.yml deleted file mode 100644 index 43d183707c..0000000000 --- a/changelogs/fragments/2163-java_keystore_1667_improve_temp_files_storage.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -bugfixes: - - "java_keystore - use tempfile lib to create temporary files with randomized - names, and remove the temporary PKCS#12 keystore as well as other materials - (https://github.com/ansible-collections/community.general/issues/1667)." diff --git a/changelogs/fragments/2174-ipa-user-userauthtype-multiselect.yml b/changelogs/fragments/2174-ipa-user-userauthtype-multiselect.yml deleted file mode 100644 index d162f19b7a..0000000000 --- a/changelogs/fragments/2174-ipa-user-userauthtype-multiselect.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - ipa_user - fix ``userauthtype`` option to take in list of strings for the multi-select field instead of single string (https://github.com/ansible-collections/community.general/pull/2174). diff --git a/changelogs/fragments/2177-java_keystore_1668_dont_expose_secrets_on_cmdline.yml b/changelogs/fragments/2177-java_keystore_1668_dont_expose_secrets_on_cmdline.yml deleted file mode 100644 index 0d961a53ac..0000000000 --- a/changelogs/fragments/2177-java_keystore_1668_dont_expose_secrets_on_cmdline.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -security_fixes: - - "java_keystore - pass secret to keytool through an environment variable to not expose it as a - commandline argument (https://github.com/ansible-collections/community.general/issues/1668)." diff --git a/changelogs/fragments/2183-java_keystore_improve_error_handling.yml b/changelogs/fragments/2183-java_keystore_improve_error_handling.yml deleted file mode 100644 index 5d6ceef511..0000000000 --- a/changelogs/fragments/2183-java_keystore_improve_error_handling.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -bugfixes: - - "java_keystore - improve error handling and return ``cmd`` as documented. - Force ``LANG``, ``LC_ALL`` and ``LC_MESSAGES`` environment variables to ``C`` to rely - on ``keytool`` output parsing. Fix pylint's ``unused-variable`` and ``no-else-return`` - hints (https://github.com/ansible-collections/community.general/pull/2183)." diff --git a/changelogs/fragments/2185-xfconf-absent-check-mode.yml b/changelogs/fragments/2185-xfconf-absent-check-mode.yml deleted file mode 100644 index 059f4acd9a..0000000000 --- a/changelogs/fragments/2185-xfconf-absent-check-mode.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - xfconf - module was not honoring check mode when ``state`` was ``absent`` (https://github.com/ansible-collections/community.general/pull/2185). diff --git a/changelogs/fragments/2188-xfconf-modhelper-variables.yml b/changelogs/fragments/2188-xfconf-modhelper-variables.yml deleted file mode 100644 index 19e94254bd..0000000000 --- a/changelogs/fragments/2188-xfconf-modhelper-variables.yml +++ /dev/null @@ -1,3 +0,0 @@ -minor_changes: - - module_helper module utils - added management of facts and adhoc setting of the initial value for variables (https://github.com/ansible-collections/community.general/pull/2188). - - xfconf - changed implementation to use ``ModuleHelper`` new features (https://github.com/ansible-collections/community.general/pull/2188). diff --git a/changelogs/fragments/2192-add-jira-attach.yml b/changelogs/fragments/2192-add-jira-attach.yml deleted file mode 100644 index 5877250541..0000000000 --- a/changelogs/fragments/2192-add-jira-attach.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - jira - added ``attach`` operation, which allows a user to attach a file to an issue (https://github.com/ansible-collections/community.general/pull/2192). diff --git a/changelogs/fragments/2203-modhelper-cause-changes-deco.yml b/changelogs/fragments/2203-modhelper-cause-changes-deco.yml deleted file mode 100644 index b61f97d6b8..0000000000 --- a/changelogs/fragments/2203-modhelper-cause-changes-deco.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - module_helper module utils - fixed decorator ``cause_changes`` (https://github.com/ansible-collections/community.general/pull/2203). diff --git a/changelogs/fragments/2204-github_repo-fix-baseurl_port.yml b/changelogs/fragments/2204-github_repo-fix-baseurl_port.yml deleted file mode 100644 index 0df3bd8ece..0000000000 --- a/changelogs/fragments/2204-github_repo-fix-baseurl_port.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - github_repo - PyGithub bug does not allow explicit port in ``base_url``. Specifying port is not required (https://github.com/PyGithub/PyGithub/issues/1913). diff --git a/changelogs/fragments/2208-jira-revamp.yml b/changelogs/fragments/2208-jira-revamp.yml deleted file mode 100644 index 32f1650aa0..0000000000 --- a/changelogs/fragments/2208-jira-revamp.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - jira - revamped the module as a class using ``ModuleHelper`` (https://github.com/ansible-collections/community.general/pull/2208). diff --git a/changelogs/fragments/2218-cpanm-revamp.yml b/changelogs/fragments/2218-cpanm-revamp.yml deleted file mode 100644 index 668a84f06b..0000000000 --- a/changelogs/fragments/2218-cpanm-revamp.yml +++ /dev/null @@ -1,5 +0,0 @@ -minor_changes: - - cpanm - rewritten using ``ModuleHelper`` (https://github.com/ansible-collections/community.general/pull/2218). - - cpanm - honor and install specified version when running in ``new`` mode; that feature is not available in ``compatibility`` mode (https://github.com/ansible-collections/community.general/issues/208). -deprecated_features: - - cpanm - parameter ``system_lib`` deprecated in favor of using ``become`` (https://github.com/ansible-collections/community.general/pull/2218). diff --git a/changelogs/fragments/2220_nmcli_wifi_support.yaml b/changelogs/fragments/2220_nmcli_wifi_support.yaml deleted file mode 100644 index 224c4dc526..0000000000 --- a/changelogs/fragments/2220_nmcli_wifi_support.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: -- "nmcli - add ability to connect to a Wifi network and also to attach it to a master (bond) (https://github.com/ansible-collections/community.general/pull/2220)." diff --git a/changelogs/fragments/2223_nmcli_no_IP_config_on_slave.yaml b/changelogs/fragments/2223_nmcli_no_IP_config_on_slave.yaml deleted file mode 100644 index 4d98b62922..0000000000 --- a/changelogs/fragments/2223_nmcli_no_IP_config_on_slave.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: -- "nmcli - do not set IP configuration on slave connection (https://github.com/ansible-collections/community.general/pull/2223)." diff --git a/changelogs/fragments/2224_nmcli_allow_MAC_overwrite.yaml b/changelogs/fragments/2224_nmcli_allow_MAC_overwrite.yaml deleted file mode 100644 index 98852463d8..0000000000 --- a/changelogs/fragments/2224_nmcli_allow_MAC_overwrite.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: -- "nmcli - don't restrict the ability to manually set the MAC address to the bridge (https://github.com/ansible-collections/community.general/pull/2224)." diff --git a/changelogs/fragments/2230-java_keystore-1669-ssl-input-files-by-path.yml b/changelogs/fragments/2230-java_keystore-1669-ssl-input-files-by-path.yml deleted file mode 100644 index 0622e93c31..0000000000 --- a/changelogs/fragments/2230-java_keystore-1669-ssl-input-files-by-path.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -minor_changes: - - "java_keystore - add options ``certificate_path`` and ``private_key_path``, - mutually exclusive with ``certificate`` and ``private_key`` respectively, and - targetting files on remote hosts rather than their contents on the controller. - (https://github.com/ansible-collections/community.general/issues/1669)." diff --git a/changelogs/fragments/2236-jira-isinstance.yml b/changelogs/fragments/2236-jira-isinstance.yml deleted file mode 100644 index e80cbacdf9..0000000000 --- a/changelogs/fragments/2236-jira-isinstance.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - jira - fixed calling of ``isinstance`` (https://github.com/ansible-collections/community.general/issues/2234). diff --git a/changelogs/fragments/2244-hashids-filters.yml b/changelogs/fragments/2244-hashids-filters.yml deleted file mode 100644 index 568119e890..0000000000 --- a/changelogs/fragments/2244-hashids-filters.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -add plugin.filter: - - name: hashids_encode - description: Encodes YouTube-like hashes from a sequence of integers - - name: hashids_decode - description: Decodes a sequence of numbers from a YouTube-like hash diff --git a/changelogs/fragments/2245-proxmox_fix_agent_string_handling.yml b/changelogs/fragments/2245-proxmox_fix_agent_string_handling.yml deleted file mode 100644 index 3eae94f4ea..0000000000 --- a/changelogs/fragments/2245-proxmox_fix_agent_string_handling.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - proxmox inventory - added handling of commas in KVM agent configuration string (https://github.com/ansible-collections/community.general/pull/2245). diff --git a/changelogs/fragments/2246-terraform.yaml b/changelogs/fragments/2246-terraform.yaml deleted file mode 100644 index d2dd93e22e..0000000000 --- a/changelogs/fragments/2246-terraform.yaml +++ /dev/null @@ -1,4 +0,0 @@ -bugfixes: - - terraform - fix issue that cause the execution fail because from Terraform 0.15 on, the ``-var`` and ``-var-file`` options are no longer available on ``terraform validate`` (https://github.com/ansible-collections/community.general/pull/2246). - - terraform - fix issue that cause the destroy to fail because from Terraform 0.15 on, the ``terraform destroy -force`` option is replaced with ``terraform destroy -auto-approve`` (https://github.com/ansible-collections/community.general/issues/2247). - - terraform - remove uses of ``use_unsafe_shell=True`` (https://github.com/ansible-collections/community.general/pull/2246). diff --git a/changelogs/fragments/2249-linode_v4-support-private_ip-option.yaml b/changelogs/fragments/2249-linode_v4-support-private_ip-option.yaml deleted file mode 100644 index e5d6ca02d7..0000000000 --- a/changelogs/fragments/2249-linode_v4-support-private_ip-option.yaml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - linode_v4 - add support for ``private_ip`` option (https://github.com/ansible-collections/community.general/pull/2249). diff --git a/changelogs/fragments/2250-allow-keycloak-modules-to-take-token-as-param.yml b/changelogs/fragments/2250-allow-keycloak-modules-to-take-token-as-param.yml deleted file mode 100644 index 5b8deb2a03..0000000000 --- a/changelogs/fragments/2250-allow-keycloak-modules-to-take-token-as-param.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -minor_changes: - - keycloak_* modules - allow the keycloak modules to use a token for the - authentication, the modules can take either a token or the credentials - (https://github.com/ansible-collections/community.general/pull/2250). diff --git a/changelogs/fragments/2257-ldap_entry-params.yml b/changelogs/fragments/2257-ldap_entry-params.yml deleted file mode 100644 index f5c92d0b9c..0000000000 --- a/changelogs/fragments/2257-ldap_entry-params.yml +++ /dev/null @@ -1,2 +0,0 @@ -removed_features: -- "ldap_entry - the ``params`` parameter is now completely removed. Using it already triggered an error since community.general 0.1.2 (https://github.com/ansible-collections/community.general/pull/2257)." diff --git a/changelogs/fragments/2259-proxmox-multi-nic-and-unsupported.yml b/changelogs/fragments/2259-proxmox-multi-nic-and-unsupported.yml deleted file mode 100644 index d8f6f80385..0000000000 --- a/changelogs/fragments/2259-proxmox-multi-nic-and-unsupported.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -bugfixes: - - proxmox inventory plugin - support network interfaces without IP addresses, multiple network interfaces and unsupported/commanddisabled guest error (https://github.com/ansible-collections/community.general/pull/2263). -minor_changes: - - proxmox inventory plugin - allow to select whether ``ansible_host`` should be set for the proxmox nodes (https://github.com/ansible-collections/community.general/pull/2263). diff --git a/changelogs/fragments/2262-java_keystore-passphrase.yml b/changelogs/fragments/2262-java_keystore-passphrase.yml deleted file mode 100644 index 882ada97c3..0000000000 --- a/changelogs/fragments/2262-java_keystore-passphrase.yml +++ /dev/null @@ -1,8 +0,0 @@ -breaking_changes: -- "java_keystore - instead of failing, now overwrites keystore if the alias (name) is changed. - This was originally the intended behavior, but did not work due to a logic error. Make sure - that your playbooks and roles do not depend on the old behavior of failing instead of - overwriting (https://github.com/ansible-collections/community.general/issues/1671)." -- "java_keystore - instead of failing, now overwrites keystore if the passphrase is changed. - Make sure that your playbooks and roles do not depend on the old behavior of failing instead - of overwriting (https://github.com/ansible-collections/community.general/issues/1671)." diff --git a/changelogs/fragments/2267-lvol_size_addition-subtraction_support.yaml b/changelogs/fragments/2267-lvol_size_addition-subtraction_support.yaml deleted file mode 100644 index 25b79f4528..0000000000 --- a/changelogs/fragments/2267-lvol_size_addition-subtraction_support.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -minor_changes: - - lvol - added proper support for ``+-`` options when extending or reducing the logical volume (https://github.com/ansible-collections/community.general/issues/1988). -bugfixes: - - lvol - fixed sizing calculation rounding to match the underlying tools (https://github.com/ansible-collections/community.general/issues/1988). diff --git a/changelogs/fragments/2268-validation-univetion.yml b/changelogs/fragments/2268-validation-univetion.yml deleted file mode 100644 index f245380441..0000000000 --- a/changelogs/fragments/2268-validation-univetion.yml +++ /dev/null @@ -1,4 +0,0 @@ -bugfixes: - - udm_dns_record - fixed default value of parameter ``data`` to match its type (https://github.com/ansible-collections/community.general/pull/2268). -minor_changes: - - udm_dns_zone - elements of list parameters ``nameserver``, ``interfaces``, and ``mx`` are now validated (https://github.com/ansible-collections/community.general/pull/2268). diff --git a/changelogs/fragments/2280-pids-new-pattern-option.yml b/changelogs/fragments/2280-pids-new-pattern-option.yml deleted file mode 100644 index fb9f07e744..0000000000 --- a/changelogs/fragments/2280-pids-new-pattern-option.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: -- pids - new options ``pattern`` and `ignore_case`` for retrieving PIDs of processes matching a supplied pattern (https://github.com/ansible-collections/community.general/pull/2280). diff --git a/changelogs/fragments/2282-nmap-fix-cache-support.yml b/changelogs/fragments/2282-nmap-fix-cache-support.yml deleted file mode 100644 index 62b026eb25..0000000000 --- a/changelogs/fragments/2282-nmap-fix-cache-support.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - nmap inventory plugin - fix cache and constructed group support (https://github.com/ansible-collections/community.general/issues/2242). diff --git a/changelogs/fragments/2284-influxdb_retention_policy-idempotence.yml b/changelogs/fragments/2284-influxdb_retention_policy-idempotence.yml deleted file mode 100644 index 0df25ca462..0000000000 --- a/changelogs/fragments/2284-influxdb_retention_policy-idempotence.yml +++ /dev/null @@ -1,4 +0,0 @@ -bugfixes: - - influxdb_retention_policy - ensure idempotent module execution with different - duration and shard duration parameter values - (https://github.com/ansible-collections/community.general/issues/2281). diff --git a/changelogs/fragments/2308-terraform-add-plugin_paths-parameter.yaml b/changelogs/fragments/2308-terraform-add-plugin_paths-parameter.yaml deleted file mode 100644 index ec389b270c..0000000000 --- a/changelogs/fragments/2308-terraform-add-plugin_paths-parameter.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: - - terraform - add ``plugin_paths`` parameter which allows disabling Terraform from performing plugin discovery and auto-download (https://github.com/ansible-collections/community.general/pull/2308). diff --git a/changelogs/fragments/2329-hiera-lookup-plugin-return-type.yaml b/changelogs/fragments/2329-hiera-lookup-plugin-return-type.yaml deleted file mode 100644 index 4cced727a2..0000000000 --- a/changelogs/fragments/2329-hiera-lookup-plugin-return-type.yaml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - hiera lookup plugin - converts the return type of plugin to unicode string (https://github.com/ansible-collections/community.general/pull/2329). diff --git a/changelogs/fragments/2340-jenkins_plugin-py2.yml b/changelogs/fragments/2340-jenkins_plugin-py2.yml deleted file mode 100644 index f3bcdbd361..0000000000 --- a/changelogs/fragments/2340-jenkins_plugin-py2.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- "jenkins_plugin - fixes Python 2 compatibility issue (https://github.com/ansible-collections/community.general/pull/2340)." \ No newline at end of file diff --git a/changelogs/fragments/2349-jira-bugfix-b64decode.yml b/changelogs/fragments/2349-jira-bugfix-b64decode.yml deleted file mode 100644 index 41a1dabb94..0000000000 --- a/changelogs/fragments/2349-jira-bugfix-b64decode.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - jira - fixed error when loading base64-encoded content as attachment (https://github.com/ansible-collections/community.general/pull/2349). diff --git a/changelogs/fragments/3.0.0.yml b/changelogs/fragments/3.0.0.yml deleted file mode 100644 index e4dc558962..0000000000 --- a/changelogs/fragments/3.0.0.yml +++ /dev/null @@ -1 +0,0 @@ -release_summary: This is release 3.0.0 of ``community.general``, released on 2021-04-26. diff --git a/changelogs/fragments/620-consul_io-env-variables-conf-based.yml b/changelogs/fragments/620-consul_io-env-variables-conf-based.yml deleted file mode 100644 index e3378428c5..0000000000 --- a/changelogs/fragments/620-consul_io-env-variables-conf-based.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -bugfixes: - - consul_io inventory script - kv_groups - fix byte chain decoding for Python 3 (https://github.com/ansible-collections/community.general/pull/620). -minor_changes: - - consul_io inventory script - conf options - allow custom configuration options via env variables (https://github.com/ansible-collections/community.general/pull/620). diff --git a/changelogs/fragments/719-manageiq-resource_id.yml b/changelogs/fragments/719-manageiq-resource_id.yml deleted file mode 100644 index bbeef5ff82..0000000000 --- a/changelogs/fragments/719-manageiq-resource_id.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - manageiq_tags and manageiq_policies - added new parameter ``resource_id``. This parameter can be used instead of parameter ``resource_name`` (https://github.com/ansible-collections/community.general/pull/719). \ No newline at end of file diff --git a/changelogs/fragments/720-cloudforms_inventory.yml b/changelogs/fragments/720-cloudforms_inventory.yml deleted file mode 100644 index f5675205d1..0000000000 --- a/changelogs/fragments/720-cloudforms_inventory.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - cloudforms inventory - fixed issue that non-existing (archived) VMs were synced (https://github.com/ansible-collections/community.general/pull/720). diff --git a/changelogs/fragments/816-only-invocate-feature-when-variable-is-set.yml b/changelogs/fragments/816-only-invocate-feature-when-variable-is-set.yml deleted file mode 100644 index 7d48c77298..0000000000 --- a/changelogs/fragments/816-only-invocate-feature-when-variable-is-set.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - proxmox lxc - only add the features flag when module parameter ``features`` is set. Before an empty string was send to proxmox in case the parameter was not used, which required to use ``root@pam`` for module execution (https://github.com/ansible-collections/community.general/pull/1763). diff --git a/changelogs/fragments/948-dellemc-migration-removal.yml b/changelogs/fragments/948-dellemc-migration-removal.yml deleted file mode 100644 index c4f64a815f..0000000000 --- a/changelogs/fragments/948-dellemc-migration-removal.yml +++ /dev/null @@ -1,13 +0,0 @@ -removed_features: - - | - The ``ome_device_info``, ``idrac_firmware`` and ``idrac_server_config_profile`` modules have now been migrated from community.general to the `dellemc.openmanage `_ Ansible collection. - If you use ansible-base 2.10 or newer, redirections have been provided. - - If you use Ansible 2.9 and installed this collection, you need to adjust the FQCNs (``community.general.idrac_firmware`` → ``dellemc.openmanage.idrac_firmware``) and make sure to install the dellemc.openmanage collection. -breaking_changes: - - | - If you use Ansible 2.9 and these plugins or modules from this collection, community.general 3.0.0 results in errors when trying to use the DellEMC content by FQCN, like ``community.general.idrac_firmware``. - Since Ansible 2.9 is not able to use redirections, you will have to adjust your playbooks and roles manually to use the new FQCNs (``dellemc.openmanage.idrac_firmware`` for the previous example) and to make sure that you have ``dellemc.openmanage`` installed. - - If you use ansible-base 2.10 or newer and did not install Ansible 4.0.0, but installed (and/or upgraded) community.general manually, you need to make sure to also install the ``dellemc.openmanage`` collection if you are using any of these plugins or modules. - While ansible-base 2.10 or newer can use the redirects that community.general 3.0.0 adds, the collection they point to (such as dellemc.openmanage) must be installed for them to work. diff --git a/changelogs/fragments/CVE-2021-20191_no_log.yml b/changelogs/fragments/CVE-2021-20191_no_log.yml deleted file mode 100644 index a2c8740598..0000000000 --- a/changelogs/fragments/CVE-2021-20191_no_log.yml +++ /dev/null @@ -1,4 +0,0 @@ -security_fixes: - - module_utils/_netapp, na_ontap_gather_facts - enabled ``no_log`` for the options ``api_key`` and ``secret_key`` to prevent accidental disclosure (CVE-2021-20191, https://github.com/ansible-collections/community.general/pull/1725). - - module_utils/identity/keycloak, keycloak_client, keycloak_clienttemplate, keycloak_group - enabled ``no_log`` for the option ``auth_client_secret`` to prevent accidental disclosure (CVE-2021-20191, https://github.com/ansible-collections/community.general/pull/1725). - - utm_proxy_auth_profile - enabled ``no_log`` for the option ``frontend_cookie_secret`` to prevent accidental disclosure (CVE-2021-20191, https://github.com/ansible-collections/community.general/pull/1725). diff --git a/changelogs/fragments/allow_funcd_to_load.yml b/changelogs/fragments/allow_funcd_to_load.yml deleted file mode 100644 index 3336b0aaf4..0000000000 --- a/changelogs/fragments/allow_funcd_to_load.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - funcd connection plugin - can now load (https://github.com/ansible-collections/community.general/pull/2235). diff --git a/changelogs/fragments/dict-filter.yml b/changelogs/fragments/dict-filter.yml deleted file mode 100644 index 1e9923e796..0000000000 --- a/changelogs/fragments/dict-filter.yml +++ /dev/null @@ -1,3 +0,0 @@ -add plugin.filter: - - name: dict - description: "The ``dict`` function as a filter: converts a list of tuples to a dictionary" diff --git a/changelogs/fragments/meta-runtime-deprecations.yml b/changelogs/fragments/meta-runtime-deprecations.yml deleted file mode 100644 index 8863f346af..0000000000 --- a/changelogs/fragments/meta-runtime-deprecations.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- "meta/runtime.yml - improve deprecation messages (https://github.com/ansible-collections/community.general/pull/1918)." diff --git a/changelogs/fragments/no_log-fixes.yml b/changelogs/fragments/no_log-fixes.yml deleted file mode 100644 index 70afd3229d..0000000000 --- a/changelogs/fragments/no_log-fixes.yml +++ /dev/null @@ -1,25 +0,0 @@ -security_fixes: - - "ovirt - mark the ``instance_rootpw`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "oneandone_firewall_policy, oneandone_load_balancer, oneandone_monitoring_policy, oneandone_private_network, oneandone_public_ip - mark the ``auth_token`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "rax_clb_ssl - mark the ``private_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "spotinst_aws_elastigroup - mark the ``multai_token`` and ``token`` parameters as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "keycloak_client - mark the ``registration_access_token`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "librato_annotation - mark the ``api_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "pagerduty_alert - mark the ``api_key``, ``service_key`` and ``integration_key`` parameters as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "nios_nsgroup - mark the ``tsig_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "pulp_repo - mark the ``feed_client_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "gitlab_runner - mark the ``registration_token`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "ibm_sa_host - mark the ``iscsi_chap_secret`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "keycloak_* modules - mark the ``auth_client_secret`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "hwc_ecs_instance - mark the ``admin_pass`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "ovirt - mark the ``instance_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "pagerduty_change - mark the ``integration_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "pingdom - mark the ``key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "rollbar_deployment - mark the ``token`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "stackdriver - mark the ``key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "dnsmadeeasy - mark the ``account_key`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "logentries_msg - mark the ``token`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "redfish_command - mark the ``update_creds.password`` parameter as ``no_log`` to avoid leakage of secrets (https://github.com/ansible-collections/community.general/pull/1736)." - - "utm_proxy_auth_profile - mark the ``frontend_cookie_secret`` parameter as ``no_log`` to avoid leakage of secrets. This causes the ``utm_proxy_auth_profile`` return value to no longer containing the correct value, but a placeholder (https://github.com/ansible-collections/community.general/pull/1736)." -breaking_changes: - - "utm_proxy_auth_profile - the ``frontend_cookie_secret`` return value now contains a placeholder string instead of the module's ``frontend_cookie_secret`` parameter (https://github.com/ansible-collections/community.general/pull/1736)." diff --git a/changelogs/fragments/path_join-shim-filter.yml b/changelogs/fragments/path_join-shim-filter.yml deleted file mode 100644 index f96922203f..0000000000 --- a/changelogs/fragments/path_join-shim-filter.yml +++ /dev/null @@ -1,3 +0,0 @@ -add plugin.filter: - - name: path_join - description: Redirects to ansible.builtin.path_join for ansible-base 2.10 or newer, and provides a compatible implementation for Ansible 2.9 diff --git a/changelogs/fragments/remove-deprecated-features.yml b/changelogs/fragments/remove-deprecated-features.yml deleted file mode 100644 index e728ce62d3..0000000000 --- a/changelogs/fragments/remove-deprecated-features.yml +++ /dev/null @@ -1,16 +0,0 @@ -removed_features: -- "airbrake_deployment - removed deprecated ``token`` parameter. Use ``project_id`` and ``project_key`` instead (https://github.com/ansible-collections/community.general/pull/1926)." -- "bigpanda - the alias ``message`` has been removed. Use ``deployment_message`` instead (https://github.com/ansible-collections/community.general/pull/1926)." -- "cisco_spark, cisco_webex - the alias ``message`` has been removed. Use ``msg`` instead (https://github.com/ansible-collections/community.general/pull/1926)." -- "clc_aa_policy - the ``wait`` parameter has been removed. It did not have any effect (https://github.com/ansible-collections/community.general/pull/1926)." -- "datadog_monitor - the alias ``message`` has been removed. Use ``notification_message`` instead (https://github.com/ansible-collections/community.general/pull/1926)." -- "django_manage - the parameter ``liveserver`` has been removed (https://github.com/ansible-collections/community.general/pull/1926)." -- "idrac_redfish_config - the parameters ``manager_attribute_name`` and ``manager_attribute_value`` have been removed. Use ``manager_attributes`` instead (https://github.com/ansible-collections/community.general/pull/1926)." -- "iso_extract - the alias ``thirsty`` has been removed. Use ``force`` instead (https://github.com/ansible-collections/community.general/pull/1926)." -- "redfish_config - the parameters ``bios_attribute_name`` and ``bios_attribute_value`` have been removed. Use ``bios_attributes`` instead (https://github.com/ansible-collections/community.general/pull/1926)." -- "syspatch - the ``apply`` parameter has been removed. This is the default mode, so simply removing it will not change the behavior (https://github.com/ansible-collections/community.general/pull/1926)." -- "xbps - the ``force`` parameter has been removed. It did not have any effect (https://github.com/ansible-collections/community.general/pull/1926)." -- "redfish modules - issuing a data modification command without specifying the ID of the target System, Chassis or Manager resource when there is more than one is no longer allowed. Use the ``resource_id`` option to specify the target ID (https://github.com/ansible-collections/community.general/pull/1926)." -- "pulp_repo - the alias ``ca_cert`` has been removed. Use ``feed_ca_cert`` instead (https://github.com/ansible-collections/community.general/pull/1926)." -- "pulp_repo - the ``feed_client_cert`` parameter no longer defaults to the value of the ``client_cert`` parameter (https://github.com/ansible-collections/community.general/pull/1926)." -- "pulp_repo - the ``feed_client_key`` parameter no longer defaults to the value of the ``client_key`` parameter (https://github.com/ansible-collections/community.general/pull/1926)." diff --git a/changelogs/fragments/remove-deprecated-modules.yml b/changelogs/fragments/remove-deprecated-modules.yml deleted file mode 100644 index fa9d9c9eb7..0000000000 --- a/changelogs/fragments/remove-deprecated-modules.yml +++ /dev/null @@ -1,66 +0,0 @@ -removed_features: -- "The deprecated ali_instance_facts module has been removed. Use ali_instance_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated hpilo_facts module has been removed. Use hpilo_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated idrac_redfish_facts module has been removed. Use idrac_redfish_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated jenkins_job_facts module has been removed. Use jenkins_job_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated memset_memstore_facts module has been removed. Use memset_memstore_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated memset_server_facts module has been removed. Use memset_server_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated na_ontap_gather_facts module has been removed. Use netapp.ontap.na_ontap_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated nginx_status_facts module has been removed. Use nginx_status_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated one_image_facts module has been removed. Use one_image_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated onepassword_facts module has been removed. Use onepassword_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated oneview_datacenter_facts module has been removed. Use oneview_datacenter_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated oneview_enclosure_facts module has been removed. Use oneview_enclosure_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated oneview_ethernet_network_facts module has been removed. Use oneview_ethernet_network_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated oneview_fc_network_facts module has been removed. Use oneview_fc_network_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated oneview_fcoe_network_facts module has been removed. Use oneview_fcoe_network_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated oneview_logical_interconnect_group_facts module has been removed. Use oneview_logical_interconnect_group_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated oneview_network_set_facts module has been removed. Use oneview_network_set_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated oneview_san_manager_facts module has been removed. Use oneview_san_manager_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated online_server_facts module has been removed. Use online_server_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated online_user_facts module has been removed. Use online_user_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated purefa_facts module has been removed. Use purestorage.flasharray.purefa_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated purefb_facts module has been removed. Use purestorage.flasharray.purefb_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated python_requirements_facts module has been removed. Use python_requirements_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated redfish_facts module has been removed. Use redfish_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated scaleway_image_facts module has been removed. Use scaleway_image_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated scaleway_ip_facts module has been removed. Use scaleway_ip_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated scaleway_organization_facts module has been removed. Use scaleway_organization_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated scaleway_security_group_facts module has been removed. Use scaleway_security_group_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated scaleway_server_facts module has been removed. Use scaleway_server_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated scaleway_snapshot_facts module has been removed. Use scaleway_snapshot_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated scaleway_volume_facts module has been removed. Use scaleway_volume_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated smartos_image_facts module has been removed. Use smartos_image_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated vertica_facts module has been removed. Use vertica_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated xenserver_guest_facts module has been removed. Use xenserver_guest_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt module has been removed. Use ovirt.ovirt.ovirt_vm instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_affinity_label_facts module has been removed. Use ovirt.ovirt.ovirt_affinity_label_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_api_facts module has been removed. Use ovirt.ovirt.ovirt_api_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_cluster_facts module has been removed. Use ovirt.ovirt.ovirt_cluster_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_datacenter_facts module has been removed. Use ovirt.ovirt.ovirt_datacenter_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_disk_facts module has been removed. Use ovirt.ovirt.ovirt_disk_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_event_facts module has been removed. Use ovirt.ovirt.ovirt_event_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_external_provider_facts module has been removed. Use ovirt.ovirt.ovirt_external_provider_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_group_facts module has been removed. Use ovirt.ovirt.ovirt_group_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_host_facts module has been removed. Use ovirt.ovirt.ovirt_host_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_host_storage_facts module has been removed. Use ovirt.ovirt.ovirt_host_storage_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_network_facts module has been removed. Use ovirt.ovirt.ovirt_network_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_nic_facts module has been removed. Use ovirt.ovirt.ovirt_nic_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_permission_facts module has been removed. Use ovirt.ovirt.ovirt_permission_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_quota_facts module has been removed. Use ovirt.ovirt.ovirt_quota_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_scheduling_policy_facts module has been removed. Use ovirt.ovirt.ovirt_scheduling_policy_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_snapshot_facts module has been removed. Use ovirt.ovirt.ovirt_snapshot_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_storage_domain_facts module has been removed. Use ovirt.ovirt.ovirt_storage_domain_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_storage_template_facts module has been removed. Use ovirt.ovirt.ovirt_storage_template_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_storage_vm_facts module has been removed. Use ovirt.ovirt.ovirt_storage_vm_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_tag_facts module has been removed. Use ovirt.ovirt.ovirt_tag_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_template_facts module has been removed. Use ovirt.ovirt.ovirt_template_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_user_facts module has been removed. Use ovirt.ovirt.ovirt_user_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_vm_facts module has been removed. Use ovirt.ovirt.ovirt_vm_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ovirt_vmpool_facts module has been removed. Use ovirt.ovirt.ovirt_vmpool_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The ovirt_facts docs fragment has been removed (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated gluster_heal_info module has been removed. Use gluster.gluster.gluster_heal_info instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated gluster_peer module has been removed. Use gluster.gluster.gluster_peer instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated gluster_volume module has been removed. Use gluster.gluster.gluster_volume instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated helm module has been removed. Use community.kubernetes.helm instead (https://github.com/ansible-collections/community.general/pull/1924)." -- "The deprecated ldap_attr module has been removed. Use ldap_attrs instead (https://github.com/ansible-collections/community.general/pull/1924)." diff --git a/changelogs/fragments/selective-core-2.11.yml b/changelogs/fragments/selective-core-2.11.yml deleted file mode 100644 index 994e555c7c..0000000000 --- a/changelogs/fragments/selective-core-2.11.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- "selective callback plugin - adjust import so that the plugin also works with ansible-core 2.11 (https://github.com/ansible-collections/community.general/pull/1807)." From 1d8c659ba2ebdd628b8740deb7c1ab27e8a02674 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 26 Apr 2021 21:19:55 +0200 Subject: [PATCH 003/139] Next expected release is 3.0.0. --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 3676516625..a4b4cad7e0 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: community name: general -version: 3.0.0 +version: 3.1.0 readme: README.md authors: - Ansible (https://github.com/ansible) From 0330f4b52c6a4b21c5d3fbd34a8dc0bdd4406b36 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 26 Apr 2021 22:24:42 +0200 Subject: [PATCH 004/139] Make inventory scripts executable (#2337) (#2359) * Make inventory scripts executable * Mark inventory scripts in vault folder as executable * Add changelog entry for making inventory scripts exectuable * Update changelogs/fragments/2337-mark-inventory-scripts-executable.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 2ad004b97b750d31dc2900868598fafd31dc8d90) Co-authored-by: Alan Rominger --- .../fragments/2337-mark-inventory-scripts-executable.yml | 3 +++ scripts/inventory/abiquo.py | 0 scripts/inventory/apache-libcloud.py | 0 scripts/inventory/apstra_aos.py | 0 scripts/inventory/azure_rm.py | 0 scripts/inventory/brook.py | 0 scripts/inventory/cloudforms.py | 0 scripts/inventory/cobbler.py | 0 scripts/inventory/collins.py | 0 scripts/inventory/consul_io.py | 0 scripts/inventory/docker.py | 0 scripts/inventory/fleet.py | 0 scripts/inventory/foreman.py | 0 scripts/inventory/freeipa.py | 0 scripts/inventory/infoblox.py | 0 scripts/inventory/jail.py | 0 scripts/inventory/landscape.py | 0 scripts/inventory/linode.py | 0 scripts/inventory/lxc_inventory.py | 0 scripts/inventory/lxd.py | 0 scripts/inventory/mdt_dynamic_inventory.py | 0 scripts/inventory/nagios_livestatus.py | 0 scripts/inventory/nagios_ndo.py | 0 scripts/inventory/nsot.py | 0 scripts/inventory/openshift.py | 0 scripts/inventory/openvz.py | 0 scripts/inventory/ovirt.py | 0 scripts/inventory/ovirt4.py | 0 scripts/inventory/packet_net.py | 0 scripts/inventory/proxmox.py | 0 scripts/inventory/rackhd.py | 0 scripts/inventory/rax.py | 0 scripts/inventory/rudder.py | 0 scripts/inventory/scaleway.py | 0 scripts/inventory/serf.py | 0 scripts/inventory/softlayer.py | 0 scripts/inventory/spacewalk.py | 0 scripts/inventory/ssh_config.py | 0 scripts/inventory/stacki.py | 0 scripts/inventory/vagrant.py | 0 scripts/inventory/vbox.py | 0 scripts/inventory/zone.py | 0 scripts/vault/azure_vault.py | 0 scripts/vault/vault-keyring-client.py | 0 scripts/vault/vault-keyring.py | 0 45 files changed, 3 insertions(+) create mode 100644 changelogs/fragments/2337-mark-inventory-scripts-executable.yml mode change 100644 => 100755 scripts/inventory/abiquo.py mode change 100644 => 100755 scripts/inventory/apache-libcloud.py mode change 100644 => 100755 scripts/inventory/apstra_aos.py mode change 100644 => 100755 scripts/inventory/azure_rm.py mode change 100644 => 100755 scripts/inventory/brook.py mode change 100644 => 100755 scripts/inventory/cloudforms.py mode change 100644 => 100755 scripts/inventory/cobbler.py mode change 100644 => 100755 scripts/inventory/collins.py mode change 100644 => 100755 scripts/inventory/consul_io.py mode change 100644 => 100755 scripts/inventory/docker.py mode change 100644 => 100755 scripts/inventory/fleet.py mode change 100644 => 100755 scripts/inventory/foreman.py mode change 100644 => 100755 scripts/inventory/freeipa.py mode change 100644 => 100755 scripts/inventory/infoblox.py mode change 100644 => 100755 scripts/inventory/jail.py mode change 100644 => 100755 scripts/inventory/landscape.py mode change 100644 => 100755 scripts/inventory/linode.py mode change 100644 => 100755 scripts/inventory/lxc_inventory.py mode change 100644 => 100755 scripts/inventory/lxd.py mode change 100644 => 100755 scripts/inventory/mdt_dynamic_inventory.py mode change 100644 => 100755 scripts/inventory/nagios_livestatus.py mode change 100644 => 100755 scripts/inventory/nagios_ndo.py mode change 100644 => 100755 scripts/inventory/nsot.py mode change 100644 => 100755 scripts/inventory/openshift.py mode change 100644 => 100755 scripts/inventory/openvz.py mode change 100644 => 100755 scripts/inventory/ovirt.py mode change 100644 => 100755 scripts/inventory/ovirt4.py mode change 100644 => 100755 scripts/inventory/packet_net.py mode change 100644 => 100755 scripts/inventory/proxmox.py mode change 100644 => 100755 scripts/inventory/rackhd.py mode change 100644 => 100755 scripts/inventory/rax.py mode change 100644 => 100755 scripts/inventory/rudder.py mode change 100644 => 100755 scripts/inventory/scaleway.py mode change 100644 => 100755 scripts/inventory/serf.py mode change 100644 => 100755 scripts/inventory/softlayer.py mode change 100644 => 100755 scripts/inventory/spacewalk.py mode change 100644 => 100755 scripts/inventory/ssh_config.py mode change 100644 => 100755 scripts/inventory/stacki.py mode change 100644 => 100755 scripts/inventory/vagrant.py mode change 100644 => 100755 scripts/inventory/vbox.py mode change 100644 => 100755 scripts/inventory/zone.py mode change 100644 => 100755 scripts/vault/azure_vault.py mode change 100644 => 100755 scripts/vault/vault-keyring-client.py mode change 100644 => 100755 scripts/vault/vault-keyring.py diff --git a/changelogs/fragments/2337-mark-inventory-scripts-executable.yml b/changelogs/fragments/2337-mark-inventory-scripts-executable.yml new file mode 100644 index 0000000000..69aa3fff62 --- /dev/null +++ b/changelogs/fragments/2337-mark-inventory-scripts-executable.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - inventory and vault scripts - change file permissions to make vendored inventory and vault scripts exectuable (https://github.com/ansible-collections/community.general/pull/2337). diff --git a/scripts/inventory/abiquo.py b/scripts/inventory/abiquo.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/apache-libcloud.py b/scripts/inventory/apache-libcloud.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/apstra_aos.py b/scripts/inventory/apstra_aos.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/azure_rm.py b/scripts/inventory/azure_rm.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/brook.py b/scripts/inventory/brook.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/cloudforms.py b/scripts/inventory/cloudforms.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/cobbler.py b/scripts/inventory/cobbler.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/collins.py b/scripts/inventory/collins.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/consul_io.py b/scripts/inventory/consul_io.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/docker.py b/scripts/inventory/docker.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/fleet.py b/scripts/inventory/fleet.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/foreman.py b/scripts/inventory/foreman.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/freeipa.py b/scripts/inventory/freeipa.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/infoblox.py b/scripts/inventory/infoblox.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/jail.py b/scripts/inventory/jail.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/landscape.py b/scripts/inventory/landscape.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/linode.py b/scripts/inventory/linode.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/lxc_inventory.py b/scripts/inventory/lxc_inventory.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/lxd.py b/scripts/inventory/lxd.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/mdt_dynamic_inventory.py b/scripts/inventory/mdt_dynamic_inventory.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/nagios_livestatus.py b/scripts/inventory/nagios_livestatus.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/nagios_ndo.py b/scripts/inventory/nagios_ndo.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/nsot.py b/scripts/inventory/nsot.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/openshift.py b/scripts/inventory/openshift.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/openvz.py b/scripts/inventory/openvz.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/ovirt.py b/scripts/inventory/ovirt.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/ovirt4.py b/scripts/inventory/ovirt4.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/packet_net.py b/scripts/inventory/packet_net.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/proxmox.py b/scripts/inventory/proxmox.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/rackhd.py b/scripts/inventory/rackhd.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/rax.py b/scripts/inventory/rax.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/rudder.py b/scripts/inventory/rudder.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/scaleway.py b/scripts/inventory/scaleway.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/serf.py b/scripts/inventory/serf.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/softlayer.py b/scripts/inventory/softlayer.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/spacewalk.py b/scripts/inventory/spacewalk.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/ssh_config.py b/scripts/inventory/ssh_config.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/stacki.py b/scripts/inventory/stacki.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/vagrant.py b/scripts/inventory/vagrant.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/vbox.py b/scripts/inventory/vbox.py old mode 100644 new mode 100755 diff --git a/scripts/inventory/zone.py b/scripts/inventory/zone.py old mode 100644 new mode 100755 diff --git a/scripts/vault/azure_vault.py b/scripts/vault/azure_vault.py old mode 100644 new mode 100755 diff --git a/scripts/vault/vault-keyring-client.py b/scripts/vault/vault-keyring-client.py old mode 100644 new mode 100755 diff --git a/scripts/vault/vault-keyring.py b/scripts/vault/vault-keyring.py old mode 100644 new mode 100755 From ea42b7537812dcb0d6d8fefcc41378b98756aa72 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 27 Apr 2021 11:46:17 +0000 Subject: [PATCH 005/139] spotinst_aws_elastigroup - fixed elements for many lists (#2355) (#2363) * fixed elements for many lists * added changelog fragment * Removed verbose types in description - still missing formatting and properly documenting dicts (cherry picked from commit 48ef05def340588393075341c3b0b4e44f5fdab8) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- ...spotinst_aws_elastigroup-list-elements.yml | 2 + .../spotinst/spotinst_aws_elastigroup.py | 165 ++++++++++-------- 2 files changed, 92 insertions(+), 75 deletions(-) create mode 100644 changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml diff --git a/changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml b/changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml new file mode 100644 index 0000000000..876b212690 --- /dev/null +++ b/changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml @@ -0,0 +1,2 @@ +minor_changes: + - spotinst_aws_elastigroup - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2355). diff --git a/plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py b/plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py index 1a0ddb9fef..5ed8028e37 100644 --- a/plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py +++ b/plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py @@ -23,26 +23,26 @@ options: credentials_path: description: - - (Path) Optional parameter that allows to set a non-default credentials path. + - Optional parameter that allows to set a non-default credentials path. default: ~/.spotinst/credentials type: path account_id: description: - - (String) Optional parameter that allows to set an account-id inside the module configuration - By default this is retrieved from the credentials path + - Optional parameter that allows to set an account-id inside the module configuration. + By default this is retrieved from the credentials path. type: str availability_vs_cost: description: - - (String) The strategy orientation. + - The strategy orientation. - "The choices available are: C(availabilityOriented), C(costOriented), C(balanced)." required: true type: str availability_zones: description: - - (List of Objects) a list of hash/dictionaries of Availability Zones that are configured in the elastigroup; + - A list of hash/dictionaries of Availability Zones that are configured in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are name (String), @@ -50,10 +50,11 @@ options: placement_group_name (String), required: true type: list + elements: dict block_device_mappings: description: - - (List of Objects) a list of hash/dictionaries of Block Device Mappings for elastigroup instances; + - A list of hash/dictionaries of Block Device Mappings for elastigroup instances; You can specify virtual devices and EBS volumes.; '[{"key":"value", "key":"value"}]'; keys allowed are @@ -68,10 +69,11 @@ options: volume_type(String), volume_size(Integer)) type: list + elements: dict chef: description: - - (Object) The Chef integration configuration.; + - The Chef integration configuration.; Expects the following keys - chef_server (String), organization (String), user (String), @@ -81,92 +83,94 @@ options: draining_timeout: description: - - (Integer) Time for instance to be drained from incoming requests and deregistered from ELB before termination. + - Time for instance to be drained from incoming requests and deregistered from ELB before termination. type: int ebs_optimized: description: - - (Boolean) Enable EBS optimization for supported instances which are not enabled by default.; + - Enable EBS optimization for supported instances which are not enabled by default.; Note - additional charges will be applied. type: bool ebs_volume_pool: description: - - (List of Objects) a list of hash/dictionaries of EBS devices to reattach to the elastigroup when available; + - A list of hash/dictionaries of EBS devices to reattach to the elastigroup when available; '[{"key":"value", "key":"value"}]'; keys allowed are - volume_ids (List of Strings), device_name (String) type: list + elements: dict ecs: description: - - (Object) The ECS integration configuration.; + - The ECS integration configuration.; Expects the following key - cluster_name (String) type: dict elastic_ips: description: - - (List of Strings) List of ElasticIps Allocation Ids (Example C(eipalloc-9d4e16f8)) to associate to the group instances + - List of ElasticIps Allocation Ids (Example C(eipalloc-9d4e16f8)) to associate to the group instances type: list + elements: str fallback_to_od: description: - - (Boolean) In case of no spots available, Elastigroup will launch an On-demand instance instead + - In case of no spots available, Elastigroup will launch an On-demand instance instead type: bool health_check_grace_period: description: - - (Integer) The amount of time, in seconds, after the instance has launched to start and check its health. + - The amount of time, in seconds, after the instance has launched to start and check its health. - If not specified, it defaults to C(300). type: int health_check_unhealthy_duration_before_replacement: description: - - (Integer) Minimal mount of time instance should be unhealthy for us to consider it unhealthy. + - Minimal mount of time instance should be unhealthy for us to consider it unhealthy. type: int health_check_type: description: - - (String) The service to use for the health check. + - The service to use for the health check. - "The choices available are: C(ELB), C(HCS), C(TARGET_GROUP), C(MLB), C(EC2)." type: str iam_role_name: description: - - (String) The instance profile iamRole name + - The instance profile iamRole name - Only use iam_role_arn, or iam_role_name type: str iam_role_arn: description: - - (String) The instance profile iamRole arn + - The instance profile iamRole arn - Only use iam_role_arn, or iam_role_name type: str id: description: - - (String) The group id if it already exists and you want to update, or delete it. + - The group id if it already exists and you want to update, or delete it. This will not work unless the uniqueness_by field is set to id. When this is set, and the uniqueness_by field is set, the group will either be updated or deleted, but not created. type: str image_id: description: - - (String) The image Id used to launch the instance.; + - The image Id used to launch the instance.; In case of conflict between Instance type and image type, an error will be returned required: true type: str key_pair: description: - - (String) Specify a Key Pair to attach to the instances + - Specify a Key Pair to attach to the instances type: str kubernetes: description: - - (Object) The Kubernetes integration configuration. + - The Kubernetes integration configuration. Expects the following keys - api_server (String), token (String) @@ -174,47 +178,48 @@ options: lifetime_period: description: - - (Integer) lifetime period + - Lifetime period type: int load_balancers: description: - - (List of Strings) List of classic ELB names + - List of classic ELB names type: list + elements: str max_size: description: - - (Integer) The upper limit number of instances that you can scale up to + - The upper limit number of instances that you can scale up to required: true type: int mesosphere: description: - - (Object) The Mesosphere integration configuration. + - The Mesosphere integration configuration. Expects the following key - api_server (String) type: dict min_size: description: - - (Integer) The lower limit number of instances that you can scale down to + - The lower limit number of instances that you can scale down to required: true type: int monitoring: description: - - (String) Describes whether instance Enhanced Monitoring is enabled + - Describes whether instance Enhanced Monitoring is enabled type: str name: description: - - (String) Unique name for elastigroup to be created, updated or deleted + - Unique name for elastigroup to be created, updated or deleted required: true type: str network_interfaces: description: - - (List of Objects) a list of hash/dictionaries of network interfaces to add to the elastigroup; + - A list of hash/dictionaries of network interfaces to add to the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - description (String), @@ -229,29 +234,30 @@ options: associate_ipv6_address (Boolean), private_ip_addresses (List of Objects, Keys are privateIpAddress (String, required) and primary (Boolean)) type: list + elements: dict on_demand_count: description: - - (Integer) Required if risk is not set + - Required if risk is not set - Number of on demand instances to launch. All other instances will be spot instances.; Either set this parameter or the risk parameter type: int on_demand_instance_type: description: - - (String) On-demand instance type that will be provisioned + - On-demand instance type that will be provisioned type: str opsworks: description: - - (Object) The elastigroup OpsWorks integration configration.; + - The elastigroup OpsWorks integration configration.; Expects the following key - layer_id (String) type: dict persistence: description: - - (Object) The Stateful elastigroup configration.; + - The Stateful elastigroup configration.; Accepts the following keys - should_persist_root_device (Boolean), should_persist_block_devices (Boolean), @@ -260,14 +266,14 @@ options: product: description: - - (String) Operation system type. + - Operation system type. - "Available choices are: C(Linux/UNIX), C(SUSE Linux), C(Windows), C(Linux/UNIX (Amazon VPC)), C(SUSE Linux (Amazon VPC))." required: true type: str rancher: description: - - (Object) The Rancher integration configuration.; + - The Rancher integration configuration.; Expects the following keys - version (String), access_key (String), @@ -277,7 +283,7 @@ options: right_scale: description: - - (Object) The Rightscale integration configuration.; + - The Rightscale integration configuration.; Expects the following keys - account_id (String), refresh_token (String) @@ -285,12 +291,12 @@ options: risk: description: - - (Integer) required if on demand is not set. The percentage of Spot instances to launch (0 - 100). + - Required if on demand is not set. The percentage of Spot instances to launch (0 - 100). type: int roll_config: description: - - (Object) Roll configuration.; + - Roll configuration.; If you would like the group to roll after updating, please use this feature. Accepts the following keys - batch_size_percentage(Integer, Required), @@ -300,7 +306,7 @@ options: scheduled_tasks: description: - - (List of Objects) a list of hash/dictionaries of scheduled tasks to configure in the elastigroup; + - A list of hash/dictionaries of scheduled tasks to configure in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - adjustment (Integer), @@ -315,84 +321,90 @@ options: task_type (String, required), is_enabled (Boolean) type: list + elements: dict security_group_ids: description: - - (List of Strings) One or more security group IDs. ; + - One or more security group IDs. ; In case of update it will override the existing Security Group with the new given array required: true type: list + elements: str shutdown_script: description: - - (String) The Base64-encoded shutdown script that executes prior to instance termination. + - The Base64-encoded shutdown script that executes prior to instance termination. Encode before setting. type: str signals: description: - - (List of Objects) a list of hash/dictionaries of signals to configure in the elastigroup; + - A list of hash/dictionaries of signals to configure in the elastigroup; keys allowed are - name (String, required), timeout (Integer) type: list + elements: dict spin_up_time: description: - - (Integer) spin up time, in seconds, for the instance + - Spin up time, in seconds, for the instance type: int spot_instance_types: description: - - (List of Strings) Spot instance type that will be provisioned. + - Spot instance type that will be provisioned. required: true type: list + elements: str state: choices: - present - absent description: - - (String) create or delete the elastigroup + - Create or delete the elastigroup default: present type: str tags: description: - - (List of tagKey:tagValue pairs) a list of tags to configure in the elastigroup. Please specify list of keys and values (key colon value); + - A list of tags to configure in the elastigroup. Please specify list of keys and values (key colon value); type: list + elements: dict target: description: - - (Integer) The number of instances to launch + - The number of instances to launch required: true type: int target_group_arns: description: - - (List of Strings) List of target group arns instances should be registered to + - List of target group arns instances should be registered to type: list + elements: str tenancy: description: - - (String) dedicated vs shared tenancy. + - Dedicated vs shared tenancy. - "The available choices are: C(default), C(dedicated)." type: str terminate_at_end_of_billing_hour: description: - - (Boolean) terminate at the end of billing hour + - Terminate at the end of billing hour type: bool unit: description: - - (String) The capacity unit to launch instances by. + - The capacity unit to launch instances by. - "The available choices are: C(instance), C(weight)." type: str up_scaling_policies: description: - - (List of Objects) a list of hash/dictionaries of scaling policies to configure in the elastigroup; + - A list of hash/dictionaries of scaling policies to configure in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - policy_name (String, required), @@ -413,10 +425,11 @@ options: maximum (String), minimum (String) type: list + elements: dict down_scaling_policies: description: - - (List of Objects) a list of hash/dictionaries of scaling policies to configure in the elastigroup; + - A list of hash/dictionaries of scaling policies to configure in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - policy_name (String, required), @@ -437,10 +450,11 @@ options: maximum (String), minimum (String) type: list + elements: dict target_tracking_policies: description: - - (List of Objects) a list of hash/dictionaries of target tracking policies to configure in the elastigroup; + - A list of hash/dictionaries of target tracking policies to configure in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - policy_name (String, required), @@ -452,37 +466,38 @@ options: cooldown (String, required), target (String, required) type: list + elements: dict uniqueness_by: choices: - id - name description: - - (String) If your group names are not unique, you may use this feature to update or delete a specific group. + - If your group names are not unique, you may use this feature to update or delete a specific group. Whenever this property is set, you must set a group_id in order to update or delete a group, otherwise a group will be created. default: name type: str user_data: description: - - (String) Base64-encoded MIME user data. Encode before setting the value. + - Base64-encoded MIME user data. Encode before setting the value. type: str utilize_reserved_instances: description: - - (Boolean) In case of any available Reserved Instances, + - In case of any available Reserved Instances, Elastigroup will utilize your reservations before purchasing Spot instances. type: bool wait_for_instances: description: - - (Boolean) Whether or not the elastigroup creation / update actions should wait for the instances to spin + - Whether or not the elastigroup creation / update actions should wait for the instances to spin type: bool default: false wait_timeout: description: - - (Integer) How long the module should wait for instances before failing the action.; + - How long the module should wait for instances before failing the action.; Only works if wait_for_instances is True. type: int @@ -1428,18 +1443,18 @@ def main(): fields = dict( account_id=dict(type='str'), availability_vs_cost=dict(type='str', required=True), - availability_zones=dict(type='list', required=True), - block_device_mappings=dict(type='list'), + availability_zones=dict(type='list', elements='dict', required=True), + 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'), - down_scaling_policies=dict(type='list'), + down_scaling_policies=dict(type='list', elements='dict'), draining_timeout=dict(type='int'), ebs_optimized=dict(type='bool'), - ebs_volume_pool=dict(type='list'), + ebs_volume_pool=dict(type='list', elements='dict'), ecs=dict(type='dict'), elastic_beanstalk=dict(type='dict'), - elastic_ips=dict(type='list'), + elastic_ips=dict(type='list', elements='str'), fallback_to_od=dict(type='bool'), id=dict(type='str'), health_check_grace_period=dict(type='int'), @@ -1451,7 +1466,7 @@ def main(): key_pair=dict(type='str', no_log=False), kubernetes=dict(type='dict'), lifetime_period=dict(type='int'), - load_balancers=dict(type='list'), + load_balancers=dict(type='list', elements='str'), max_size=dict(type='int', required=True), mesosphere=dict(type='dict'), min_size=dict(type='int', required=True), @@ -1459,7 +1474,7 @@ def main(): multai_load_balancers=dict(type='list'), multai_token=dict(type='str', no_log=True), name=dict(type='str', required=True), - network_interfaces=dict(type='list'), + network_interfaces=dict(type='list', elements='dict'), on_demand_count=dict(type='int'), on_demand_instance_type=dict(type='str'), opsworks=dict(type='dict'), @@ -1469,16 +1484,16 @@ def main(): right_scale=dict(type='dict'), risk=dict(type='int'), roll_config=dict(type='dict'), - scheduled_tasks=dict(type='list'), - security_group_ids=dict(type='list', required=True), + scheduled_tasks=dict(type='list', elements='dict'), + security_group_ids=dict(type='list', elements='str', required=True), shutdown_script=dict(type='str'), - signals=dict(type='list'), + signals=dict(type='list', elements='dict'), spin_up_time=dict(type='int'), - spot_instance_types=dict(type='list', required=True), + spot_instance_types=dict(type='list', elements='str', required=True), state=dict(default='present', choices=['present', 'absent']), - tags=dict(type='list'), + tags=dict(type='list', elements='dict'), target=dict(type='int', required=True), - target_group_arns=dict(type='list'), + target_group_arns=dict(type='list', elements='str'), tenancy=dict(type='str'), terminate_at_end_of_billing_hour=dict(type='bool'), token=dict(type='str', no_log=True), @@ -1486,8 +1501,8 @@ def main(): user_data=dict(type='str'), utilize_reserved_instances=dict(type='bool'), uniqueness_by=dict(default='name', choices=['name', 'id']), - up_scaling_policies=dict(type='list'), - target_tracking_policies=dict(type='list'), + up_scaling_policies=dict(type='list', elements='dict'), + target_tracking_policies=dict(type='list', elements='dict'), wait_for_instances=dict(type='bool', default=False), wait_timeout=dict(type='int') ) From 1c05908ff60fea1842f4c13dda4fd7a838a1c281 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 27 Apr 2021 13:46:28 +0200 Subject: [PATCH 006/139] BOTMETA.yml: team_suse - add a maintainer (#2354) (#2362) (cherry picked from commit 9d13acd68e3b9104e48ddddedc811603330d6b7b) Co-authored-by: Andrew Klychkov --- .github/BOTMETA.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 06501fc2aa..c14fb0d0e1 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -707,7 +707,8 @@ files: labels: zypper ignore: dirtyharrycallahan robinro $modules/packaging/os/zypper_repository.py: - maintainers: matze + maintainers: $team_suse matze + labels: zypper $modules/remote_management/cobbler/: maintainers: dagwieers $modules/remote_management/hpilo/: @@ -1025,5 +1026,5 @@ macros: team_rhn: FlossWare alikins barnabycourt vritant team_scaleway: QuentinBrosse abarbare jerome-quere kindermoumoute remyleone sieben team_solaris: bcoca fishman jasperla jpdasma mator scathatheworm troy2914 xen0l - team_suse: commel dcermak evrardjp lrupp toabctl AnderEnder alxgu andytom + team_suse: commel dcermak evrardjp lrupp toabctl AnderEnder alxgu andytom sealor team_virt: joshainglis karmab tleguern Thulium-Drake Ajpantuso From be42fd4af75241dee0df0e5fd760e2bac9b195c4 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 27 Apr 2021 22:44:21 +0200 Subject: [PATCH 007/139] No longer required for devel's ansible-test. (#2365) (#2367) ci_complete (cherry picked from commit 77d4bc29421a78b479c6e826ca7d68f00fa82f57) Co-authored-by: Felix Fontein --- tests/sanity/ignore-2.12.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index 80975cf389..68684f000d 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -69,7 +69,5 @@ plugins/modules/system/ssh_config.py use-argspec-type-path # Required since modu plugins/modules/system/xfconf.py validate-modules:parameter-state-invalid-choice plugins/modules/system/xfconf.py validate-modules:return-syntax-error plugins/modules/web_infrastructure/jenkins_plugin.py use-argspec-type-path -tests/integration/targets/django_manage/files/base_test/simple_project/p1/manage.py compile-2.6 # django generated code -tests/integration/targets/django_manage/files/base_test/simple_project/p1/manage.py compile-2.7 # django generated code tests/utils/shippable/check_matrix.py replace-urlopen tests/utils/shippable/timing.py shebang From 75c0004e1ea73e5c29ee9030848c43b1c433d733 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 30 Apr 2021 05:32:23 +0200 Subject: [PATCH 008/139] Use Ansible's codecov uploader. (#2377) (#2380) (cherry picked from commit b3f436aa6325c34e1824ccc39e8446969b70ab95) Co-authored-by: Felix Fontein --- .azure-pipelines/scripts/publish-codecov.sh | 2 +- tests/utils/shippable/shippable.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines/scripts/publish-codecov.sh b/.azure-pipelines/scripts/publish-codecov.sh index 7aeabda0c0..6d184f0b8d 100755 --- a/.azure-pipelines/scripts/publish-codecov.sh +++ b/.azure-pipelines/scripts/publish-codecov.sh @@ -7,7 +7,7 @@ set -o pipefail -eu output_path="$1" -curl --silent --show-error https://codecov.io/bash > codecov.sh +curl --silent --show-error https://ansible-ci-files.s3.us-east-1.amazonaws.com/codecov/codecov.sh > codecov.sh for file in "${output_path}"/reports/coverage*.xml; do name="${file}" diff --git a/tests/utils/shippable/shippable.sh b/tests/utils/shippable/shippable.sh index f239e86975..f70aa11380 100755 --- a/tests/utils/shippable/shippable.sh +++ b/tests/utils/shippable/shippable.sh @@ -181,7 +181,7 @@ function cleanup flags="${flags//=/,}" flags="${flags//[^a-zA-Z0-9_,]/_}" - bash <(curl -s https://codecov.io/bash) \ + bash <(curl -s https://ansible-ci-files.s3.us-east-1.amazonaws.com/codecov/codecov.sh) \ -f "${file}" \ -F "${flags}" \ -n "${test}" \ From b920e8abf203851a2a03f41ba778004f51de5bc2 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 1 May 2021 14:10:07 +0200 Subject: [PATCH 009/139] Add Fedora 34 to CI (#2384) (#2391) * Add fedora 34 and fix typo * Remove Fedora 32 from devel testing * Use one newer version of Fedora for fixed ansible versions * Revert "Use one newer version of Fedora for fixed ansible versions" This reverts commit cbd006bd385865905c18b87655bd98b0610d4abc. * Try to skip task. * Revert "Try to skip task." This reverts commit ff0c899a8650e78967a1933b93fd8015695a6a61. * Temporary disable Fedora 34 on setup_postgresql_db Co-authored-by: Felix Fontein (cherry picked from commit ae21af882075948f9e427919776e5c155b263ea2) Co-authored-by: Amin Vakil --- .azure-pipelines/azure-pipelines.yml | 6 +++--- .../integration/targets/setup_postgresql_db/tasks/main.yml | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index 8c0804ab31..a3b2dbdb04 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -256,10 +256,10 @@ stages: test: centos7 - name: CentOS 8 test: centos8 - - name: Fedora 32 - test: fedora32 - name: Fedora 33 test: fedora33 + - name: Fedora 34 + test: fedora34 - name: openSUSE 15 py2 test: opensuse15py2 - name: openSUSE 15 py3 @@ -282,7 +282,7 @@ stages: targets: - name: CentOS 8 test: centos8 - - name: Fedora 32 + - name: Fedora 33 test: fedora33 - name: openSUSE 15 py3 test: opensuse15 diff --git a/tests/integration/targets/setup_postgresql_db/tasks/main.yml b/tests/integration/targets/setup_postgresql_db/tasks/main.yml index 2322ee2cbf..f535ecdcf9 100644 --- a/tests/integration/targets/setup_postgresql_db/tasks/main.yml +++ b/tests/integration/targets/setup_postgresql_db/tasks/main.yml @@ -11,6 +11,10 @@ - meta: end_play when: ansible_facts.distribution == 'CentOS' and ansible_facts.distribution_major_version == '8' +# Temporary disable Fedora 34 +- meta: end_play + when: ansible_facts.distribution == 'Fedora' and ansible_facts.distribution_major_version == '34' + - name: python 2 set_fact: python_suffix: '' From 74eba52028d77bdbddd02567c90c0fe109076ee7 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 1 May 2021 14:11:16 +0200 Subject: [PATCH 010/139] Remove resmo as composer maintainer. (#2392) (#2395) (cherry picked from commit 276880aac1a4df7cd9cfbea983c3e743de0a1bbf) Co-authored-by: Felix Fontein --- .github/BOTMETA.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index c14fb0d0e1..6fcfdff4c1 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -560,7 +560,8 @@ files: $modules/packaging/language/bundler.py: maintainers: thoiberg $modules/packaging/language/composer.py: - maintainers: dmtrs resmo + maintainers: dmtrs + ignore: resmo $modules/packaging/language/cpanm.py: maintainers: fcuny russoz $modules/packaging/language/easy_install.py: From 51540f63458d7465e0248bb494d02a69e66741cc Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 1 May 2021 14:37:19 +0200 Subject: [PATCH 011/139] influxdb_retention_policy: fix duration parsing to support INF values (#2396) (#2401) * influxdb_retention_policy: fix duration parsing to support INF values * add changelog (cherry picked from commit 26c3bd25f676b67a89a625e13991ab41394f5098) Co-authored-by: Xabier Napal --- .../2284-influxdb_retention_policy-fix_duration_parsing.yml | 3 +++ .../modules/database/influxdb/influxdb_retention_policy.py | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/2284-influxdb_retention_policy-fix_duration_parsing.yml diff --git a/changelogs/fragments/2284-influxdb_retention_policy-fix_duration_parsing.yml b/changelogs/fragments/2284-influxdb_retention_policy-fix_duration_parsing.yml new file mode 100644 index 0000000000..04c82480c1 --- /dev/null +++ b/changelogs/fragments/2284-influxdb_retention_policy-fix_duration_parsing.yml @@ -0,0 +1,3 @@ +bugfixes: + - influxdb_retention_policy - fix bug where ``INF`` duration values failed parsing + (https://github.com/ansible-collections/community.general/pull/2385). diff --git a/plugins/modules/database/influxdb/influxdb_retention_policy.py b/plugins/modules/database/influxdb/influxdb_retention_policy.py index 2c2f9674b7..883adaffa6 100644 --- a/plugins/modules/database/influxdb/influxdb_retention_policy.py +++ b/plugins/modules/database/influxdb/influxdb_retention_policy.py @@ -129,7 +129,7 @@ from ansible_collections.community.general.plugins.module_utils.influxdb import from ansible.module_utils._text import to_native -VALID_DURATION_REGEX = re.compile(r'^(\d+(ns|u|µ|ms|s|m|h|d|w))+$') +VALID_DURATION_REGEX = re.compile(r'^(INF|(\d+(ns|u|µ|ms|s|m|h|d|w)))+$') DURATION_REGEX = re.compile(r'(\d+)(ns|u|µ|ms|s|m|h|d|w)') EXTENDED_DURATION_REGEX = re.compile(r'(?:(\d+)(ns|u|µ|ms|m|h|d|w)|(\d+(?:\.\d+)?)(s))') @@ -217,7 +217,7 @@ def create_retention_policy(module, client): influxdb_shard_group_duration_format = parse_duration_literal(shard_group_duration) if influxdb_shard_group_duration_format < 3600000000000: - module.fail_json(msg="shard_group_duration value must be at least 1h") + module.fail_json(msg="shard_group_duration value must be finite and at least 1h") if not module.check_mode: try: @@ -256,7 +256,7 @@ def alter_retention_policy(module, client, retention_policy): influxdb_shard_group_duration_format = parse_duration_literal(shard_group_duration) if influxdb_shard_group_duration_format < 3600000000000: - module.fail_json(msg="shard_group_duration value must be at least 1h") + module.fail_json(msg="shard_group_duration value must be finite and at least 1h") if (retention_policy['duration'] != influxdb_duration_format or retention_policy['shardGroupDuration'] != influxdb_shard_group_duration_format or From 45343e6bc07a9363b48443357bed924b92bb6bbf Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 1 May 2021 18:46:16 +0200 Subject: [PATCH 012/139] composer: --no-interaction when discovering available options (#2348) (#2403) The composer module always uses the no-interaction option if it discovers it _after_ calling "composer help ..." but not on the help call itself. The lack of this option caused composer to not exit when called through the ansible module. The same example command when ran interactively does not prompt for user interaction and exits immediately. It is therefore currently unknown why the same command hangs when called through the ansible composer module or even directly with the command module. Example command which hangs: php /usr/local/bin/composer help install --format=json (cherry picked from commit eb455c69a2c7f7ec28f6162e0c5a34f0bc7932e3) Co-authored-by: George Angelopoulos --- ...-composer-no-interaction-option-discovery-to-avoid-hang.yaml | 2 ++ plugins/modules/packaging/language/composer.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2348-composer-no-interaction-option-discovery-to-avoid-hang.yaml diff --git a/changelogs/fragments/2348-composer-no-interaction-option-discovery-to-avoid-hang.yaml b/changelogs/fragments/2348-composer-no-interaction-option-discovery-to-avoid-hang.yaml new file mode 100644 index 0000000000..0728aeb28b --- /dev/null +++ b/changelogs/fragments/2348-composer-no-interaction-option-discovery-to-avoid-hang.yaml @@ -0,0 +1,2 @@ +bugfixes: + - composer - use ``no-interaction`` option when discovering available options to avoid an issue where composer hangs (https://github.com/ansible-collections/community.general/pull/2348). diff --git a/plugins/modules/packaging/language/composer.py b/plugins/modules/packaging/language/composer.py index c792098b04..64157cb685 100644 --- a/plugins/modules/packaging/language/composer.py +++ b/plugins/modules/packaging/language/composer.py @@ -169,7 +169,7 @@ def has_changed(string): def get_available_options(module, command='install'): # get all available options from a composer command using composer help to json - rc, out, err = composer_command(module, "help %s --format=json" % command) + rc, out, err = composer_command(module, "help %s" % command, arguments="--no-interaction --format=json") if rc != 0: output = parse_out(err) module.fail_json(msg=output) From cf50990fed8a18788752b444124c94b996225124 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 1 May 2021 22:54:44 +0200 Subject: [PATCH 013/139] Add ansible-test config file. (#2404) (#2406) (cherry picked from commit 4e90ee752ed8d9586bb0df69511b0d040a0946ff) Co-authored-by: Felix Fontein --- tests/config.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 tests/config.yml diff --git a/tests/config.yml b/tests/config.yml new file mode 100644 index 0000000000..ba0238e305 --- /dev/null +++ b/tests/config.yml @@ -0,0 +1,5 @@ +--- +# See template for more information: +# https://github.com/ansible/ansible/blob/devel/test/lib/ansible_test/config/config.yml +modules: + python_requires: default From b752fea1212349d98ba8f1188fad293870696de8 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 2 May 2021 13:27:43 +0200 Subject: [PATCH 014/139] BOTMETA.yml: terraform - add a new maintainer (#2290) (#2413) (cherry picked from commit c0221b75afffda7b55852d6510e04bb7f13f292d) Co-authored-by: Andrew Klychkov --- .github/BOTMETA.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 6fcfdff4c1..fd23d0c9e4 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -225,7 +225,7 @@ files: $modules/cloud/misc/: ignore: ryansb $modules/cloud/misc/terraform.py: - maintainers: m-yosefpor + maintainers: m-yosefpor rainerleber $modules/cloud/misc/xenserver_facts.py: maintainers: caphrim007 cheese labels: xenserver_facts From b95176dbc8cad647656c090b69249549dd0de1b7 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Sun, 2 May 2021 13:35:45 +0200 Subject: [PATCH 015/139] Copy schedule to stable branches. --- .azure-pipelines/azure-pipelines.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index a3b2dbdb04..8d1b81865e 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -14,12 +14,24 @@ pr: schedules: - cron: 0 8 * * * - displayName: Nightly + displayName: Nightly (main) always: true branches: include: - main - - stable-* + - cron: 0 10 * * * + displayName: Nightly (active stable branches) + always: true + branches: + include: + - stable-2 + - stable-3 + - cron: 0 11 * * 0 + displayName: Weekly (old stable branches) + always: true + branches: + include: + - stable-1 variables: - name: checkoutPath From a6379e45ce9b1d9b9308294489115e8b9a97bbef Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 3 May 2021 07:47:48 +0200 Subject: [PATCH 016/139] Prepare 3.0.1 release. --- changelogs/fragments/3.0.1.yml | 1 + galaxy.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/3.0.1.yml diff --git a/changelogs/fragments/3.0.1.yml b/changelogs/fragments/3.0.1.yml new file mode 100644 index 0000000000..f2697847bc --- /dev/null +++ b/changelogs/fragments/3.0.1.yml @@ -0,0 +1 @@ +release_summary: Bugfix release for the next Ansible 4.0.0 beta. diff --git a/galaxy.yml b/galaxy.yml index a4b4cad7e0..30cb36cde2 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: community name: general -version: 3.1.0 +version: 3.0.1 readme: README.md authors: - Ansible (https://github.com/ansible) From 5b15e4089af401ac47f3fb63eec22eda7c728d44 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 3 May 2021 07:48:12 +0200 Subject: [PATCH 017/139] Revert "spotinst_aws_elastigroup - fixed elements for many lists (#2355) (#2363)" This reverts commit ea42b7537812dcb0d6d8fefcc41378b98756aa72. (Will be re-reverted after the 3.0.1 release.) --- ...spotinst_aws_elastigroup-list-elements.yml | 2 - .../spotinst/spotinst_aws_elastigroup.py | 165 ++++++++---------- 2 files changed, 75 insertions(+), 92 deletions(-) delete mode 100644 changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml diff --git a/changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml b/changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml deleted file mode 100644 index 876b212690..0000000000 --- a/changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - spotinst_aws_elastigroup - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2355). diff --git a/plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py b/plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py index 5ed8028e37..1a0ddb9fef 100644 --- a/plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py +++ b/plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py @@ -23,26 +23,26 @@ options: credentials_path: description: - - Optional parameter that allows to set a non-default credentials path. + - (Path) Optional parameter that allows to set a non-default credentials path. default: ~/.spotinst/credentials type: path account_id: description: - - Optional parameter that allows to set an account-id inside the module configuration. - By default this is retrieved from the credentials path. + - (String) Optional parameter that allows to set an account-id inside the module configuration + By default this is retrieved from the credentials path type: str availability_vs_cost: description: - - The strategy orientation. + - (String) The strategy orientation. - "The choices available are: C(availabilityOriented), C(costOriented), C(balanced)." required: true type: str availability_zones: description: - - A list of hash/dictionaries of Availability Zones that are configured in the elastigroup; + - (List of Objects) a list of hash/dictionaries of Availability Zones that are configured in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are name (String), @@ -50,11 +50,10 @@ options: placement_group_name (String), required: true type: list - elements: dict block_device_mappings: description: - - A list of hash/dictionaries of Block Device Mappings for elastigroup instances; + - (List of Objects) a list of hash/dictionaries of Block Device Mappings for elastigroup instances; You can specify virtual devices and EBS volumes.; '[{"key":"value", "key":"value"}]'; keys allowed are @@ -69,11 +68,10 @@ options: volume_type(String), volume_size(Integer)) type: list - elements: dict chef: description: - - The Chef integration configuration.; + - (Object) The Chef integration configuration.; Expects the following keys - chef_server (String), organization (String), user (String), @@ -83,94 +81,92 @@ options: draining_timeout: description: - - Time for instance to be drained from incoming requests and deregistered from ELB before termination. + - (Integer) Time for instance to be drained from incoming requests and deregistered from ELB before termination. type: int ebs_optimized: description: - - Enable EBS optimization for supported instances which are not enabled by default.; + - (Boolean) Enable EBS optimization for supported instances which are not enabled by default.; Note - additional charges will be applied. type: bool ebs_volume_pool: description: - - A list of hash/dictionaries of EBS devices to reattach to the elastigroup when available; + - (List of Objects) a list of hash/dictionaries of EBS devices to reattach to the elastigroup when available; '[{"key":"value", "key":"value"}]'; keys allowed are - volume_ids (List of Strings), device_name (String) type: list - elements: dict ecs: description: - - The ECS integration configuration.; + - (Object) The ECS integration configuration.; Expects the following key - cluster_name (String) type: dict elastic_ips: description: - - List of ElasticIps Allocation Ids (Example C(eipalloc-9d4e16f8)) to associate to the group instances + - (List of Strings) List of ElasticIps Allocation Ids (Example C(eipalloc-9d4e16f8)) to associate to the group instances type: list - elements: str fallback_to_od: description: - - In case of no spots available, Elastigroup will launch an On-demand instance instead + - (Boolean) In case of no spots available, Elastigroup will launch an On-demand instance instead type: bool health_check_grace_period: description: - - The amount of time, in seconds, after the instance has launched to start and check its health. + - (Integer) The amount of time, in seconds, after the instance has launched to start and check its health. - If not specified, it defaults to C(300). type: int health_check_unhealthy_duration_before_replacement: description: - - Minimal mount of time instance should be unhealthy for us to consider it unhealthy. + - (Integer) Minimal mount of time instance should be unhealthy for us to consider it unhealthy. type: int health_check_type: description: - - The service to use for the health check. + - (String) The service to use for the health check. - "The choices available are: C(ELB), C(HCS), C(TARGET_GROUP), C(MLB), C(EC2)." type: str iam_role_name: description: - - The instance profile iamRole name + - (String) The instance profile iamRole name - Only use iam_role_arn, or iam_role_name type: str iam_role_arn: description: - - The instance profile iamRole arn + - (String) The instance profile iamRole arn - Only use iam_role_arn, or iam_role_name type: str id: description: - - The group id if it already exists and you want to update, or delete it. + - (String) The group id if it already exists and you want to update, or delete it. This will not work unless the uniqueness_by field is set to id. When this is set, and the uniqueness_by field is set, the group will either be updated or deleted, but not created. type: str image_id: description: - - The image Id used to launch the instance.; + - (String) The image Id used to launch the instance.; In case of conflict between Instance type and image type, an error will be returned required: true type: str key_pair: description: - - Specify a Key Pair to attach to the instances + - (String) Specify a Key Pair to attach to the instances type: str kubernetes: description: - - The Kubernetes integration configuration. + - (Object) The Kubernetes integration configuration. Expects the following keys - api_server (String), token (String) @@ -178,48 +174,47 @@ options: lifetime_period: description: - - Lifetime period + - (Integer) lifetime period type: int load_balancers: description: - - List of classic ELB names + - (List of Strings) List of classic ELB names type: list - elements: str max_size: description: - - The upper limit number of instances that you can scale up to + - (Integer) The upper limit number of instances that you can scale up to required: true type: int mesosphere: description: - - The Mesosphere integration configuration. + - (Object) The Mesosphere integration configuration. Expects the following key - api_server (String) type: dict min_size: description: - - The lower limit number of instances that you can scale down to + - (Integer) The lower limit number of instances that you can scale down to required: true type: int monitoring: description: - - Describes whether instance Enhanced Monitoring is enabled + - (String) Describes whether instance Enhanced Monitoring is enabled type: str name: description: - - Unique name for elastigroup to be created, updated or deleted + - (String) Unique name for elastigroup to be created, updated or deleted required: true type: str network_interfaces: description: - - A list of hash/dictionaries of network interfaces to add to the elastigroup; + - (List of Objects) a list of hash/dictionaries of network interfaces to add to the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - description (String), @@ -234,30 +229,29 @@ options: associate_ipv6_address (Boolean), private_ip_addresses (List of Objects, Keys are privateIpAddress (String, required) and primary (Boolean)) type: list - elements: dict on_demand_count: description: - - Required if risk is not set + - (Integer) Required if risk is not set - Number of on demand instances to launch. All other instances will be spot instances.; Either set this parameter or the risk parameter type: int on_demand_instance_type: description: - - On-demand instance type that will be provisioned + - (String) On-demand instance type that will be provisioned type: str opsworks: description: - - The elastigroup OpsWorks integration configration.; + - (Object) The elastigroup OpsWorks integration configration.; Expects the following key - layer_id (String) type: dict persistence: description: - - The Stateful elastigroup configration.; + - (Object) The Stateful elastigroup configration.; Accepts the following keys - should_persist_root_device (Boolean), should_persist_block_devices (Boolean), @@ -266,14 +260,14 @@ options: product: description: - - Operation system type. + - (String) Operation system type. - "Available choices are: C(Linux/UNIX), C(SUSE Linux), C(Windows), C(Linux/UNIX (Amazon VPC)), C(SUSE Linux (Amazon VPC))." required: true type: str rancher: description: - - The Rancher integration configuration.; + - (Object) The Rancher integration configuration.; Expects the following keys - version (String), access_key (String), @@ -283,7 +277,7 @@ options: right_scale: description: - - The Rightscale integration configuration.; + - (Object) The Rightscale integration configuration.; Expects the following keys - account_id (String), refresh_token (String) @@ -291,12 +285,12 @@ options: risk: description: - - Required if on demand is not set. The percentage of Spot instances to launch (0 - 100). + - (Integer) required if on demand is not set. The percentage of Spot instances to launch (0 - 100). type: int roll_config: description: - - Roll configuration.; + - (Object) Roll configuration.; If you would like the group to roll after updating, please use this feature. Accepts the following keys - batch_size_percentage(Integer, Required), @@ -306,7 +300,7 @@ options: scheduled_tasks: description: - - A list of hash/dictionaries of scheduled tasks to configure in the elastigroup; + - (List of Objects) a list of hash/dictionaries of scheduled tasks to configure in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - adjustment (Integer), @@ -321,90 +315,84 @@ options: task_type (String, required), is_enabled (Boolean) type: list - elements: dict security_group_ids: description: - - One or more security group IDs. ; + - (List of Strings) One or more security group IDs. ; In case of update it will override the existing Security Group with the new given array required: true type: list - elements: str shutdown_script: description: - - The Base64-encoded shutdown script that executes prior to instance termination. + - (String) The Base64-encoded shutdown script that executes prior to instance termination. Encode before setting. type: str signals: description: - - A list of hash/dictionaries of signals to configure in the elastigroup; + - (List of Objects) a list of hash/dictionaries of signals to configure in the elastigroup; keys allowed are - name (String, required), timeout (Integer) type: list - elements: dict spin_up_time: description: - - Spin up time, in seconds, for the instance + - (Integer) spin up time, in seconds, for the instance type: int spot_instance_types: description: - - Spot instance type that will be provisioned. + - (List of Strings) Spot instance type that will be provisioned. required: true type: list - elements: str state: choices: - present - absent description: - - Create or delete the elastigroup + - (String) create or delete the elastigroup default: present type: str tags: description: - - A list of tags to configure in the elastigroup. Please specify list of keys and values (key colon value); + - (List of tagKey:tagValue pairs) a list of tags to configure in the elastigroup. Please specify list of keys and values (key colon value); type: list - elements: dict target: description: - - The number of instances to launch + - (Integer) The number of instances to launch required: true type: int target_group_arns: description: - - List of target group arns instances should be registered to + - (List of Strings) List of target group arns instances should be registered to type: list - elements: str tenancy: description: - - Dedicated vs shared tenancy. + - (String) dedicated vs shared tenancy. - "The available choices are: C(default), C(dedicated)." type: str terminate_at_end_of_billing_hour: description: - - Terminate at the end of billing hour + - (Boolean) terminate at the end of billing hour type: bool unit: description: - - The capacity unit to launch instances by. + - (String) The capacity unit to launch instances by. - "The available choices are: C(instance), C(weight)." type: str up_scaling_policies: description: - - A list of hash/dictionaries of scaling policies to configure in the elastigroup; + - (List of Objects) a list of hash/dictionaries of scaling policies to configure in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - policy_name (String, required), @@ -425,11 +413,10 @@ options: maximum (String), minimum (String) type: list - elements: dict down_scaling_policies: description: - - A list of hash/dictionaries of scaling policies to configure in the elastigroup; + - (List of Objects) a list of hash/dictionaries of scaling policies to configure in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - policy_name (String, required), @@ -450,11 +437,10 @@ options: maximum (String), minimum (String) type: list - elements: dict target_tracking_policies: description: - - A list of hash/dictionaries of target tracking policies to configure in the elastigroup; + - (List of Objects) a list of hash/dictionaries of target tracking policies to configure in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - policy_name (String, required), @@ -466,38 +452,37 @@ options: cooldown (String, required), target (String, required) type: list - elements: dict uniqueness_by: choices: - id - name description: - - If your group names are not unique, you may use this feature to update or delete a specific group. + - (String) If your group names are not unique, you may use this feature to update or delete a specific group. Whenever this property is set, you must set a group_id in order to update or delete a group, otherwise a group will be created. default: name type: str user_data: description: - - Base64-encoded MIME user data. Encode before setting the value. + - (String) Base64-encoded MIME user data. Encode before setting the value. type: str utilize_reserved_instances: description: - - In case of any available Reserved Instances, + - (Boolean) In case of any available Reserved Instances, Elastigroup will utilize your reservations before purchasing Spot instances. type: bool wait_for_instances: description: - - Whether or not the elastigroup creation / update actions should wait for the instances to spin + - (Boolean) Whether or not the elastigroup creation / update actions should wait for the instances to spin type: bool default: false wait_timeout: description: - - How long the module should wait for instances before failing the action.; + - (Integer) How long the module should wait for instances before failing the action.; Only works if wait_for_instances is True. type: int @@ -1443,18 +1428,18 @@ def main(): fields = dict( account_id=dict(type='str'), availability_vs_cost=dict(type='str', required=True), - availability_zones=dict(type='list', elements='dict', required=True), - block_device_mappings=dict(type='list', elements='dict'), + availability_zones=dict(type='list', required=True), + block_device_mappings=dict(type='list'), chef=dict(type='dict'), credentials_path=dict(type='path', default="~/.spotinst/credentials"), do_not_update=dict(default=[], type='list'), - down_scaling_policies=dict(type='list', elements='dict'), + down_scaling_policies=dict(type='list'), draining_timeout=dict(type='int'), ebs_optimized=dict(type='bool'), - ebs_volume_pool=dict(type='list', elements='dict'), + ebs_volume_pool=dict(type='list'), ecs=dict(type='dict'), elastic_beanstalk=dict(type='dict'), - elastic_ips=dict(type='list', elements='str'), + elastic_ips=dict(type='list'), fallback_to_od=dict(type='bool'), id=dict(type='str'), health_check_grace_period=dict(type='int'), @@ -1466,7 +1451,7 @@ def main(): key_pair=dict(type='str', no_log=False), kubernetes=dict(type='dict'), lifetime_period=dict(type='int'), - load_balancers=dict(type='list', elements='str'), + load_balancers=dict(type='list'), max_size=dict(type='int', required=True), mesosphere=dict(type='dict'), min_size=dict(type='int', required=True), @@ -1474,7 +1459,7 @@ def main(): multai_load_balancers=dict(type='list'), multai_token=dict(type='str', no_log=True), name=dict(type='str', required=True), - network_interfaces=dict(type='list', elements='dict'), + network_interfaces=dict(type='list'), on_demand_count=dict(type='int'), on_demand_instance_type=dict(type='str'), opsworks=dict(type='dict'), @@ -1484,16 +1469,16 @@ def main(): right_scale=dict(type='dict'), risk=dict(type='int'), roll_config=dict(type='dict'), - scheduled_tasks=dict(type='list', elements='dict'), - security_group_ids=dict(type='list', elements='str', required=True), + scheduled_tasks=dict(type='list'), + security_group_ids=dict(type='list', required=True), shutdown_script=dict(type='str'), - signals=dict(type='list', elements='dict'), + signals=dict(type='list'), spin_up_time=dict(type='int'), - spot_instance_types=dict(type='list', elements='str', required=True), + spot_instance_types=dict(type='list', required=True), state=dict(default='present', choices=['present', 'absent']), - tags=dict(type='list', elements='dict'), + tags=dict(type='list'), target=dict(type='int', required=True), - target_group_arns=dict(type='list', elements='str'), + target_group_arns=dict(type='list'), tenancy=dict(type='str'), terminate_at_end_of_billing_hour=dict(type='bool'), token=dict(type='str', no_log=True), @@ -1501,8 +1486,8 @@ def main(): user_data=dict(type='str'), utilize_reserved_instances=dict(type='bool'), uniqueness_by=dict(default='name', choices=['name', 'id']), - up_scaling_policies=dict(type='list', elements='dict'), - target_tracking_policies=dict(type='list', elements='dict'), + up_scaling_policies=dict(type='list'), + target_tracking_policies=dict(type='list'), wait_for_instances=dict(type='bool', default=False), wait_timeout=dict(type='int') ) From c934d9aeb59478d788e0b82bbf1785d0a2050d8b Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 07:56:05 +0200 Subject: [PATCH 018/139] Fix #2373 - TypeError: a bytes-like object is required, not 'str' (#2375) (#2419) * Fix #2373 * Changelog fragment for #2373 * Update changelogs/fragments/2373-svr4pkg-fix-typeerror.yml Co-authored-by: Amin Vakil * Update changelogs/fragments/2373-svr4pkg-fix-typeerror.yml Co-authored-by: Felix Fontein Co-authored-by: Amin Vakil Co-authored-by: Felix Fontein (cherry picked from commit cd957fae4cbee051c16e899c2d06a54e227c14fc) Co-authored-by: Daniel Werner --- changelogs/fragments/2373-svr4pkg-fix-typeerror.yml | 3 +++ plugins/modules/packaging/os/svr4pkg.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2373-svr4pkg-fix-typeerror.yml diff --git a/changelogs/fragments/2373-svr4pkg-fix-typeerror.yml b/changelogs/fragments/2373-svr4pkg-fix-typeerror.yml new file mode 100644 index 0000000000..d0b3580889 --- /dev/null +++ b/changelogs/fragments/2373-svr4pkg-fix-typeerror.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - svr4pkg - convert string to a bytes-like object to avoid ``TypeError`` with Python 3 (https://github.com/ansible-collections/community.general/issues/2373). diff --git a/plugins/modules/packaging/os/svr4pkg.py b/plugins/modules/packaging/os/svr4pkg.py index ea3cd7d468..aa7a5c2e52 100644 --- a/plugins/modules/packaging/os/svr4pkg.py +++ b/plugins/modules/packaging/os/svr4pkg.py @@ -121,7 +121,7 @@ def package_installed(module, name, category): def create_admin_file(): (desc, filename) = tempfile.mkstemp(prefix='ansible_svr4pkg', text=True) - fullauto = ''' + fullauto = b''' mail= instance=unique partial=nocheck From 05666b0e4d541c2a62dd357cf1ab5af5df8a8417 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 07:59:33 +0200 Subject: [PATCH 019/139] puppet - replace stdout with console in logdest option (#2407) (#2421) * Change stdout to console * readd stdout, resulting in console * add changelog * readd stdout to docs and add a warning when it is used * version of what??? Co-authored-by: Felix Fontein * postpone deprecation in another PR * remove console option, so it can be backported * change changelog respectively * Fix changelog formatting Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 26aba8e76687fb36688540194bec08a82c8b3070) Co-authored-by: Amin Vakil --- .../fragments/2407-puppet-change_stdout_to_console.yaml | 3 +++ plugins/modules/system/puppet.py | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/2407-puppet-change_stdout_to_console.yaml diff --git a/changelogs/fragments/2407-puppet-change_stdout_to_console.yaml b/changelogs/fragments/2407-puppet-change_stdout_to_console.yaml new file mode 100644 index 0000000000..697b8e78d7 --- /dev/null +++ b/changelogs/fragments/2407-puppet-change_stdout_to_console.yaml @@ -0,0 +1,3 @@ +--- +bugfixes: + - puppet - replace ``console` with ``stdout`` in ``logdest`` option when ``all`` has been chosen (https://github.com/ansible-collections/community.general/issues/1190). diff --git a/plugins/modules/system/puppet.py b/plugins/modules/system/puppet.py index 309da290d0..b83ef89aa5 100644 --- a/plugins/modules/system/puppet.py +++ b/plugins/modules/system/puppet.py @@ -54,7 +54,8 @@ options: logdest: description: - Where the puppet logs should go, if puppet apply is being used. - - C(all) will go to both C(stdout) and C(syslog). + - C(all) will go to both C(console) and C(syslog). + - C(stdout) will be deprecated and replaced by C(console). type: str choices: [ all, stdout, syslog ] default: stdout @@ -127,7 +128,7 @@ EXAMPLES = r''' community.general.puppet: noop: yes -- name: Run a manifest with debug, log to both syslog and stdout, specify module path +- name: Run a manifest with debug, log to both syslog and console, specify module path community.general.puppet: modulepath: /etc/puppet/modules:/opt/stack/puppet-modules:/usr/share/openstack-puppet/modules logdest: all @@ -269,7 +270,7 @@ def main(): if p['logdest'] == 'syslog': cmd += "--logdest syslog " if p['logdest'] == 'all': - cmd += " --logdest syslog --logdest stdout" + cmd += " --logdest syslog --logdest console" if p['modulepath']: cmd += "--modulepath='%s'" % p['modulepath'] if p['environment']: From 007333dbfe05961aeb0334112b3e88279b85dc99 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 08:12:31 +0200 Subject: [PATCH 020/139] =?UTF-8?q?=F0=9F=93=9D=20Document=20nested=20node?= =?UTF-8?q?=20addition=20with=20"=5F"=20in=20xml=20module=20(#2371)=20(#24?= =?UTF-8?q?27)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 📝 Document nested node addition with "_" in xml module Nested node addition using "_" to indicate sub nodes, and attributes are only documented in tests and issues, where is hard to find. * 🚨 Fix trailing space * Apply suggestions from code review Add missing collection prefix for modules. Co-authored-by: Felix Fontein * Add missing comments * Update xml.py * Fix linter warnings Co-authored-by: Felix Fontein (cherry picked from commit 4b0d2dcfe04591d67c5cdf82599ac33156c221ce) Co-authored-by: Daniel-Sanchez-Fabregas <33929811+Daniel-Sanchez-Fabregas@users.noreply.github.com> --- plugins/modules/files/xml.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/plugins/modules/files/xml.py b/plugins/modules/files/xml.py index df3562df8c..f93c8e4dc4 100644 --- a/plugins/modules/files/xml.py +++ b/plugins/modules/files/xml.py @@ -285,6 +285,22 @@ EXAMPLES = r''' z: http://z.test attribute: z:my_namespaced_attribute value: 'false' + +- name: Adding building nodes with floor subnodes from a YAML variable + community.general.xml: + path: /foo/bar.xml + xpath: /business + add_children: + - building: + # Attributes + name: Scumm bar + location: Monkey island + # Subnodes + _: + - floor: Pirate hall + - floor: Grog storage + - construction_date: "1990" # Only strings are valid + - building: Grog factory ''' RETURN = r''' From 5691e3aff3239752b40efe210981e48bcbe35fb0 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 08:16:19 +0200 Subject: [PATCH 021/139] nmcli: Add 'slave-type bridge' to nmcli command if type is bridge-slave (#2409) (#2423) (cherry picked from commit b5f8ae43204748c7f9e1719296ef81931c56c296) Co-authored-by: spike77453 --- ...ave-type_bridge_to_nmcli_command_if_type_is_bridge-slave.yml | 2 ++ plugins/modules/net_tools/nmcli.py | 1 + tests/unit/plugins/modules/net_tools/test_nmcli.py | 1 + 3 files changed, 4 insertions(+) create mode 100644 changelogs/fragments/2409-nmcli_add_slave-type_bridge_to_nmcli_command_if_type_is_bridge-slave.yml diff --git a/changelogs/fragments/2409-nmcli_add_slave-type_bridge_to_nmcli_command_if_type_is_bridge-slave.yml b/changelogs/fragments/2409-nmcli_add_slave-type_bridge_to_nmcli_command_if_type_is_bridge-slave.yml new file mode 100644 index 0000000000..8d0b4c1617 --- /dev/null +++ b/changelogs/fragments/2409-nmcli_add_slave-type_bridge_to_nmcli_command_if_type_is_bridge-slave.yml @@ -0,0 +1,2 @@ +bugfixes: + - nmcli - if type is ``bridge-slave`` add ``slave-type bridge`` to ``nmcli`` command (https://github.com/ansible-collections/community.general/issues/2408). diff --git a/plugins/modules/net_tools/nmcli.py b/plugins/modules/net_tools/nmcli.py index 4ae5a1dac9..02fbbd038b 100644 --- a/plugins/modules/net_tools/nmcli.py +++ b/plugins/modules/net_tools/nmcli.py @@ -780,6 +780,7 @@ class Nmcli(object): }) elif self.type == 'bridge-slave': options.update({ + 'connection.slave-type': 'bridge', 'bridge-port.path-cost': self.path_cost, 'bridge-port.hairpin-mode': self.hairpin, 'bridge-port.priority': self.slavepriority, diff --git a/tests/unit/plugins/modules/net_tools/test_nmcli.py b/tests/unit/plugins/modules/net_tools/test_nmcli.py index 8d830bcf19..a05c8ccbf8 100644 --- a/tests/unit/plugins/modules/net_tools/test_nmcli.py +++ b/tests/unit/plugins/modules/net_tools/test_nmcli.py @@ -223,6 +223,7 @@ TESTCASE_BRIDGE_SLAVE_SHOW_OUTPUT = """\ connection.id: non_existent_nw_device connection.interface-name: br0_non_existant connection.autoconnect: yes +connection.slave-type: bridge ipv4.never-default: no bridge-port.path-cost: 100 bridge-port.hairpin-mode: yes From 0da9d956a0cfcbcd61f644b3119399ee6192cd73 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 08:17:32 +0200 Subject: [PATCH 022/139] nmcli: Compare MAC addresses case insensitively (#2416) (#2425) * nmcli: Compare MAC addresses case insensitively * Update changelogs/fragments/2416-nmcli_compare_mac_addresses_case_insensitively.yml Co-authored-by: Felix Fontein * Update plugins/modules/net_tools/nmcli.py Co-authored-by: Felix Fontein * Add mac to TESTCASE_BRIDGE so test_bridge_connection_unchanged covers case sensitive mac address comparison * Update plugins/modules/net_tools/nmcli.py Co-authored-by: Felix Fontein * Convert current_value to uppercase as well in case nmcli changes behaviour Co-authored-by: Felix Fontein (cherry picked from commit 7359b1fbe57f75619d09d759ceba7cf124c5f0b5) Co-authored-by: spike77453 --- .../2416-nmcli_compare_mac_addresses_case_insensitively.yml | 2 ++ plugins/modules/net_tools/nmcli.py | 6 +++++- tests/unit/plugins/modules/net_tools/test_nmcli.py | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2416-nmcli_compare_mac_addresses_case_insensitively.yml diff --git a/changelogs/fragments/2416-nmcli_compare_mac_addresses_case_insensitively.yml b/changelogs/fragments/2416-nmcli_compare_mac_addresses_case_insensitively.yml new file mode 100644 index 0000000000..6694638964 --- /dev/null +++ b/changelogs/fragments/2416-nmcli_compare_mac_addresses_case_insensitively.yml @@ -0,0 +1,2 @@ +bugfixes: + - nmcli - compare MAC addresses case insensitively to fix idempotency issue (https://github.com/ansible-collections/community.general/issues/2409). diff --git a/plugins/modules/net_tools/nmcli.py b/plugins/modules/net_tools/nmcli.py index 02fbbd038b..e2ed4ad572 100644 --- a/plugins/modules/net_tools/nmcli.py +++ b/plugins/modules/net_tools/nmcli.py @@ -1042,7 +1042,6 @@ class Nmcli(object): 'con-name': 'connection.id', 'autoconnect': 'connection.autoconnect', 'ifname': 'connection.interface-name', - 'mac': self.mac_setting, 'master': 'connection.master', 'slave-type': 'connection.slave-type', 'zone': 'connection.zone', @@ -1066,6 +1065,11 @@ class Nmcli(object): current_value = [re.sub(r'^{\s*ip\s*=\s*([^, ]+),\s*nh\s*=\s*([^} ]+),\s*mt\s*=\s*([^} ]+)\s*}', r'\1 \2 \3', route) for route in current_value] current_value = [re.sub(r'^{\s*ip\s*=\s*([^, ]+),\s*nh\s*=\s*([^} ]+)\s*}', r'\1 \2', route) for route in current_value] + if key == self.mac_setting: + # MAC addresses are case insensitive, nmcli always reports them in uppercase + value = value.upper() + # ensure current_value is also converted to uppercase in case nmcli changes behaviour + current_value = current_value.upper() elif key in param_alias: real_key = param_alias[key] if real_key in conn_info: diff --git a/tests/unit/plugins/modules/net_tools/test_nmcli.py b/tests/unit/plugins/modules/net_tools/test_nmcli.py index a05c8ccbf8..dceb5e5f3f 100644 --- a/tests/unit/plugins/modules/net_tools/test_nmcli.py +++ b/tests/unit/plugins/modules/net_tools/test_nmcli.py @@ -184,6 +184,7 @@ TESTCASE_BRIDGE = [ 'ifname': 'br0_non_existant', 'ip4': '10.10.10.10/24', 'gw4': '10.10.10.1', + 'mac': '52:54:00:ab:cd:ef', 'maxage': 100, 'stp': True, 'state': 'present', @@ -200,6 +201,7 @@ ipv4.addresses: 10.10.10.10/24 ipv4.gateway: 10.10.10.1 ipv4.never-default: no ipv6.method: auto +bridge.mac-address: 52:54:00:AB:CD:EF bridge.stp: yes bridge.max-age: 100 bridge.ageing-time: 300 From 020b47a1a9a4f0a1a8193dcbf453487d58311007 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 13:51:10 +0200 Subject: [PATCH 023/139] Make plugins pass validation. (#2414) (#2431) (cherry picked from commit 6a72c3b3385a739d049d23a24d5a5f186962d606) Co-authored-by: Felix Fontein --- plugins/become/sudosu.py | 2 +- plugins/callback/loganalytics.py | 2 +- plugins/inventory/lxd.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/become/sudosu.py b/plugins/become/sudosu.py index e9668e6522..410b881b96 100644 --- a/plugins/become/sudosu.py +++ b/plugins/become/sudosu.py @@ -5,7 +5,7 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type DOCUMENTATION = """ - become: sudosu + name: sudosu short_description: Run tasks using sudo su - description: - This become plugins allows your remote/login user to execute commands as another user via the C(sudo) and C(su) utilities combined. diff --git a/plugins/callback/loganalytics.py b/plugins/callback/loganalytics.py index 507d6fccd9..ef1ea02f87 100644 --- a/plugins/callback/loganalytics.py +++ b/plugins/callback/loganalytics.py @@ -4,7 +4,7 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type DOCUMENTATION = ''' - callback: loganalytics + name: loganalytics type: aggregate short_description: Posts task results to Azure Log Analytics author: "Cyrus Li (@zhcli) " diff --git a/plugins/inventory/lxd.py b/plugins/inventory/lxd.py index c48818d595..d1e47b0505 100644 --- a/plugins/inventory/lxd.py +++ b/plugins/inventory/lxd.py @@ -6,7 +6,7 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type DOCUMENTATION = r''' - name: community.general.lxd + name: lxd short_description: Returns Ansible inventory from lxd host description: - Get inventory from the lxd. @@ -68,7 +68,7 @@ DOCUMENTATION = r''' description: - Create groups by the following keywords C(location), C(pattern), C(network_range), C(os), C(release), C(profile), C(vlanid). - See example for syntax. - type: json + type: dict ''' EXAMPLES = ''' From 4d23b7a48b58d1a7f2c0b5e68c44902fc7b3da09 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 13:51:38 +0200 Subject: [PATCH 024/139] linode_v4 - fixed error message (#2430) (#2433) * fixed error message * added changelog fragment (cherry picked from commit 5064aa8ec6d967e9c6867af9fdeb4496377a2e4d) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- changelogs/fragments/2430-linodev4-error-message.yml | 2 ++ plugins/modules/cloud/linode/linode_v4.py | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/2430-linodev4-error-message.yml diff --git a/changelogs/fragments/2430-linodev4-error-message.yml b/changelogs/fragments/2430-linodev4-error-message.yml new file mode 100644 index 0000000000..3dbfda1b9c --- /dev/null +++ b/changelogs/fragments/2430-linodev4-error-message.yml @@ -0,0 +1,2 @@ +bugfixes: + - linode_v4 - changed the error message to point to the correct bugtracker URL (https://github.com/ansible-collections/community.general/pull/2430). diff --git a/plugins/modules/cloud/linode/linode_v4.py b/plugins/modules/cloud/linode/linode_v4.py index 0f1133bac0..fcf3725bfc 100644 --- a/plugins/modules/cloud/linode/linode_v4.py +++ b/plugins/modules/cloud/linode/linode_v4.py @@ -208,9 +208,8 @@ def create_linode(module, client, **kwargs): else: return response._raw_json except TypeError: - module.fail_json(msg='Unable to parse Linode instance creation' - ' response. Please raise a bug against this' - ' module on https://github.com/ansible/ansible/issues' + module.fail_json(msg='Unable to parse Linode instance creation response. Please raise a bug against this' + ' module on https://github.com/ansible-collections/community.general/issues' ) From 797ea23e505db25a347e897448576621fee7cdc1 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 21:34:19 +0200 Subject: [PATCH 025/139] Clean up test entries from sysrc tests (#2330) (#2438) * Clean up test entries from sysrc tests * sysrc: enable tests * sysrc: cache the files to be changed and restore them * Update the ezjail archive host and remove obsolete file * sysrc: set ezjail to use archives for 12.0 or less * sysrc: Detect the version to use ftp vs ftp-archive using http * sysrc: Skip ezjail test on FreeBSD 12.0 (cherry picked from commit 7007c68ab786e6d51ecab5d97d2e3b891bd476c9) Co-authored-by: David Lundgren --- tests/integration/targets/sysrc/aliases | 1 - .../integration/targets/sysrc/tasks/main.yml | 21 ++++++++++++++++++- .../targets/sysrc/tasks/setup-testjail.yml | 9 +++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/tests/integration/targets/sysrc/aliases b/tests/integration/targets/sysrc/aliases index c7d183fb65..360849e61b 100644 --- a/tests/integration/targets/sysrc/aliases +++ b/tests/integration/targets/sysrc/aliases @@ -3,4 +3,3 @@ needs/root skip/docker skip/osx skip/rhel -disabled # FIXME diff --git a/tests/integration/targets/sysrc/tasks/main.yml b/tests/integration/targets/sysrc/tasks/main.yml index c8b7de4160..b8292f785b 100644 --- a/tests/integration/targets/sysrc/tasks/main.yml +++ b/tests/integration/targets/sysrc/tasks/main.yml @@ -6,7 +6,11 @@ block: - name: Cache original contents of /etc/rc.conf shell: "cat /etc/rc.conf" - register: sysrc_original_content + register: cached_etc_rcconf_content + + - name: Cache original contents of /boot/loader.conf + shell: "cat /boot/loader.conf" + register: cached_boot_loaderconf_content ## ## sysrc - example - set mysqlpidfile @@ -130,6 +134,11 @@ ## sysrc - example - Enable nginx in testjail ## - name: Test within jail + # + # 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 + # + when: ansible_distribution_version is version('12.01', '>=') block: - name: Setup testjail include: setup-testjail.yml @@ -316,3 +325,13 @@ - not sysrc_value_absent_idempotent.changed - "'sysrc_delim=\"t1,t2\"' in sysrc_delim_content.stdout_lines" - "'sysrc_delim_delete' not in sysrc_delim_content.stdout_lines" + always: + - name: Restore /etc/rc.conf + copy: + content: "{{ cached_etc_rcconf_content }}" + dest: /etc/rc.conf + + - name: Restore /boot/loader.conf + copy: + content: "{{ cached_boot_loaderconf_content }}" + dest: /boot/loader.conf \ No newline at end of file diff --git a/tests/integration/targets/sysrc/tasks/setup-testjail.yml b/tests/integration/targets/sysrc/tasks/setup-testjail.yml index 9bd15320ae..e75957d19f 100644 --- a/tests/integration/targets/sysrc/tasks/setup-testjail.yml +++ b/tests/integration/targets/sysrc/tasks/setup-testjail.yml @@ -17,12 +17,19 @@ pkgng: name: ezjail +- name: Configure ezjail to use http + when: ansible_distribution_version is version('11.01', '>') + lineinfile: + dest: /usr/local/etc/ezjail.conf + regexp: ^ezjail_ftphost + line: ezjail_ftphost=http://ftp.freebsd.org + - name: Configure ezjail to use archive for old freebsd releases when: ansible_distribution_version is version('11.01', '<=') lineinfile: dest: /usr/local/etc/ezjail.conf regexp: ^ezjail_ftphost - line: ezjail_ftphost=ftp-archive.freebsd.org + line: ezjail_ftphost=http://ftp-archive.freebsd.org - name: Start ezjail ignore_errors: yes From e6cc671a0dbcdd88590823c05d5210123d0d6317 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 22:07:52 +0200 Subject: [PATCH 026/139] lvol - bug fix - Convert units to lowercase when using LVS or VGS command (#2369) (#2439) * Added lower call for units when checking lvs/vgs size * Changelog * Size roudning correction * Rounding * Changelog * Remove whitespace (cherry picked from commit 06bdabcad93846f37f70fd868fdce421ef366f8c) Co-authored-by: zigaSRC <65527456+zigaSRC@users.noreply.github.com> --- changelogs/fragments/2369-lvol_size_bug_fixes.yml | 3 +++ plugins/modules/system/lvol.py | 13 +++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 changelogs/fragments/2369-lvol_size_bug_fixes.yml diff --git a/changelogs/fragments/2369-lvol_size_bug_fixes.yml b/changelogs/fragments/2369-lvol_size_bug_fixes.yml new file mode 100644 index 0000000000..fcd2f17b11 --- /dev/null +++ b/changelogs/fragments/2369-lvol_size_bug_fixes.yml @@ -0,0 +1,3 @@ +bugfixes: + - lvol - fixed size unit capitalization to match units used between different tools for comparison (https://github.com/ansible-collections/community.general/issues/2360). + - lvol - fixed rounding errors (https://github.com/ansible-collections/community.general/issues/2370). \ No newline at end of file diff --git a/plugins/modules/system/lvol.py b/plugins/modules/system/lvol.py index 8dc3fac7f5..fafa7db38a 100644 --- a/plugins/modules/system/lvol.py +++ b/plugins/modules/system/lvol.py @@ -389,7 +389,7 @@ def main(): # Get information on volume group requested vgs_cmd = module.get_bin_path("vgs", required=True) rc, current_vgs, err = module.run_command( - "%s --noheadings --nosuffix -o vg_name,size,free,vg_extent_size --units %s --separator ';' %s" % (vgs_cmd, unit, vg)) + "%s --noheadings --nosuffix -o vg_name,size,free,vg_extent_size --units %s --separator ';' %s" % (vgs_cmd, unit.lower(), vg)) if rc != 0: if state == 'absent': @@ -403,7 +403,7 @@ def main(): # Get information on logical volume requested lvs_cmd = module.get_bin_path("lvs", required=True) rc, current_lvs, err = module.run_command( - "%s -a --noheadings --nosuffix -o lv_name,size,lv_attr --units %s --separator ';' %s" % (lvs_cmd, unit, vg)) + "%s -a --noheadings --nosuffix -o lv_name,size,lv_attr --units %s --separator ';' %s" % (lvs_cmd, unit.lower(), vg)) if rc != 0: if state == 'absent': @@ -505,16 +505,13 @@ def main(): else: # size_whole == 'FREE': size_requested = size_percent * this_vg['free'] / 100 - # from LVEXTEND(8) - The resulting value is rounded upward. - # from LVREDUCE(8) - The resulting value for the substraction is rounded downward, for the absolute size it is rounded upward. if size_operator == '+': size_requested += this_lv['size'] - size_requested += this_vg['ext_size'] - (size_requested % this_vg['ext_size']) elif size_operator == '-': size_requested = this_lv['size'] - size_requested - size_requested -= (size_requested % this_vg['ext_size']) - else: - size_requested += this_vg['ext_size'] - (size_requested % this_vg['ext_size']) + + # According to latest documentation (LVM2-2.03.11) all tools round down + size_requested -= (size_requested % this_vg['ext_size']) if this_lv['size'] < size_requested: if (size_free > 0) and (size_free >= (size_requested - this_lv['size'])): From 49b991527e591e866a064dda94f53d12ae2fea09 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 3 May 2021 22:56:40 +0200 Subject: [PATCH 027/139] Remove shippable config. (#2440) (#2444) (cherry picked from commit 1f41e66f098647af4c393a27ee5648e3371b2ed2) Co-authored-by: Felix Fontein --- shippable.yml | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) delete mode 100644 shippable.yml diff --git a/shippable.yml b/shippable.yml deleted file mode 100644 index 7cbbdc24e7..0000000000 --- a/shippable.yml +++ /dev/null @@ -1,48 +0,0 @@ -language: python - -env: - matrix: - - T=none - -matrix: - exclude: - - env: T=none - include: - - env: T=devel/sanity/1 - - env: T=devel/sanity/2 - - env: T=devel/sanity/3 - - env: T=devel/sanity/4 - - - env: T=2.11/sanity/1 - - env: T=2.11/sanity/2 - - env: T=2.11/sanity/3 - - env: T=2.11/sanity/4 - - - env: T=2.10/sanity/1 - - env: T=2.10/sanity/2 - - env: T=2.10/sanity/3 - - env: T=2.10/sanity/4 - - - env: T=2.9/sanity/1 - - env: T=2.9/sanity/2 - - env: T=2.9/sanity/3 - - env: T=2.9/sanity/4 - -branches: - except: - - "*-patch-*" - - "revert-*-*" - - "patchback/backports/*" - -build: - ci: - - tests/utils/shippable/timing.sh tests/utils/shippable/shippable.sh $T - -integrations: - notifications: - - integrationName: email - type: email - on_success: never - on_failure: never - on_start: never - on_pull_request: never From e670ca666ae8c0bcde92fdd647c9bff50d0e2eae Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 4 May 2021 12:43:25 +0200 Subject: [PATCH 028/139] OpenNebula one_vm.py: Fix missing keys (#2435) (#2447) * OpenNebula one_vm.py: Fix missing keys * fixup OpenNebula one_vm.py: Fix missing keys (cherry picked from commit aaa561163b705dbf7e1f06b58382e3a072550e31) Co-authored-by: Jan Orel --- .../fragments/2435-one_vm-fix_missing_keys.yml | 2 ++ plugins/modules/cloud/opennebula/one_vm.py | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 changelogs/fragments/2435-one_vm-fix_missing_keys.yml diff --git a/changelogs/fragments/2435-one_vm-fix_missing_keys.yml b/changelogs/fragments/2435-one_vm-fix_missing_keys.yml new file mode 100644 index 0000000000..395c024b26 --- /dev/null +++ b/changelogs/fragments/2435-one_vm-fix_missing_keys.yml @@ -0,0 +1,2 @@ +bugfixes: + - one_vm - Allow missing NIC keys (https://github.com/ansible-collections/community.general/pull/2435). diff --git a/plugins/modules/cloud/opennebula/one_vm.py b/plugins/modules/cloud/opennebula/one_vm.py index 425a1c464a..fa3d4abaab 100644 --- a/plugins/modules/cloud/opennebula/one_vm.py +++ b/plugins/modules/cloud/opennebula/one_vm.py @@ -752,11 +752,20 @@ def get_vm_info(client, vm): if 'NIC' in vm.TEMPLATE: if isinstance(vm.TEMPLATE['NIC'], list): for nic in vm.TEMPLATE['NIC']: - networks_info.append({'ip': nic['IP'], 'mac': nic['MAC'], 'name': nic['NETWORK'], 'security_groups': nic['SECURITY_GROUPS']}) + networks_info.append({ + 'ip': nic.get('IP', ''), + 'mac': nic.get('MAC', ''), + 'name': nic.get('NETWORK', ''), + 'security_groups': nic.get('SECURITY_GROUPS', '') + }) else: - networks_info.append( - {'ip': vm.TEMPLATE['NIC']['IP'], 'mac': vm.TEMPLATE['NIC']['MAC'], - 'name': vm.TEMPLATE['NIC']['NETWORK'], 'security_groups': vm.TEMPLATE['NIC']['SECURITY_GROUPS']}) + networks_info.append({ + 'ip': vm.TEMPLATE['NIC'].get('IP', ''), + 'mac': vm.TEMPLATE['NIC'].get('MAC', ''), + 'name': vm.TEMPLATE['NIC'].get('NETWORK', ''), + 'security_groups': + vm.TEMPLATE['NIC'].get('SECURITY_GROUPS', '') + }) import time current_time = time.localtime() From b0b783f8ff14c4975f5d039a96ddfbb60650c8e1 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 4 May 2021 12:45:19 +0200 Subject: [PATCH 029/139] Release 3.0.1. --- CHANGELOG.rst | 23 ++++++++++++ changelogs/changelog.yaml | 37 +++++++++++++++++++ ..._retention_policy-fix_duration_parsing.yml | 3 -- ...2337-mark-inventory-scripts-executable.yml | 3 -- ...action-option-discovery-to-avoid-hang.yaml | 2 - .../fragments/2369-lvol_size_bug_fixes.yml | 3 -- .../fragments/2373-svr4pkg-fix-typeerror.yml | 3 -- .../2407-puppet-change_stdout_to_console.yaml | 3 -- ..._nmcli_command_if_type_is_bridge-slave.yml | 2 - ...mpare_mac_addresses_case_insensitively.yml | 2 - .../fragments/2430-linodev4-error-message.yml | 2 - .../2435-one_vm-fix_missing_keys.yml | 2 - changelogs/fragments/3.0.1.yml | 1 - 13 files changed, 60 insertions(+), 26 deletions(-) delete mode 100644 changelogs/fragments/2284-influxdb_retention_policy-fix_duration_parsing.yml delete mode 100644 changelogs/fragments/2337-mark-inventory-scripts-executable.yml delete mode 100644 changelogs/fragments/2348-composer-no-interaction-option-discovery-to-avoid-hang.yaml delete mode 100644 changelogs/fragments/2369-lvol_size_bug_fixes.yml delete mode 100644 changelogs/fragments/2373-svr4pkg-fix-typeerror.yml delete mode 100644 changelogs/fragments/2407-puppet-change_stdout_to_console.yaml delete mode 100644 changelogs/fragments/2409-nmcli_add_slave-type_bridge_to_nmcli_command_if_type_is_bridge-slave.yml delete mode 100644 changelogs/fragments/2416-nmcli_compare_mac_addresses_case_insensitively.yml delete mode 100644 changelogs/fragments/2430-linodev4-error-message.yml delete mode 100644 changelogs/fragments/2435-one_vm-fix_missing_keys.yml delete mode 100644 changelogs/fragments/3.0.1.yml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9c6cf15746..42e68508ad 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,29 @@ Community General Release Notes This changelog describes changes after version 2.0.0. +v3.0.1 +====== + +Release Summary +--------------- + +Bugfix release for the next Ansible 4.0.0 beta. + +Bugfixes +-------- + +- composer - use ``no-interaction`` option when discovering available options to avoid an issue where composer hangs (https://github.com/ansible-collections/community.general/pull/2348). +- influxdb_retention_policy - fix bug where ``INF`` duration values failed parsing (https://github.com/ansible-collections/community.general/pull/2385). +- inventory and vault scripts - change file permissions to make vendored inventory and vault scripts exectuable (https://github.com/ansible-collections/community.general/pull/2337). +- linode_v4 - changed the error message to point to the correct bugtracker URL (https://github.com/ansible-collections/community.general/pull/2430). +- lvol - fixed rounding errors (https://github.com/ansible-collections/community.general/issues/2370). +- lvol - fixed size unit capitalization to match units used between different tools for comparison (https://github.com/ansible-collections/community.general/issues/2360). +- nmcli - compare MAC addresses case insensitively to fix idempotency issue (https://github.com/ansible-collections/community.general/issues/2409). +- nmcli - if type is ``bridge-slave`` add ``slave-type bridge`` to ``nmcli`` command (https://github.com/ansible-collections/community.general/issues/2408). +- one_vm - Allow missing NIC keys (https://github.com/ansible-collections/community.general/pull/2435). +- puppet - replace ``console` with ``stdout`` in ``logdest`` option when ``all`` has been chosen (https://github.com/ansible-collections/community.general/issues/1190). +- svr4pkg - convert string to a bytes-like object to avoid ``TypeError`` with Python 3 (https://github.com/ansible-collections/community.general/issues/2373). + v3.0.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 344ddea77c..a7354e47b2 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -973,3 +973,40 @@ releases: name: lxd namespace: null release_date: '2021-04-26' + 3.0.1: + changes: + bugfixes: + - composer - use ``no-interaction`` option when discovering available options + to avoid an issue where composer hangs (https://github.com/ansible-collections/community.general/pull/2348). + - influxdb_retention_policy - fix bug where ``INF`` duration values failed parsing + (https://github.com/ansible-collections/community.general/pull/2385). + - inventory and vault scripts - change file permissions to make vendored inventory + and vault scripts exectuable (https://github.com/ansible-collections/community.general/pull/2337). + - linode_v4 - changed the error message to point to the correct bugtracker URL + (https://github.com/ansible-collections/community.general/pull/2430). + - lvol - fixed rounding errors (https://github.com/ansible-collections/community.general/issues/2370). + - lvol - fixed size unit capitalization to match units used between different + tools for comparison (https://github.com/ansible-collections/community.general/issues/2360). + - nmcli - compare MAC addresses case insensitively to fix idempotency issue + (https://github.com/ansible-collections/community.general/issues/2409). + - nmcli - if type is ``bridge-slave`` add ``slave-type bridge`` to ``nmcli`` + command (https://github.com/ansible-collections/community.general/issues/2408). + - one_vm - Allow missing NIC keys (https://github.com/ansible-collections/community.general/pull/2435). + - puppet - replace ``console` with ``stdout`` in ``logdest`` option when ``all`` + has been chosen (https://github.com/ansible-collections/community.general/issues/1190). + - svr4pkg - convert string to a bytes-like object to avoid ``TypeError`` with + Python 3 (https://github.com/ansible-collections/community.general/issues/2373). + release_summary: Bugfix release for the next Ansible 4.0.0 beta. + fragments: + - 2284-influxdb_retention_policy-fix_duration_parsing.yml + - 2337-mark-inventory-scripts-executable.yml + - 2348-composer-no-interaction-option-discovery-to-avoid-hang.yaml + - 2369-lvol_size_bug_fixes.yml + - 2373-svr4pkg-fix-typeerror.yml + - 2407-puppet-change_stdout_to_console.yaml + - 2409-nmcli_add_slave-type_bridge_to_nmcli_command_if_type_is_bridge-slave.yml + - 2416-nmcli_compare_mac_addresses_case_insensitively.yml + - 2430-linodev4-error-message.yml + - 2435-one_vm-fix_missing_keys.yml + - 3.0.1.yml + release_date: '2021-05-04' diff --git a/changelogs/fragments/2284-influxdb_retention_policy-fix_duration_parsing.yml b/changelogs/fragments/2284-influxdb_retention_policy-fix_duration_parsing.yml deleted file mode 100644 index 04c82480c1..0000000000 --- a/changelogs/fragments/2284-influxdb_retention_policy-fix_duration_parsing.yml +++ /dev/null @@ -1,3 +0,0 @@ -bugfixes: - - influxdb_retention_policy - fix bug where ``INF`` duration values failed parsing - (https://github.com/ansible-collections/community.general/pull/2385). diff --git a/changelogs/fragments/2337-mark-inventory-scripts-executable.yml b/changelogs/fragments/2337-mark-inventory-scripts-executable.yml deleted file mode 100644 index 69aa3fff62..0000000000 --- a/changelogs/fragments/2337-mark-inventory-scripts-executable.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - inventory and vault scripts - change file permissions to make vendored inventory and vault scripts exectuable (https://github.com/ansible-collections/community.general/pull/2337). diff --git a/changelogs/fragments/2348-composer-no-interaction-option-discovery-to-avoid-hang.yaml b/changelogs/fragments/2348-composer-no-interaction-option-discovery-to-avoid-hang.yaml deleted file mode 100644 index 0728aeb28b..0000000000 --- a/changelogs/fragments/2348-composer-no-interaction-option-discovery-to-avoid-hang.yaml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - composer - use ``no-interaction`` option when discovering available options to avoid an issue where composer hangs (https://github.com/ansible-collections/community.general/pull/2348). diff --git a/changelogs/fragments/2369-lvol_size_bug_fixes.yml b/changelogs/fragments/2369-lvol_size_bug_fixes.yml deleted file mode 100644 index fcd2f17b11..0000000000 --- a/changelogs/fragments/2369-lvol_size_bug_fixes.yml +++ /dev/null @@ -1,3 +0,0 @@ -bugfixes: - - lvol - fixed size unit capitalization to match units used between different tools for comparison (https://github.com/ansible-collections/community.general/issues/2360). - - lvol - fixed rounding errors (https://github.com/ansible-collections/community.general/issues/2370). \ No newline at end of file diff --git a/changelogs/fragments/2373-svr4pkg-fix-typeerror.yml b/changelogs/fragments/2373-svr4pkg-fix-typeerror.yml deleted file mode 100644 index d0b3580889..0000000000 --- a/changelogs/fragments/2373-svr4pkg-fix-typeerror.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - svr4pkg - convert string to a bytes-like object to avoid ``TypeError`` with Python 3 (https://github.com/ansible-collections/community.general/issues/2373). diff --git a/changelogs/fragments/2407-puppet-change_stdout_to_console.yaml b/changelogs/fragments/2407-puppet-change_stdout_to_console.yaml deleted file mode 100644 index 697b8e78d7..0000000000 --- a/changelogs/fragments/2407-puppet-change_stdout_to_console.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - puppet - replace ``console` with ``stdout`` in ``logdest`` option when ``all`` has been chosen (https://github.com/ansible-collections/community.general/issues/1190). diff --git a/changelogs/fragments/2409-nmcli_add_slave-type_bridge_to_nmcli_command_if_type_is_bridge-slave.yml b/changelogs/fragments/2409-nmcli_add_slave-type_bridge_to_nmcli_command_if_type_is_bridge-slave.yml deleted file mode 100644 index 8d0b4c1617..0000000000 --- a/changelogs/fragments/2409-nmcli_add_slave-type_bridge_to_nmcli_command_if_type_is_bridge-slave.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - nmcli - if type is ``bridge-slave`` add ``slave-type bridge`` to ``nmcli`` command (https://github.com/ansible-collections/community.general/issues/2408). diff --git a/changelogs/fragments/2416-nmcli_compare_mac_addresses_case_insensitively.yml b/changelogs/fragments/2416-nmcli_compare_mac_addresses_case_insensitively.yml deleted file mode 100644 index 6694638964..0000000000 --- a/changelogs/fragments/2416-nmcli_compare_mac_addresses_case_insensitively.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - nmcli - compare MAC addresses case insensitively to fix idempotency issue (https://github.com/ansible-collections/community.general/issues/2409). diff --git a/changelogs/fragments/2430-linodev4-error-message.yml b/changelogs/fragments/2430-linodev4-error-message.yml deleted file mode 100644 index 3dbfda1b9c..0000000000 --- a/changelogs/fragments/2430-linodev4-error-message.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - linode_v4 - changed the error message to point to the correct bugtracker URL (https://github.com/ansible-collections/community.general/pull/2430). diff --git a/changelogs/fragments/2435-one_vm-fix_missing_keys.yml b/changelogs/fragments/2435-one_vm-fix_missing_keys.yml deleted file mode 100644 index 395c024b26..0000000000 --- a/changelogs/fragments/2435-one_vm-fix_missing_keys.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - one_vm - Allow missing NIC keys (https://github.com/ansible-collections/community.general/pull/2435). diff --git a/changelogs/fragments/3.0.1.yml b/changelogs/fragments/3.0.1.yml deleted file mode 100644 index f2697847bc..0000000000 --- a/changelogs/fragments/3.0.1.yml +++ /dev/null @@ -1 +0,0 @@ -release_summary: Bugfix release for the next Ansible 4.0.0 beta. From a1a4ba43378817574648c2fc9e77288706f9cf7e Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 4 May 2021 13:21:05 +0200 Subject: [PATCH 030/139] Next expected release is 3.0.2 next week. --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index 30cb36cde2..edad7d7aee 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: community name: general -version: 3.0.1 +version: 3.0.2 readme: README.md authors: - Ansible (https://github.com/ansible) From f5f862617a40e35e89294c628086a7b60609c760 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 5 May 2021 07:52:09 +0200 Subject: [PATCH 031/139] Add more plugin authors to BOTMETA. (#2451) (#2453) (cherry picked from commit 188a4eeb0c9c7b89de952d8bb76d962ee17dc490) Co-authored-by: Felix Fontein --- .github/BOTMETA.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index fd23d0c9e4..f27c96e049 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -88,6 +88,8 @@ files: maintainers: $team_linode labels: cloud linode keywords: linode dynamic inventory script + $inventories/lxd.py: + maintainers: conloos $inventories/proxmox.py: maintainers: $team_virt ilijamt $inventories/scaleway.py: @@ -373,6 +375,8 @@ files: maintainers: $team_keycloak $modules/identity/keycloak/keycloak_group.py: maintainers: adamgoossens + $modules/identity/keycloak/keycloak_realm.py: + maintainers: kris2kris $modules/identity/onepassword_info.py: maintainers: Rylon $modules/identity/opendj/opendj_backendprop.py: From af0ce4284fc221ff5972030a201b3e398277ed66 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 8 May 2021 12:18:28 +0200 Subject: [PATCH 032/139] Small Documentation Example Of Cask Leveraging (#2462) (#2470) * Small Documentation Example Of Cask Leveraging - Just a lil' demo showing that we can utilize homebrew/cask/foo syntax for given name of package to grab associated cask pacakge Resolves: patch/sml-doc-example-update * Slight Documentation Example Edit - adjusting documentation example to provide better info surrounding installing a given formula from brew via cask Resolves: patch/sml-doc-example-update * Small Edits To Make PEP8 Happy - format code with autopep8 in vs code Resolves: patch/sml-doc-example-update * Only Making Small PEP8 Change - reverting previous mass PEP8 format, focus on trimming whitespace on doc example entry Resolves: patch/sml-doc-example-update * Remove Trailing Whitespace PEP8 - removed trailing whitespace on doc example chunk Resolves: patch/sml-doc-example-update (cherry picked from commit 73863262584ba58043e5357d8c45b468dd7de5e2) Co-authored-by: Mike Russell --- plugins/modules/packaging/os/homebrew.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/modules/packaging/os/homebrew.py b/plugins/modules/packaging/os/homebrew.py index 9a41370c3d..47ec930a2c 100644 --- a/plugins/modules/packaging/os/homebrew.py +++ b/plugins/modules/packaging/os/homebrew.py @@ -127,6 +127,11 @@ EXAMPLES = ''' state: present install_options: with-baz,enable-debug +- name: Install formula foo with 'brew' from cask + community.general.homebrew: + name: homebrew/cask/foo + state: present + - name: Use ignored-pinned option while upgrading all community.general.homebrew: upgrade_all: yes From b49607f12d5d83a1965517734af68e95900e564a Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 9 May 2021 22:46:17 +0200 Subject: [PATCH 033/139] fix stackpath_compute validate_config (#2448) (#2475) * fix stackpath_compute validate_config get the lenght for the client_id / client_secret to validate inventory configuration * Add changelog fragment. Co-authored-by: Felix Fontein (cherry picked from commit 4cdff8654a8ef793736b95d84b872acf3779bdea) Co-authored-by: vbarba --- changelogs/fragments/2448-stackpath_compute-fix.yml | 2 ++ plugins/inventory/stackpath_compute.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/2448-stackpath_compute-fix.yml diff --git a/changelogs/fragments/2448-stackpath_compute-fix.yml b/changelogs/fragments/2448-stackpath_compute-fix.yml new file mode 100644 index 0000000000..196db780b1 --- /dev/null +++ b/changelogs/fragments/2448-stackpath_compute-fix.yml @@ -0,0 +1,2 @@ +bugfixes: +- "stackpath_compute inventory script - fix broken validation checks for client ID and client secret (https://github.com/ansible-collections/community.general/pull/2448)." diff --git a/plugins/inventory/stackpath_compute.py b/plugins/inventory/stackpath_compute.py index 393edac384..fb879e869e 100644 --- a/plugins/inventory/stackpath_compute.py +++ b/plugins/inventory/stackpath_compute.py @@ -102,13 +102,13 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): raise AnsibleError("plugin doesn't match this plugin") try: client_id = config['client_id'] - if client_id != 32: + if len(client_id) != 32: raise AnsibleError("client_id must be 32 characters long") except KeyError: raise AnsibleError("config missing client_id, a required option") try: client_secret = config['client_secret'] - if client_secret != 64: + if len(client_secret) != 64: raise AnsibleError("client_secret must be 64 characters long") except KeyError: raise AnsibleError("config missing client_id, a required option") From d4656ffca29e3ec04aa2923d3b9e82d99b93010d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 10 May 2021 17:14:34 +0200 Subject: [PATCH 034/139] Clarify Windows (non-)support. (#2476) (#2482) (cherry picked from commit 2e58dfe52afd715a967c01b4994c1a3574e835dd) Co-authored-by: Felix Fontein --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index aba74a6853..f0881f9aee 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ This repo contains the `community.general` Ansible Collection. The collection in You can find [documentation for this collection on the Ansible docs site](https://docs.ansible.com/ansible/latest/collections/community/general/). +Please note that this collection does **not** support Windows targets. Only connection plugins included in this collection might support Windows targets, and will explicitly mention that in their documentation if they do so. + ## Tested with Ansible Tested with the current Ansible 2.9, ansible-base 2.10 and ansible-core 2.11 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported. From 19c8d2164dd5d70e152a51985d9d027b5bf7d531 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 10 May 2021 18:00:08 +0200 Subject: [PATCH 035/139] Prepare 3.0.2 release. --- changelogs/fragments/3.0.2.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/fragments/3.0.2.yml diff --git a/changelogs/fragments/3.0.2.yml b/changelogs/fragments/3.0.2.yml new file mode 100644 index 0000000000..fbd0669c36 --- /dev/null +++ b/changelogs/fragments/3.0.2.yml @@ -0,0 +1 @@ +release_summary: Bugfix release for the first Ansible 4.0.0 release candidate. From a722e038ccb685baa003ab0f0eb79912ea57dbe5 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 10 May 2021 18:17:03 +0200 Subject: [PATCH 036/139] Avoid incorrectly marking zfs tasks as changed (#2454) (#2484) * Avoid incorrectly marking zfs tasks as changed The zfs module will incorrectly mark certain tasks as having been changed. For example, if a dataset has a quota of "1G" and the user changes it to "1024M", the actual quota vale has not changed, but since the module is doing a simple string comparison between "1G" and "1024M", it marks the step as "changed". Instead of trying to handle all the corner cases of zfs (another example is when the zpool "altroot" property has been set), this change simply compares the output of "zfs-get" from before and after "zfs-set" is called * update changelog format * Update changelogs/fragments/2454-detect_zfs_changed.yml Co-authored-by: Felix Fontein * add note about check_mode * Update plugins/modules/storage/zfs/zfs.py Co-authored-by: Felix Fontein * Update plugins/modules/storage/zfs/zfs.py Co-authored-by: Felix Fontein * clarify check mode qualifications * rephrase to avoid hypothetical Co-authored-by: Felix Fontein (cherry picked from commit 8e7aff00b5f3af2ed7dbc377255832da68817144) Co-authored-by: sam-lunt --- .../fragments/2454-detect_zfs_changed.yml | 2 ++ plugins/modules/storage/zfs/zfs.py | 24 +++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/2454-detect_zfs_changed.yml diff --git a/changelogs/fragments/2454-detect_zfs_changed.yml b/changelogs/fragments/2454-detect_zfs_changed.yml new file mode 100644 index 0000000000..0604278f6b --- /dev/null +++ b/changelogs/fragments/2454-detect_zfs_changed.yml @@ -0,0 +1,2 @@ +bugfixes: + - zfs - certain ZFS properties, especially sizes, would lead to a task being falsely marked as "changed" even when no actual change was made (https://github.com/ansible-collections/community.general/issues/975, https://github.com/ansible-collections/community.general/pull/2454). diff --git a/plugins/modules/storage/zfs/zfs.py b/plugins/modules/storage/zfs/zfs.py index fe693a5045..2d5d4487dd 100644 --- a/plugins/modules/storage/zfs/zfs.py +++ b/plugins/modules/storage/zfs/zfs.py @@ -37,6 +37,12 @@ options: - A dictionary of zfs properties to be set. - See the zfs(8) man page for more information. type: dict +notes: + - C(check_mode) is supported, but in certain situations it may report a task + as changed that will not be reported as changed when C(check_mode) is disabled. + For example, this might occur when the zpool C(altroot) option is set or when + a size is written using human-readable notation, such as C(1M) or C(1024K), + instead of as an unqualified byte count, such as C(1048576). author: - Johan Wiren (@johanwiren) ''' @@ -184,9 +190,7 @@ class Zfs(object): return cmd = [self.zfs_cmd, 'set', prop + '=' + str(value), self.name] (rc, out, err) = self.module.run_command(cmd) - if rc == 0: - self.changed = True - else: + if rc != 0: self.module.fail_json(msg=err) def set_properties_if_changed(self): @@ -194,15 +198,25 @@ class Zfs(object): for prop, value in self.properties.items(): if current_properties.get(prop, None) != value: self.set_property(prop, value) + if self.module.check_mode: + return + updated_properties = self.get_current_properties() + for prop in self.properties: + value = updated_properties.get(prop, None) + if value is None: + self.module.fail_json(msg="zfsprop was not present after being successfully set: %s" % prop) + if current_properties.get(prop, None) != value: + self.changed = True def get_current_properties(self): - cmd = [self.zfs_cmd, 'get', '-H'] + cmd = [self.zfs_cmd, 'get', '-H', '-p', '-o', "property,value,source"] if self.enhanced_sharing: cmd += ['-e'] cmd += ['all', self.name] rc, out, err = self.module.run_command(" ".join(cmd)) properties = dict() - for prop, value, source in [l.split('\t')[1:4] for l in out.splitlines()]: + for line in out.splitlines(): + prop, value, source = line.split('\t') # include source '-' so that creation-only properties are not removed # to avoids errors when the dataset already exists and the property is not changed # this scenario is most likely when the same playbook is run more than once From 80fbcf2f989564480567c208ff131c51983332fa Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 11 May 2021 07:08:11 +0200 Subject: [PATCH 037/139] Release 3.0.2. --- CHANGELOG.rst | 14 ++++++++++++++ changelogs/changelog.yaml | 14 ++++++++++++++ .../fragments/2448-stackpath_compute-fix.yml | 2 -- changelogs/fragments/2454-detect_zfs_changed.yml | 2 -- changelogs/fragments/3.0.2.yml | 1 - 5 files changed, 28 insertions(+), 5 deletions(-) delete mode 100644 changelogs/fragments/2448-stackpath_compute-fix.yml delete mode 100644 changelogs/fragments/2454-detect_zfs_changed.yml delete mode 100644 changelogs/fragments/3.0.2.yml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 42e68508ad..ba15b4e7a4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,20 @@ Community General Release Notes This changelog describes changes after version 2.0.0. +v3.0.2 +====== + +Release Summary +--------------- + +Bugfix release for the first Ansible 4.0.0 release candidate. + +Bugfixes +-------- + +- stackpath_compute inventory script - fix broken validation checks for client ID and client secret (https://github.com/ansible-collections/community.general/pull/2448). +- zfs - certain ZFS properties, especially sizes, would lead to a task being falsely marked as "changed" even when no actual change was made (https://github.com/ansible-collections/community.general/issues/975, https://github.com/ansible-collections/community.general/pull/2454). + v3.0.1 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index a7354e47b2..600b51463b 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -1010,3 +1010,17 @@ releases: - 2435-one_vm-fix_missing_keys.yml - 3.0.1.yml release_date: '2021-05-04' + 3.0.2: + changes: + bugfixes: + - stackpath_compute inventory script - fix broken validation checks for client + ID and client secret (https://github.com/ansible-collections/community.general/pull/2448). + - zfs - certain ZFS properties, especially sizes, would lead to a task being + falsely marked as "changed" even when no actual change was made (https://github.com/ansible-collections/community.general/issues/975, + https://github.com/ansible-collections/community.general/pull/2454). + release_summary: Bugfix release for the first Ansible 4.0.0 release candidate. + fragments: + - 2448-stackpath_compute-fix.yml + - 2454-detect_zfs_changed.yml + - 3.0.2.yml + release_date: '2021-05-11' diff --git a/changelogs/fragments/2448-stackpath_compute-fix.yml b/changelogs/fragments/2448-stackpath_compute-fix.yml deleted file mode 100644 index 196db780b1..0000000000 --- a/changelogs/fragments/2448-stackpath_compute-fix.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: -- "stackpath_compute inventory script - fix broken validation checks for client ID and client secret (https://github.com/ansible-collections/community.general/pull/2448)." diff --git a/changelogs/fragments/2454-detect_zfs_changed.yml b/changelogs/fragments/2454-detect_zfs_changed.yml deleted file mode 100644 index 0604278f6b..0000000000 --- a/changelogs/fragments/2454-detect_zfs_changed.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - zfs - certain ZFS properties, especially sizes, would lead to a task being falsely marked as "changed" even when no actual change was made (https://github.com/ansible-collections/community.general/issues/975, https://github.com/ansible-collections/community.general/pull/2454). diff --git a/changelogs/fragments/3.0.2.yml b/changelogs/fragments/3.0.2.yml deleted file mode 100644 index fbd0669c36..0000000000 --- a/changelogs/fragments/3.0.2.yml +++ /dev/null @@ -1 +0,0 @@ -release_summary: Bugfix release for the first Ansible 4.0.0 release candidate. From fd32af1ac3d1eda86368e462d3af8fc41c66a581 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 11 May 2021 08:15:11 +0200 Subject: [PATCH 038/139] Next expected release will be 3.1.0. --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index edad7d7aee..a4b4cad7e0 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: community name: general -version: 3.0.2 +version: 3.1.0 readme: README.md authors: - Ansible (https://github.com/ansible) From 703660c81d8f848e84924c8f44c02171540d354e Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 11 May 2021 08:27:35 +0200 Subject: [PATCH 039/139] Run unit tests also with Python 3.10. (#2486) (#2488) ci_complete (cherry picked from commit 624eb7171e8afc72684695aaad6c12d1a27c3c26) Co-authored-by: Felix Fontein --- .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 8d1b81865e..8dc49e5c03 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -124,6 +124,7 @@ stages: - test: 3.7 - test: 3.8 - test: 3.9 + - test: '3.10' - stage: Units_2_11 displayName: Units 2.11 dependsOn: [] From 19c03cff96339665a80c12c32ea78e091f4b9b79 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 11 May 2021 19:27:36 +0200 Subject: [PATCH 040/139] Revert "Revert "spotinst_aws_elastigroup - fixed elements for many lists (#2355) (#2363)"" (#2428) This reverts commit 5b15e4089af401ac47f3fb63eec22eda7c728d44. --- ...spotinst_aws_elastigroup-list-elements.yml | 2 + .../spotinst/spotinst_aws_elastigroup.py | 165 ++++++++++-------- 2 files changed, 92 insertions(+), 75 deletions(-) create mode 100644 changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml diff --git a/changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml b/changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml new file mode 100644 index 0000000000..876b212690 --- /dev/null +++ b/changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml @@ -0,0 +1,2 @@ +minor_changes: + - spotinst_aws_elastigroup - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2355). diff --git a/plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py b/plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py index 1a0ddb9fef..5ed8028e37 100644 --- a/plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py +++ b/plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py @@ -23,26 +23,26 @@ options: credentials_path: description: - - (Path) Optional parameter that allows to set a non-default credentials path. + - Optional parameter that allows to set a non-default credentials path. default: ~/.spotinst/credentials type: path account_id: description: - - (String) Optional parameter that allows to set an account-id inside the module configuration - By default this is retrieved from the credentials path + - Optional parameter that allows to set an account-id inside the module configuration. + By default this is retrieved from the credentials path. type: str availability_vs_cost: description: - - (String) The strategy orientation. + - The strategy orientation. - "The choices available are: C(availabilityOriented), C(costOriented), C(balanced)." required: true type: str availability_zones: description: - - (List of Objects) a list of hash/dictionaries of Availability Zones that are configured in the elastigroup; + - A list of hash/dictionaries of Availability Zones that are configured in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are name (String), @@ -50,10 +50,11 @@ options: placement_group_name (String), required: true type: list + elements: dict block_device_mappings: description: - - (List of Objects) a list of hash/dictionaries of Block Device Mappings for elastigroup instances; + - A list of hash/dictionaries of Block Device Mappings for elastigroup instances; You can specify virtual devices and EBS volumes.; '[{"key":"value", "key":"value"}]'; keys allowed are @@ -68,10 +69,11 @@ options: volume_type(String), volume_size(Integer)) type: list + elements: dict chef: description: - - (Object) The Chef integration configuration.; + - The Chef integration configuration.; Expects the following keys - chef_server (String), organization (String), user (String), @@ -81,92 +83,94 @@ options: draining_timeout: description: - - (Integer) Time for instance to be drained from incoming requests and deregistered from ELB before termination. + - Time for instance to be drained from incoming requests and deregistered from ELB before termination. type: int ebs_optimized: description: - - (Boolean) Enable EBS optimization for supported instances which are not enabled by default.; + - Enable EBS optimization for supported instances which are not enabled by default.; Note - additional charges will be applied. type: bool ebs_volume_pool: description: - - (List of Objects) a list of hash/dictionaries of EBS devices to reattach to the elastigroup when available; + - A list of hash/dictionaries of EBS devices to reattach to the elastigroup when available; '[{"key":"value", "key":"value"}]'; keys allowed are - volume_ids (List of Strings), device_name (String) type: list + elements: dict ecs: description: - - (Object) The ECS integration configuration.; + - The ECS integration configuration.; Expects the following key - cluster_name (String) type: dict elastic_ips: description: - - (List of Strings) List of ElasticIps Allocation Ids (Example C(eipalloc-9d4e16f8)) to associate to the group instances + - List of ElasticIps Allocation Ids (Example C(eipalloc-9d4e16f8)) to associate to the group instances type: list + elements: str fallback_to_od: description: - - (Boolean) In case of no spots available, Elastigroup will launch an On-demand instance instead + - In case of no spots available, Elastigroup will launch an On-demand instance instead type: bool health_check_grace_period: description: - - (Integer) The amount of time, in seconds, after the instance has launched to start and check its health. + - The amount of time, in seconds, after the instance has launched to start and check its health. - If not specified, it defaults to C(300). type: int health_check_unhealthy_duration_before_replacement: description: - - (Integer) Minimal mount of time instance should be unhealthy for us to consider it unhealthy. + - Minimal mount of time instance should be unhealthy for us to consider it unhealthy. type: int health_check_type: description: - - (String) The service to use for the health check. + - The service to use for the health check. - "The choices available are: C(ELB), C(HCS), C(TARGET_GROUP), C(MLB), C(EC2)." type: str iam_role_name: description: - - (String) The instance profile iamRole name + - The instance profile iamRole name - Only use iam_role_arn, or iam_role_name type: str iam_role_arn: description: - - (String) The instance profile iamRole arn + - The instance profile iamRole arn - Only use iam_role_arn, or iam_role_name type: str id: description: - - (String) The group id if it already exists and you want to update, or delete it. + - The group id if it already exists and you want to update, or delete it. This will not work unless the uniqueness_by field is set to id. When this is set, and the uniqueness_by field is set, the group will either be updated or deleted, but not created. type: str image_id: description: - - (String) The image Id used to launch the instance.; + - The image Id used to launch the instance.; In case of conflict between Instance type and image type, an error will be returned required: true type: str key_pair: description: - - (String) Specify a Key Pair to attach to the instances + - Specify a Key Pair to attach to the instances type: str kubernetes: description: - - (Object) The Kubernetes integration configuration. + - The Kubernetes integration configuration. Expects the following keys - api_server (String), token (String) @@ -174,47 +178,48 @@ options: lifetime_period: description: - - (Integer) lifetime period + - Lifetime period type: int load_balancers: description: - - (List of Strings) List of classic ELB names + - List of classic ELB names type: list + elements: str max_size: description: - - (Integer) The upper limit number of instances that you can scale up to + - The upper limit number of instances that you can scale up to required: true type: int mesosphere: description: - - (Object) The Mesosphere integration configuration. + - The Mesosphere integration configuration. Expects the following key - api_server (String) type: dict min_size: description: - - (Integer) The lower limit number of instances that you can scale down to + - The lower limit number of instances that you can scale down to required: true type: int monitoring: description: - - (String) Describes whether instance Enhanced Monitoring is enabled + - Describes whether instance Enhanced Monitoring is enabled type: str name: description: - - (String) Unique name for elastigroup to be created, updated or deleted + - Unique name for elastigroup to be created, updated or deleted required: true type: str network_interfaces: description: - - (List of Objects) a list of hash/dictionaries of network interfaces to add to the elastigroup; + - A list of hash/dictionaries of network interfaces to add to the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - description (String), @@ -229,29 +234,30 @@ options: associate_ipv6_address (Boolean), private_ip_addresses (List of Objects, Keys are privateIpAddress (String, required) and primary (Boolean)) type: list + elements: dict on_demand_count: description: - - (Integer) Required if risk is not set + - Required if risk is not set - Number of on demand instances to launch. All other instances will be spot instances.; Either set this parameter or the risk parameter type: int on_demand_instance_type: description: - - (String) On-demand instance type that will be provisioned + - On-demand instance type that will be provisioned type: str opsworks: description: - - (Object) The elastigroup OpsWorks integration configration.; + - The elastigroup OpsWorks integration configration.; Expects the following key - layer_id (String) type: dict persistence: description: - - (Object) The Stateful elastigroup configration.; + - The Stateful elastigroup configration.; Accepts the following keys - should_persist_root_device (Boolean), should_persist_block_devices (Boolean), @@ -260,14 +266,14 @@ options: product: description: - - (String) Operation system type. + - Operation system type. - "Available choices are: C(Linux/UNIX), C(SUSE Linux), C(Windows), C(Linux/UNIX (Amazon VPC)), C(SUSE Linux (Amazon VPC))." required: true type: str rancher: description: - - (Object) The Rancher integration configuration.; + - The Rancher integration configuration.; Expects the following keys - version (String), access_key (String), @@ -277,7 +283,7 @@ options: right_scale: description: - - (Object) The Rightscale integration configuration.; + - The Rightscale integration configuration.; Expects the following keys - account_id (String), refresh_token (String) @@ -285,12 +291,12 @@ options: risk: description: - - (Integer) required if on demand is not set. The percentage of Spot instances to launch (0 - 100). + - Required if on demand is not set. The percentage of Spot instances to launch (0 - 100). type: int roll_config: description: - - (Object) Roll configuration.; + - Roll configuration.; If you would like the group to roll after updating, please use this feature. Accepts the following keys - batch_size_percentage(Integer, Required), @@ -300,7 +306,7 @@ options: scheduled_tasks: description: - - (List of Objects) a list of hash/dictionaries of scheduled tasks to configure in the elastigroup; + - A list of hash/dictionaries of scheduled tasks to configure in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - adjustment (Integer), @@ -315,84 +321,90 @@ options: task_type (String, required), is_enabled (Boolean) type: list + elements: dict security_group_ids: description: - - (List of Strings) One or more security group IDs. ; + - One or more security group IDs. ; In case of update it will override the existing Security Group with the new given array required: true type: list + elements: str shutdown_script: description: - - (String) The Base64-encoded shutdown script that executes prior to instance termination. + - The Base64-encoded shutdown script that executes prior to instance termination. Encode before setting. type: str signals: description: - - (List of Objects) a list of hash/dictionaries of signals to configure in the elastigroup; + - A list of hash/dictionaries of signals to configure in the elastigroup; keys allowed are - name (String, required), timeout (Integer) type: list + elements: dict spin_up_time: description: - - (Integer) spin up time, in seconds, for the instance + - Spin up time, in seconds, for the instance type: int spot_instance_types: description: - - (List of Strings) Spot instance type that will be provisioned. + - Spot instance type that will be provisioned. required: true type: list + elements: str state: choices: - present - absent description: - - (String) create or delete the elastigroup + - Create or delete the elastigroup default: present type: str tags: description: - - (List of tagKey:tagValue pairs) a list of tags to configure in the elastigroup. Please specify list of keys and values (key colon value); + - A list of tags to configure in the elastigroup. Please specify list of keys and values (key colon value); type: list + elements: dict target: description: - - (Integer) The number of instances to launch + - The number of instances to launch required: true type: int target_group_arns: description: - - (List of Strings) List of target group arns instances should be registered to + - List of target group arns instances should be registered to type: list + elements: str tenancy: description: - - (String) dedicated vs shared tenancy. + - Dedicated vs shared tenancy. - "The available choices are: C(default), C(dedicated)." type: str terminate_at_end_of_billing_hour: description: - - (Boolean) terminate at the end of billing hour + - Terminate at the end of billing hour type: bool unit: description: - - (String) The capacity unit to launch instances by. + - The capacity unit to launch instances by. - "The available choices are: C(instance), C(weight)." type: str up_scaling_policies: description: - - (List of Objects) a list of hash/dictionaries of scaling policies to configure in the elastigroup; + - A list of hash/dictionaries of scaling policies to configure in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - policy_name (String, required), @@ -413,10 +425,11 @@ options: maximum (String), minimum (String) type: list + elements: dict down_scaling_policies: description: - - (List of Objects) a list of hash/dictionaries of scaling policies to configure in the elastigroup; + - A list of hash/dictionaries of scaling policies to configure in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - policy_name (String, required), @@ -437,10 +450,11 @@ options: maximum (String), minimum (String) type: list + elements: dict target_tracking_policies: description: - - (List of Objects) a list of hash/dictionaries of target tracking policies to configure in the elastigroup; + - A list of hash/dictionaries of target tracking policies to configure in the elastigroup; '[{"key":"value", "key":"value"}]'; keys allowed are - policy_name (String, required), @@ -452,37 +466,38 @@ options: cooldown (String, required), target (String, required) type: list + elements: dict uniqueness_by: choices: - id - name description: - - (String) If your group names are not unique, you may use this feature to update or delete a specific group. + - If your group names are not unique, you may use this feature to update or delete a specific group. Whenever this property is set, you must set a group_id in order to update or delete a group, otherwise a group will be created. default: name type: str user_data: description: - - (String) Base64-encoded MIME user data. Encode before setting the value. + - Base64-encoded MIME user data. Encode before setting the value. type: str utilize_reserved_instances: description: - - (Boolean) In case of any available Reserved Instances, + - In case of any available Reserved Instances, Elastigroup will utilize your reservations before purchasing Spot instances. type: bool wait_for_instances: description: - - (Boolean) Whether or not the elastigroup creation / update actions should wait for the instances to spin + - Whether or not the elastigroup creation / update actions should wait for the instances to spin type: bool default: false wait_timeout: description: - - (Integer) How long the module should wait for instances before failing the action.; + - How long the module should wait for instances before failing the action.; Only works if wait_for_instances is True. type: int @@ -1428,18 +1443,18 @@ def main(): fields = dict( account_id=dict(type='str'), availability_vs_cost=dict(type='str', required=True), - availability_zones=dict(type='list', required=True), - block_device_mappings=dict(type='list'), + availability_zones=dict(type='list', elements='dict', required=True), + 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'), - down_scaling_policies=dict(type='list'), + down_scaling_policies=dict(type='list', elements='dict'), draining_timeout=dict(type='int'), ebs_optimized=dict(type='bool'), - ebs_volume_pool=dict(type='list'), + ebs_volume_pool=dict(type='list', elements='dict'), ecs=dict(type='dict'), elastic_beanstalk=dict(type='dict'), - elastic_ips=dict(type='list'), + elastic_ips=dict(type='list', elements='str'), fallback_to_od=dict(type='bool'), id=dict(type='str'), health_check_grace_period=dict(type='int'), @@ -1451,7 +1466,7 @@ def main(): key_pair=dict(type='str', no_log=False), kubernetes=dict(type='dict'), lifetime_period=dict(type='int'), - load_balancers=dict(type='list'), + load_balancers=dict(type='list', elements='str'), max_size=dict(type='int', required=True), mesosphere=dict(type='dict'), min_size=dict(type='int', required=True), @@ -1459,7 +1474,7 @@ def main(): multai_load_balancers=dict(type='list'), multai_token=dict(type='str', no_log=True), name=dict(type='str', required=True), - network_interfaces=dict(type='list'), + network_interfaces=dict(type='list', elements='dict'), on_demand_count=dict(type='int'), on_demand_instance_type=dict(type='str'), opsworks=dict(type='dict'), @@ -1469,16 +1484,16 @@ def main(): right_scale=dict(type='dict'), risk=dict(type='int'), roll_config=dict(type='dict'), - scheduled_tasks=dict(type='list'), - security_group_ids=dict(type='list', required=True), + scheduled_tasks=dict(type='list', elements='dict'), + security_group_ids=dict(type='list', elements='str', required=True), shutdown_script=dict(type='str'), - signals=dict(type='list'), + signals=dict(type='list', elements='dict'), spin_up_time=dict(type='int'), - spot_instance_types=dict(type='list', required=True), + spot_instance_types=dict(type='list', elements='str', required=True), state=dict(default='present', choices=['present', 'absent']), - tags=dict(type='list'), + tags=dict(type='list', elements='dict'), target=dict(type='int', required=True), - target_group_arns=dict(type='list'), + target_group_arns=dict(type='list', elements='str'), tenancy=dict(type='str'), terminate_at_end_of_billing_hour=dict(type='bool'), token=dict(type='str', no_log=True), @@ -1486,8 +1501,8 @@ def main(): user_data=dict(type='str'), utilize_reserved_instances=dict(type='bool'), uniqueness_by=dict(default='name', choices=['name', 'id']), - up_scaling_policies=dict(type='list'), - target_tracking_policies=dict(type='list'), + up_scaling_policies=dict(type='list', elements='dict'), + target_tracking_policies=dict(type='list', elements='dict'), wait_for_instances=dict(type='bool', default=False), wait_timeout=dict(type='int') ) From e05769d4bf9ccf23cee585a1bafab722753eebba Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 11 May 2021 19:27:46 +0200 Subject: [PATCH 041/139] Deprecate vendored ipaddress copy. (#2459) --- changelogs/fragments/deprecate-ipaddress.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelogs/fragments/deprecate-ipaddress.yml diff --git a/changelogs/fragments/deprecate-ipaddress.yml b/changelogs/fragments/deprecate-ipaddress.yml new file mode 100644 index 0000000000..545a66c7f1 --- /dev/null +++ b/changelogs/fragments/deprecate-ipaddress.yml @@ -0,0 +1,4 @@ +deprecated_features: +- "The vendored copy of ``ipaddress`` will be removed in community.general 4.0.0. Please switch to ``ipaddress`` from the Python 3 standard library, or `from pypi `_, if your code relies on the vendored version of ``ipaddress`` (https://github.com/ansible-collections/community.general/pull/2459)." +- "scaleway_security_group_rule - the module will require ``ipaddress`` installed when used with Python 2 from community.general 4.0.0 on. ``ipaddress`` is part of the Python 3 standard library, but can be installed for Python 2 from pypi (https://github.com/ansible-collections/community.general/pull/2459)." +- "lxd inventory plugin - the plugin will require ``ipaddress`` installed when used with Python 2 from community.general 4.0.0 on. ``ipaddress`` is part of the Python 3 standard library, but can be installed for Python 2 from pypi (https://github.com/ansible-collections/community.general/pull/2459)." From 3539957bac108c4617c9901cedbe751d1fc0c2a6 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 11 May 2021 20:05:24 +0200 Subject: [PATCH 042/139] modified redfish_config and idrac_redfish_config to skip incorrect attributes (#2334) (#2491) * modified redfish_config and idrac_redfish_config to skip incorrect attributes Signed-off-by: Trevor Squillario Trevor_Squillario@Dell.com * modified redfish_utils.py and idrac_redfish_config.py to return empty warning message * modified redfish_config.py and idrac_redfish_config.py to use module.warn() * updated changelog fragment for pr 2334 (cherry picked from commit 9d46ccf1b2aacac8136432f0abb85ae65082d8a8) Co-authored-by: TrevorSquillario <72882537+TrevorSquillario@users.noreply.github.com> --- ...dfish_config-skip-incorrect-attributes.yml | 4 +++ plugins/module_utils/redfish_utils.py | 28 ++++++++++++++----- .../redfish/idrac_redfish_config.py | 24 ++++++++++++---- .../redfish/redfish_config.py | 3 ++ 4 files changed, 47 insertions(+), 12 deletions(-) create mode 100644 changelogs/fragments/2334-redfish_config-skip-incorrect-attributes.yml diff --git a/changelogs/fragments/2334-redfish_config-skip-incorrect-attributes.yml b/changelogs/fragments/2334-redfish_config-skip-incorrect-attributes.yml new file mode 100644 index 0000000000..2e609c43fc --- /dev/null +++ b/changelogs/fragments/2334-redfish_config-skip-incorrect-attributes.yml @@ -0,0 +1,4 @@ +minor_changes: + - redfish_utils module utils - modified set_bios_attributes function to skip invalid attribute instead of returning. Added skipped attributes to output (https://github.com/ansible-collections/community.general/issues/1995). + - idrac_redfish_config - modified set_manager_attributes function to skip invalid attribute instead of returning. Added skipped attributes to output. Modified module exit to add warning variable (https://github.com/ansible-collections/community.general/issues/1995). + - redfish_config - modified module exit to add warning variable (https://github.com/ansible-collections/community.general/issues/1995). diff --git a/plugins/module_utils/redfish_utils.py b/plugins/module_utils/redfish_utils.py index d8cc4061f8..df7011a0b4 100644 --- a/plugins/module_utils/redfish_utils.py +++ b/plugins/module_utils/redfish_utils.py @@ -1671,19 +1671,31 @@ class RedfishUtils(object): # Make a copy of the attributes dict attrs_to_patch = dict(attributes) + # List to hold attributes not found + attrs_bad = {} # Check the attributes - for attr in attributes: - if attr not in data[u'Attributes']: - return {'ret': False, 'msg': "BIOS attribute %s not found" % attr} + for attr_name, attr_value in attributes.items(): + # Check if attribute exists + if attr_name not in data[u'Attributes']: + # Remove and proceed to next attribute if this isn't valid + attrs_bad.update({attr_name: attr_value}) + del attrs_to_patch[attr_name] + continue + # If already set to requested value, remove it from PATCH payload - if data[u'Attributes'][attr] == attributes[attr]: - del attrs_to_patch[attr] + if data[u'Attributes'][attr_name] == attributes[attr_name]: + del attrs_to_patch[attr_name] + + warning = "" + if attrs_bad: + warning = "Incorrect attributes %s" % (attrs_bad) # Return success w/ changed=False if no attrs need to be changed if not attrs_to_patch: return {'ret': True, 'changed': False, - 'msg': "BIOS attributes already set"} + 'msg': "BIOS attributes already set", + 'warning': warning} # Get the SettingsObject URI set_bios_attr_uri = data["@Redfish.Settings"]["SettingsObject"]["@odata.id"] @@ -1693,7 +1705,9 @@ class RedfishUtils(object): response = self.patch_request(self.root_uri + set_bios_attr_uri, payload) if response['ret'] is False: return response - return {'ret': True, 'changed': True, 'msg': "Modified BIOS attribute"} + return {'ret': True, 'changed': True, + 'msg': "Modified BIOS attributes %s" % (attrs_to_patch), + 'warning': warning} def set_boot_order(self, boot_list): if not boot_list: diff --git a/plugins/modules/remote_management/redfish/idrac_redfish_config.py b/plugins/modules/remote_management/redfish/idrac_redfish_config.py index e27ef6a2a6..b16401311b 100644 --- a/plugins/modules/remote_management/redfish/idrac_redfish_config.py +++ b/plugins/modules/remote_management/redfish/idrac_redfish_config.py @@ -179,6 +179,7 @@ class IdracRedfishUtils(RedfishUtils): attrs_to_patch = {} attrs_skipped = {} + attrs_bad = {} # Store attrs which were not found in the system # Search for key entry and extract URI from it response = self.get_request(self.root_uri + manager_uri + "/" + key) @@ -189,13 +190,15 @@ class IdracRedfishUtils(RedfishUtils): if key not in data: return {'ret': False, - 'msg': "%s: Key %s not found" % (command, key)} + 'msg': "%s: Key %s not found" % (command, key), + 'warning': ""} for attr_name, attr_value in attributes.items(): # Check if attribute exists if attr_name not in data[u'Attributes']: - return {'ret': False, - 'msg': "%s: Manager attribute %s not found" % (command, attr_name)} + # Skip and proceed to next attribute if this isn't valid + attrs_bad.update({attr_name: attr_value}) + continue # Find out if value is already set to what we want. If yes, exclude # those attributes @@ -204,16 +207,23 @@ class IdracRedfishUtils(RedfishUtils): else: attrs_to_patch.update({attr_name: attr_value}) + warning = "" + if attrs_bad: + warning = "Incorrect attributes %s" % (attrs_bad) + if not attrs_to_patch: return {'ret': True, 'changed': False, - 'msg': "Manager attributes already set"} + 'msg': "No changes made. Manager attributes already set.", + 'warning': warning} payload = {"Attributes": attrs_to_patch} response = self.patch_request(self.root_uri + manager_uri + "/" + key, payload) if response['ret'] is False: return response + return {'ret': True, 'changed': True, - 'msg': "%s: Modified Manager attributes %s" % (command, attrs_to_patch)} + 'msg': "%s: Modified Manager attributes %s" % (command, attrs_to_patch), + 'warning': warning} CATEGORY_COMMANDS_ALL = { @@ -221,6 +231,7 @@ CATEGORY_COMMANDS_ALL = { "SetSystemAttributes"] } + # list of mutually exclusive commands for a category CATEGORY_COMMANDS_MUTUALLY_EXCLUSIVE = { "Manager": [["SetManagerAttributes", "SetLifecycleControllerAttributes", @@ -308,6 +319,9 @@ def main(): # Return data back or fail with proper message if result['ret'] is True: + if result.get('warning'): + module.warn(to_native(result['warning'])) + module.exit_json(changed=result['changed'], msg=to_native(result['msg'])) else: module.fail_json(msg=to_native(result['msg'])) diff --git a/plugins/modules/remote_management/redfish/redfish_config.py b/plugins/modules/remote_management/redfish/redfish_config.py index 5c1df16c4e..e084c670f4 100644 --- a/plugins/modules/remote_management/redfish/redfish_config.py +++ b/plugins/modules/remote_management/redfish/redfish_config.py @@ -321,6 +321,9 @@ def main(): # Return data back or fail with proper message if result['ret'] is True: + if result.get('warning'): + module.warn(to_native(result['warning'])) + module.exit_json(changed=result['changed'], msg=to_native(result['msg'])) else: module.fail_json(msg=to_native(result['msg'])) From 4cb6f39a8044d726b2bee031f471cc8d072b3a2c Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 11 May 2021 20:05:42 +0200 Subject: [PATCH 043/139] module_helper.py Breakdown (#2393) (#2492) * break down of module_helper into smaller pieces, keeping compatibility * removed abc.ABC (py3 only) from code + fixed reference to vars.py * multiple changes: - mh.base - moved more functionalities to ModuleHelperBase - mh.mixins.(cmd, state) - CmdMixin no longer inherits from ModuleHelperBase - mh.mixins.deps - DependencyMixin now overrides run() method to test dependency - mh.mixins.vars - created class VarsMixin - mh.module_helper - moved functions to base class, added VarsMixin - module_helper - importing AnsibleModule as well, for backward compatibility in test * removed unnecessary __all__ * make pylint happy * PR adjustments + bot config + changelog frag * Update plugins/module_utils/mh/module_helper.py Co-authored-by: Felix Fontein * Update plugins/module_utils/mh/module_helper.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit d22dd5056e62d6b2b8929f732b453214354253b9) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .github/BOTMETA.yml | 3 + .../2393-module_helper-breakdown.yml | 2 + plugins/module_utils/mh/__init__.py | 0 plugins/module_utils/mh/base.py | 56 ++ plugins/module_utils/mh/deco.py | 54 ++ plugins/module_utils/mh/exceptions.py | 22 + plugins/module_utils/mh/mixins/__init__.py | 0 plugins/module_utils/mh/mixins/cmd.py | 167 ++++++ plugins/module_utils/mh/mixins/deps.py | 58 ++ plugins/module_utils/mh/mixins/state.py | 39 ++ plugins/module_utils/mh/mixins/vars.py | 132 +++++ plugins/module_utils/mh/module_helper.py | 79 +++ plugins/module_utils/module_helper.py | 511 +----------------- .../module_utils/test_module_helper.py | 6 +- .../plugins/modules/system/test_xfconf.py | 4 +- 15 files changed, 625 insertions(+), 508 deletions(-) create mode 100644 changelogs/fragments/2393-module_helper-breakdown.yml create mode 100644 plugins/module_utils/mh/__init__.py create mode 100644 plugins/module_utils/mh/base.py create mode 100644 plugins/module_utils/mh/deco.py create mode 100644 plugins/module_utils/mh/exceptions.py create mode 100644 plugins/module_utils/mh/mixins/__init__.py create mode 100644 plugins/module_utils/mh/mixins/cmd.py create mode 100644 plugins/module_utils/mh/mixins/deps.py create mode 100644 plugins/module_utils/mh/mixins/state.py create mode 100644 plugins/module_utils/mh/mixins/vars.py create mode 100644 plugins/module_utils/mh/module_helper.py diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index f27c96e049..cdef437f90 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -142,6 +142,9 @@ files: $module_utils/memset.py: maintainers: glitchcrab labels: cloud memset + $module_utils/mh/: + maintainers: russoz + labels: module_helper $module_utils/module_helper.py: maintainers: russoz labels: module_helper diff --git a/changelogs/fragments/2393-module_helper-breakdown.yml b/changelogs/fragments/2393-module_helper-breakdown.yml new file mode 100644 index 0000000000..472a1c3569 --- /dev/null +++ b/changelogs/fragments/2393-module_helper-breakdown.yml @@ -0,0 +1,2 @@ +minor_changes: + - module_helper module utils - break down of the long file into smaller pieces (https://github.com/ansible-collections/community.general/pull/2393). diff --git a/plugins/module_utils/mh/__init__.py b/plugins/module_utils/mh/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/module_utils/mh/base.py b/plugins/module_utils/mh/base.py new file mode 100644 index 0000000000..2a2dd88f7b --- /dev/null +++ b/plugins/module_utils/mh/base.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# (c) 2020, Alexei Znamensky +# Copyright: (c) 2020, Ansible Project +# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.general.plugins.module_utils.mh.exceptions import ModuleHelperException as _MHE +from ansible_collections.community.general.plugins.module_utils.mh.deco import module_fails_on_exception + + +class ModuleHelperBase(object): + module = None + ModuleHelperException = _MHE + + def __init__(self, module=None): + self._changed = False + + if module: + self.module = module + + if not isinstance(self.module, AnsibleModule): + self.module = AnsibleModule(**self.module) + + def __init_module__(self): + pass + + def __run__(self): + raise NotImplementedError() + + def __quit_module__(self): + pass + + @property + def changed(self): + return self._changed + + @changed.setter + def changed(self, value): + self._changed = value + + def has_changed(self): + raise NotImplementedError() + + @property + def output(self): + raise NotImplementedError() + + @module_fails_on_exception + def run(self): + self.__init_module__() + self.__run__() + self.__quit_module__() + self.module.exit_json(changed=self.has_changed(), **self.output) diff --git a/plugins/module_utils/mh/deco.py b/plugins/module_utils/mh/deco.py new file mode 100644 index 0000000000..91f0d97744 --- /dev/null +++ b/plugins/module_utils/mh/deco.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# (c) 2020, Alexei Znamensky +# Copyright: (c) 2020, Ansible Project +# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +import traceback +from functools import wraps + +from ansible_collections.community.general.plugins.module_utils.mh.exceptions import ModuleHelperException + + +def cause_changes(on_success=None, on_failure=None): + + def deco(func): + if on_success is None and on_failure is None: + return func + + @wraps(func) + def wrapper(*args, **kwargs): + try: + self = args[0] + func(*args, **kwargs) + if on_success is not None: + self.changed = on_success + except Exception: + if on_failure is not None: + self.changed = on_failure + raise + + return wrapper + + return deco + + +def module_fails_on_exception(func): + @wraps(func) + def wrapper(self, *args, **kwargs): + try: + func(self, *args, **kwargs) + except SystemExit: + raise + except ModuleHelperException as e: + if e.update_output: + self.update_output(e.update_output) + self.module.fail_json(msg=e.msg, exception=traceback.format_exc(), + output=self.output, vars=self.vars.output(), **self.output) + except Exception as e: + 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) + return wrapper diff --git a/plugins/module_utils/mh/exceptions.py b/plugins/module_utils/mh/exceptions.py new file mode 100644 index 0000000000..558dcca05f --- /dev/null +++ b/plugins/module_utils/mh/exceptions.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# (c) 2020, Alexei Znamensky +# Copyright: (c) 2020, Ansible Project +# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +class ModuleHelperException(Exception): + @staticmethod + def _get_remove(key, kwargs): + if key in kwargs: + result = kwargs[key] + del kwargs[key] + return result + return None + + def __init__(self, *args, **kwargs): + self.msg = self._get_remove('msg', kwargs) or "Module failed with exception: {0}".format(self) + self.update_output = self._get_remove('update_output', kwargs) or {} + super(ModuleHelperException, self).__init__(*args) diff --git a/plugins/module_utils/mh/mixins/__init__.py b/plugins/module_utils/mh/mixins/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/module_utils/mh/mixins/cmd.py b/plugins/module_utils/mh/mixins/cmd.py new file mode 100644 index 0000000000..fc66638f69 --- /dev/null +++ b/plugins/module_utils/mh/mixins/cmd.py @@ -0,0 +1,167 @@ +# -*- coding: utf-8 -*- +# (c) 2020, Alexei Znamensky +# Copyright: (c) 2020, Ansible Project +# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +from functools import partial + + +class ArgFormat(object): + """ + Argument formatter for use as a command line parameter. Used in CmdMixin. + """ + BOOLEAN = 0 + PRINTF = 1 + FORMAT = 2 + + @staticmethod + def stars_deco(num): + if num == 1: + def deco(f): + return lambda v: f(*v) + return deco + elif num == 2: + def deco(f): + return lambda v: f(**v) + return deco + + return lambda f: f + + def __init__(self, name, fmt=None, style=FORMAT, stars=0): + """ + Creates a CLI-formatter for one specific argument. The argument may be a module parameter or just a named parameter for + the CLI command execution. + :param name: Name of the argument to be formatted + :param fmt: Either a str to be formatted (using or not printf-style) or a callable that does that + :param style: Whether arg_format (as str) should use printf-style formatting. + Ignored if arg_format is None or not a str (should be callable). + :param stars: A int with 0, 1 or 2 value, indicating to formatting the value as: value, *value or **value + """ + def printf_fmt(_fmt, v): + try: + return [_fmt % v] + except TypeError as e: + if e.args[0] != 'not all arguments converted during string formatting': + raise + return [_fmt] + + _fmts = { + ArgFormat.BOOLEAN: lambda _fmt, v: ([_fmt] if bool(v) else []), + ArgFormat.PRINTF: printf_fmt, + ArgFormat.FORMAT: lambda _fmt, v: [_fmt.format(v)], + } + + self.name = name + self.stars = stars + + if fmt is None: + fmt = "{0}" + style = ArgFormat.FORMAT + + if isinstance(fmt, str): + func = _fmts[style] + self.arg_format = partial(func, fmt) + elif isinstance(fmt, list) or isinstance(fmt, tuple): + self.arg_format = lambda v: [_fmts[style](f, v)[0] for f in fmt] + elif hasattr(fmt, '__call__'): + self.arg_format = fmt + else: + raise TypeError('Parameter fmt must be either: a string, a list/tuple of ' + 'strings or a function: type={0}, value={1}'.format(type(fmt), fmt)) + + if stars: + self.arg_format = (self.stars_deco(stars))(self.arg_format) + + def to_text(self, value): + if value is None: + return [] + func = self.arg_format + return [str(p) for p in func(value)] + + +class CmdMixin(object): + """ + Mixin for mapping module options to running a CLI command with its arguments. + """ + command = None + command_args_formats = {} + run_command_fixed_options = {} + check_rc = False + force_lang = "C" + + @property + def module_formats(self): + result = {} + for param in self.module.params.keys(): + result[param] = ArgFormat(param) + return result + + @property + def custom_formats(self): + result = {} + for param, fmt_spec in self.command_args_formats.items(): + result[param] = ArgFormat(param, **fmt_spec) + return result + + def _calculate_args(self, extra_params=None, params=None): + def add_arg_formatted_param(_cmd_args, arg_format, _value): + args = list(arg_format.to_text(_value)) + return _cmd_args + args + + def find_format(_param): + return self.custom_formats.get(_param, self.module_formats.get(_param)) + + extra_params = extra_params or dict() + cmd_args = list([self.command]) if isinstance(self.command, str) else list(self.command) + try: + cmd_args[0] = self.module.get_bin_path(cmd_args[0], required=True) + except ValueError: + pass + param_list = params if params else self.module.params.keys() + + for param in param_list: + if isinstance(param, dict): + if len(param) != 1: + raise self.ModuleHelperException("run_command parameter as a dict must " + "contain only one key: {0}".format(param)) + _param = list(param.keys())[0] + fmt = find_format(_param) + value = param[_param] + elif isinstance(param, str): + if param in self.module.argument_spec: + fmt = find_format(param) + value = self.module.params[param] + elif param in extra_params: + fmt = find_format(param) + value = extra_params[param] + else: + self.module.deprecate("Cannot determine value for parameter: {0}. " + "From version 4.0.0 onwards this will generate an exception".format(param), + version="4.0.0", collection_name="community.general") + continue + + else: + raise self.ModuleHelperException("run_command parameter must be either a str or a dict: {0}".format(param)) + cmd_args = add_arg_formatted_param(cmd_args, fmt, value) + + return cmd_args + + def process_command_output(self, rc, out, err): + return rc, out, err + + def run_command(self, extra_params=None, params=None, *args, **kwargs): + self.vars.cmd_args = self._calculate_args(extra_params, params) + options = dict(self.run_command_fixed_options) + env_update = dict(options.get('environ_update', {})) + options['check_rc'] = options.get('check_rc', self.check_rc) + if self.force_lang: + env_update.update({'LANGUAGE': self.force_lang}) + self.update_output(force_lang=self.force_lang) + options['environ_update'] = env_update + options.update(kwargs) + rc, out, err = self.module.run_command(self.vars.cmd_args, *args, **options) + self.update_output(rc=rc, stdout=out, stderr=err) + return self.process_command_output(rc, out, err) diff --git a/plugins/module_utils/mh/mixins/deps.py b/plugins/module_utils/mh/mixins/deps.py new file mode 100644 index 0000000000..1c6c9ae484 --- /dev/null +++ b/plugins/module_utils/mh/mixins/deps.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# (c) 2020, Alexei Znamensky +# Copyright: (c) 2020, Ansible Project +# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +import traceback + +from ansible_collections.community.general.plugins.module_utils.mh.base import ModuleHelperBase +from ansible_collections.community.general.plugins.module_utils.mh.deco import module_fails_on_exception + + +class DependencyCtxMgr(object): + def __init__(self, name, msg=None): + self.name = name + self.msg = msg + self.has_it = False + self.exc_type = None + self.exc_val = None + self.exc_tb = None + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.has_it = exc_type is None + self.exc_type = exc_type + self.exc_val = exc_val + self.exc_tb = exc_tb + return not self.has_it + + @property + def text(self): + return self.msg or str(self.exc_val) + + +class DependencyMixin(ModuleHelperBase): + _dependencies = [] + + @classmethod + def dependency(cls, name, msg): + cls._dependencies.append(DependencyCtxMgr(name, msg)) + return cls._dependencies[-1] + + def fail_on_missing_deps(self): + for d in self._dependencies: + if not d.has_it: + self.module.fail_json(changed=False, + exception="\n".join(traceback.format_exception(d.exc_type, d.exc_val, d.exc_tb)), + msg=d.text, + **self.output) + + @module_fails_on_exception + def run(self): + self.fail_on_missing_deps() + super(DependencyMixin, self).run() diff --git a/plugins/module_utils/mh/mixins/state.py b/plugins/module_utils/mh/mixins/state.py new file mode 100644 index 0000000000..b946090ac9 --- /dev/null +++ b/plugins/module_utils/mh/mixins/state.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# (c) 2020, Alexei Znamensky +# Copyright: (c) 2020, Ansible Project +# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +class StateMixin(object): + state_param = 'state' + default_state = None + + def _state(self): + state = self.module.params.get(self.state_param) + return self.default_state if state is None else state + + def _method(self, state): + return "{0}_{1}".format(self.state_param, state) + + def __run__(self): + state = self._state() + self.vars.state = state + + # resolve aliases + if state not in self.module.params: + aliased = [name for name, param in self.module.argument_spec.items() if state in param.get('aliases', [])] + if aliased: + state = aliased[0] + self.vars.effective_state = state + + method = self._method(state) + if not hasattr(self, method): + return self.__state_fallback__() + func = getattr(self, method) + return func() + + def __state_fallback__(self): + raise ValueError("Cannot find method: {0}".format(self._method(self._state()))) diff --git a/plugins/module_utils/mh/mixins/vars.py b/plugins/module_utils/mh/mixins/vars.py new file mode 100644 index 0000000000..7c936e04ac --- /dev/null +++ b/plugins/module_utils/mh/mixins/vars.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +# (c) 2020, Alexei Znamensky +# Copyright: (c) 2020, Ansible Project +# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +class VarMeta(object): + NOTHING = object() + + def __init__(self, diff=False, output=True, change=None, fact=False): + self.init = False + self.initial_value = None + self.value = None + + self.diff = diff + self.change = diff if change is None else change + self.output = output + self.fact = fact + + def set(self, diff=None, output=None, change=None, fact=None, initial_value=NOTHING): + if diff is not None: + self.diff = diff + if output is not None: + self.output = output + if change is not None: + self.change = change + if fact is not None: + self.fact = fact + if initial_value is not self.NOTHING: + self.initial_value = initial_value + + def set_value(self, value): + if not self.init: + self.initial_value = value + self.init = True + self.value = value + return self + + @property + def has_changed(self): + return self.change and (self.initial_value != self.value) + + @property + def diff_result(self): + return None if not (self.diff and self.has_changed) else { + 'before': self.initial_value, + 'after': self.value, + } + + def __str__(self): + return "".format( + self.value, self.initial_value, self.diff, self.output, self.change + ) + + +class VarDict(object): + def __init__(self): + self._data = dict() + self._meta = dict() + + def __getitem__(self, item): + return self._data[item] + + def __setitem__(self, key, value): + self.set(key, value) + + def __getattr__(self, item): + try: + return self._data[item] + except KeyError: + return getattr(self._data, item) + + def __setattr__(self, key, value): + if key in ('_data', '_meta'): + super(VarDict, self).__setattr__(key, value) + else: + self.set(key, value) + + def meta(self, name): + return self._meta[name] + + def set_meta(self, name, **kwargs): + self.meta(name).set(**kwargs) + + def set(self, name, value, **kwargs): + if name in ('_data', '_meta'): + raise ValueError("Names _data and _meta are reserved for use by ModuleHelper") + self._data[name] = value + if name in self._meta: + meta = self.meta(name) + else: + meta = VarMeta(**kwargs) + meta.set_value(value) + self._meta[name] = meta + + def output(self): + return dict((k, v) for k, v in self._data.items() if self.meta(k).output) + + def diff(self): + diff_results = [(k, self.meta(k).diff_result) for k in self._data] + diff_results = [dr for dr in diff_results if dr[1] is not None] + if diff_results: + before = dict((dr[0], dr[1]['before']) for dr in diff_results) + after = dict((dr[0], dr[1]['after']) for dr in diff_results) + return {'before': before, 'after': after} + return None + + def facts(self): + facts_result = dict((k, v) for k, v in self._data.items() if self._meta[k].fact) + return facts_result if facts_result else None + + def change_vars(self): + return [v for v in self._data if self.meta(v).change] + + def has_changed(self, v): + return self._meta[v].has_changed + + +class VarsMixin(object): + + def __init__(self, module=None): + self.vars = VarDict() + super(VarsMixin, self).__init__(module) + + def update_vars(self, meta=None, **kwargs): + if meta is None: + meta = {} + for k, v in kwargs.items(): + self.vars.set(k, v, **meta) diff --git a/plugins/module_utils/mh/module_helper.py b/plugins/module_utils/mh/module_helper.py new file mode 100644 index 0000000000..b27b60df9a --- /dev/null +++ b/plugins/module_utils/mh/module_helper.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +# (c) 2020, Alexei Znamensky +# Copyright: (c) 2020, Ansible Project +# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +from ansible.module_utils.common.dict_transformations import dict_merge + +from ansible_collections.community.general.plugins.module_utils.mh.base import ModuleHelperBase, AnsibleModule +from ansible_collections.community.general.plugins.module_utils.mh.mixins.cmd import CmdMixin +from ansible_collections.community.general.plugins.module_utils.mh.mixins.state import StateMixin +from ansible_collections.community.general.plugins.module_utils.mh.mixins.deps import DependencyMixin +from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarsMixin, VarDict as _VD + + +class ModuleHelper(VarsMixin, DependencyMixin, ModuleHelperBase): + _output_conflict_list = ('msg', 'exception', 'output', 'vars', 'changed') + facts_name = None + output_params = () + diff_params = () + change_params = () + facts_params = () + + VarDict = _VD # for backward compatibility, will be deprecated at some point + + def __init__(self, module=None): + super(ModuleHelper, self).__init__(module) + for name, value in self.module.params.items(): + self.vars.set( + name, value, + diff=name in self.diff_params, + output=name in self.output_params, + change=None if not self.change_params else name in self.change_params, + fact=name in self.facts_params, + ) + + def update_output(self, **kwargs): + self.update_vars(meta={"output": True}, **kwargs) + + def update_facts(self, **kwargs): + self.update_vars(meta={"fact": True}, **kwargs) + + def _vars_changed(self): + return any(self.vars.has_changed(v) for v in self.vars.change_vars()) + + def has_changed(self): + return self.changed or self._vars_changed() + + @property + def output(self): + result = dict(self.vars.output()) + if self.facts_name: + facts = self.vars.facts() + if facts is not None: + result['ansible_facts'] = {self.facts_name: facts} + if self.module._diff: + diff = result.get('diff', {}) + vars_diff = self.vars.diff() or {} + result['diff'] = dict_merge(dict(diff), vars_diff) + + for varname in result: + if varname in self._output_conflict_list: + result["_" + varname] = result[varname] + del result[varname] + return result + + +class StateModuleHelper(StateMixin, ModuleHelper): + pass + + +class CmdModuleHelper(CmdMixin, ModuleHelper): + pass + + +class CmdStateModuleHelper(CmdMixin, StateMixin, ModuleHelper): + pass diff --git a/plugins/module_utils/module_helper.py b/plugins/module_utils/module_helper.py index d241eba5af..a6b35bdd33 100644 --- a/plugins/module_utils/module_helper.py +++ b/plugins/module_utils/module_helper.py @@ -6,506 +6,13 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -from functools import partial, wraps -import traceback -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.dict_transformations import dict_merge - - -class ModuleHelperException(Exception): - @staticmethod - def _get_remove(key, kwargs): - if key in kwargs: - result = kwargs[key] - del kwargs[key] - return result - return None - - def __init__(self, *args, **kwargs): - self.msg = self._get_remove('msg', kwargs) or "Module failed with exception: {0}".format(self) - self.update_output = self._get_remove('update_output', kwargs) or {} - super(ModuleHelperException, self).__init__(*args) - - -class ArgFormat(object): - """ - Argument formatter for use as a command line parameter. Used in CmdMixin. - """ - BOOLEAN = 0 - PRINTF = 1 - FORMAT = 2 - - @staticmethod - def stars_deco(num): - if num == 1: - def deco(f): - return lambda v: f(*v) - return deco - elif num == 2: - def deco(f): - return lambda v: f(**v) - return deco - - return lambda f: f - - def __init__(self, name, fmt=None, style=FORMAT, stars=0): - """ - Creates a CLI-formatter for one specific argument. The argument may be a module parameter or just a named parameter for - the CLI command execution. - :param name: Name of the argument to be formatted - :param fmt: Either a str to be formatted (using or not printf-style) or a callable that does that - :param style: Whether arg_format (as str) should use printf-style formatting. - Ignored if arg_format is None or not a str (should be callable). - :param stars: A int with 0, 1 or 2 value, indicating to formatting the value as: value, *value or **value - """ - def printf_fmt(_fmt, v): - try: - return [_fmt % v] - except TypeError as e: - if e.args[0] != 'not all arguments converted during string formatting': - raise - return [_fmt] - - _fmts = { - ArgFormat.BOOLEAN: lambda _fmt, v: ([_fmt] if bool(v) else []), - ArgFormat.PRINTF: printf_fmt, - ArgFormat.FORMAT: lambda _fmt, v: [_fmt.format(v)], - } - - self.name = name - self.stars = stars - - if fmt is None: - fmt = "{0}" - style = ArgFormat.FORMAT - - if isinstance(fmt, str): - func = _fmts[style] - self.arg_format = partial(func, fmt) - elif isinstance(fmt, list) or isinstance(fmt, tuple): - self.arg_format = lambda v: [_fmts[style](f, v)[0] for f in fmt] - elif hasattr(fmt, '__call__'): - self.arg_format = fmt - else: - raise TypeError('Parameter fmt must be either: a string, a list/tuple of ' - 'strings or a function: type={0}, value={1}'.format(type(fmt), fmt)) - - if stars: - self.arg_format = (self.stars_deco(stars))(self.arg_format) - - def to_text(self, value): - if value is None: - return [] - func = self.arg_format - return [str(p) for p in func(value)] - - -def cause_changes(on_success=None, on_failure=None): - - def deco(func): - if on_success is None and on_failure is None: - return func - - @wraps(func) - def wrapper(*args, **kwargs): - try: - self = args[0] - func(*args, **kwargs) - if on_success is not None: - self.changed = on_success - except Exception: - if on_failure is not None: - self.changed = on_failure - raise - - return wrapper - - return deco - - -def module_fails_on_exception(func): - @wraps(func) - def wrapper(self, *args, **kwargs): - try: - func(self, *args, **kwargs) - except SystemExit: - raise - except ModuleHelperException as e: - if e.update_output: - self.update_output(e.update_output) - self.module.fail_json(msg=e.msg, exception=traceback.format_exc(), - output=self.output, vars=self.vars.output(), **self.output) - except Exception as e: - 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) - return wrapper - - -class DependencyCtxMgr(object): - def __init__(self, name, msg=None): - self.name = name - self.msg = msg - self.has_it = False - self.exc_type = None - self.exc_val = None - self.exc_tb = None - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.has_it = exc_type is None - self.exc_type = exc_type - self.exc_val = exc_val - self.exc_tb = exc_tb - return not self.has_it - - @property - def text(self): - return self.msg or str(self.exc_val) - - -class VarMeta(object): - NOTHING = object() - - def __init__(self, diff=False, output=True, change=None, fact=False): - self.init = False - self.initial_value = None - self.value = None - - self.diff = diff - self.change = diff if change is None else change - self.output = output - self.fact = fact - - def set(self, diff=None, output=None, change=None, fact=None, initial_value=NOTHING): - if diff is not None: - self.diff = diff - if output is not None: - self.output = output - if change is not None: - self.change = change - if fact is not None: - self.fact = fact - if initial_value is not self.NOTHING: - self.initial_value = initial_value - - def set_value(self, value): - if not self.init: - self.initial_value = value - self.init = True - self.value = value - return self - - @property - def has_changed(self): - return self.change and (self.initial_value != self.value) - - @property - def diff_result(self): - return None if not (self.diff and self.has_changed) else { - 'before': self.initial_value, - 'after': self.value, - } - - def __str__(self): - return "".format( - self.value, self.initial_value, self.diff, self.output, self.change - ) - - -class ModuleHelper(object): - _output_conflict_list = ('msg', 'exception', 'output', 'vars', 'changed') - _dependencies = [] - module = None - facts_name = None - output_params = () - diff_params = () - change_params = () - facts_params = () - - class VarDict(object): - def __init__(self): - self._data = dict() - self._meta = dict() - - def __getitem__(self, item): - return self._data[item] - - def __setitem__(self, key, value): - self.set(key, value) - - def __getattr__(self, item): - try: - return self._data[item] - except KeyError: - return getattr(self._data, item) - - def __setattr__(self, key, value): - if key in ('_data', '_meta'): - super(ModuleHelper.VarDict, self).__setattr__(key, value) - else: - self.set(key, value) - - def meta(self, name): - return self._meta[name] - - def set_meta(self, name, **kwargs): - self.meta(name).set(**kwargs) - - def set(self, name, value, **kwargs): - if name in ('_data', '_meta'): - raise ValueError("Names _data and _meta are reserved for use by ModuleHelper") - self._data[name] = value - if name in self._meta: - meta = self.meta(name) - else: - meta = VarMeta(**kwargs) - meta.set_value(value) - self._meta[name] = meta - - def output(self): - return dict((k, v) for k, v in self._data.items() if self.meta(k).output) - - def diff(self): - diff_results = [(k, self.meta(k).diff_result) for k in self._data] - diff_results = [dr for dr in diff_results if dr[1] is not None] - if diff_results: - before = dict((dr[0], dr[1]['before']) for dr in diff_results) - after = dict((dr[0], dr[1]['after']) for dr in diff_results) - return {'before': before, 'after': after} - return None - - def facts(self): - facts_result = dict((k, v) for k, v in self._data.items() if self._meta[k].fact) - return facts_result if facts_result else None - - def change_vars(self): - return [v for v in self._data if self.meta(v).change] - - def has_changed(self, v): - return self._meta[v].has_changed - - def __init__(self, module=None): - self.vars = ModuleHelper.VarDict() - self._changed = False - - if module: - self.module = module - - if not isinstance(self.module, AnsibleModule): - self.module = AnsibleModule(**self.module) - - for name, value in self.module.params.items(): - self.vars.set( - name, value, - diff=name in self.diff_params, - output=name in self.output_params, - change=None if not self.change_params else name in self.change_params, - fact=name in self.facts_params, - ) - - def update_vars(self, meta=None, **kwargs): - if meta is None: - meta = {} - for k, v in kwargs.items(): - self.vars.set(k, v, **meta) - - def update_output(self, **kwargs): - self.update_vars(meta={"output": True}, **kwargs) - - def update_facts(self, **kwargs): - self.update_vars(meta={"fact": True}, **kwargs) - - def __init_module__(self): - pass - - def __run__(self): - raise NotImplementedError() - - def __quit_module__(self): - pass - - def _vars_changed(self): - return any(self.vars.has_changed(v) for v in self.vars.change_vars()) - - @property - def changed(self): - return self._changed - - @changed.setter - def changed(self, value): - self._changed = value - - def has_changed(self): - return self.changed or self._vars_changed() - - @property - def output(self): - result = dict(self.vars.output()) - if self.facts_name: - facts = self.vars.facts() - if facts is not None: - result['ansible_facts'] = {self.facts_name: facts} - if self.module._diff: - diff = result.get('diff', {}) - vars_diff = self.vars.diff() or {} - result['diff'] = dict_merge(dict(diff), vars_diff) - - for varname in result: - if varname in self._output_conflict_list: - result["_" + varname] = result[varname] - del result[varname] - return result - - @module_fails_on_exception - def run(self): - self.fail_on_missing_deps() - self.__init_module__() - self.__run__() - self.__quit_module__() - self.module.exit_json(changed=self.has_changed(), **self.output) - - @classmethod - def dependency(cls, name, msg): - cls._dependencies.append(DependencyCtxMgr(name, msg)) - return cls._dependencies[-1] - - def fail_on_missing_deps(self): - for d in self._dependencies: - if not d.has_it: - self.module.fail_json(changed=False, - exception="\n".join(traceback.format_exception(d.exc_type, d.exc_val, d.exc_tb)), - msg=d.text, - **self.output) - - -class StateMixin(object): - state_param = 'state' - default_state = None - - def _state(self): - state = self.module.params.get(self.state_param) - return self.default_state if state is None else state - - def _method(self, state): - return "{0}_{1}".format(self.state_param, state) - - def __run__(self): - state = self._state() - self.vars.state = state - - # resolve aliases - if state not in self.module.params: - aliased = [name for name, param in self.module.argument_spec.items() if state in param.get('aliases', [])] - if aliased: - state = aliased[0] - self.vars.effective_state = state - - method = self._method(state) - if not hasattr(self, method): - return self.__state_fallback__() - func = getattr(self, method) - return func() - - def __state_fallback__(self): - raise ValueError("Cannot find method: {0}".format(self._method(self._state()))) - - -class CmdMixin(object): - """ - Mixin for mapping module options to running a CLI command with its arguments. - """ - command = None - command_args_formats = {} - run_command_fixed_options = {} - check_rc = False - force_lang = "C" - - @property - def module_formats(self): - result = {} - for param in self.module.params.keys(): - result[param] = ArgFormat(param) - return result - - @property - def custom_formats(self): - result = {} - for param, fmt_spec in self.command_args_formats.items(): - result[param] = ArgFormat(param, **fmt_spec) - return result - - def _calculate_args(self, extra_params=None, params=None): - def add_arg_formatted_param(_cmd_args, arg_format, _value): - args = list(arg_format.to_text(_value)) - return _cmd_args + args - - def find_format(_param): - return self.custom_formats.get(_param, self.module_formats.get(_param)) - - extra_params = extra_params or dict() - cmd_args = list([self.command]) if isinstance(self.command, str) else list(self.command) - try: - cmd_args[0] = self.module.get_bin_path(cmd_args[0], required=True) - except ValueError: - pass - param_list = params if params else self.module.params.keys() - - for param in param_list: - if isinstance(param, dict): - if len(param) != 1: - raise ModuleHelperException("run_command parameter as a dict must " - "contain only one key: {0}".format(param)) - _param = list(param.keys())[0] - fmt = find_format(_param) - value = param[_param] - elif isinstance(param, str): - if param in self.module.argument_spec: - fmt = find_format(param) - value = self.module.params[param] - elif param in extra_params: - fmt = find_format(param) - value = extra_params[param] - else: - self.module.deprecate("Cannot determine value for parameter: {0}. " - "From version 4.0.0 onwards this will generate an exception".format(param), - version="4.0.0", collection_name="community.general") - continue - - else: - raise ModuleHelperException("run_command parameter must be either a str or a dict: {0}".format(param)) - cmd_args = add_arg_formatted_param(cmd_args, fmt, value) - - return cmd_args - - def process_command_output(self, rc, out, err): - return rc, out, err - - def run_command(self, extra_params=None, params=None, *args, **kwargs): - self.vars.cmd_args = self._calculate_args(extra_params, params) - options = dict(self.run_command_fixed_options) - env_update = dict(options.get('environ_update', {})) - options['check_rc'] = options.get('check_rc', self.check_rc) - if self.force_lang: - env_update.update({'LANGUAGE': self.force_lang}) - self.update_output(force_lang=self.force_lang) - options['environ_update'] = env_update - options.update(kwargs) - rc, out, err = self.module.run_command(self.vars.cmd_args, *args, **options) - self.update_output(rc=rc, stdout=out, stderr=err) - return self.process_command_output(rc, out, err) - - -class StateModuleHelper(StateMixin, ModuleHelper): - pass - - -class CmdModuleHelper(CmdMixin, ModuleHelper): - pass - - -class CmdStateModuleHelper(CmdMixin, StateMixin, ModuleHelper): - pass +from ansible_collections.community.general.plugins.module_utils.mh.module_helper import ( + ModuleHelper, StateModuleHelper, CmdModuleHelper, CmdStateModuleHelper, AnsibleModule +) +from ansible_collections.community.general.plugins.module_utils.mh.mixins.cmd import CmdMixin, ArgFormat +from ansible_collections.community.general.plugins.module_utils.mh.mixins.state import StateMixin +from ansible_collections.community.general.plugins.module_utils.mh.mixins.deps import DependencyCtxMgr +from ansible_collections.community.general.plugins.module_utils.mh.exceptions import ModuleHelperException +from ansible_collections.community.general.plugins.module_utils.mh.deco import cause_changes, module_fails_on_exception +from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarMeta, VarDict diff --git a/tests/unit/plugins/module_utils/test_module_helper.py b/tests/unit/plugins/module_utils/test_module_helper.py index 6f77ca7662..6452784182 100644 --- a/tests/unit/plugins/module_utils/test_module_helper.py +++ b/tests/unit/plugins/module_utils/test_module_helper.py @@ -6,12 +6,10 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type -from collections import namedtuple - import pytest from ansible_collections.community.general.plugins.module_utils.module_helper import ( - ArgFormat, DependencyCtxMgr, ModuleHelper, VarMeta, cause_changes + ArgFormat, DependencyCtxMgr, VarMeta, VarDict, cause_changes ) @@ -144,7 +142,7 @@ def test_variable_meta_diff(): def test_vardict(): - vd = ModuleHelper.VarDict() + vd = VarDict() vd.set('a', 123) assert vd['a'] == 123 assert vd.a == 123 diff --git a/tests/unit/plugins/modules/system/test_xfconf.py b/tests/unit/plugins/modules/system/test_xfconf.py index 1002952ce3..dee387bd7d 100644 --- a/tests/unit/plugins/modules/system/test_xfconf.py +++ b/tests/unit/plugins/modules/system/test_xfconf.py @@ -21,7 +21,7 @@ def patch_xfconf(mocker): """ Function used for mocking some parts of redhat_subscribtion module """ - mocker.patch('ansible_collections.community.general.plugins.module_utils.module_helper.AnsibleModule.get_bin_path', + mocker.patch('ansible_collections.community.general.plugins.module_utils.mh.module_helper.AnsibleModule.get_bin_path', return_value='/testbin/xfconf-query') @@ -332,7 +332,7 @@ def test_xfconf(mocker, capfd, patch_xfconf, testcase): # 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.module_helper.AnsibleModule.run_command', + 'ansible_collections.community.general.plugins.module_utils.mh.module_helper.AnsibleModule.run_command', side_effect=call_results) # Try to run test case From 4032dd6b082bc1786f9eaef301bb1f3e3ff73e08 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 11 May 2021 20:05:59 +0200 Subject: [PATCH 044/139] discord.py: Add new module for discord notifications (#2398) (#2493) * first push: add discord module and test for notifications * fix the yaml docs and edit the result output * add link * fix link * fix docs and remove required=False in argument spec * add elements specd and more info about embeds * called str... * elements for embeds oc. * fix typo's in description and set checkmode to false * edit docs and module return * support checkmode with get method * fix unit test * handle exception and add new example for embeds * quote line * fix typos * fix yaml (cherry picked from commit 0912e8cc7ab1bc2b70f6552e84b3430fb7cd1dfc) Co-authored-by: CWollinger --- plugins/modules/discord.py | 1 + plugins/modules/notification/discord.py | 215 ++++++++++++++++++ .../modules/notification/test_discord.py | 103 +++++++++ 3 files changed, 319 insertions(+) create mode 120000 plugins/modules/discord.py create mode 100644 plugins/modules/notification/discord.py create mode 100644 tests/unit/plugins/modules/notification/test_discord.py diff --git a/plugins/modules/discord.py b/plugins/modules/discord.py new file mode 120000 index 0000000000..1acf222f94 --- /dev/null +++ b/plugins/modules/discord.py @@ -0,0 +1 @@ +./notification/discord.py \ No newline at end of file diff --git a/plugins/modules/notification/discord.py b/plugins/modules/notification/discord.py new file mode 100644 index 0000000000..27dc6fc85c --- /dev/null +++ b/plugins/modules/notification/discord.py @@ -0,0 +1,215 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2021, Christian Wollinger +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: discord +short_description: Send Discord messages +version_added: 3.1.0 +description: + - Sends a message to a Discord channel using the Discord webhook API. +author: Christian Wollinger (@cwollinger) +seealso: + - name: API documentation + description: Documentation for Discord API + link: https://discord.com/developers/docs/resources/webhook#execute-webhook +options: + webhook_id: + description: + - The webhook ID. + - "Format from Discord webhook URL: C(/webhooks/{webhook.id}/{webhook.token})." + required: yes + type: str + webhook_token: + description: + - The webhook token. + - "Format from Discord webhook URL: C(/webhooks/{webhook.id}/{webhook.token})." + required: yes + type: str + content: + description: + - Content of the message to the Discord channel. + - At least one of I(content) and I(embeds) must be specified. + type: str + username: + description: + - Overrides the default username of the webhook. + type: str + avatar_url: + description: + - Overrides the default avatar of the webhook. + type: str + tts: + description: + - Set this to C(true) if this is a TTS (Text to Speech) message. + type: bool + default: false + embeds: + description: + - Send messages as Embeds to the Discord channel. + - Embeds can have a colored border, embedded images, text fields and more. + - "Allowed parameters are described in the Discord Docs: U(https://discord.com/developers/docs/resources/channel#embed-object)" + - At least one of I(content) and I(embeds) must be specified. + type: list + elements: dict +''' + +EXAMPLES = """ +- name: Send a message to the Discord channel + community.general.discord: + webhook_id: "00000" + webhook_token: "XXXYYY" + content: "This is a message from ansible" + +- name: Send a message to the Discord channel with specific username and avatar + community.general.discord: + webhook_id: "00000" + webhook_token: "XXXYYY" + content: "This is a message from ansible" + username: Ansible + avatar_url: "https://docs.ansible.com/ansible/latest/_static/images/logo_invert.png" + +- name: Send a embedded message to the Discord channel + community.general.discord: + webhook_id: "00000" + webhook_token: "XXXYYY" + embeds: + - title: "Embedded message" + description: "This is an embedded message" + footer: + text: "Author: Ansible" + image: + url: "https://docs.ansible.com/ansible/latest/_static/images/logo_invert.png" + +- name: Send two embedded messages + community.general.discord: + webhook_id: "00000" + webhook_token: "XXXYYY" + embeds: + - title: "First message" + description: "This is my first embedded message" + footer: + text: "Author: Ansible" + image: + url: "https://docs.ansible.com/ansible/latest/_static/images/logo_invert.png" + - title: "Second message" + description: "This is my first second message" + footer: + text: "Author: Ansible" + icon_url: "https://docs.ansible.com/ansible/latest/_static/images/logo_invert.png" + fields: + - name: "Field 1" + value: "Value of my first field" + - name: "Field 2" + value: "Value of my second field" + timestamp: "{{ ansible_date_time.iso8601 }}" +""" + +RETURN = """ +http_code: + description: + - Response Code returned by Discord API. + returned: always + type: int + sample: 204 +""" + +from ansible.module_utils.urls import fetch_url +from ansible.module_utils.basic import AnsibleModule + + +def discord_check_mode(module): + + webhook_id = module.params['webhook_id'] + webhook_token = module.params['webhook_token'] + + headers = { + 'content-type': 'application/json' + } + + url = "https://discord.com/api/webhooks/%s/%s" % ( + webhook_id, webhook_token) + + response, info = fetch_url(module, url, method='GET', headers=headers) + return response, info + + +def discord_text_msg(module): + + webhook_id = module.params['webhook_id'] + webhook_token = module.params['webhook_token'] + content = module.params['content'] + user = module.params['username'] + avatar_url = module.params['avatar_url'] + tts = module.params['tts'] + embeds = module.params['embeds'] + + headers = { + 'content-type': 'application/json' + } + + url = "https://discord.com/api/webhooks/%s/%s" % ( + webhook_id, webhook_token) + + payload = { + 'content': content, + 'username': user, + 'avatar_url': avatar_url, + 'tts': tts, + 'embeds': embeds, + } + + payload = module.jsonify(payload) + + response, info = fetch_url(module, url, data=payload, headers=headers, method='POST') + return response, info + + +def main(): + module = AnsibleModule( + argument_spec=dict( + webhook_id=dict(type='str', required=True), + webhook_token=dict(type='str', required=True, no_log=True), + content=dict(type='str'), + username=dict(type='str'), + avatar_url=dict(type='str'), + tts=dict(type='bool', default=False), + embeds=dict(type='list', elements='dict'), + ), + required_one_of=[['content', 'embeds']], + supports_check_mode=True + ) + + result = dict( + changed=False, + http_code='', + ) + + if module.check_mode: + response, info = discord_check_mode(module) + if info['status'] != 200: + try: + module.fail_json(http_code=info['status'], msg=info['msg'], response=module.from_json(info['body']), info=info) + except Exception: + module.fail_json(http_code=info['status'], msg=info['msg'], info=info) + else: + module.exit_json(msg=info['msg'], changed=False, http_code=info['status'], response=module.from_json(response.read())) + else: + response, info = discord_text_msg(module) + if info['status'] != 204: + try: + module.fail_json(http_code=info['status'], msg=info['msg'], response=module.from_json(info['body']), info=info) + except Exception: + module.fail_json(http_code=info['status'], msg=info['msg'], info=info) + else: + module.exit_json(msg=info['msg'], changed=True, http_code=info['status']) + + +if __name__ == "__main__": + main() diff --git a/tests/unit/plugins/modules/notification/test_discord.py b/tests/unit/plugins/modules/notification/test_discord.py new file mode 100644 index 0000000000..257b0d4dab --- /dev/null +++ b/tests/unit/plugins/modules/notification/test_discord.py @@ -0,0 +1,103 @@ +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json +import pytest +from ansible_collections.community.general.tests.unit.compat.mock import Mock, patch +from ansible_collections.community.general.plugins.modules.notification import discord +from ansible_collections.community.general.tests.unit.plugins.modules.utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase, set_module_args + + +class TestDiscordModule(ModuleTestCase): + + def setUp(self): + super(TestDiscordModule, self).setUp() + self.module = discord + + def tearDown(self): + super(TestDiscordModule, self).tearDown() + + @pytest.fixture + def fetch_url_mock(self, mocker): + return mocker.patch('ansible.module_utils.notification.discord.fetch_url') + + def test_without_parameters(self): + """Failure if no parameters set""" + with self.assertRaises(AnsibleFailJson): + set_module_args({}) + self.module.main() + + def test_without_content(self): + """Failure if content and embeds both are missing""" + set_module_args({ + 'webhook_id': 'xxx', + 'webhook_token': 'xxx' + }) + with self.assertRaises(AnsibleFailJson): + self.module.main() + + def test_successful_message(self): + """Test a basic message successfully.""" + set_module_args({ + 'webhook_id': 'xxx', + 'webhook_token': 'xxx', + 'content': 'test' + }) + + with patch.object(discord, "fetch_url") as fetch_url_mock: + fetch_url_mock.return_value = (None, {"status": 204, 'msg': 'OK (0 bytes)'}) + with self.assertRaises(AnsibleExitJson): + self.module.main() + + self.assertTrue(fetch_url_mock.call_count, 1) + call_data = json.loads(fetch_url_mock.call_args[1]['data']) + assert call_data['content'] == "test" + + def test_message_with_username(self): + """Test a message with username set successfully.""" + set_module_args({ + 'webhook_id': 'xxx', + 'webhook_token': 'xxx', + 'content': 'test', + 'username': 'Ansible Bot' + }) + + with patch.object(discord, "fetch_url") as fetch_url_mock: + fetch_url_mock.return_value = (None, {"status": 204, 'msg': 'OK (0 bytes)'}) + with self.assertRaises(AnsibleExitJson): + self.module.main() + + self.assertTrue(fetch_url_mock.call_count, 1) + call_data = json.loads(fetch_url_mock.call_args[1]['data']) + assert call_data['username'] == "Ansible Bot" + assert call_data['content'] == "test" + + def test_failed_message(self): + """Test failure because webhook id is wrong.""" + + set_module_args({ + 'webhook_id': 'wrong', + 'webhook_token': 'xxx', + 'content': 'test' + }) + + with patch.object(discord, "fetch_url") as fetch_url_mock: + fetch_url_mock.return_value = (None, {"status": 404, 'msg': 'HTTP Error 404: Not Found', 'body': '{"message": "Unknown Webhook", "code": 10015}'}) + with self.assertRaises(AnsibleFailJson): + self.module.main() + + def test_failed_message_without_body(self): + """Test failure with empty response body.""" + + set_module_args({ + 'webhook_id': 'wrong', + 'webhook_token': 'xxx', + 'content': 'test' + }) + + with patch.object(discord, "fetch_url") as fetch_url_mock: + fetch_url_mock.return_value = (None, {"status": 404, 'msg': 'HTTP Error 404: Not Found'}) + with self.assertRaises(AnsibleFailJson): + self.module.main() From 23da67cc725dc4a81f36dcfc1122cb76459ac869 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 11 May 2021 20:14:30 +0200 Subject: [PATCH 045/139] Add dependent lookup plugin (#2164) (#2490) * Add dependent lookup plugin. * Use correct YAML booleans. * Began complete rewrite. * Only match start of error msg. * Improve tests. * Work around old Jinja2 versions. * Fix metadata. * Fix filter name. (cherry picked from commit eea4f4596541fb0a3fc348bf36f6208c2a408b5f) Co-authored-by: Felix Fontein --- plugins/lookup/dependent.py | 208 ++++++++++++++++++ .../targets/lookup_dependent/aliases | 2 + .../targets/lookup_dependent/tasks/main.yml | 179 +++++++++++++++ tests/unit/plugins/lookup/test_dependent.py | 44 ++++ 4 files changed, 433 insertions(+) create mode 100644 plugins/lookup/dependent.py create mode 100644 tests/integration/targets/lookup_dependent/aliases create mode 100644 tests/integration/targets/lookup_dependent/tasks/main.yml create mode 100644 tests/unit/plugins/lookup/test_dependent.py diff --git a/plugins/lookup/dependent.py b/plugins/lookup/dependent.py new file mode 100644 index 0000000000..a22a98476c --- /dev/null +++ b/plugins/lookup/dependent.py @@ -0,0 +1,208 @@ +# (c) 2015-2021, Felix Fontein +# (c) 2018 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +DOCUMENTATION = """ +name: dependent +short_description: Composes a list with nested elements of other lists or dicts which can depend on previous loop variables +version_added: 3.1.0 +description: + - "Takes the input lists and returns a list with elements that are lists, dictionaries, + or template expressions which evaluate to lists or dicts, composed of the elements of + the input evaluated lists and dictionaries." +options: + _raw: + description: + - A list where the elements are one-element dictionaries, mapping a name to a string, list, or dictionary. + The name is the index that is used in the result object. The value is iterated over as described below. + - If the value is a list, it is simply iterated over. + - If the value is a dictionary, it is iterated over and returned as if they would be processed by the + R(ansible.builtin.dict2items filter,ansible_collections.ansible.builtin.dict2items_filter). + - If the value is a string, it is evaluated as Jinja2 expressions which can access the previously chosen + elements with C(item.). The result must be a list or a dictionary. + type: list + elements: dict + required: true +""" + +EXAMPLES = """ +- name: Install/remove public keys for active admin users + ansible.posix.authorized_key: + user: "{{ item.admin.key }}" + key: "{{ lookup('file', item.key.public_key) }}" + state: "{{ 'present' if item.key.active else 'absent' }}" + when: item.admin.value.active + with_community.general.dependent: + - admin: admin_user_data + - key: admin_ssh_keys[item.admin.key] + loop_control: + # Makes the output readable, so that it doesn't contain the whole subdictionaries and lists + label: "{{ [item.admin.key, 'active' if item.key.active else 'inactive', item.key.public_key] }}" + vars: + admin_user_data: + admin1: + name: Alice + active: true + admin2: + name: Bob + active: true + admin_ssh_keys: + admin1: + - private_key: keys/private_key_admin1.pem + public_key: keys/private_key_admin1.pub + active: true + admin2: + - private_key: keys/private_key_admin2.pem + public_key: keys/private_key_admin2.pub + active: true + - private_key: keys/private_key_admin2-old.pem + public_key: keys/private_key_admin2-old.pub + active: false + +- name: Update DNS records + community.aws.route53: + zone: "{{ item.zone.key }}" + record: "{{ item.prefix.key ~ '.' if item.prefix.key else '' }}{{ item.zone.key }}" + type: "{{ item.entry.key }}" + ttl: "{{ item.entry.value.ttl | default(3600) }}" + value: "{{ item.entry.value.value }}" + state: "{{ 'absent' if (item.entry.value.absent | default(False)) else 'present' }}" + overwrite: true + loop_control: + # Makes the output readable, so that it doesn't contain the whole subdictionaries and lists + label: |- + {{ [item.zone.key, item.prefix.key, item.entry.key, + item.entry.value.ttl | default(3600), + item.entry.value.absent | default(False), item.entry.value.value] }} + with_community.general.dependent: + - zone: dns_setup + - prefix: item.zone.value + - entry: item.prefix.value + vars: + dns_setup: + example.com: + '': + A: + value: + - 1.2.3.4 + AAAA: + value: + - "2a01:1:2:3::1" + 'test._domainkey': + TXT: + ttl: 300 + value: + - '"k=rsa; t=s; p=MIGfMA..."' + example.org: + 'www': + A: + value: + - 1.2.3.4 + - 5.6.7.8 +""" + +RETURN = """ + _list: + description: + - A list composed of dictionaries whose keys are the variable names from the input list. + type: list + elements: dict + sample: + - key1: a + key2: test + - key1: a + key2: foo + - key1: b + key2: bar +""" + +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.template import Templar + + +class LookupModule(LookupBase): + def __evaluate(self, expression, templar, variables): + """Evaluate expression with templar. + + ``expression`` is the expression to evaluate. + ``variables`` are the variables to use. + """ + templar.available_variables = variables or {} + return templar.template("{0}{1}{2}".format("{{", expression, "}}"), cache=False) + + def __process(self, result, terms, index, current, templar, variables): + """Fills ``result`` list with evaluated items. + + ``result`` is a list where the resulting items are placed. + ``terms`` is the parsed list of terms + ``index`` is the current index to be processed in the list. + ``current`` is a dictionary where the first ``index`` values are filled in. + ``variables`` are the variables currently available. + """ + # If we are done, add to result list: + if index == len(terms): + result.append(current.copy()) + return + + key, expression, values = terms[index] + + if expression is not None: + # Evaluate expression in current context + vars = variables.copy() + vars['item'] = current.copy() + try: + values = self.__evaluate(expression, templar, variables=vars) + except Exception as e: + raise AnsibleLookupError( + 'Caught "{error}" while evaluating {key!r} with item == {item!r}'.format( + error=e, key=key, item=current)) + + if isinstance(values, Mapping): + for idx, val in sorted(values.items()): + current[key] = dict([('key', idx), ('value', val)]) + self.__process(result, terms, index + 1, current, templar, variables) + elif isinstance(values, Sequence): + for elt in values: + current[key] = elt + self.__process(result, terms, index + 1, current, templar, variables) + else: + raise AnsibleLookupError( + 'Did not obtain dictionary or list while evaluating {key!r} with item == {item!r}, but {type}'.format( + key=key, item=current, type=type(values))) + + def run(self, terms, variables=None, **kwargs): + """Generate list.""" + result = [] + if len(terms) > 0: + templar = Templar(loader=self._templar._loader) + data = [] + vars_so_far = set() + for index, term in enumerate(terms): + if not isinstance(term, Mapping): + raise AnsibleLookupError( + 'Parameter {index} must be a dictionary, got {type}'.format( + index=index, type=type(term))) + if len(term) != 1: + raise AnsibleLookupError( + 'Parameter {index} must be a one-element dictionary, got {count} elements'.format( + index=index, count=len(term))) + k, v = list(term.items())[0] + if k in vars_so_far: + raise AnsibleLookupError( + 'The variable {key!r} appears more than once'.format(key=k)) + vars_so_far.add(k) + if isinstance(v, string_types): + data.append((k, v, None)) + elif isinstance(v, (Sequence, Mapping)): + data.append((k, None, v)) + else: + raise AnsibleLookupError( + 'Parameter {key!r} (index {index}) must have a value of type string, dictionary or list, got type {type}'.format( + index=index, key=k, type=type(v))) + self.__process(result, data, 0, {}, templar, variables) + return result diff --git a/tests/integration/targets/lookup_dependent/aliases b/tests/integration/targets/lookup_dependent/aliases new file mode 100644 index 0000000000..45489be80c --- /dev/null +++ b/tests/integration/targets/lookup_dependent/aliases @@ -0,0 +1,2 @@ +shippable/posix/group2 +skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller diff --git a/tests/integration/targets/lookup_dependent/tasks/main.yml b/tests/integration/targets/lookup_dependent/tasks/main.yml new file mode 100644 index 0000000000..0f1b8d34fb --- /dev/null +++ b/tests/integration/targets/lookup_dependent/tasks/main.yml @@ -0,0 +1,179 @@ +--- +- name: Test 1 + set_fact: + loop_result: >- + {{ + query('community.general.dependent', + dict(key1=[1, 2]), + dict(key2='[item.key1 + 3, item.key1 + 6]'), + dict(key3='[item.key1 + item.key2 * 10]')) + }} + +- name: Check result of Test 1 + assert: + that: + - loop_result == expected_result + vars: + expected_result: + - key1: 1 + key2: 4 + key3: 41 + - key1: 1 + key2: 7 + key3: 71 + - key1: 2 + key2: 5 + key3: 52 + - key1: 2 + key2: 8 + key3: 82 + +- name: Test 2 + set_fact: + loop_result: >- + {{ query('community.general.dependent', + dict([['a', [1, 2, 3]]]), + dict([['b', '[1, 2, 3, 4] if item.a == 1 else [2, 3, 4] if item.a == 2 else [3, 4]']])) }} + # The last expression could have been `range(item.a, 5)`, but that's not supported by all Jinja2 versions used in CI + +- name: Check result of Test 2 + assert: + that: + - loop_result == expected_result + vars: + expected_result: + - a: 1 + b: 1 + - a: 1 + b: 2 + - a: 1 + b: 3 + - a: 1 + b: 4 + - a: 2 + b: 2 + - a: 2 + b: 3 + - a: 2 + b: 4 + - a: 3 + b: 3 + - a: 3 + b: 4 + +- name: Test 3 + debug: + var: item + with_community.general.dependent: + - var1: + a: + - 1 + - 2 + b: + - 3 + - 4 + - var2: 'item.var1.value' + - var3: 'dependent_lookup_test[item.var1.key ~ "_" ~ item.var2]' + loop_control: + label: "{{ [item.var1.key, item.var2, item.var3] }}" + register: dependent + vars: + dependent_lookup_test: + a_1: + - A + - B + a_2: + - C + b_3: + - D + b_4: + - E + - F + - G + +- name: Check result of Test 3 + assert: + that: + - (dependent.results | length) == 7 + - dependent.results[0].item.var1.key == "a" + - dependent.results[0].item.var2 == 1 + - dependent.results[0].item.var3 == "A" + - dependent.results[1].item.var1.key == "a" + - dependent.results[1].item.var2 == 1 + - dependent.results[1].item.var3 == "B" + - dependent.results[2].item.var1.key == "a" + - dependent.results[2].item.var2 == 2 + - dependent.results[2].item.var3 == "C" + - dependent.results[3].item.var1.key == "b" + - dependent.results[3].item.var2 == 3 + - dependent.results[3].item.var3 == "D" + - dependent.results[4].item.var1.key == "b" + - dependent.results[4].item.var2 == 4 + - dependent.results[4].item.var3 == "E" + - dependent.results[5].item.var1.key == "b" + - dependent.results[5].item.var2 == 4 + - dependent.results[5].item.var3 == "F" + - dependent.results[6].item.var1.key == "b" + - dependent.results[6].item.var2 == 4 + - dependent.results[6].item.var3 == "G" + +- name: "Test 4: template failure" + debug: + msg: "{{ item }}" + with_community.general.dependent: + - a: + - 1 + - 2 + - b: "[item.a + foo]" + ignore_errors: true + register: eval_error + +- name: Check result of Test 4 + assert: + that: + - eval_error is failed + - eval_error.msg.startswith("Caught \"'foo' is undefined\" while evaluating ") + +- name: "Test 5: same variable name reused" + debug: + msg: "{{ item }}" + with_community.general.dependent: + - a: x + - b: x + ignore_errors: true + register: eval_error + +- name: Check result of Test 5 + assert: + that: + - eval_error is failed + - eval_error.msg.startswith("Caught \"'x' is undefined\" while evaluating ") + +- name: "Test 6: multi-value dict" + debug: + msg: "{{ item }}" + with_community.general.dependent: + - a: x + b: x + ignore_errors: true + register: eval_error + +- name: Check result of Test 6 + assert: + that: + - eval_error is failed + - eval_error.msg == 'Parameter 0 must be a one-element dictionary, got 2 elements' + +- name: "Test 7: empty dict" + debug: + msg: "{{ item }}" + with_community.general.dependent: + - {} + ignore_errors: true + register: eval_error + +- name: Check result of Test 7 + assert: + that: + - eval_error is failed + - eval_error.msg == 'Parameter 0 must be a one-element dictionary, got 0 elements' diff --git a/tests/unit/plugins/lookup/test_dependent.py b/tests/unit/plugins/lookup/test_dependent.py new file mode 100644 index 0000000000..f2a31ff4b6 --- /dev/null +++ b/tests/unit/plugins/lookup/test_dependent.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# (c) 2020-2021, Felix Fontein +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +from ansible_collections.community.internal_test_tools.tests.unit.compat.unittest import TestCase +from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import ( + MagicMock, +) + +from ansible.plugins.loader import lookup_loader + + +class TestLookupModule(TestCase): + def setUp(self): + templar = MagicMock() + templar._loader = None + self.lookup = lookup_loader.get("community.general.dependent", templar=templar) + + def test_empty(self): + self.assertListEqual(self.lookup.run([], None), []) + + def test_simple(self): + self.assertListEqual( + self.lookup.run( + [ + {'a': '[1, 2]'}, + {'b': '[item.a + 3, item.a + 6]'}, + {'c': '[item.a + item.b * 10]'}, + ], + {}, + ), + [ + {'a': 1, 'b': 4, 'c': 41}, + {'a': 1, 'b': 7, 'c': 71}, + {'a': 2, 'b': 5, 'c': 52}, + {'a': 2, 'b': 8, 'c': 82}, + ], + ) From 1c5e44c64905b36597e86f612bdf5442af1a3cfe Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 11 May 2021 20:22:13 +0200 Subject: [PATCH 046/139] nmcli: Remove dead code, 'options' never contains keys from 'param_alias' (#2417) (#2494) * nmcli: Remove dead code, 'options' never contains keys from 'param_alias' * Update changelogs/fragments/2417-nmcli_remove_dead_code.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit b9fa9116c15f5d6e90eb8626ec67650854429b14) Co-authored-by: spike77453 --- .../fragments/2417-nmcli_remove_dead_code.yml | 2 ++ plugins/modules/net_tools/nmcli.py | 18 ------------------ 2 files changed, 2 insertions(+), 18 deletions(-) create mode 100644 changelogs/fragments/2417-nmcli_remove_dead_code.yml diff --git a/changelogs/fragments/2417-nmcli_remove_dead_code.yml b/changelogs/fragments/2417-nmcli_remove_dead_code.yml new file mode 100644 index 0000000000..9d94c393fa --- /dev/null +++ b/changelogs/fragments/2417-nmcli_remove_dead_code.yml @@ -0,0 +1,2 @@ +minor_changes: + - nmcli - remove dead code, ``options`` never contains keys from ``param_alias`` (https://github.com/ansible-collections/community.general/pull/2417). diff --git a/plugins/modules/net_tools/nmcli.py b/plugins/modules/net_tools/nmcli.py index e2ed4ad572..929d88c654 100644 --- a/plugins/modules/net_tools/nmcli.py +++ b/plugins/modules/net_tools/nmcli.py @@ -1036,17 +1036,6 @@ class Nmcli(object): return conn_info def _compare_conn_params(self, conn_info, options): - # See nmcli(1) for details - param_alias = { - 'type': 'connection.type', - 'con-name': 'connection.id', - 'autoconnect': 'connection.autoconnect', - 'ifname': 'connection.interface-name', - 'master': 'connection.master', - 'slave-type': 'connection.slave-type', - 'zone': 'connection.zone', - } - changed = False diff_before = dict() diff_after = dict() @@ -1070,13 +1059,6 @@ class Nmcli(object): value = value.upper() # ensure current_value is also converted to uppercase in case nmcli changes behaviour current_value = current_value.upper() - elif key in param_alias: - real_key = param_alias[key] - if real_key in conn_info: - current_value = conn_info[real_key] - else: - # alias parameter does not exist - current_value = None else: # parameter does not exist current_value = None From ab5b379b302a4bb90121a57dde8e9e835944572c Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 12 May 2021 18:17:40 +0200 Subject: [PATCH 047/139] linode - docs/validation changes + minor refactorings (#2410) (#2498) * multiple changes: - documentation fixes - minor refactorings * added param deprecation note to the documentation * added changelog fragment * Update changelogs/fragments/2410-linode-improvements.yml Co-authored-by: Felix Fontein * Update changelogs/fragments/2410-linode-improvements.yml Co-authored-by: Felix Fontein * Update plugins/modules/cloud/linode/linode.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 265d034e310fd3704d4779108be910f611bca91e) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../fragments/2410-linode-improvements.yml | 5 ++ plugins/modules/cloud/linode/linode.py | 71 +++++++++---------- tests/sanity/ignore-2.10.txt | 3 - tests/sanity/ignore-2.11.txt | 3 - tests/sanity/ignore-2.12.txt | 3 - tests/sanity/ignore-2.9.txt | 2 - 6 files changed, 39 insertions(+), 48 deletions(-) create mode 100644 changelogs/fragments/2410-linode-improvements.yml diff --git a/changelogs/fragments/2410-linode-improvements.yml b/changelogs/fragments/2410-linode-improvements.yml new file mode 100644 index 0000000000..cdf8551b08 --- /dev/null +++ b/changelogs/fragments/2410-linode-improvements.yml @@ -0,0 +1,5 @@ +deprecated_features: + - linode - parameter ``backupsenabled`` is deprecated and will be removed in community.general 5.0.0 (https://github.com/ansible-collections/community.general/pull/2410). +minor_changes: + - linode - added proper traceback when failing due to exceptions (https://github.com/ansible-collections/community.general/pull/2410). + - linode - parameter ``additional_disks`` is now validated as a list of dictionaries (https://github.com/ansible-collections/community.general/pull/2410). diff --git a/plugins/modules/cloud/linode/linode.py b/plugins/modules/cloud/linode/linode.py index a35b25b6c7..c9ee0e61ed 100644 --- a/plugins/modules/cloud/linode/linode.py +++ b/plugins/modules/cloud/linode/linode.py @@ -21,8 +21,10 @@ options: type: str api_key: description: - - Linode API key + - Linode API key. + - C(LINODE_API_KEY) env variable can be used instead. type: str + required: yes name: description: - Name to give the instance (alphanumeric, dashes, underscore). @@ -46,6 +48,7 @@ options: - List of dictionaries for creating additional disks that are added to the Linode configuration settings. - Dictionary takes Size, Label, Type. Size is in MB. type: list + elements: dict alert_bwin_enabled: description: - Set status of bandwidth in alerts. @@ -86,9 +89,18 @@ options: description: - Set threshold for average IO ops/sec over 2 hour period. type: int + backupsenabled: + description: + - Deprecated parameter, it will be removed in community.general C(5.0.0). + - To enable backups pass values to either I(backupweeklyday) or I(backupwindow). + type: int backupweeklyday: description: - - Integer value for what day of the week to store weekly backups. + - Day of the week to take backups. + type: int + backupwindow: + description: + - The time window in which backups will be taken. type: int plan: description: @@ -153,7 +165,6 @@ author: notes: - Please note, linode-python does not have python 3 support. - This module uses the now deprecated v3 of the Linode API. - - C(LINODE_API_KEY) env variable can be used instead. - Please review U(https://www.linode.com/api/linode) for determining the required parameters. ''' @@ -262,7 +273,6 @@ EXAMPLES = ''' delegate_to: localhost ''' -import os import time import traceback @@ -274,7 +284,7 @@ except ImportError: LINODE_IMP_ERR = traceback.format_exc() HAS_LINODE = False -from ansible.module_utils.basic import AnsibleModule, missing_required_lib +from ansible.module_utils.basic import AnsibleModule, missing_required_lib, env_fallback def randompass(): @@ -358,7 +368,7 @@ def linodeServers(module, api, state, name, if not servers: for arg in (name, plan, distribution, datacenter): if not arg: - module.fail_json(msg='%s is required for %s state' % (arg, state)) # @TODO use required_if instead + module.fail_json(msg='%s is required for %s state' % (arg, state)) # Create linode entity new_server = True @@ -383,7 +393,7 @@ def linodeServers(module, api, state, name, try: res = api.linode_ip_addprivate(LinodeID=linode_id) except Exception as e: - module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE']) + module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE'], exception=traceback.format_exc()) if not disks: for arg in (name, linode_id, distribution): @@ -428,7 +438,7 @@ def linodeServers(module, api, state, name, jobs.append(res['JobID']) except Exception as e: # TODO: destroy linode ? - module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE']) + module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE'], exception=traceback.format_exc()) if not configs: for arg in (name, linode_id, distribution): @@ -471,7 +481,7 @@ def linodeServers(module, api, state, name, Disklist=disks_list, Label='%s config' % name) configs = api.linode_config_list(LinodeId=linode_id) except Exception as e: - module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE']) + module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE'], exception=traceback.format_exc()) # Start / Ensure servers are running for server in servers: @@ -517,10 +527,7 @@ def linodeServers(module, api, state, name, instance['password'] = password instances.append(instance) - elif state in ('stopped'): - if not linode_id: - module.fail_json(msg='linode_id is required for stopped state') - + elif state in ('stopped',): if not servers: module.fail_json(msg='Server (lid: %s) not found' % (linode_id)) @@ -530,17 +537,14 @@ def linodeServers(module, api, state, name, try: res = api.linode_shutdown(LinodeId=linode_id) except Exception as e: - module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE']) + module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE'], exception=traceback.format_exc()) instance['status'] = 'Stopping' changed = True else: instance['status'] = 'Stopped' instances.append(instance) - elif state in ('restarted'): - if not linode_id: - module.fail_json(msg='linode_id is required for restarted state') - + elif state in ('restarted',): if not servers: module.fail_json(msg='Server (lid: %s) not found' % (linode_id)) @@ -549,7 +553,7 @@ def linodeServers(module, api, state, name, try: res = api.linode_reboot(LinodeId=server['LINODEID']) except Exception as e: - module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE']) + module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE'], exception=traceback.format_exc()) instance['status'] = 'Restarting' changed = True instances.append(instance) @@ -560,7 +564,7 @@ def linodeServers(module, api, state, name, try: api.linode_delete(LinodeId=server['LINODEID'], skipChecks=True) except Exception as e: - module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE']) + module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE'], exception=traceback.format_exc()) instance['status'] = 'Deleting' changed = True instances.append(instance) @@ -577,7 +581,7 @@ def main(): argument_spec=dict( state=dict(type='str', default='present', choices=['absent', 'active', 'deleted', 'present', 'restarted', 'started', 'stopped']), - api_key=dict(type='str', no_log=True), + api_key=dict(type='str', no_log=True, required=True, fallback=(env_fallback, ['LINODE_API_KEY'])), name=dict(type='str', required=True), alert_bwin_enabled=dict(type='bool'), alert_bwin_threshold=dict(type='int'), @@ -589,12 +593,12 @@ def main(): alert_cpu_threshold=dict(type='int'), alert_diskio_enabled=dict(type='bool'), alert_diskio_threshold=dict(type='int'), - backupsenabled=dict(type='int'), + backupsenabled=dict(type='int', removed_in_version='5.0.0', removed_from_collection='community.general'), backupweeklyday=dict(type='int'), backupwindow=dict(type='int'), displaygroup=dict(type='str', default=''), plan=dict(type='int'), - additional_disks=dict(type='list'), + additional_disks=dict(type='list', elements='dict'), distribution=dict(type='int'), datacenter=dict(type='int'), kernel_id=dict(type='int'), @@ -608,6 +612,10 @@ def main(): wait_timeout=dict(type='int', default=300), watchdog=dict(type='bool', default=True), ), + required_if=[ + ('state', 'restarted', ['linode_id']), + ('state', 'stopped', ['linode_id']), + ] ) if not HAS_LINODE: @@ -626,7 +634,6 @@ def main(): alert_cpu_threshold = module.params.get('alert_cpu_threshold') alert_diskio_enabled = module.params.get('alert_diskio_enabled') alert_diskio_threshold = module.params.get('alert_diskio_threshold') - backupsenabled = module.params.get('backupsenabled') backupweeklyday = module.params.get('backupweeklyday') backupwindow = module.params.get('backupwindow') displaygroup = module.params.get('displaygroup') @@ -642,10 +649,9 @@ def main(): ssh_pub_key = module.params.get('ssh_pub_key') swap = module.params.get('swap') wait = module.params.get('wait') - wait_timeout = int(module.params.get('wait_timeout')) + wait_timeout = module.params.get('wait_timeout') watchdog = int(module.params.get('watchdog')) - kwargs = dict() check_items = dict( alert_bwin_enabled=alert_bwin_enabled, alert_bwin_threshold=alert_bwin_threshold, @@ -661,23 +667,14 @@ def main(): backupwindow=backupwindow, ) - for key, value in check_items.items(): - if value is not None: - kwargs[key] = value - - # Setup the api_key - if not api_key: - try: - api_key = os.environ['LINODE_API_KEY'] - except KeyError as e: - module.fail_json(msg='Unable to load %s' % e.message) + kwargs = dict((k, v) for k, v in check_items.items() if v is not None) # setup the auth try: api = linode_api.Api(api_key) api.test_echo() except Exception as e: - module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE']) + module.fail_json(msg='%s' % e.value[0]['ERRORMESSAGE'], exception=traceback.format_exc()) linodeServers(module, api, state, name, displaygroup, plan, diff --git a/tests/sanity/ignore-2.10.txt b/tests/sanity/ignore-2.10.txt index 7beedfa206..7af6144507 100644 --- a/tests/sanity/ignore-2.10.txt +++ b/tests/sanity/ignore-2.10.txt @@ -3,9 +3,6 @@ plugins/module_utils/compat/ipaddress.py no-assert plugins/module_utils/compat/ipaddress.py no-unicode-literals plugins/module_utils/_mount.py future-import-boilerplate plugins/module_utils/_mount.py metaclass-boilerplate -plugins/modules/cloud/linode/linode.py validate-modules:parameter-list-no-elements -plugins/modules/cloud/linode/linode.py validate-modules:parameter-type-not-in-doc -plugins/modules/cloud/linode/linode.py validate-modules:undocumented-parameter plugins/modules/cloud/lxc/lxc_container.py use-argspec-type-path plugins/modules/cloud/lxc/lxc_container.py validate-modules:use-run-command-not-popen plugins/modules/cloud/misc/rhevm.py validate-modules:parameter-state-invalid-choice diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 80975cf389..1df87b7e33 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -2,9 +2,6 @@ plugins/module_utils/compat/ipaddress.py no-assert plugins/module_utils/compat/ipaddress.py no-unicode-literals plugins/module_utils/_mount.py future-import-boilerplate plugins/module_utils/_mount.py metaclass-boilerplate -plugins/modules/cloud/linode/linode.py validate-modules:parameter-list-no-elements -plugins/modules/cloud/linode/linode.py validate-modules:parameter-type-not-in-doc -plugins/modules/cloud/linode/linode.py validate-modules:undocumented-parameter plugins/modules/cloud/lxc/lxc_container.py use-argspec-type-path plugins/modules/cloud/lxc/lxc_container.py validate-modules:use-run-command-not-popen plugins/modules/cloud/misc/rhevm.py validate-modules:parameter-state-invalid-choice diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index 68684f000d..c111c750a8 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -2,9 +2,6 @@ plugins/module_utils/compat/ipaddress.py no-assert plugins/module_utils/compat/ipaddress.py no-unicode-literals plugins/module_utils/_mount.py future-import-boilerplate plugins/module_utils/_mount.py metaclass-boilerplate -plugins/modules/cloud/linode/linode.py validate-modules:parameter-list-no-elements -plugins/modules/cloud/linode/linode.py validate-modules:parameter-type-not-in-doc -plugins/modules/cloud/linode/linode.py validate-modules:undocumented-parameter plugins/modules/cloud/lxc/lxc_container.py use-argspec-type-path plugins/modules/cloud/lxc/lxc_container.py validate-modules:use-run-command-not-popen plugins/modules/cloud/misc/rhevm.py validate-modules:parameter-state-invalid-choice diff --git a/tests/sanity/ignore-2.9.txt b/tests/sanity/ignore-2.9.txt index 36a0c3e08e..c6c1afcdd4 100644 --- a/tests/sanity/ignore-2.9.txt +++ b/tests/sanity/ignore-2.9.txt @@ -3,8 +3,6 @@ plugins/module_utils/compat/ipaddress.py no-assert plugins/module_utils/compat/ipaddress.py no-unicode-literals plugins/module_utils/_mount.py future-import-boilerplate plugins/module_utils/_mount.py metaclass-boilerplate -plugins/modules/cloud/linode/linode.py validate-modules:parameter-type-not-in-doc -plugins/modules/cloud/linode/linode.py validate-modules:undocumented-parameter plugins/modules/cloud/lxc/lxc_container.py use-argspec-type-path plugins/modules/cloud/lxc/lxc_container.py validate-modules:use-run-command-not-popen plugins/modules/cloud/online/online_server_info.py validate-modules:return-syntax-error From f5594aefd5e569e62297f0e181b86e2fe32e1667 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 12 May 2021 18:19:03 +0200 Subject: [PATCH 048/139] influxdb_retention_policy - add state argument to module spec (#2383) (#2385) (#2497) * influxdb_retention_policy: add state option to module argument spec * influxdb_retention_policy: simplify duration parsing logic (suggested in #2284) * add changelog * fix documentation and changelog * add constants for duration and sgduration validations * restyle ansible module spec Co-authored-by: Felix Fontein * improve changelog Co-authored-by: Felix Fontein * set changed result in check mode for state absent * remove required flag in optional module arguments * influxdb_retention_policy: improve examples readability Co-authored-by: Felix Fontein (cherry picked from commit 83a0c32269210c33c978ecf1a11096608ff91a20) Co-authored-by: Xabier Napal --- ...uxdb_retention_policy-add-state-option.yml | 6 + .../influxdb/influxdb_retention_policy.py | 132 ++++++++++++------ 2 files changed, 92 insertions(+), 46 deletions(-) create mode 100644 changelogs/fragments/2383-influxdb_retention_policy-add-state-option.yml diff --git a/changelogs/fragments/2383-influxdb_retention_policy-add-state-option.yml b/changelogs/fragments/2383-influxdb_retention_policy-add-state-option.yml new file mode 100644 index 0000000000..b8e358848e --- /dev/null +++ b/changelogs/fragments/2383-influxdb_retention_policy-add-state-option.yml @@ -0,0 +1,6 @@ +minor_changes: + - influxdb_retention_policy - add ``state`` parameter with allowed values + ``present`` and ``absent`` to support deletion of existing retention policies + (https://github.com/ansible-collections/community.general/issues/2383). + - influxdb_retention_policy - simplify duration logic parsing + (https://github.com/ansible-collections/community.general/pull/2385). diff --git a/plugins/modules/database/influxdb/influxdb_retention_policy.py b/plugins/modules/database/influxdb/influxdb_retention_policy.py index 883adaffa6..3ff48cbad0 100644 --- a/plugins/modules/database/influxdb/influxdb_retention_policy.py +++ b/plugins/modules/database/influxdb/influxdb_retention_policy.py @@ -29,17 +29,24 @@ options: - Name of the retention policy. required: true type: str + state: + description: + - State of the retention policy. + choices: [ absent, present ] + default: present + type: str + version_added: 3.1.0 duration: description: - Determines how long InfluxDB should keep the data. If specified, it should be C(INF) or at least one hour. If not specified, C(INF) is assumed. Supports complex duration expressions with multiple units. - required: true + - Required only if I(state) is set to C(present). type: str replication: description: - Determines how many independent copies of each point are stored in the cluster. - required: true + - Required only if I(state) is set to C(present). type: int default: description: @@ -63,53 +70,65 @@ EXAMPLES = r''' # Example influxdb_retention_policy command from Ansible Playbooks - name: Create 1 hour retention policy community.general.influxdb_retention_policy: - hostname: "{{influxdb_ip_address}}" - database_name: "{{influxdb_database_name}}" + hostname: "{{ influxdb_ip_address }}" + database_name: "{{ influxdb_database_name }}" policy_name: test duration: 1h replication: 1 ssl: yes validate_certs: yes + state: present - name: Create 1 day retention policy with 1 hour shard group duration community.general.influxdb_retention_policy: - hostname: "{{influxdb_ip_address}}" - database_name: "{{influxdb_database_name}}" + hostname: "{{ influxdb_ip_address }}" + database_name: "{{ influxdb_database_name }}" policy_name: test duration: 1d replication: 1 shard_group_duration: 1h + state: present - name: Create 1 week retention policy with 1 day shard group duration community.general.influxdb_retention_policy: - hostname: "{{influxdb_ip_address}}" - database_name: "{{influxdb_database_name}}" + hostname: "{{ influxdb_ip_address }}" + database_name: "{{ influxdb_database_name }}" policy_name: test duration: 1w replication: 1 shard_group_duration: 1d + state: present - name: Create infinite retention policy with 1 week of shard group duration community.general.influxdb_retention_policy: - hostname: "{{influxdb_ip_address}}" - database_name: "{{influxdb_database_name}}" + hostname: "{{ influxdb_ip_address }}" + database_name: "{{ influxdb_database_name }}" policy_name: test duration: INF replication: 1 ssl: no validate_certs: no shard_group_duration: 1w + state: present - name: Create retention policy with complex durations community.general.influxdb_retention_policy: - hostname: "{{influxdb_ip_address}}" - database_name: "{{influxdb_database_name}}" + hostname: "{{ influxdb_ip_address }}" + database_name: "{{ influxdb_database_name }}" policy_name: test duration: 5d1h30m replication: 1 ssl: no validate_certs: no shard_group_duration: 1d10h30m + state: present + +- name: Drop retention policy + community.general.influxdb_retention_policy: + hostname: "{{ influxdb_ip_address }}" + database_name: "{{ influxdb_database_name }}" + policy_name: test + state: absent ''' RETURN = r''' @@ -134,6 +153,21 @@ VALID_DURATION_REGEX = re.compile(r'^(INF|(\d+(ns|u|µ|ms|s|m|h|d|w)))+$') DURATION_REGEX = re.compile(r'(\d+)(ns|u|µ|ms|s|m|h|d|w)') EXTENDED_DURATION_REGEX = re.compile(r'(?:(\d+)(ns|u|µ|ms|m|h|d|w)|(\d+(?:\.\d+)?)(s))') +DURATION_UNIT_NANOSECS = { + 'ns': 1, + 'u': 1000, + 'µ': 1000, + 'ms': 1000 * 1000, + 's': 1000 * 1000 * 1000, + 'm': 1000 * 1000 * 1000 * 60, + 'h': 1000 * 1000 * 1000 * 60 * 60, + 'd': 1000 * 1000 * 1000 * 60 * 60 * 24, + 'w': 1000 * 1000 * 1000 * 60 * 60 * 24 * 7, +} + +MINIMUM_VALID_DURATION = 1 * DURATION_UNIT_NANOSECS['h'] +MINIMUM_VALID_SHARD_GROUP_DURATION = 1 * DURATION_UNIT_NANOSECS['h'] + def check_duration_literal(value): return VALID_DURATION_REGEX.search(value) is not None @@ -148,28 +182,9 @@ def parse_duration_literal(value, extended=False): lookup = (EXTENDED_DURATION_REGEX if extended else DURATION_REGEX).findall(value) for duration_literal in lookup: - if extended and duration_literal[3] == 's': - duration_val = float(duration_literal[2]) - duration += duration_val * 1000 * 1000 * 1000 - else: - duration_val = int(duration_literal[0]) - - if duration_literal[1] == 'ns': - duration += duration_val - elif duration_literal[1] == 'u' or duration_literal[1] == 'µ': - duration += duration_val * 1000 - elif duration_literal[1] == 'ms': - duration += duration_val * 1000 * 1000 - elif duration_literal[1] == 's': - duration += duration_val * 1000 * 1000 * 1000 - elif duration_literal[1] == 'm': - duration += duration_val * 1000 * 1000 * 1000 * 60 - elif duration_literal[1] == 'h': - duration += duration_val * 1000 * 1000 * 1000 * 60 * 60 - elif duration_literal[1] == 'd': - duration += duration_val * 1000 * 1000 * 1000 * 60 * 60 * 24 - elif duration_literal[1] == 'w': - duration += duration_val * 1000 * 1000 * 1000 * 60 * 60 * 24 * 7 + filtered_literal = list(filter(None, duration_literal)) + duration_val = float(filtered_literal[0]) + duration += duration_val * DURATION_UNIT_NANOSECS[filtered_literal[1]] return duration @@ -208,7 +223,7 @@ def create_retention_policy(module, client): module.fail_json(msg="Failed to parse value of duration") influxdb_duration_format = parse_duration_literal(duration) - if influxdb_duration_format != 0 and influxdb_duration_format < 3600000000000: + if influxdb_duration_format != 0 and influxdb_duration_format < MINIMUM_VALID_DURATION: module.fail_json(msg="duration value must be at least 1h") if shard_group_duration is not None: @@ -216,7 +231,7 @@ def create_retention_policy(module, client): module.fail_json(msg="Failed to parse value of shard_group_duration") influxdb_shard_group_duration_format = parse_duration_literal(shard_group_duration) - if influxdb_shard_group_duration_format < 3600000000000: + if influxdb_shard_group_duration_format < MINIMUM_VALID_SHARD_GROUP_DURATION: module.fail_json(msg="shard_group_duration value must be finite and at least 1h") if not module.check_mode: @@ -245,7 +260,7 @@ def alter_retention_policy(module, client, retention_policy): module.fail_json(msg="Failed to parse value of duration") influxdb_duration_format = parse_duration_literal(duration) - if influxdb_duration_format != 0 and influxdb_duration_format < 3600000000000: + if influxdb_duration_format != 0 and influxdb_duration_format < MINIMUM_VALID_DURATION: module.fail_json(msg="duration value must be at least 1h") if shard_group_duration is None: @@ -255,7 +270,7 @@ def alter_retention_policy(module, client, retention_policy): module.fail_json(msg="Failed to parse value of shard_group_duration") influxdb_shard_group_duration_format = parse_duration_literal(shard_group_duration) - if influxdb_shard_group_duration_format < 3600000000000: + if influxdb_shard_group_duration_format < MINIMUM_VALID_SHARD_GROUP_DURATION: module.fail_json(msg="shard_group_duration value must be finite and at least 1h") if (retention_policy['duration'] != influxdb_duration_format or @@ -272,30 +287,55 @@ def alter_retention_policy(module, client, retention_policy): module.exit_json(changed=changed) +def drop_retention_policy(module, client): + database_name = module.params['database_name'] + policy_name = module.params['policy_name'] + + if not module.check_mode: + try: + client.drop_retention_policy(policy_name, database_name) + except exceptions.InfluxDBClientError as e: + module.fail_json(msg=e.content) + module.exit_json(changed=True) + + def main(): argument_spec = InfluxDb.influxdb_argument_spec() argument_spec.update( + state=dict(default='present', type='str', choices=['present', 'absent']), database_name=dict(required=True, type='str'), policy_name=dict(required=True, type='str'), - duration=dict(required=True, type='str'), - replication=dict(required=True, type='int'), + duration=dict(type='str'), + replication=dict(type='int'), default=dict(default=False, type='bool'), - shard_group_duration=dict(required=False, type='str'), + shard_group_duration=dict(type='str'), ) module = AnsibleModule( argument_spec=argument_spec, - supports_check_mode=True + supports_check_mode=True, + required_if=( + ('state', 'present', ['duration', 'replication']), + ), ) + state = module.params['state'] + influxdb = InfluxDb(module) client = influxdb.connect_to_influxdb() retention_policy = find_retention_policy(module, client) - if retention_policy: - alter_retention_policy(module, client, retention_policy) - else: - create_retention_policy(module, client) + if state == 'present': + if retention_policy: + alter_retention_policy(module, client, retention_policy) + else: + create_retention_policy(module, client) + + if state == 'absent': + if retention_policy: + drop_retention_policy(module, client) + else: + module.exit_json(changed=False) if __name__ == '__main__': From ad5482f63d50dc886d793b2f573efcc21e050853 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 14 May 2021 09:47:39 +0200 Subject: [PATCH 049/139] Add proxmox_nic module (#2449) (#2502) * Add proxmox_nic module Add proxmox_nic module to manage NIC's on Qemu(KVM) VM's in a Proxmox VE cluster. Update proxmox integration tests and add tests for proxmox_nic module. This partially solves https://github.com/ansible-collections/community.general/issues/1964#issuecomment-790499397 and allows for adding/updating/deleting network interface cards after creating/cloning a VM. The proxmox_nic module will keep MAC-addresses the same when updating a NIC. It only changes when explicitly setting a MAC-address. * Apply suggestions from code review Co-authored-by: Felix Fontein * Add check_mode and implement review comments - check_mode added - some documentation updates - when MTU is set, check if the model is virtio, else fail - trunks can now be provided as list of ints instead of vlanid[;vlanid...] * Make returns on update_nic and delete_nic more readable Co-authored-by: Felix Fontein * Increase readability on update_nic and delete_nic * Implement check in get_vmid - get_vmid will now fail when multiple vmid's are returned as proxmox doesn't guarantee uniqueness - remove an unused import - fix a typo in an error message * Add some error checking to get_vmid - get_vmid will now return the error message when proxmoxer fails - get_vmid will return the vmid directly instead of a list of one - Some minor documentation updates * Warn instead of fail when setting mtu on unsupported nic - When setting the MTU on an unsupported NIC model (virtio is the only supported model) this module will now print a warning instead of failing. - Some minor documentation updates. * Take advantage of proxmox_auth_argument_spec Make use of proxmox_auth_argument_spec from plugins/module_utils/proxmox.py This provides some extra environment fallbacks. * Add blank line to conform with pep8 Co-authored-by: Felix Fontein (cherry picked from commit 23dda56913c19fdd8f1156be9496b7762fc7c11a) Co-authored-by: Kogelvis --- plugins/modules/cloud/misc/proxmox_nic.py | 349 ++++++++++++++++++ plugins/modules/proxmox_nic.py | 1 + .../targets/proxmox/tasks/main.yml | 88 ++++- 3 files changed, 437 insertions(+), 1 deletion(-) create mode 100644 plugins/modules/cloud/misc/proxmox_nic.py create mode 120000 plugins/modules/proxmox_nic.py diff --git a/plugins/modules/cloud/misc/proxmox_nic.py b/plugins/modules/cloud/misc/proxmox_nic.py new file mode 100644 index 0000000000..a9c9f14ddc --- /dev/null +++ b/plugins/modules/cloud/misc/proxmox_nic.py @@ -0,0 +1,349 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2021, Lammert Hellinga (@Kogelvis) +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: proxmox_nic +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. +author: "Lammert Hellinga (@Kogelvis) " +options: + bridge: + description: + - Add this interface to the specified bridge device. The Proxmox VE default bridge is called C(vmbr0). + type: str + firewall: + description: + - Whether this interface should be protected by the firewall. + type: bool + default: false + interface: + description: + - Name of the interface, should be C(net[n]) where C(1 ≤ n ≤ 31). + type: str + required: true + link_down: + description: + - Whether this interface should be disconnected (like pulling the plug). + type: bool + default: false + mac: + description: + - C(XX:XX:XX:XX:XX:XX) should be a unique MAC address. This is automatically generated if not specified. + - When not specified this module will keep the MAC address the same when changing an existing interface. + type: str + model: + description: + - The NIC emulator model. + type: str + choices: ['e1000', 'e1000-82540em', 'e1000-82544gc', 'e1000-82545em', 'i82551', 'i82557b', 'i82559er', 'ne2k_isa', 'ne2k_pci', 'pcnet', + 'rtl8139', 'virtio', 'vmxnet3'] + default: virtio + mtu: + description: + - Force MTU, for C(virtio) model only, setting will be ignored otherwise. + - Set to C(1) to use the bridge MTU. + - Value should be C(1 ≤ n ≤ 65520). + type: int + name: + description: + - Specifies the VM name. Only used on the configuration web interface. + - Required only for I(state=present). + type: str + queues: + description: + - Number of packet queues to be used on the device. + - Value should be C(0 ≤ n ≤ 16). + type: int + rate: + description: + - Rate limit in MBps (MegaBytes per second) as floating point number. + type: float + state: + description: + - Indicates desired state of the NIC. + type: str + choices: ['present', 'absent'] + default: present + tag: + description: + - VLAN tag to apply to packets on this interface. + - Value should be C(1 ≤ n ≤ 4094). + type: int + trunks: + description: + - List of VLAN trunks to pass through this interface. + type: list + elements: int + vmid: + description: + - Specifies the instance ID. + type: int +extends_documentation_fragment: + - community.general.proxmox.documentation +''' + +EXAMPLES = ''' +- name: Create NIC net0 targeting the vm by name + community.general.proxmox_nic: + api_user: root@pam + api_password: secret + api_host: proxmoxhost + name: my_vm + interface: net0 + bridge: vmbr0 + tag: 3 + +- name: Create NIC net0 targeting the vm by id + community.general.proxmox_nic: + api_user: root@pam + api_password: secret + api_host: proxmoxhost + vmid: 103 + interface: net0 + bridge: vmbr0 + mac: "12:34:56:C0:FF:EE" + firewall: true + +- name: Delete NIC net0 targeting the vm by name + community.general.proxmox_nic: + api_user: root@pam + api_password: secret + api_host: proxmoxhost + name: my_vm + interface: net0 + state: absent +''' + +RETURN = ''' +vmid: + description: The VM vmid. + returned: success + type: int + sample: 115 +msg: + description: A short message + returned: always + type: str + sample: "Nic net0 unchanged on VM with vmid 103" +''' + +try: + from proxmoxer import ProxmoxAPI + HAS_PROXMOXER = True +except ImportError: + HAS_PROXMOXER = False + +from ansible.module_utils.basic import AnsibleModule, env_fallback +from ansible_collections.community.general.plugins.module_utils.proxmox import proxmox_auth_argument_spec + + +def get_vmid(module, proxmox, name): + try: + vms = [vm['vmid'] for vm in proxmox.cluster.resources.get(type='vm') if vm.get('name') == name] + except Exception as e: + module.fail_json(msg='Error: %s occurred while retrieving VM with name = %s' % (e, name)) + + if not vms: + module.fail_json(msg='No VM found with name: %s' % name) + elif len(vms) > 1: + module.fail_json(msg='Multiple VMs found with name: %s, provide vmid instead' % name) + + return vms[0] + + +def get_vm(proxmox, vmid): + return [vm for vm in proxmox.cluster.resources.get(type='vm') if vm['vmid'] == int(vmid)] + + +def update_nic(module, proxmox, vmid, interface, model, **kwargs): + vm = get_vm(proxmox, vmid) + + try: + vminfo = proxmox.nodes(vm[0]['node']).qemu(vmid).config.get() + except Exception as e: + module.fail_json(msg='Getting information for VM with vmid = %s failed with exception: %s' % (vmid, e)) + + if interface in vminfo: + # Convert the current config to a dictionary + config = vminfo[interface].split(',') + config.sort() + + config_current = {} + + for i in config: + kv = i.split('=') + try: + config_current[kv[0]] = kv[1] + except IndexError: + config_current[kv[0]] = '' + + # determine the current model nic and mac-address + models = ['e1000', 'e1000-82540em', 'e1000-82544gc', 'e1000-82545em', 'i82551', 'i82557b', + 'i82559er', 'ne2k_isa', 'ne2k_pci', 'pcnet', 'rtl8139', 'virtio', 'vmxnet3'] + current_model = set(models) & set(config_current.keys()) + current_model = current_model.pop() + current_mac = config_current[current_model] + + # build nic config string + config_provided = "{0}={1}".format(model, current_mac) + else: + config_provided = model + + if kwargs['mac']: + config_provided = "{0}={1}".format(model, kwargs['mac']) + + if kwargs['bridge']: + config_provided += ",bridge={0}".format(kwargs['bridge']) + + if kwargs['firewall']: + config_provided += ",firewall=1" + + if kwargs['link_down']: + config_provided += ',link_down=1' + + if kwargs['mtu']: + if model == 'virtio': + config_provided += ",mtu={0}".format(kwargs['mtu']) + else: + module.warn( + 'Ignoring MTU for nic {0} on VM with vmid {1}, ' + 'model should be set to \'virtio\': '.format(interface, vmid)) + + if kwargs['queues']: + config_provided += ",queues={0}".format(kwargs['queues']) + + if kwargs['rate']: + config_provided += ",rate={0}".format(kwargs['rate']) + + if kwargs['tag']: + config_provided += ",tag={0}".format(kwargs['tag']) + + if kwargs['trunks']: + config_provided += ",trunks={0}".format(';'.join(str(x) for x in kwargs['trunks'])) + + net = {interface: config_provided} + vm = get_vm(proxmox, vmid) + + if ((interface not in vminfo) or (vminfo[interface] != config_provided)): + if not module.check_mode: + proxmox.nodes(vm[0]['node']).qemu(vmid).config.set(**net) + return True + + return False + + +def delete_nic(module, proxmox, vmid, interface): + vm = get_vm(proxmox, vmid) + vminfo = proxmox.nodes(vm[0]['node']).qemu(vmid).config.get() + + if interface in vminfo: + if not module.check_mode: + proxmox.nodes(vm[0]['node']).qemu(vmid).config.set(vmid=vmid, delete=interface) + return True + + return False + + +def main(): + module_args = proxmox_auth_argument_spec() + nic_args = dict( + bridge=dict(type='str'), + firewall=dict(type='bool', default=False), + interface=dict(type='str', required=True), + link_down=dict(type='bool', default=False), + mac=dict(type='str'), + model=dict(choices=['e1000', 'e1000-82540em', 'e1000-82544gc', 'e1000-82545em', + 'i82551', 'i82557b', 'i82559er', 'ne2k_isa', 'ne2k_pci', 'pcnet', + 'rtl8139', 'virtio', 'vmxnet3'], default='virtio'), + mtu=dict(type='int'), + name=dict(type='str'), + queues=dict(type='int'), + rate=dict(type='float'), + state=dict(default='present', choices=['present', 'absent']), + tag=dict(type='int'), + trunks=dict(type='list', elements='int'), + vmid=dict(type='int'), + ) + module_args.update(nic_args) + + module = AnsibleModule( + argument_spec=module_args, + required_together=[('api_token_id', 'api_token_secret')], + required_one_of=[('name', 'vmid'), ('api_password', 'api_token_id')], + supports_check_mode=True, + ) + + if not HAS_PROXMOXER: + module.fail_json(msg='proxmoxer required for this module') + + api_host = module.params['api_host'] + api_password = module.params['api_password'] + api_token_id = module.params['api_token_id'] + api_token_secret = module.params['api_token_secret'] + api_user = module.params['api_user'] + interface = module.params['interface'] + model = module.params['model'] + name = module.params['name'] + state = module.params['state'] + validate_certs = module.params['validate_certs'] + vmid = module.params['vmid'] + + auth_args = {'user': api_user} + if not (api_token_id and api_token_secret): + auth_args['password'] = api_password + else: + auth_args['token_name'] = api_token_id + auth_args['token_value'] = api_token_secret + + try: + proxmox = ProxmoxAPI(api_host, verify_ssl=validate_certs, **auth_args) + except Exception as e: + module.fail_json(msg='authorization on proxmox cluster failed with exception: %s' % e) + + # If vmid is not defined then retrieve its value from the vm name, + if not vmid: + vmid = get_vmid(module, proxmox, name) + + # Ensure VM id exists + if not get_vm(proxmox, vmid): + module.fail_json(vmid=vmid, msg='VM with vmid = %s does not exist in cluster' % vmid) + + if state == 'present': + try: + if update_nic(module, proxmox, vmid, interface, model, + bridge=module.params['bridge'], + firewall=module.params['firewall'], + link_down=module.params['link_down'], + mac=module.params['mac'], + mtu=module.params['mtu'], + queues=module.params['queues'], + rate=module.params['rate'], + tag=module.params['tag'], + trunks=module.params['trunks']): + module.exit_json(changed=True, vmid=vmid, msg="Nic {0} updated on VM with vmid {1}".format(interface, vmid)) + else: + module.exit_json(vmid=vmid, msg="Nic {0} unchanged on VM with vmid {1}".format(interface, vmid)) + except Exception as e: + module.fail_json(vmid=vmid, msg='Unable to change nic {0} on VM with vmid {1}: '.format(interface, vmid) + str(e)) + + elif state == 'absent': + try: + if delete_nic(module, proxmox, vmid, interface): + module.exit_json(changed=True, vmid=vmid, msg="Nic {0} deleted on VM with vmid {1}".format(interface, vmid)) + else: + module.exit_json(vmid=vmid, msg="Nic {0} does not exist on VM with vmid {1}".format(interface, vmid)) + except Exception as e: + module.fail_json(vmid=vmid, msg='Unable to delete nic {0} on VM with vmid {1}: '.format(interface, vmid) + str(e)) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/proxmox_nic.py b/plugins/modules/proxmox_nic.py new file mode 120000 index 0000000000..88756ab636 --- /dev/null +++ b/plugins/modules/proxmox_nic.py @@ -0,0 +1 @@ +cloud/misc/proxmox_nic.py \ No newline at end of file diff --git a/tests/integration/targets/proxmox/tasks/main.yml b/tests/integration/targets/proxmox/tasks/main.yml index 6301cb66ef..5954d3f11f 100644 --- a/tests/integration/targets/proxmox/tasks/main.yml +++ b/tests/integration/targets/proxmox/tasks/main.yml @@ -48,7 +48,7 @@ api_token_secret: "{{ api_token_secret | default(omit) }}" validate_certs: "{{ validate_certs }}" register: results - + - assert: that: - results is not changed @@ -226,6 +226,92 @@ - results_action_current.vmid == {{ vmid }} - results_action_current.msg == "VM test-instance with vmid = {{ vmid }} is running" +- name: VM add/change/delete NIC + tags: [ 'nic' ] + block: + - name: Add NIC to test VM + proxmox_nic: + api_host: "{{ api_host }}" + api_user: "{{ user }}@{{ domain }}" + api_password: "{{ api_password | default(omit) }}" + api_token_id: "{{ api_token_id | default(omit) }}" + api_token_secret: "{{ api_token_secret | default(omit) }}" + validate_certs: "{{ validate_certs }}" + vmid: "{{ vmid }}" + state: present + interface: net5 + bridge: vmbr0 + tag: 42 + register: results + + - assert: + that: + - results is changed + - results.vmid == {{ vmid }} + - results.msg == "Nic net5 updated on VM with vmid {{ vmid }}" + + - name: Update NIC no changes + proxmox_nic: + api_host: "{{ api_host }}" + api_user: "{{ user }}@{{ domain }}" + api_password: "{{ api_password | default(omit) }}" + api_token_id: "{{ api_token_id | default(omit) }}" + api_token_secret: "{{ api_token_secret | default(omit) }}" + validate_certs: "{{ validate_certs }}" + vmid: "{{ vmid }}" + state: present + interface: net5 + bridge: vmbr0 + tag: 42 + register: results + + - assert: + that: + - results is not changed + - results.vmid == {{ vmid }} + - results.msg == "Nic net5 unchanged on VM with vmid {{ vmid }}" + + - name: Update NIC with changes + proxmox_nic: + api_host: "{{ api_host }}" + api_user: "{{ user }}@{{ domain }}" + api_password: "{{ api_password | default(omit) }}" + api_token_id: "{{ api_token_id | default(omit) }}" + api_token_secret: "{{ api_token_secret | default(omit) }}" + validate_certs: "{{ validate_certs }}" + vmid: "{{ vmid }}" + state: present + interface: net5 + bridge: vmbr0 + tag: 24 + firewall: True + register: results + + - assert: + that: + - results is changed + - results.vmid == {{ vmid }} + - results.msg == "Nic net5 updated on VM with vmid {{ vmid }}" + + - name: Delete NIC + proxmox_nic: + api_host: "{{ api_host }}" + api_user: "{{ user }}@{{ domain }}" + api_password: "{{ api_password | default(omit) }}" + api_token_id: "{{ api_token_id | default(omit) }}" + api_token_secret: "{{ api_token_secret | default(omit) }}" + validate_certs: "{{ validate_certs }}" + vmid: "{{ vmid }}" + state: absent + interface: net5 + register: results + + - assert: + that: + - results is changed + - results.vmid == {{ vmid }} + - results.msg == "Nic net5 deleted on VM with vmid {{ vmid }}" + - name: VM stop tags: [ 'stop' ] block: From 6013c77c2bdd1fdfdeb4a650a5814efa79589fae Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 14 May 2021 09:47:53 +0200 Subject: [PATCH 050/139] Add groupby_as_dict filter (#2323) (#2503) * Add groupby_as_dict filter. * Test all error cases. (cherry picked from commit 384655e15c7e36e5b4c56578c534053404f9f1d1) Co-authored-by: Felix Fontein --- .../fragments/2323-groupby_as_dict-filter.yml | 3 ++ plugins/filter/groupby.py | 42 +++++++++++++++++ .../targets/filter_groupby/aliases | 2 + .../targets/filter_groupby/tasks/main.yml | 45 +++++++++++++++++++ .../targets/filter_groupby/vars/main.yml | 31 +++++++++++++ 5 files changed, 123 insertions(+) create mode 100644 changelogs/fragments/2323-groupby_as_dict-filter.yml create mode 100644 plugins/filter/groupby.py create mode 100644 tests/integration/targets/filter_groupby/aliases create mode 100644 tests/integration/targets/filter_groupby/tasks/main.yml create mode 100644 tests/integration/targets/filter_groupby/vars/main.yml diff --git a/changelogs/fragments/2323-groupby_as_dict-filter.yml b/changelogs/fragments/2323-groupby_as_dict-filter.yml new file mode 100644 index 0000000000..e72f323a60 --- /dev/null +++ b/changelogs/fragments/2323-groupby_as_dict-filter.yml @@ -0,0 +1,3 @@ +add plugin.filter: + - name: groupby_as_dict + description: Transform a sequence of dictionaries to a dictionary where the dictionaries are indexed by an attribute diff --git a/plugins/filter/groupby.py b/plugins/filter/groupby.py new file mode 100644 index 0000000000..a2a85aa905 --- /dev/null +++ b/plugins/filter/groupby.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2021, Felix Fontein +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.errors import AnsibleFilterError +from ansible.module_utils.common._collections_compat import Mapping, Sequence + + +def groupby_as_dict(sequence, attribute): + ''' + Given a sequence of dictionaries and an attribute name, returns a dictionary mapping + the value of this attribute to the dictionary. + + If multiple dictionaries in the sequence have the same value for this attribute, + the filter will fail. + ''' + if not isinstance(sequence, Sequence): + raise AnsibleFilterError('Input is not a sequence') + + result = dict() + for list_index, element in enumerate(sequence): + if not isinstance(element, Mapping): + raise AnsibleFilterError('Sequence element #{0} is not a mapping'.format(list_index)) + if attribute not in element: + raise AnsibleFilterError('Attribute not contained in element #{0} of sequence'.format(list_index)) + result_index = element[attribute] + if result_index in result: + raise AnsibleFilterError('Multiple sequence entries have attribute value {0!r}'.format(result_index)) + result[result_index] = element + return result + + +class FilterModule(object): + ''' Ansible list filters ''' + + def filters(self): + return { + 'groupby_as_dict': groupby_as_dict, + } diff --git a/tests/integration/targets/filter_groupby/aliases b/tests/integration/targets/filter_groupby/aliases new file mode 100644 index 0000000000..6e79abdd02 --- /dev/null +++ b/tests/integration/targets/filter_groupby/aliases @@ -0,0 +1,2 @@ +shippable/posix/group4 +skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller diff --git a/tests/integration/targets/filter_groupby/tasks/main.yml b/tests/integration/targets/filter_groupby/tasks/main.yml new file mode 100644 index 0000000000..29036a3bc5 --- /dev/null +++ b/tests/integration/targets/filter_groupby/tasks/main.yml @@ -0,0 +1,45 @@ +--- +- name: Test functionality + assert: + that: + - list1 | community.general.groupby_as_dict('name') == dict1 + +- name: 'Test error: not a list' + set_fact: + test: "{{ list_no_list | community.general.groupby_as_dict('name') }}" + ignore_errors: true + register: result + +- assert: + that: + - result.msg == 'Input is not a sequence' + +- name: 'Test error: list element not a mapping' + set_fact: + test: "{{ list_no_dict | community.general.groupby_as_dict('name') }}" + ignore_errors: true + register: result + +- assert: + that: + - "result.msg == 'Sequence element #0 is not a mapping'" + +- name: 'Test error: list element does not have attribute' + set_fact: + test: "{{ list_no_attribute | community.general.groupby_as_dict('name') }}" + ignore_errors: true + register: result + +- assert: + that: + - "result.msg == 'Attribute not contained in element #1 of sequence'" + +- name: 'Test error: attribute collision' + set_fact: + test: "{{ list_collision | community.general.groupby_as_dict('name') }}" + ignore_errors: true + register: result + +- assert: + that: + - result.msg == "Multiple sequence entries have attribute value 'a'" diff --git a/tests/integration/targets/filter_groupby/vars/main.yml b/tests/integration/targets/filter_groupby/vars/main.yml new file mode 100644 index 0000000000..15d38a351a --- /dev/null +++ b/tests/integration/targets/filter_groupby/vars/main.yml @@ -0,0 +1,31 @@ +--- +list1: + - name: a + x: y + - name: b + z: 1 + +dict1: + a: + name: a + x: y + b: + name: b + z: 1 + +list_no_list: + a: + name: a + +list_no_dict: + - [] + - 1 + +list_no_attribute: + - name: a + foo: baz + - foo: bar + +list_collision: + - name: a + - name: a From 145435cdd97242d6685d7223120a5c6b2ae4f6f1 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 14 May 2021 09:55:46 +0200 Subject: [PATCH 051/139] Deprecate nios content (#2458) (#2504) * Deprecate nios content. * Make 2.9's ansible-test happy. * Add module_utils deprecation. (cherry picked from commit ee9770cff720259cb781f0b1d9705f33a5d83fb1) Co-authored-by: Felix Fontein --- changelogs/fragments/nios-deprecation.yml | 2 + meta/runtime.yml | 88 ++++++++++++++++++- plugins/lookup/nios.py | 4 + plugins/lookup/nios_next_ip.py | 4 + plugins/lookup/nios_next_network.py | 4 + .../modules/net_tools/nios/nios_a_record.py | 4 + .../net_tools/nios/nios_aaaa_record.py | 4 + .../net_tools/nios/nios_cname_record.py | 4 + .../modules/net_tools/nios/nios_dns_view.py | 4 + .../net_tools/nios/nios_fixed_address.py | 4 + .../net_tools/nios/nios_host_record.py | 4 + plugins/modules/net_tools/nios/nios_member.py | 4 + .../modules/net_tools/nios/nios_mx_record.py | 4 + .../net_tools/nios/nios_naptr_record.py | 4 + .../modules/net_tools/nios/nios_network.py | 4 + .../net_tools/nios/nios_network_view.py | 4 + .../modules/net_tools/nios/nios_nsgroup.py | 4 + .../modules/net_tools/nios/nios_ptr_record.py | 4 + .../modules/net_tools/nios/nios_srv_record.py | 4 + .../modules/net_tools/nios/nios_txt_record.py | 4 + plugins/modules/net_tools/nios/nios_zone.py | 4 + tests/sanity/ignore-2.9.txt | 32 +++++++ 22 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/nios-deprecation.yml diff --git a/changelogs/fragments/nios-deprecation.yml b/changelogs/fragments/nios-deprecation.yml new file mode 100644 index 0000000000..bcfc2b4128 --- /dev/null +++ b/changelogs/fragments/nios-deprecation.yml @@ -0,0 +1,2 @@ +deprecated_features: +- "The nios, nios_next_ip, nios_next_network lookup plugins, the nios documentation fragment, and the nios_host_record, nios_ptr_record, nios_mx_record, nios_fixed_address, nios_zone, nios_member, nios_a_record, nios_aaaa_record, nios_network, nios_dns_view, nios_txt_record, nios_naptr_record, nios_srv_record, nios_cname_record, nios_nsgroup, and nios_network_view module have been deprecated and will be removed from community.general 5.0.0. Please install the `infoblox.nios_modules `_ collection instead and use its plugins and modules (https://github.com/ansible-collections/community.general/pull/2458)." diff --git a/meta/runtime.yml b/meta/runtime.yml index c116029974..e5b59bc046 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -37,6 +37,18 @@ plugin_routing: redirect: community.google.gcp_storage_file hashi_vault: redirect: community.hashi_vault.hashi_vault + nios: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios lookup plugin has been deprecated. Please use infoblox.nios_modules.nios_lookup instead. + nios_next_ip: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_next_ip lookup plugin has been deprecated. Please use infoblox.nios_modules.nios_next_ip instead. + nios_next_network: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_next_network lookup plugin has been deprecated. Please use infoblox.nios_modules.nios_next_network instead. modules: ali_instance_facts: tombstone: @@ -283,6 +295,70 @@ plugin_routing: tombstone: removal_version: 3.0.0 warning_text: Use netapp.ontap.na_ontap_info instead. + nios_a_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_a_record module has been deprecated. Please use infoblox.nios_modules.nios_a_record instead. + nios_aaaa_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_aaaa_record module has been deprecated. Please use infoblox.nios_modules.nios_aaaa_record instead. + nios_cname_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_cname_record module has been deprecated. Please use infoblox.nios_modules.nios_cname_record instead. + nios_dns_view: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_dns_view module has been deprecated. Please use infoblox.nios_modules.nios_dns_view instead. + nios_fixed_address: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_fixed_address module has been deprecated. Please use infoblox.nios_modules.nios_fixed_address instead. + nios_host_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_host_record module has been deprecated. Please use infoblox.nios_modules.nios_host_record instead. + nios_member: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_member module has been deprecated. Please use infoblox.nios_modules.nios_member instead. + nios_mx_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_mx_record module has been deprecated. Please use infoblox.nios_modules.nios_mx_record instead. + nios_naptr_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_naptr_record module has been deprecated. Please use infoblox.nios_modules.nios_naptr_record instead. + nios_network: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_network module has been deprecated. Please use infoblox.nios_modules.nios_network instead. + nios_network_view: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_network_view module has been deprecated. Please use infoblox.nios_modules.nios_network_view instead. + nios_nsgroup: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_nsgroup module has been deprecated. Please use infoblox.nios_modules.nios_nsgroup instead. + nios_ptr_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_ptr_record module has been deprecated. Please use infoblox.nios_modules.nios_ptr_record instead. + nios_srv_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_srv_record module has been deprecated. Please use infoblox.nios_modules.nios_srv_record instead. + nios_txt_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_txt_record module has been deprecated. Please use infoblox.nios_modules.nios_txt_record instead. + nios_zone: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_zone module has been deprecated. Please use infoblox.nios_modules.nios_zone instead. nginx_status_facts: tombstone: removal_version: 3.0.0 @@ -568,11 +644,13 @@ plugin_routing: redirect: community.kubevirt.kubevirt_common_options kubevirt_vm_options: redirect: community.kubevirt.kubevirt_vm_options + nios: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios document fragment has been deprecated. Please use infoblox.nios_modules.nios instead. postgresql: redirect: community.postgresql.postgresql module_utils: - remote_management.dellemc.dellemc_idrac: - redirect: dellemc.openmanage.dellemc_idrac docker.common: redirect: community.docker.common docker.swarm: @@ -587,6 +665,12 @@ plugin_routing: redirect: community.hrobot.robot kubevirt: redirect: community.kubevirt.kubevirt + net_tools.nios.api: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.net_tools.nios.api module_utils has been deprecated. Please use infoblox.nios_modules.api instead. + remote_management.dellemc.dellemc_idrac: + redirect: dellemc.openmanage.dellemc_idrac remote_management.dellemc.ome: redirect: dellemc.openmanage.ome postgresql: diff --git a/plugins/lookup/nios.py b/plugins/lookup/nios.py index 4b606e78ba..819d8077e6 100644 --- a/plugins/lookup/nios.py +++ b/plugins/lookup/nios.py @@ -25,6 +25,10 @@ DOCUMENTATION = ''' author: Unknown (!UNKNOWN) name: nios short_description: Query Infoblox NIOS objects +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding lookup from it. + alternative: infoblox.nios_modules.nios_lookup + removed_in: 5.0.0 description: - Uses the Infoblox WAPI API to fetch NIOS specified objects. This lookup supports adding additional keywords to filter the return data and specify diff --git a/plugins/lookup/nios_next_ip.py b/plugins/lookup/nios_next_ip.py index 5b979b8d07..21773cb53e 100644 --- a/plugins/lookup/nios_next_ip.py +++ b/plugins/lookup/nios_next_ip.py @@ -25,6 +25,10 @@ DOCUMENTATION = ''' author: Unknown (!UNKNOWN) name: nios_next_ip short_description: Return the next available IP address for a network +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding lookup from it. + alternative: infoblox.nios_modules.nios_next_ip + removed_in: 5.0.0 description: - Uses the Infoblox WAPI API to return the next available IP addresses for a given network CIDR diff --git a/plugins/lookup/nios_next_network.py b/plugins/lookup/nios_next_network.py index 84b230d1fe..2aa22ab704 100644 --- a/plugins/lookup/nios_next_network.py +++ b/plugins/lookup/nios_next_network.py @@ -25,6 +25,10 @@ DOCUMENTATION = ''' author: Unknown (!UNKNOWN) name: nios_next_network short_description: Return the next available network range for a network-container +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding lookup from it. + alternative: infoblox.nios_modules.nios_next_network + removed_in: 5.0.0 description: - Uses the Infoblox WAPI API to return the next available network addresses for a given network CIDR diff --git a/plugins/modules/net_tools/nios/nios_a_record.py b/plugins/modules/net_tools/nios/nios_a_record.py index 7e8b273024..b4adfe0103 100644 --- a/plugins/modules/net_tools/nios/nios_a_record.py +++ b/plugins/modules/net_tools/nios/nios_a_record.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_a_record author: "Blair Rampling (@brampling)" short_description: Configure Infoblox NIOS A records +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_a_record + removed_in: 5.0.0 description: - Adds and/or removes instances of A record objects from Infoblox NIOS servers. This module manages NIOS C(record:a) objects diff --git a/plugins/modules/net_tools/nios/nios_aaaa_record.py b/plugins/modules/net_tools/nios/nios_aaaa_record.py index d35b779f10..9b22f86948 100644 --- a/plugins/modules/net_tools/nios/nios_aaaa_record.py +++ b/plugins/modules/net_tools/nios/nios_aaaa_record.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_aaaa_record author: "Blair Rampling (@brampling)" short_description: Configure Infoblox NIOS AAAA records +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_aaaa_record + removed_in: 5.0.0 description: - Adds and/or removes instances of AAAA record objects from Infoblox NIOS servers. This module manages NIOS C(record:aaaa) objects diff --git a/plugins/modules/net_tools/nios/nios_cname_record.py b/plugins/modules/net_tools/nios/nios_cname_record.py index 2ab38473f3..099cb02572 100644 --- a/plugins/modules/net_tools/nios/nios_cname_record.py +++ b/plugins/modules/net_tools/nios/nios_cname_record.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_cname_record author: "Blair Rampling (@brampling)" short_description: Configure Infoblox NIOS CNAME records +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_cname_record + removed_in: 5.0.0 description: - Adds and/or removes instances of CNAME record objects from Infoblox NIOS servers. This module manages NIOS C(record:cname) objects diff --git a/plugins/modules/net_tools/nios/nios_dns_view.py b/plugins/modules/net_tools/nios/nios_dns_view.py index af5d56d4ca..46c56fc7bb 100644 --- a/plugins/modules/net_tools/nios/nios_dns_view.py +++ b/plugins/modules/net_tools/nios/nios_dns_view.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_dns_view author: "Peter Sprygada (@privateip)" short_description: Configure Infoblox NIOS DNS views +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_dns_view + removed_in: 5.0.0 description: - Adds and/or removes instances of DNS view objects from Infoblox NIOS servers. This module manages NIOS C(view) objects diff --git a/plugins/modules/net_tools/nios/nios_fixed_address.py b/plugins/modules/net_tools/nios/nios_fixed_address.py index cab3b5e1b5..bc2969bbe5 100644 --- a/plugins/modules/net_tools/nios/nios_fixed_address.py +++ b/plugins/modules/net_tools/nios/nios_fixed_address.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_fixed_address author: "Sumit Jaiswal (@sjaiswal)" short_description: Configure Infoblox NIOS DHCP Fixed Address +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_fixed_address + removed_in: 5.0.0 description: - A fixed address is a specific IP address that a DHCP server always assigns when a lease request comes from a particular diff --git a/plugins/modules/net_tools/nios/nios_host_record.py b/plugins/modules/net_tools/nios/nios_host_record.py index d3e9d3de95..6fed663657 100644 --- a/plugins/modules/net_tools/nios/nios_host_record.py +++ b/plugins/modules/net_tools/nios/nios_host_record.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_host_record author: "Peter Sprygada (@privateip)" short_description: Configure Infoblox NIOS host records +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_host_record + removed_in: 5.0.0 description: - Adds and/or removes instances of host record objects from Infoblox NIOS servers. This module manages NIOS C(record:host) objects diff --git a/plugins/modules/net_tools/nios/nios_member.py b/plugins/modules/net_tools/nios/nios_member.py index f8bf3e2595..186933864a 100644 --- a/plugins/modules/net_tools/nios/nios_member.py +++ b/plugins/modules/net_tools/nios/nios_member.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_member author: "Krishna Vasudevan (@krisvasudevan)" short_description: Configure Infoblox NIOS members +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_member + removed_in: 5.0.0 description: - Adds and/or removes Infoblox NIOS servers. This module manages NIOS C(member) objects using the Infoblox WAPI interface over REST. requirements: diff --git a/plugins/modules/net_tools/nios/nios_mx_record.py b/plugins/modules/net_tools/nios/nios_mx_record.py index a5c93b92bf..6e54ff2bda 100644 --- a/plugins/modules/net_tools/nios/nios_mx_record.py +++ b/plugins/modules/net_tools/nios/nios_mx_record.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_mx_record author: "Blair Rampling (@brampling)" short_description: Configure Infoblox NIOS MX records +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_mx_record + removed_in: 5.0.0 description: - Adds and/or removes instances of MX record objects from Infoblox NIOS servers. This module manages NIOS C(record:mx) objects diff --git a/plugins/modules/net_tools/nios/nios_naptr_record.py b/plugins/modules/net_tools/nios/nios_naptr_record.py index 387dd1dd98..f943d3d6d9 100644 --- a/plugins/modules/net_tools/nios/nios_naptr_record.py +++ b/plugins/modules/net_tools/nios/nios_naptr_record.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_naptr_record author: "Blair Rampling (@brampling)" short_description: Configure Infoblox NIOS NAPTR records +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_naptr_record + removed_in: 5.0.0 description: - Adds and/or removes instances of NAPTR record objects from Infoblox NIOS servers. This module manages NIOS C(record:naptr) objects diff --git a/plugins/modules/net_tools/nios/nios_network.py b/plugins/modules/net_tools/nios/nios_network.py index 98d06a2ede..6a7decb894 100644 --- a/plugins/modules/net_tools/nios/nios_network.py +++ b/plugins/modules/net_tools/nios/nios_network.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_network author: "Peter Sprygada (@privateip)" short_description: Configure Infoblox NIOS network object +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_network + removed_in: 5.0.0 description: - Adds and/or removes instances of network objects from Infoblox NIOS servers. This module manages NIOS C(network) objects diff --git a/plugins/modules/net_tools/nios/nios_network_view.py b/plugins/modules/net_tools/nios/nios_network_view.py index c8925adcfb..a27f8519a0 100644 --- a/plugins/modules/net_tools/nios/nios_network_view.py +++ b/plugins/modules/net_tools/nios/nios_network_view.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_network_view author: "Peter Sprygada (@privateip)" short_description: Configure Infoblox NIOS network views +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_network_view + removed_in: 5.0.0 description: - Adds and/or removes instances of network view objects from Infoblox NIOS servers. This module manages NIOS C(networkview) objects diff --git a/plugins/modules/net_tools/nios/nios_nsgroup.py b/plugins/modules/net_tools/nios/nios_nsgroup.py index b56c3f0b8d..8e8cde399c 100644 --- a/plugins/modules/net_tools/nios/nios_nsgroup.py +++ b/plugins/modules/net_tools/nios/nios_nsgroup.py @@ -11,6 +11,10 @@ DOCUMENTATION = ''' --- module: nios_nsgroup short_description: Configure InfoBlox DNS Nameserver Groups +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_nsgroup + removed_in: 5.0.0 extends_documentation_fragment: - community.general.nios diff --git a/plugins/modules/net_tools/nios/nios_ptr_record.py b/plugins/modules/net_tools/nios/nios_ptr_record.py index 04c1370920..22550f129a 100644 --- a/plugins/modules/net_tools/nios/nios_ptr_record.py +++ b/plugins/modules/net_tools/nios/nios_ptr_record.py @@ -11,6 +11,10 @@ DOCUMENTATION = ''' module: nios_ptr_record author: "Trebuchet Clement (@clementtrebuchet)" short_description: Configure Infoblox NIOS PTR records +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_ptr_record + removed_in: 5.0.0 description: - Adds and/or removes instances of PTR record objects from Infoblox NIOS servers. This module manages NIOS C(record:ptr) objects diff --git a/plugins/modules/net_tools/nios/nios_srv_record.py b/plugins/modules/net_tools/nios/nios_srv_record.py index 8a12aa7fd3..574a5fcf8b 100644 --- a/plugins/modules/net_tools/nios/nios_srv_record.py +++ b/plugins/modules/net_tools/nios/nios_srv_record.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_srv_record author: "Blair Rampling (@brampling)" short_description: Configure Infoblox NIOS SRV records +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_srv_record + removed_in: 5.0.0 description: - Adds and/or removes instances of SRV record objects from Infoblox NIOS servers. This module manages NIOS C(record:srv) objects diff --git a/plugins/modules/net_tools/nios/nios_txt_record.py b/plugins/modules/net_tools/nios/nios_txt_record.py index 761a895052..b3267af41f 100644 --- a/plugins/modules/net_tools/nios/nios_txt_record.py +++ b/plugins/modules/net_tools/nios/nios_txt_record.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_txt_record author: "Corey Wanless (@coreywan)" short_description: Configure Infoblox NIOS txt records +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_txt_record + removed_in: 5.0.0 description: - Adds and/or removes instances of txt record objects from Infoblox NIOS servers. This module manages NIOS C(record:txt) objects diff --git a/plugins/modules/net_tools/nios/nios_zone.py b/plugins/modules/net_tools/nios/nios_zone.py index 3c59aab298..f97098351b 100644 --- a/plugins/modules/net_tools/nios/nios_zone.py +++ b/plugins/modules/net_tools/nios/nios_zone.py @@ -10,6 +10,10 @@ DOCUMENTATION = ''' module: nios_zone author: "Peter Sprygada (@privateip)" short_description: Configure Infoblox NIOS DNS zones +deprecated: + why: Please install the infoblox.nios_modules collection and use the corresponding module from it. + alternative: infoblox.nios_modules.nios_zone + removed_in: 5.0.0 description: - Adds and/or removes instances of DNS zone objects from Infoblox NIOS servers. This module manages NIOS C(zone_auth) objects diff --git a/tests/sanity/ignore-2.9.txt b/tests/sanity/ignore-2.9.txt index c6c1afcdd4..68ceade157 100644 --- a/tests/sanity/ignore-2.9.txt +++ b/tests/sanity/ignore-2.9.txt @@ -43,6 +43,38 @@ plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules plugins/modules/remote_management/stacki/stacki_host.py validate-modules:doc-default-does-not-match-spec plugins/modules/remote_management/stacki/stacki_host.py validate-modules:parameter-type-not-in-doc plugins/modules/remote_management/stacki/stacki_host.py validate-modules:undocumented-parameter +plugins/modules/net_tools/nios/nios_a_record.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_a_record.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_cname_record.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_dns_view.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_fixed_address.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_host_record.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_host_record.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_member.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_member.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_mx_record.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_naptr_record.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_network.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_network.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_network_view.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_network_view.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_nsgroup.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_ptr_record.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_srv_record.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_txt_record.py validate-modules:invalid-documentation +plugins/modules/net_tools/nios/nios_zone.py validate-modules:deprecation-mismatch +plugins/modules/net_tools/nios/nios_zone.py validate-modules:invalid-documentation plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-invalid plugins/modules/system/iptables_state.py validate-modules:undocumented-parameter plugins/modules/system/launchd.py use-argspec-type-path # False positive From bf185573a694f4d805ace16063d8493433d352e6 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 14 May 2021 10:34:47 +0200 Subject: [PATCH 052/139] gitlab_user: add expires_at option (#2450) (#2506) * gitlab_user: add expires_at option * Add changelog * Add integration test * Add expires_at to addSshKeyToUser function * password is required if state is set to present * Check expires_at will not be added to a present ssh key * add documentation about present ssh key * add expires_at to unit tests * Improve documentation Co-authored-by: Felix Fontein * Only pass expires_at to api when it is not None * Emphasize on SSH public key * Apply felixfontein suggestion Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 054eb90ae52b6065caf7d5a52dc887bff06b46a2) Co-authored-by: Amin Vakil --- ...450-gitlab_user-add_expires_at_option.yaml | 3 + .../source_control/gitlab/gitlab_user.py | 28 +++- .../targets/gitlab_user/defaults/main.yml | 3 + .../targets/gitlab_user/tasks/main.yml | 12 +- .../targets/gitlab_user/tasks/sshkey.yml | 134 ++++++++++++++++++ .../source_control/gitlab/test_gitlab_user.py | 6 +- 6 files changed, 172 insertions(+), 14 deletions(-) create mode 100644 changelogs/fragments/2450-gitlab_user-add_expires_at_option.yaml create mode 100644 tests/integration/targets/gitlab_user/tasks/sshkey.yml diff --git a/changelogs/fragments/2450-gitlab_user-add_expires_at_option.yaml b/changelogs/fragments/2450-gitlab_user-add_expires_at_option.yaml new file mode 100644 index 0000000000..290e13847a --- /dev/null +++ b/changelogs/fragments/2450-gitlab_user-add_expires_at_option.yaml @@ -0,0 +1,3 @@ +--- +minor_changes: + - gitlab_user - add ``expires_at`` option (https://github.com/ansible-collections/community.general/issues/2325). diff --git a/plugins/modules/source_control/gitlab/gitlab_user.py b/plugins/modules/source_control/gitlab/gitlab_user.py index 9fefe1aff9..4d300ea842 100644 --- a/plugins/modules/source_control/gitlab/gitlab_user.py +++ b/plugins/modules/source_control/gitlab/gitlab_user.py @@ -57,16 +57,22 @@ options: type: str sshkey_name: description: - - The name of the sshkey + - The name of the SSH public key. type: str sshkey_file: description: - - The ssh key itself. + - The SSH public key itself. type: str + sshkey_expires_at: + description: + - The expiration date of the SSH public key in ISO 8601 format C(YYYY-MM-DDTHH:MM:SSZ). + - This is only used when adding new SSH public keys. + type: str + version_added: 3.1.0 group: description: - Id or Full path of parent group in the form of group/name. - - Add user as an member to this group. + - Add user as a member to this group. type: str access_level: description: @@ -254,7 +260,8 @@ class GitLabUser(object): if options['sshkey_name'] and options['sshkey_file']: key_changed = self.addSshKeyToUser(user, { 'name': options['sshkey_name'], - 'file': options['sshkey_file']}) + 'file': options['sshkey_file'], + 'expires_at': options['sshkey_expires_at']}) changed = changed or key_changed # Assign group @@ -295,7 +302,7 @@ class GitLabUser(object): ''' @param user User object - @param sshkey Dict containing sshkey infos {"name": "", "file": ""} + @param sshkey Dict containing sshkey infos {"name": "", "file": "", "expires_at": ""} ''' def addSshKeyToUser(self, user, sshkey): if not self.sshKeyExists(user, sshkey['name']): @@ -303,9 +310,13 @@ class GitLabUser(object): return True try: - user.keys.create({ + parameter = { 'title': sshkey['name'], - 'key': sshkey['file']}) + 'key': sshkey['file'], + } + if sshkey['expires_at'] is not None: + parameter['expires_at'] = sshkey['expires_at'] + user.keys.create(parameter) except gitlab.exceptions.GitlabCreateError as e: self._module.fail_json(msg="Failed to assign sshkey to user: %s" % to_native(e)) return True @@ -471,6 +482,7 @@ def main(): email=dict(type='str'), sshkey_name=dict(type='str'), sshkey_file=dict(type='str', no_log=False), + sshkey_expires_at=dict(type='str', no_log=False), group=dict(type='str'), access_level=dict(type='str', default="guest", choices=["developer", "guest", "maintainer", "master", "owner", "reporter"]), confirm=dict(type='bool', default=True), @@ -503,6 +515,7 @@ def main(): user_email = module.params['email'] user_sshkey_name = module.params['sshkey_name'] user_sshkey_file = module.params['sshkey_file'] + user_sshkey_expires_at = module.params['sshkey_expires_at'] group_path = module.params['group'] access_level = module.params['access_level'] confirm = module.params['confirm'] @@ -549,6 +562,7 @@ def main(): "email": user_email, "sshkey_name": user_sshkey_name, "sshkey_file": user_sshkey_file, + "sshkey_expires_at": user_sshkey_expires_at, "group_path": group_path, "access_level": access_level, "confirm": confirm, diff --git a/tests/integration/targets/gitlab_user/defaults/main.yml b/tests/integration/targets/gitlab_user/defaults/main.yml index a6755cf412..bbe016b0a8 100644 --- a/tests/integration/targets/gitlab_user/defaults/main.yml +++ b/tests/integration/targets/gitlab_user/defaults/main.yml @@ -1,3 +1,6 @@ gitlab_user: ansible_test_user gitlab_user_pass: Secr3tPassw00rd gitlab_user_email: root@localhost +gitlab_sshkey_name: ansibletest +gitlab_sshkey_file: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDI8GIMlrirf+zsvBpxnF0daykP6YEJ5wytZXhDGD2dZXg9Tln0KUSDgreT3FDgoabjlOmG1L/nhu6ML76WCsmc/wnVMlXlDlQpVJSQ2PCxGNs9WRW7Y/Pk6t9KtV/VSYr0LaPgLEU8VkffSUBJezbKa1cssjb4CmRRqcePRNYpgCXdK05TEgFvmXl9qIM8Domf1ak1PlbyMmi/MytzHmnVFzxgUKv5c0Mr+vguCi131gPdh3QSf5AHPLEoO9LcMfu2IO1zvl61wYfsJ0Wn2Fncw+tJQfUin0ffTFgUIsGqki04/YjXyWynjSwQf5Jym4BYM0i2zlDUyRxs4/Tfp4yvJFik42ambzjLK6poq+iCpQReeYih9WZUaZwUQe7zYWhTOuoV7ydsk8+kDRMPidF9K5zWkQnglGrOzdbTqnhxNpwHCg2eSRJ49kPYLOH76g8P7IQvl+zluG0o8Nndir1WcYil4D4CCBskM8WbmrElZH1CRyP/NQMNIf4hFMItTjk= ansible@ansible +gitlab_sshkey_expires_at: 2030-01-01T00:00:00.000Z diff --git a/tests/integration/targets/gitlab_user/tasks/main.yml b/tests/integration/targets/gitlab_user/tasks/main.yml index 6cbcd14c34..dddf7aaea8 100644 --- a/tests/integration/targets/gitlab_user/tasks/main.yml +++ b/tests/integration/targets/gitlab_user/tasks/main.yml @@ -56,7 +56,7 @@ - gitlab_user_state_again.user.is_admin == False -- name: Update User Test => Make User Admin +- name: Update User Test => Make User Admin gitlab_user: api_url: "{{ gitlab_host }}" email: "{{ gitlab_user_email }}" @@ -189,8 +189,8 @@ api_url: "{{ gitlab_host }}" validate_certs: False - # note: the only way to check if a password really is what it is expected - # to be is to use it for login, so we use it here instead of the + # note: the only way to check if a password really is what it is expected + # to be is to use it for login, so we use it here instead of the # default token assuming that a user can always change its own password api_username: "{{ gitlab_user }}" api_password: "{{ gitlab_user_pass }}" @@ -205,8 +205,8 @@ - name: Check PW setting return state assert: that: - # note: there is no way to determine if a password has changed or - # not, so it can only be always yellow or always green, we + # note: there is no way to determine if a password has changed or + # not, so it can only be always yellow or always green, we # decided for always green for now - gitlab_user_state is not changed @@ -248,3 +248,5 @@ assert: that: - gitlab_user_state is not changed + +- include_tasks: sshkey.yml diff --git a/tests/integration/targets/gitlab_user/tasks/sshkey.yml b/tests/integration/targets/gitlab_user/tasks/sshkey.yml new file mode 100644 index 0000000000..2d2067e74b --- /dev/null +++ b/tests/integration/targets/gitlab_user/tasks/sshkey.yml @@ -0,0 +1,134 @@ +#################################################################### +# WARNING: These are designed specifically for Ansible tests # +# and should not be used as examples of how to write Ansible roles # +#################################################################### + +- name: Create gitlab user with sshkey credentials + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + password: "{{ gitlab_user_pass }}" + validate_certs: false + sshkey_name: "{{ gitlab_sshkey_name }}" + sshkey_file: "{{ gitlab_sshkey_file }}" + state: present + register: gitlab_user_sshkey + +- name: Check user has been created correctly + assert: + that: + - gitlab_user_sshkey is changed + +- name: Create gitlab user again + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + password: "{{ gitlab_user_pass }}" + validate_certs: false + sshkey_name: "{{ gitlab_sshkey_name }}" + sshkey_file: "{{ gitlab_sshkey_file }}" + state: present + register: gitlab_user_sshkey_again + +- name: Check state is not changed + assert: + that: + - gitlab_user_sshkey_again is not changed + +- name: Add expires_at to an already created gitlab user with ssh key + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + password: "{{ gitlab_user_pass }}" + validate_certs: false + sshkey_name: "{{ gitlab_sshkey_name }}" + sshkey_file: "{{ gitlab_sshkey_file }}" + sshkey_expires_at: "{{ gitlab_sshkey_expires_at }}" + state: present + register: gitlab_user_created_user_sshkey_expires_at + +- name: Check expires_at will not be added to a present ssh key + assert: + that: + - gitlab_user_created_user_sshkey_expires_at is not changed + +- name: Remove created gitlab user + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + validate_certs: false + state: absent + register: gitlab_user_sshkey_remove + +- name: Check user has been removed correctly + assert: + that: + - gitlab_user_sshkey_remove is changed + +- name: Create gitlab user with sshkey and expires_at + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + password: "{{ gitlab_user_pass }}" + validate_certs: false + sshkey_name: "{{ gitlab_sshkey_name }}" + sshkey_file: "{{ gitlab_sshkey_file }}" + sshkey_expires_at: "{{ gitlab_sshkey_expires_at }}" + state: present + register: gitlab_user_sshkey_expires_at + +- name: Check user has been created correctly + assert: + that: + - gitlab_user_sshkey_expires_at is changed + +- name: Create gitlab user with sshkey and expires_at again + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + password: "{{ gitlab_user_pass }}" + validate_certs: false + sshkey_name: "{{ gitlab_sshkey_name }}" + sshkey_file: "{{ gitlab_sshkey_file }}" + sshkey_expires_at: "{{ gitlab_sshkey_expires_at }}" + state: present + register: gitlab_user_sshkey_expires_at_again + +- name: Check state is not changed + assert: + that: + - gitlab_user_sshkey_expires_at_again is not changed + +- name: Remove created gitlab user + gitlab_user: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + email: "{{ gitlab_user_email }}" + name: "{{ gitlab_user }}" + username: "{{ gitlab_user }}" + validate_certs: false + state: absent + register: gitlab_user_sshkey_expires_at_remove + +- name: Check user has been removed correctly + assert: + that: + - gitlab_user_sshkey_expires_at_remove is changed diff --git a/tests/unit/plugins/modules/source_control/gitlab/test_gitlab_user.py b/tests/unit/plugins/modules/source_control/gitlab/test_gitlab_user.py index 4a47654a8c..5722854e17 100644 --- a/tests/unit/plugins/modules/source_control/gitlab/test_gitlab_user.py +++ b/tests/unit/plugins/modules/source_control/gitlab/test_gitlab_user.py @@ -144,7 +144,8 @@ class TestGitlabUser(GitlabModuleTestCase): 'name': "Public key", 'file': "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJe" "jgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4" - "soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0="}) + "soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=", + 'expires_at': ""}) self.assertEqual(rvalue, False) rvalue = self.moduleUtil.addSshKeyToUser(user, { @@ -153,7 +154,8 @@ class TestGitlabUser(GitlabModuleTestCase): "dRuSuA5zszUJzYPPUSRAX3BCgTqLqYx//UuVncK7YqLVSbbwjKR2Ez5lISgCnVfLVEXzwhv+" "xawxKWmI7hJ5S0tOv6MJ+IxyTa4xcKwJTwB86z22n9fVOQeJTR2dSOH1WJrf0PvRk+KVNY2j" "TiGHTi9AIjLnyD/jWRpOgtdfkLRc8EzAWrWlgNmH2WOKBw6za0az6XoG75obUdFVdW3qcD0x" - "c809OHLi7FDf+E7U4wiZJCFuUizMeXyuK/SkaE1aee4Qp5R4dxTR4TP9M1XAYkf+kF0W9srZ+mhF069XD/zhUPJsvwEF"}) + "c809OHLi7FDf+E7U4wiZJCFuUizMeXyuK/SkaE1aee4Qp5R4dxTR4TP9M1XAYkf+kF0W9srZ+mhF069XD/zhUPJsvwEF", + 'expires_at': "2027-01-01"}) self.assertEqual(rvalue, True) @with_httmock(resp_get_group) From e78517ca935d205ce7eac138fa18f3eba568c74c Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 14 May 2021 16:24:47 +0200 Subject: [PATCH 053/139] proxmox_nic: set mtu on interface even if it's not virtio (#2505) (#2507) * Set mtu on interface whatsoever * add changelog fragment * Revert "add changelog fragment" This reverts commit 5f2f1e7febd848b1fd095635a85bf5215fbcd17d. (cherry picked from commit e2dfd42dd49115dfb4b07d484c98dfd7b300da49) Co-authored-by: Amin Vakil --- plugins/modules/cloud/misc/proxmox_nic.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/modules/cloud/misc/proxmox_nic.py b/plugins/modules/cloud/misc/proxmox_nic.py index a9c9f14ddc..23be9473eb 100644 --- a/plugins/modules/cloud/misc/proxmox_nic.py +++ b/plugins/modules/cloud/misc/proxmox_nic.py @@ -211,9 +211,8 @@ def update_nic(module, proxmox, vmid, interface, model, **kwargs): config_provided += ',link_down=1' if kwargs['mtu']: - if model == 'virtio': - config_provided += ",mtu={0}".format(kwargs['mtu']) - else: + config_provided += ",mtu={0}".format(kwargs['mtu']) + if model != 'virtio': module.warn( 'Ignoring MTU for nic {0} on VM with vmid {1}, ' 'model should be set to \'virtio\': '.format(interface, vmid)) From aa1aa1d540f040a09c0bdbd3234e390f97b7ee40 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 14 May 2021 16:25:40 +0200 Subject: [PATCH 054/139] random_pet: Random pet name generator (#2479) (#2509) A lookup plugin to generate random pet names based upon criteria. Signed-off-by: Abhijeet Kasurde (cherry picked from commit 5d0a7f40f2dd87e60b59f4ca7c3390fcc168d9ff) Co-authored-by: Abhijeet Kasurde --- plugins/lookup/random_pet.py | 99 +++++++++++++++++++ .../targets/lookup_random_pet/aliases | 3 + .../lookup_random_pet/dependencies.yml | 6 ++ .../targets/lookup_random_pet/runme.sh | 9 ++ .../targets/lookup_random_pet/test.yml | 25 +++++ 5 files changed, 142 insertions(+) create mode 100644 plugins/lookup/random_pet.py create mode 100644 tests/integration/targets/lookup_random_pet/aliases create mode 100644 tests/integration/targets/lookup_random_pet/dependencies.yml create mode 100755 tests/integration/targets/lookup_random_pet/runme.sh create mode 100644 tests/integration/targets/lookup_random_pet/test.yml diff --git a/plugins/lookup/random_pet.py b/plugins/lookup/random_pet.py new file mode 100644 index 0000000000..6caf178e4b --- /dev/null +++ b/plugins/lookup/random_pet.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +# Copyright: (c) 2021, Abhijeet Kasurde +# Copyright: (c) 2018, Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) + +__metaclass__ = type + +DOCUMENTATION = r''' + name: random_pet + author: + - Abhijeet Kasurde (@Akasurde) + short_description: Generates random pet names + version_added: '3.1.0' + requirements: + - petname U(https://github.com/dustinkirkland/python-petname) + description: + - Generates random pet names that can be used as unique identifiers for the resources. + options: + words: + description: + - The number of words in the pet name. + default: 2 + type: int + length: + description: + - The maximal length of every component of the pet name. + - Values below 3 will be set to 3 by petname. + default: 6 + type: int + prefix: + description: A string to prefix with the name. + type: str + separator: + description: The character to separate words in the pet name. + default: "-" + type: str +''' + +EXAMPLES = r''' +- name: Generate pet name + ansible.builtin.debug: + var: lookup('community.general.random_pet') + # Example result: 'loving-raptor' + +- name: Generate pet name with 3 words + ansible.builtin.debug: + var: lookup('community.general.random_pet', words=3) + # Example result: 'fully-fresh-macaw' + +- name: Generate pet name with separator + ansible.builtin.debug: + var: lookup('community.general.random_pet', separator="_") + # Example result: 'causal_snipe' + +- name: Generate pet name with length + ansible.builtin.debug: + var: lookup('community.general.random_pet', length=7) + # Example result: 'natural-peacock' +''' + +RETURN = r''' + _raw: + description: A one-element list containing a random pet name + type: list + elements: str +''' + +try: + import petname + + HAS_PETNAME = True +except ImportError: + HAS_PETNAME = False + +from ansible.errors import AnsibleError +from ansible.plugins.lookup import LookupBase + + +class LookupModule(LookupBase): + + def run(self, terms, variables=None, **kwargs): + + if not HAS_PETNAME: + raise AnsibleError('Python petname library is required. ' + 'Please install using "pip install petname"') + + self.set_options(var_options=variables, direct=kwargs) + words = self.get_option('words') + length = self.get_option('length') + prefix = self.get_option('prefix') + separator = self.get_option('separator') + + values = petname.Generate(words=words, separator=separator, letters=length) + if prefix: + values = "%s%s%s" % (prefix, separator, values) + + return [values] diff --git a/tests/integration/targets/lookup_random_pet/aliases b/tests/integration/targets/lookup_random_pet/aliases new file mode 100644 index 0000000000..bc987654d9 --- /dev/null +++ b/tests/integration/targets/lookup_random_pet/aliases @@ -0,0 +1,3 @@ +shippable/posix/group2 +skip/aix +skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller diff --git a/tests/integration/targets/lookup_random_pet/dependencies.yml b/tests/integration/targets/lookup_random_pet/dependencies.yml new file mode 100644 index 0000000000..b6b679d966 --- /dev/null +++ b/tests/integration/targets/lookup_random_pet/dependencies.yml @@ -0,0 +1,6 @@ +--- +- hosts: localhost + tasks: + - name: Install Petname Python package + pip: + name: petname \ No newline at end of file diff --git a/tests/integration/targets/lookup_random_pet/runme.sh b/tests/integration/targets/lookup_random_pet/runme.sh new file mode 100755 index 0000000000..afdff7bb9d --- /dev/null +++ b/tests/integration/targets/lookup_random_pet/runme.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +set -eux + +ANSIBLE_ROLES_PATH=../ \ + ansible-playbook dependencies.yml -v "$@" + +ANSIBLE_ROLES_PATH=../ \ + ansible-playbook test.yml -v "$@" diff --git a/tests/integration/targets/lookup_random_pet/test.yml b/tests/integration/targets/lookup_random_pet/test.yml new file mode 100644 index 0000000000..1ab619d2f4 --- /dev/null +++ b/tests/integration/targets/lookup_random_pet/test.yml @@ -0,0 +1,25 @@ +- hosts: localhost + gather_facts: no + tasks: + - name: Call plugin + set_fact: + result1: "{{ query('community.general.random_pet', words=3) }}" + result2: "{{ query('community.general.random_pet', length=3) }}" + result3: "{{ query('community.general.random_pet', prefix='kubernetes') }}" + result4: "{{ query('community.general.random_pet', separator='_') }}" + result5: "{{ query('community.general.random_pet', words=2, length=6, prefix='kubernetes', separator='_') }}" + + - name: Check results + assert: + that: + - result1 | length == 1 + - result1[0].split('-') | length == 3 + - result2 | length == 1 + - result2[0].split('-')[0] | length <= 3 + - result3 | length == 1 + - result3[0].split('-')[0] == 'kubernetes' + - result4 | length == 1 + - result4[0].split('_') | length == 2 + - result5 | length == 1 + - result5[0].split('_') | length == 3 + - result5[0].split('_')[0] == 'kubernetes' From 048f15fe683b24a52928b6afebda04a9281fa916 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 14 May 2021 22:47:26 +0200 Subject: [PATCH 055/139] java_keystore: New ssl_backend option for cryptography (#2485) (#2513) * Adding cryptography as a backend for OpenSSL operations * Updating unit tests and adding changelog fragment * Allowing private key password option when using unprotected key * Incorporating suggestions from initial review * Centralizing module exit path (cherry picked from commit a385cbb11dd22953451890c9c2157538977972a8) Co-authored-by: Ajpantuso --- ...85-java_keystore-ssl_backend-parameter.yml | 2 + plugins/modules/system/java_keystore.py | 461 ++++++++++++------ .../targets/java_keystore/tasks/main.yml | 13 + .../targets/java_keystore/tasks/tests.yml | 1 + .../modules/system/test_java_keystore.py | 168 ++++--- 5 files changed, 414 insertions(+), 231 deletions(-) create mode 100644 changelogs/fragments/2485-java_keystore-ssl_backend-parameter.yml diff --git a/changelogs/fragments/2485-java_keystore-ssl_backend-parameter.yml b/changelogs/fragments/2485-java_keystore-ssl_backend-parameter.yml new file mode 100644 index 0000000000..b446476f82 --- /dev/null +++ b/changelogs/fragments/2485-java_keystore-ssl_backend-parameter.yml @@ -0,0 +1,2 @@ +minor_changes: + - java_keystore - added ``ssl_backend`` parameter for using the cryptography library instead of the OpenSSL binary (https://github.com/ansible-collections/community.general/pull/2485). diff --git a/plugins/modules/system/java_keystore.py b/plugins/modules/system/java_keystore.py index ebfe6abdd7..78bcfb6af6 100644 --- a/plugins/modules/system/java_keystore.py +++ b/plugins/modules/system/java_keystore.py @@ -88,9 +88,19 @@ options: description: - Mode the file should be. required: false + ssl_backend: + description: + - Backend for loading private keys and certificates. + type: str + default: openssl + choices: + - openssl + - cryptography + version_added: 3.1.0 requirements: - - openssl in PATH + - openssl in PATH (when I(ssl_backend=openssl)) - keytool in PATH + - cryptography >= 3.0 (when I(ssl_backend=cryptography)) author: - Guillaume Grossetie (@Mogztter) - quidame (@quidame) @@ -164,55 +174,283 @@ import os import re import tempfile -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import PY2 +from ansible.module_utils.basic import AnsibleModule, missing_required_lib +from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text + +try: + from cryptography.hazmat.primitives.serialization.pkcs12 import serialize_key_and_certificates + from cryptography.hazmat.primitives.serialization import ( + BestAvailableEncryption, + NoEncryption, + load_pem_private_key, + load_der_private_key, + ) + from cryptography.x509 import ( + load_pem_x509_certificate, + load_der_x509_certificate, + ) + from cryptography.hazmat.primitives import hashes + from cryptography.exceptions import UnsupportedAlgorithm + from cryptography.hazmat.backends.openssl import backend + HAS_CRYPTOGRAPHY_PKCS12 = True +except ImportError: + HAS_CRYPTOGRAPHY_PKCS12 = False -def read_certificate_fingerprint(module, openssl_bin, certificate_path): - current_certificate_fingerprint_cmd = [openssl_bin, "x509", "-noout", "-in", certificate_path, "-fingerprint", "-sha256"] - (rc, current_certificate_fingerprint_out, current_certificate_fingerprint_err) = run_commands(module, current_certificate_fingerprint_cmd) - if rc != 0: - return module.fail_json(msg=current_certificate_fingerprint_out, - err=current_certificate_fingerprint_err, - cmd=current_certificate_fingerprint_cmd, - rc=rc) +class JavaKeystore: + def __init__(self, module): + self.module = module - current_certificate_match = re.search(r"=([\w:]+)", current_certificate_fingerprint_out) - if not current_certificate_match: - return module.fail_json(msg="Unable to find the current certificate fingerprint in %s" % current_certificate_fingerprint_out, - cmd=current_certificate_fingerprint_cmd, - rc=rc) + self.keytool_bin = module.get_bin_path('keytool', True) - return current_certificate_match.group(1) - - -def read_stored_certificate_fingerprint(module, keytool_bin, alias, keystore_path, keystore_password): - stored_certificate_fingerprint_cmd = [keytool_bin, "-list", "-alias", alias, "-keystore", keystore_path, "-storepass:env", "STOREPASS", "-v"] - (rc, stored_certificate_fingerprint_out, stored_certificate_fingerprint_err) = run_commands( - module, stored_certificate_fingerprint_cmd, environ_update=dict(STOREPASS=keystore_password)) - if rc != 0: - if "keytool error: java.lang.Exception: Alias <%s> does not exist" % alias in stored_certificate_fingerprint_out: - return "alias mismatch" - if re.match(r'keytool error: java\.io\.IOException: [Kk]eystore( was tampered with, or)? password was incorrect', - stored_certificate_fingerprint_out): - return "password mismatch" - return module.fail_json(msg=stored_certificate_fingerprint_out, - err=stored_certificate_fingerprint_err, - cmd=stored_certificate_fingerprint_cmd, - rc=rc) - - stored_certificate_match = re.search(r"SHA256: ([\w:]+)", stored_certificate_fingerprint_out) - if not stored_certificate_match: - return module.fail_json(msg="Unable to find the stored certificate fingerprint in %s" % stored_certificate_fingerprint_out, - cmd=stored_certificate_fingerprint_cmd, - rc=rc) - - return stored_certificate_match.group(1) - - -def run_commands(module, cmd, data=None, environ_update=None, check_rc=False): - return module.run_command(cmd, check_rc=check_rc, data=data, environ_update=environ_update) + self.certificate = module.params['certificate'] + self.keypass = module.params['private_key_passphrase'] + self.keystore_path = module.params['dest'] + self.name = module.params['name'] + self.password = module.params['password'] + self.private_key = module.params['private_key'] + self.ssl_backend = module.params['ssl_backend'] + + if self.ssl_backend == 'openssl': + self.openssl_bin = module.get_bin_path('openssl', True) + else: + if not HAS_CRYPTOGRAPHY_PKCS12: + self.module.fail_json(msg=missing_required_lib('cryptography >= 3.0')) + + if module.params['certificate_path'] is None: + self.certificate_path = create_file(self.certificate) + self.module.add_cleanup_file(self.certificate_path) + else: + self.certificate_path = module.params['certificate_path'] + + if module.params['private_key_path'] is None: + self.private_key_path = create_file(self.private_key) + self.module.add_cleanup_file(self.private_key_path) + else: + self.private_key_path = module.params['private_key_path'] + + def update_permissions(self): + try: + file_args = self.module.load_file_common_arguments(self.module.params, path=self.keystore_path) + except TypeError: + # The path argument is only supported in Ansible-base 2.10+. Fall back to + # pre-2.10 behavior for older Ansible versions. + self.module.params['path'] = self.keystore_path + file_args = self.module.load_file_common_arguments(self.module.params) + return self.module.set_fs_attributes_if_different(file_args, False) + + def read_certificate_fingerprint(self, cert_format='PEM'): + if self.ssl_backend == 'cryptography': + if cert_format == 'PEM': + cert_loader = load_pem_x509_certificate + else: + cert_loader = load_der_x509_certificate + + try: + with open(self.certificate_path, 'rb') as cert_file: + cert = cert_loader( + cert_file.read(), + backend=backend + ) + except (OSError, ValueError) as e: + self.module.fail_json(msg="Unable to read the provided certificate: %s" % to_native(e)) + + fp = hex_decode(cert.fingerprint(hashes.SHA256())).upper() + fingerprint = ':'.join([fp[i:i + 2] for i in range(0, len(fp), 2)]) + else: + current_certificate_fingerprint_cmd = [ + self.openssl_bin, "x509", "-noout", "-in", self.certificate_path, "-fingerprint", "-sha256" + ] + (rc, current_certificate_fingerprint_out, current_certificate_fingerprint_err) = self.module.run_command( + current_certificate_fingerprint_cmd, + environ_update=None, + check_rc=False + ) + if rc != 0: + return self.module.fail_json( + msg=current_certificate_fingerprint_out, + err=current_certificate_fingerprint_err, + cmd=current_certificate_fingerprint_cmd, + rc=rc + ) + + current_certificate_match = re.search(r"=([\w:]+)", current_certificate_fingerprint_out) + if not current_certificate_match: + return self.module.fail_json( + msg="Unable to find the current certificate fingerprint in %s" % ( + current_certificate_fingerprint_out + ), + cmd=current_certificate_fingerprint_cmd, + rc=rc + ) + + fingerprint = current_certificate_match.group(1) + return fingerprint + + def read_stored_certificate_fingerprint(self): + stored_certificate_fingerprint_cmd = [ + self.keytool_bin, "-list", "-alias", self.name, "-keystore", + self.keystore_path, "-storepass:env", "STOREPASS", "-v" + ] + (rc, stored_certificate_fingerprint_out, stored_certificate_fingerprint_err) = self.module.run_command( + stored_certificate_fingerprint_cmd, environ_update=dict(STOREPASS=self.password), check_rc=False) + if rc != 0: + if "keytool error: java.lang.Exception: Alias <%s> does not exist" % self.name \ + in stored_certificate_fingerprint_out: + return "alias mismatch" + if re.match( + r'keytool error: java\.io\.IOException: ' + + '[Kk]eystore( was tampered with, or)? password was incorrect', + stored_certificate_fingerprint_out + ): + return "password mismatch" + return self.module.fail_json( + msg=stored_certificate_fingerprint_out, + err=stored_certificate_fingerprint_err, + cmd=stored_certificate_fingerprint_cmd, + rc=rc + ) + + stored_certificate_match = re.search(r"SHA256: ([\w:]+)", stored_certificate_fingerprint_out) + if not stored_certificate_match: + return self.module.fail_json( + msg="Unable to find the stored certificate fingerprint in %s" % stored_certificate_fingerprint_out, + cmd=stored_certificate_fingerprint_cmd, + rc=rc + ) + + return stored_certificate_match.group(1) + + def cert_changed(self): + current_certificate_fingerprint = self.read_certificate_fingerprint() + stored_certificate_fingerprint = self.read_stored_certificate_fingerprint() + return current_certificate_fingerprint != stored_certificate_fingerprint + + def cryptography_create_pkcs12_bundle(self, keystore_p12_path, key_format='PEM', cert_format='PEM'): + if key_format == 'PEM': + key_loader = load_pem_private_key + else: + key_loader = load_der_private_key + + if cert_format == 'PEM': + cert_loader = load_pem_x509_certificate + else: + cert_loader = load_der_x509_certificate + + try: + with open(self.private_key_path, 'rb') as key_file: + private_key = key_loader( + key_file.read(), + password=to_bytes(self.keypass), + backend=backend + ) + except TypeError: + # Re-attempt with no password to match existing behavior + try: + with open(self.private_key_path, 'rb') as key_file: + private_key = key_loader( + key_file.read(), + password=None, + backend=backend + ) + except (OSError, TypeError, ValueError, UnsupportedAlgorithm) as e: + self.module.fail_json( + msg="The following error occurred while loading the provided private_key: %s" % to_native(e) + ) + except (OSError, ValueError, UnsupportedAlgorithm) as e: + self.module.fail_json( + msg="The following error occurred while loading the provided private_key: %s" % to_native(e) + ) + try: + with open(self.certificate_path, 'rb') as cert_file: + cert = cert_loader( + cert_file.read(), + backend=backend + ) + except (OSError, ValueError, UnsupportedAlgorithm) as e: + self.module.fail_json( + msg="The following error occurred while loading the provided certificate: %s" % to_native(e) + ) + + if self.password: + encryption = BestAvailableEncryption(to_bytes(self.password)) + else: + encryption = NoEncryption() + + pkcs12_bundle = serialize_key_and_certificates( + name=to_bytes(self.name), + key=private_key, + cert=cert, + cas=None, + encryption_algorithm=encryption + ) + + with open(keystore_p12_path, 'wb') as p12_file: + p12_file.write(pkcs12_bundle) + + def openssl_create_pkcs12_bundle(self, keystore_p12_path): + export_p12_cmd = [self.openssl_bin, "pkcs12", "-export", "-name", self.name, "-in", self.certificate_path, + "-inkey", self.private_key_path, "-out", keystore_p12_path, "-passout", "stdin"] + + # when keypass is provided, add -passin + cmd_stdin = "" + if self.keypass: + export_p12_cmd.append("-passin") + export_p12_cmd.append("stdin") + cmd_stdin = "%s\n" % self.keypass + cmd_stdin += "%s\n%s" % (self.password, self.password) + + (rc, export_p12_out, dummy) = self.module.run_command( + export_p12_cmd, data=cmd_stdin, environ_update=None, check_rc=False + ) + + if rc != 0: + self.module.fail_json(msg=export_p12_out, cmd=export_p12_cmd, rc=rc) + + def create(self): + if self.module.check_mode: + return {'changed': True} + + if os.path.exists(self.keystore_path): + os.remove(self.keystore_path) + + keystore_p12_path = create_path() + self.module.add_cleanup_file(keystore_p12_path) + + if self.ssl_backend == 'cryptography': + self.cryptography_create_pkcs12_bundle(keystore_p12_path) + else: + self.openssl_create_pkcs12_bundle(keystore_p12_path) + + import_keystore_cmd = [self.keytool_bin, "-importkeystore", + "-destkeystore", self.keystore_path, + "-srckeystore", keystore_p12_path, + "-srcstoretype", "pkcs12", + "-alias", self.name, + "-deststorepass:env", "STOREPASS", + "-srcstorepass:env", "STOREPASS", + "-noprompt"] + + (rc, import_keystore_out, dummy) = self.module.run_command( + import_keystore_cmd, data=None, environ_update=dict(STOREPASS=self.password), check_rc=False + ) + if rc != 0: + return self.module.fail_json(msg=import_keystore_out, cmd=import_keystore_cmd, rc=rc) + + self.update_permissions() + return { + 'changed': True, + 'msg': import_keystore_out, + 'cmd': import_keystore_cmd, + 'rc': rc + } + + def exists(self): + return os.path.exists(self.keystore_path) +# Utility functions def create_path(): dummy, tmpfile = tempfile.mkstemp() os.remove(tmpfile) @@ -226,123 +464,11 @@ def create_file(content): return tmpfile -def create_tmp_certificate(module): - return create_file(module.params['certificate']) - - -def create_tmp_private_key(module): - return create_file(module.params['private_key']) - - -def cert_changed(module, openssl_bin, keytool_bin, keystore_path, keystore_pass, alias): - certificate_path = module.params['certificate_path'] - if certificate_path is None: - certificate_path = create_tmp_certificate(module) - try: - current_certificate_fingerprint = read_certificate_fingerprint(module, openssl_bin, certificate_path) - stored_certificate_fingerprint = read_stored_certificate_fingerprint(module, keytool_bin, alias, keystore_path, keystore_pass) - return current_certificate_fingerprint != stored_certificate_fingerprint - finally: - if module.params['certificate_path'] is None: - os.remove(certificate_path) - - -def create_jks(module, name, openssl_bin, keytool_bin, keystore_path, password, keypass): - if module.check_mode: - return module.exit_json(changed=True) - - certificate_path = module.params['certificate_path'] - if certificate_path is None: - certificate_path = create_tmp_certificate(module) - - private_key_path = module.params['private_key_path'] - if private_key_path is None: - private_key_path = create_tmp_private_key(module) - - keystore_p12_path = create_path() - - try: - if os.path.exists(keystore_path): - os.remove(keystore_path) - - export_p12_cmd = [openssl_bin, "pkcs12", "-export", "-name", name, "-in", certificate_path, - "-inkey", private_key_path, "-out", keystore_p12_path, "-passout", "stdin"] - - # when keypass is provided, add -passin - cmd_stdin = "" - if keypass: - export_p12_cmd.append("-passin") - export_p12_cmd.append("stdin") - cmd_stdin = "%s\n" % keypass - cmd_stdin += "%s\n%s" % (password, password) - - (rc, export_p12_out, dummy) = run_commands(module, export_p12_cmd, data=cmd_stdin) - if rc != 0: - return module.fail_json(msg=export_p12_out, - cmd=export_p12_cmd, - rc=rc) - - import_keystore_cmd = [keytool_bin, "-importkeystore", - "-destkeystore", keystore_path, - "-srckeystore", keystore_p12_path, - "-srcstoretype", "pkcs12", - "-alias", name, - "-deststorepass:env", "STOREPASS", - "-srcstorepass:env", "STOREPASS", - "-noprompt"] - - (rc, import_keystore_out, dummy) = run_commands(module, import_keystore_cmd, data=None, - environ_update=dict(STOREPASS=password)) - if rc != 0: - return module.fail_json(msg=import_keystore_out, - cmd=import_keystore_cmd, - rc=rc) - - update_jks_perm(module, keystore_path) - return module.exit_json(changed=True, - msg=import_keystore_out, - cmd=import_keystore_cmd, - rc=rc) - finally: - if module.params['certificate_path'] is None: - os.remove(certificate_path) - if module.params['private_key_path'] is None: - os.remove(private_key_path) - os.remove(keystore_p12_path) - - -def update_jks_perm(module, keystore_path): - try: - file_args = module.load_file_common_arguments(module.params, path=keystore_path) - except TypeError: - # The path argument is only supported in Ansible-base 2.10+. Fall back to - # pre-2.10 behavior for older Ansible versions. - module.params['path'] = keystore_path - file_args = module.load_file_common_arguments(module.params) - module.set_fs_attributes_if_different(file_args, False) - - -def process_jks(module): - name = module.params['name'] - password = module.params['password'] - keypass = module.params['private_key_passphrase'] - keystore_path = module.params['dest'] - force = module.params['force'] - openssl_bin = module.get_bin_path('openssl', True) - keytool_bin = module.get_bin_path('keytool', True) - - if os.path.exists(keystore_path): - if force: - create_jks(module, name, openssl_bin, keytool_bin, keystore_path, password, keypass) - else: - if cert_changed(module, openssl_bin, keytool_bin, keystore_path, password, name): - create_jks(module, name, openssl_bin, keytool_bin, keystore_path, password, keypass) - else: - if not module.check_mode: - update_jks_perm(module, keystore_path) - module.exit_json(changed=False) +def hex_decode(s): + if PY2: + return s.decode('hex') else: - create_jks(module, name, openssl_bin, keytool_bin, keystore_path, password, keypass) + return s.hex() class ArgumentSpec(object): @@ -358,6 +484,7 @@ class ArgumentSpec(object): private_key_path=dict(type='path', no_log=False), private_key_passphrase=dict(type='str', no_log=True), password=dict(type='str', required=True, no_log=True), + ssl_backend=dict(type='str', default='openssl', choices=['openssl', 'cryptography']), force=dict(type='bool', default=False), ) choose_between = ( @@ -379,7 +506,19 @@ def main(): add_file_common_args=spec.add_file_common_args, ) module.run_command_environ_update = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C') - process_jks(module) + + result = dict() + jks = JavaKeystore(module) + + if jks.exists(): + if module.params['force'] or jks.cert_changed(): + result = jks.create() + else: + result['changed'] = jks.update_permissions() + else: + result = jks.create() + + module.exit_json(**result) if __name__ == '__main__': diff --git a/tests/integration/targets/java_keystore/tasks/main.yml b/tests/integration/targets/java_keystore/tasks/main.yml index 358222aea8..b5f1f01624 100644 --- a/tests/integration/targets/java_keystore/tasks/main.yml +++ b/tests/integration/targets/java_keystore/tasks/main.yml @@ -9,12 +9,22 @@ - name: Include tasks to create ssl materials on the controller include_tasks: prepare.yml +- set_fact: + ssl_backends: ['openssl'] + +- set_fact: + ssl_backends: "{{ ssl_backends + ['cryptography'] }}" + when: cryptography_version.stdout is version('3.0', '>=') + - when: has_java_keytool block: - name: Include tasks to play with 'certificate' and 'private_key' contents include_tasks: tests.yml vars: remote_cert: false + loop: "{{ ssl_backends }}" + loop_control: + loop_var: ssl_backend - name: Include tasks to create ssl materials on the remote host include_tasks: prepare.yml @@ -23,3 +33,6 @@ include_tasks: tests.yml vars: remote_cert: true + loop: "{{ ssl_backends }}" + loop_control: + loop_var: ssl_backend diff --git a/tests/integration/targets/java_keystore/tasks/tests.yml b/tests/integration/targets/java_keystore/tasks/tests.yml index e0de1c6836..b892dd1d29 100644 --- a/tests/integration/targets/java_keystore/tasks/tests.yml +++ b/tests/integration/targets/java_keystore/tasks/tests.yml @@ -23,6 +23,7 @@ private_key_path: "{{ omit if not remote_cert else output_dir ~ '/' ~ (item.keyname | d(item.name)) ~ '.key' }}" private_key_passphrase: "{{ item.passphrase | d(omit) }}" password: changeit + ssl_backend: "{{ ssl_backend }}" loop: "{{ java_keystore_certs }}" check_mode: yes register: result_check diff --git a/tests/unit/plugins/modules/system/test_java_keystore.py b/tests/unit/plugins/modules/system/test_java_keystore.py index ec14b3734d..5e99074c95 100644 --- a/tests/unit/plugins/modules/system/test_java_keystore.py +++ b/tests/unit/plugins/modules/system/test_java_keystore.py @@ -14,7 +14,7 @@ from ansible_collections.community.general.tests.unit.plugins.modules.utils impo from ansible_collections.community.general.tests.unit.compat.mock import patch from ansible_collections.community.general.tests.unit.compat.mock import Mock from ansible.module_utils.basic import AnsibleModule -from ansible_collections.community.general.plugins.modules.system.java_keystore import create_jks, cert_changed, ArgumentSpec +from ansible_collections.community.general.plugins.modules.system.java_keystore import JavaKeystore, ArgumentSpec class TestCreateJavaKeystore(ModuleTestCase): @@ -28,14 +28,16 @@ class TestCreateJavaKeystore(ModuleTestCase): self.spec = ArgumentSpec() self.mock_create_file = patch('ansible_collections.community.general.plugins.modules.system.java_keystore.create_file') self.mock_create_path = patch('ansible_collections.community.general.plugins.modules.system.java_keystore.create_path') - self.mock_run_commands = patch('ansible_collections.community.general.plugins.modules.system.java_keystore.run_commands') + self.mock_run_command = patch('ansible.module_utils.basic.AnsibleModule.run_command') + self.mock_get_bin_path = patch('ansible.module_utils.basic.AnsibleModule.get_bin_path') self.mock_os_path_exists = patch('os.path.exists', side_effect=lambda path: True if path == '/path/to/keystore.jks' else orig_exists(path)) self.mock_selinux_context = patch('ansible.module_utils.basic.AnsibleModule.selinux_context', side_effect=lambda path: ['unconfined_u', 'object_r', 'user_home_t', 's0']) self.mock_is_special_selinux_path = patch('ansible.module_utils.basic.AnsibleModule.is_special_selinux_path', side_effect=lambda path: (False, None)) - self.run_commands = self.mock_run_commands.start() + self.run_command = self.mock_run_command.start() + self.get_bin_path = self.mock_get_bin_path.start() self.create_file = self.mock_create_file.start() self.create_path = self.mock_create_path.start() self.selinux_context = self.mock_selinux_context.start() @@ -47,7 +49,8 @@ class TestCreateJavaKeystore(ModuleTestCase): super(TestCreateJavaKeystore, self).tearDown() self.mock_create_file.stop() self.mock_create_path.stop() - self.mock_run_commands.stop() + self.mock_run_command.stop() + self.mock_get_bin_path.stop() self.mock_selinux_context.stop() self.mock_is_special_selinux_path.stop() self.mock_os_path_exists.stop() @@ -57,7 +60,38 @@ class TestCreateJavaKeystore(ModuleTestCase): certificate='cert-foo', private_key='private-foo', dest='/path/to/keystore.jks', - name='foo', + name='test', + password='changeit' + )) + + module = AnsibleModule( + argument_spec=self.spec.argument_spec, + supports_check_mode=self.spec.supports_check_mode + ) + + with patch('os.remove', return_value=True): + self.create_path.side_effect = ['/tmp/tmpgrzm2ah7'] + self.create_file.side_effect = ['/tmp/etacifitrec', '/tmp/yek_etavirp', ''] + self.run_command.side_effect = [(0, '', ''), (0, '', '')] + self.get_bin_path.side_effect = ['keytool', 'openssl', ''] + jks = JavaKeystore(module) + assert jks.create() == { + 'changed': True, + 'cmd': ["keytool", "-importkeystore", + "-destkeystore", "/path/to/keystore.jks", + "-srckeystore", "/tmp/tmpgrzm2ah7", "-srcstoretype", "pkcs12", "-alias", "test", + "-deststorepass:env", "STOREPASS", "-srcstorepass:env", "STOREPASS", "-noprompt"], + 'msg': '', + 'rc': 0 + } + + def test_create_jks_keypass_fail_export_pkcs12(self): + set_module_args(dict( + certificate='cert-foo', + private_key='private-foo', + private_key_passphrase='passphrase-foo', + dest='/path/to/keystore.jks', + name='test', password='changeit' )) @@ -67,44 +101,15 @@ class TestCreateJavaKeystore(ModuleTestCase): ) module.exit_json = Mock() - - with patch('os.remove', return_value=True): - self.create_path.side_effect = ['/tmp/tmpgrzm2ah7'] - self.create_file.side_effect = ['/tmp/etacifitrec', '/tmp/yek_etavirp'] - self.run_commands.side_effect = [(0, '', ''), (0, '', '')] - create_jks(module, "test", "openssl", "keytool", "/path/to/keystore.jks", "changeit", "") - module.exit_json.assert_called_once_with( - changed=True, - cmd=["keytool", "-importkeystore", - "-destkeystore", "/path/to/keystore.jks", - "-srckeystore", "/tmp/tmpgrzm2ah7", "-srcstoretype", "pkcs12", "-alias", "test", - "-deststorepass:env", "STOREPASS", "-srcstorepass:env", "STOREPASS", "-noprompt"], - msg='', - rc=0 - ) - - def test_create_jks_keypass_fail_export_pkcs12(self): - set_module_args(dict( - certificate='cert-foo', - private_key='private-foo', - private_key_passphrase='passphrase-foo', - dest='/path/to/keystore.jks', - name='foo', - password='changeit' - )) - - module = AnsibleModule( - argument_spec=self.spec.argument_spec, - supports_check_mode=self.spec.supports_check_mode - ) - module.fail_json = Mock() with patch('os.remove', return_value=True): self.create_path.side_effect = ['/tmp/tmp1cyp12xa'] - self.create_file.side_effect = ['/tmp/tmpvalcrt32', '/tmp/tmpwh4key0c'] - self.run_commands.side_effect = [(1, '', ''), (0, '', '')] - create_jks(module, "test", "openssl", "keytool", "/path/to/keystore.jks", "changeit", "passphrase-foo") + self.create_file.side_effect = ['/tmp/tmpvalcrt32', '/tmp/tmpwh4key0c', ''] + self.run_command.side_effect = [(1, '', ''), (0, '', '')] + self.get_bin_path.side_effect = ['keytool', 'openssl', ''] + jks = JavaKeystore(module) + jks.create() module.fail_json.assert_called_once_with( cmd=["openssl", "pkcs12", "-export", "-name", "test", "-in", "/tmp/tmpvalcrt32", @@ -121,7 +126,7 @@ class TestCreateJavaKeystore(ModuleTestCase): certificate='cert-foo', private_key='private-foo', dest='/path/to/keystore.jks', - name='foo', + name='test', password='changeit' )) @@ -130,13 +135,16 @@ class TestCreateJavaKeystore(ModuleTestCase): supports_check_mode=self.spec.supports_check_mode ) + module.exit_json = Mock() module.fail_json = Mock() with patch('os.remove', return_value=True): self.create_path.side_effect = ['/tmp/tmp1cyp12xa'] - self.create_file.side_effect = ['/tmp/tmpvalcrt32', '/tmp/tmpwh4key0c'] - self.run_commands.side_effect = [(1, '', ''), (0, '', '')] - create_jks(module, "test", "openssl", "keytool", "/path/to/keystore.jks", "changeit", "") + self.create_file.side_effect = ['/tmp/tmpvalcrt32', '/tmp/tmpwh4key0c', ''] + self.run_command.side_effect = [(1, '', ''), (0, '', '')] + self.get_bin_path.side_effect = ['keytool', 'openssl', ''] + jks = JavaKeystore(module) + jks.create() module.fail_json.assert_called_once_with( cmd=["openssl", "pkcs12", "-export", "-name", "test", "-in", "/tmp/tmpvalcrt32", @@ -152,7 +160,7 @@ class TestCreateJavaKeystore(ModuleTestCase): certificate='cert-foo', private_key='private-foo', dest='/path/to/keystore.jks', - name='foo', + name='test', password='changeit' )) @@ -161,13 +169,16 @@ class TestCreateJavaKeystore(ModuleTestCase): supports_check_mode=self.spec.supports_check_mode ) + module.exit_json = Mock() module.fail_json = Mock() with patch('os.remove', return_value=True): self.create_path.side_effect = ['/tmp/tmpgrzm2ah7'] - self.create_file.side_effect = ['/tmp/etacifitrec', '/tmp/yek_etavirp'] - self.run_commands.side_effect = [(0, '', ''), (1, '', '')] - create_jks(module, "test", "openssl", "keytool", "/path/to/keystore.jks", "changeit", "") + self.create_file.side_effect = ['/tmp/etacifitrec', '/tmp/yek_etavirp', ''] + self.run_command.side_effect = [(0, '', ''), (1, '', '')] + self.get_bin_path.side_effect = ['keytool', 'openssl', ''] + jks = JavaKeystore(module) + jks.create() module.fail_json.assert_called_once_with( cmd=["keytool", "-importkeystore", "-destkeystore", "/path/to/keystore.jks", @@ -186,15 +197,18 @@ class TestCertChanged(ModuleTestCase): super(TestCertChanged, self).setUp() self.spec = ArgumentSpec() self.mock_create_file = patch('ansible_collections.community.general.plugins.modules.system.java_keystore.create_file') - self.mock_run_commands = patch('ansible_collections.community.general.plugins.modules.system.java_keystore.run_commands') - self.run_commands = self.mock_run_commands.start() + self.mock_run_command = patch('ansible.module_utils.basic.AnsibleModule.run_command') + self.mock_get_bin_path = patch('ansible.module_utils.basic.AnsibleModule.get_bin_path') + self.run_command = self.mock_run_command.start() self.create_file = self.mock_create_file.start() + self.get_bin_path = self.mock_get_bin_path.start() def tearDown(self): """Teardown.""" super(TestCertChanged, self).tearDown() self.mock_create_file.stop() - self.mock_run_commands.stop() + self.mock_run_command.stop() + self.mock_get_bin_path.stop() def test_cert_unchanged_same_fingerprint(self): set_module_args(dict( @@ -211,9 +225,11 @@ class TestCertChanged(ModuleTestCase): ) with patch('os.remove', return_value=True): - self.create_file.side_effect = ['/tmp/placeholder'] - self.run_commands.side_effect = [(0, 'foo=abcd:1234:efgh', ''), (0, 'SHA256: abcd:1234:efgh', '')] - result = cert_changed(module, "openssl", "keytool", "/path/to/keystore.jks", "changeit", 'foo') + self.create_file.side_effect = ['/tmp/placeholder', ''] + self.run_command.side_effect = [(0, 'foo=abcd:1234:efgh', ''), (0, 'SHA256: abcd:1234:efgh', '')] + self.get_bin_path.side_effect = ['keytool', 'openssl', ''] + jks = JavaKeystore(module) + result = jks.cert_changed() self.assertFalse(result, 'Fingerprint is identical') def test_cert_changed_fingerprint_mismatch(self): @@ -231,9 +247,11 @@ class TestCertChanged(ModuleTestCase): ) with patch('os.remove', return_value=True): - self.create_file.side_effect = ['/tmp/placeholder'] - self.run_commands.side_effect = [(0, 'foo=abcd:1234:efgh', ''), (0, 'SHA256: wxyz:9876:stuv', '')] - result = cert_changed(module, "openssl", "keytool", "/path/to/keystore.jks", "changeit", 'foo') + self.create_file.side_effect = ['/tmp/placeholder', ''] + self.run_command.side_effect = [(0, 'foo=abcd:1234:efgh', ''), (0, 'SHA256: wxyz:9876:stuv', '')] + self.get_bin_path.side_effect = ['keytool', 'openssl', ''] + jks = JavaKeystore(module) + result = jks.cert_changed() self.assertTrue(result, 'Fingerprint mismatch') def test_cert_changed_fail_alias_does_not_exist(self): @@ -251,10 +269,12 @@ class TestCertChanged(ModuleTestCase): ) with patch('os.remove', return_value=True): - self.create_file.side_effect = ['/tmp/placeholder'] - self.run_commands.side_effect = [(0, 'foo=abcd:1234:efgh', ''), - (1, 'keytool error: java.lang.Exception: Alias does not exist', '')] - result = cert_changed(module, "openssl", "keytool", "/path/to/keystore.jks", "changeit", 'foo') + self.create_file.side_effect = ['/tmp/placeholder', ''] + self.run_command.side_effect = [(0, 'foo=abcd:1234:efgh', ''), + (1, 'keytool error: java.lang.Exception: Alias does not exist', '')] + self.get_bin_path.side_effect = ['keytool', 'openssl', ''] + jks = JavaKeystore(module) + result = jks.cert_changed() self.assertTrue(result, 'Alias mismatch detected') def test_cert_changed_password_mismatch(self): @@ -272,10 +292,12 @@ class TestCertChanged(ModuleTestCase): ) with patch('os.remove', return_value=True): - self.create_file.side_effect = ['/tmp/placeholder'] - self.run_commands.side_effect = [(0, 'foo=abcd:1234:efgh', ''), - (1, 'keytool error: java.io.IOException: Keystore password was incorrect', '')] - result = cert_changed(module, "openssl", "keytool", "/path/to/keystore.jks", "changeit", 'foo') + self.create_file.side_effect = ['/tmp/placeholder', ''] + self.run_command.side_effect = [(0, 'foo=abcd:1234:efgh', ''), + (1, 'keytool error: java.io.IOException: Keystore password was incorrect', '')] + self.get_bin_path.side_effect = ['keytool', 'openssl', ''] + jks = JavaKeystore(module) + result = jks.cert_changed() self.assertTrue(result, 'Password mismatch detected') def test_cert_changed_fail_read_cert(self): @@ -292,12 +314,15 @@ class TestCertChanged(ModuleTestCase): supports_check_mode=self.spec.supports_check_mode ) + module.exit_json = Mock() module.fail_json = Mock() with patch('os.remove', return_value=True): - self.create_file.side_effect = ['/tmp/tmpdj6bvvme'] - self.run_commands.side_effect = [(1, '', 'Oops'), (0, 'SHA256: wxyz:9876:stuv', '')] - cert_changed(module, "openssl", "keytool", "/path/to/keystore.jks", "changeit", 'foo') + self.create_file.side_effect = ['/tmp/tmpdj6bvvme', ''] + self.run_command.side_effect = [(1, '', 'Oops'), (0, 'SHA256: wxyz:9876:stuv', '')] + self.get_bin_path.side_effect = ['keytool', 'openssl', ''] + jks = JavaKeystore(module) + jks.cert_changed() module.fail_json.assert_called_once_with( cmd=["openssl", "x509", "-noout", "-in", "/tmp/tmpdj6bvvme", "-fingerprint", "-sha256"], msg='', @@ -319,12 +344,15 @@ class TestCertChanged(ModuleTestCase): supports_check_mode=self.spec.supports_check_mode ) + module.exit_json = Mock() module.fail_json = Mock(return_value=True) with patch('os.remove', return_value=True): - self.create_file.side_effect = ['/tmp/placeholder'] - self.run_commands.side_effect = [(0, 'foo: wxyz:9876:stuv', ''), (1, '', 'Oops')] - cert_changed(module, "openssl", "keytool", "/path/to/keystore.jks", "changeit", 'foo') + self.create_file.side_effect = ['/tmp/placeholder', ''] + self.run_command.side_effect = [(0, 'foo: wxyz:9876:stuv', ''), (1, '', 'Oops')] + self.get_bin_path.side_effect = ['keytool', 'openssl', ''] + jks = JavaKeystore(module) + jks.cert_changed() module.fail_json.assert_called_with( cmd=["keytool", "-list", "-alias", "foo", "-keystore", "/path/to/keystore.jks", "-storepass:env", "STOREPASS", "-v"], msg='', From 69ea487005409a1d90574ca6ab28fc7968a91498 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 16 May 2021 13:45:26 +0200 Subject: [PATCH 056/139] Cleanup connections plugins (#2520) (#2522) * minor refactors * minor refactors in plugins/connection/saltstack.py * minor refactors in plugins/connection/qubes.py * minor refactor in plugins/connection/lxc.py * minor refactors in plugins/connection/chroot.py * minor refactors in plugins/connection/funcd.py * minor refactors in plugins/connection/iocage.py * minor refactors in plugins/connection/jail.py * added changelog fragment (cherry picked from commit c8f402806fe1f7d8ee8a0a716c986b1b47860cae) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../fragments/2520-connection-refactors.yml | 9 ++++++ plugins/connection/chroot.py | 27 ++++++++-------- plugins/connection/funcd.py | 18 ++++++----- plugins/connection/iocage.py | 2 +- plugins/connection/jail.py | 26 +++++++-------- plugins/connection/lxc.py | 10 +++--- plugins/connection/qubes.py | 8 +---- plugins/connection/saltstack.py | 32 ++++++++----------- plugins/connection/zone.py | 27 ++++++++-------- 9 files changed, 79 insertions(+), 80 deletions(-) create mode 100644 changelogs/fragments/2520-connection-refactors.yml diff --git a/changelogs/fragments/2520-connection-refactors.yml b/changelogs/fragments/2520-connection-refactors.yml new file mode 100644 index 0000000000..2e5c8273d7 --- /dev/null +++ b/changelogs/fragments/2520-connection-refactors.yml @@ -0,0 +1,9 @@ +minor_changes: + - chroot connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - funcd connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - iocage connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - jail connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - lxc connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - qubes connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - saltstack connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - zone connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). diff --git a/plugins/connection/chroot.py b/plugins/connection/chroot.py index ffaea2b198..a18506cb80 100644 --- a/plugins/connection/chroot.py +++ b/plugins/connection/chroot.py @@ -62,7 +62,7 @@ display = Display() class Connection(ConnectionBase): - ''' Local chroot based connections ''' + """ Local chroot based connections """ transport = 'community.general.chroot' has_pipelining = True @@ -95,7 +95,7 @@ class Connection(ConnectionBase): raise AnsibleError("%s does not look like a chrootable dir (/bin/sh missing)" % self.chroot) def _connect(self): - ''' connect to the chroot ''' + """ connect to the chroot """ if os.path.isabs(self.get_option('chroot_exe')): self.chroot_cmd = self.get_option('chroot_exe') else: @@ -110,17 +110,17 @@ class Connection(ConnectionBase): self._connected = True def _buffered_exec_command(self, cmd, stdin=subprocess.PIPE): - ''' run a command on the chroot. This is only needed for implementing + """ run a command on the chroot. This is only needed for implementing put_file() get_file() so that we don't have to read the whole file into memory. compared to exec_command() it looses some niceties like being able to return the process's exit code immediately. - ''' + """ executable = self.get_option('executable') local_cmd = [self.chroot_cmd, self.chroot, executable, '-c', cmd] - display.vvv("EXEC %s" % (local_cmd), host=self.chroot) + display.vvv("EXEC %s" % local_cmd, host=self.chroot) local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd] p = subprocess.Popen(local_cmd, shell=False, stdin=stdin, stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -128,16 +128,17 @@ class Connection(ConnectionBase): return p def exec_command(self, cmd, in_data=None, sudoable=False): - ''' run a command on the chroot ''' + """ run a command on the chroot """ super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable) p = self._buffered_exec_command(cmd) stdout, stderr = p.communicate(in_data) - return (p.returncode, stdout, stderr) + return p.returncode, stdout, stderr - def _prefix_login_path(self, remote_path): - ''' Make sure that we put files into a standard path + @staticmethod + def _prefix_login_path(remote_path): + """ Make sure that we put files into a standard path If a path is relative, then we need to choose where to put it. ssh chooses $HOME but we aren't guaranteed that a home dir will @@ -145,13 +146,13 @@ class Connection(ConnectionBase): This also happens to be the former default. Can revisit using $HOME instead if it's a problem - ''' + """ if not remote_path.startswith(os.path.sep): remote_path = os.path.join(os.path.sep, remote_path) return os.path.normpath(remote_path) def put_file(self, in_path, out_path): - ''' transfer a file from local to chroot ''' + """ transfer a file from local to chroot """ super(Connection, self).put_file(in_path, out_path) display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.chroot) @@ -177,7 +178,7 @@ class Connection(ConnectionBase): raise AnsibleError("file or module does not exist at: %s" % in_path) def fetch_file(self, in_path, out_path): - ''' fetch a file from chroot to local ''' + """ fetch a file from chroot to local """ super(Connection, self).fetch_file(in_path, out_path) display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.chroot) @@ -201,6 +202,6 @@ class Connection(ConnectionBase): raise AnsibleError("failed to transfer file %s to %s:\n%s\n%s" % (in_path, out_path, stdout, stderr)) def close(self): - ''' terminate the connection; nothing to do here ''' + """ terminate the connection; nothing to do here """ super(Connection, self).close() self._connected = False diff --git a/plugins/connection/funcd.py b/plugins/connection/funcd.py index 3aed7145cb..109e251146 100644 --- a/plugins/connection/funcd.py +++ b/plugins/connection/funcd.py @@ -44,7 +44,7 @@ display = Display() class Connection(ConnectionBase): - ''' Func-based connections ''' + """ Func-based connections """ has_pipelining = False @@ -53,6 +53,7 @@ class Connection(ConnectionBase): self.host = host # port is unused, this go on func self.port = port + self.client = None def connect(self, port=None): if not HAVE_FUNC: @@ -62,31 +63,32 @@ class Connection(ConnectionBase): return self def exec_command(self, cmd, become_user=None, sudoable=False, executable='/bin/sh', in_data=None): - ''' run a command on the remote minion ''' + """ run a command on the remote minion """ if in_data: raise AnsibleError("Internal Error: this module does not support optimized module pipelining") # totally ignores privlege escalation - display.vvv("EXEC %s" % (cmd), host=self.host) + display.vvv("EXEC %s" % cmd, host=self.host) p = self.client.command.run(cmd)[self.host] - return (p[0], p[1], p[2]) + return p[0], p[1], p[2] - def _normalize_path(self, path, prefix): + @staticmethod + def _normalize_path(path, prefix): if not path.startswith(os.path.sep): path = os.path.join(os.path.sep, path) normpath = os.path.normpath(path) return os.path.join(prefix, normpath[1:]) def put_file(self, in_path, out_path): - ''' transfer a file from local to remote ''' + """ transfer a file from local to remote """ out_path = self._normalize_path(out_path, '/') display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.host) self.client.local.copyfile.send(in_path, out_path) def fetch_file(self, in_path, out_path): - ''' fetch a file from remote to local ''' + """ fetch a file from remote to local """ in_path = self._normalize_path(in_path, '/') display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host) @@ -99,5 +101,5 @@ class Connection(ConnectionBase): shutil.rmtree(tmpdir) def close(self): - ''' terminate the connection; nothing to do here ''' + """ terminate the connection; nothing to do here """ pass diff --git a/plugins/connection/iocage.py b/plugins/connection/iocage.py index 435c789fd2..beb440eae3 100644 --- a/plugins/connection/iocage.py +++ b/plugins/connection/iocage.py @@ -40,7 +40,7 @@ display = Display() class Connection(Jail): - ''' Local iocage based connections ''' + """ Local iocage based connections """ transport = 'community.general.iocage' diff --git a/plugins/connection/jail.py b/plugins/connection/jail.py index 5252e3c4eb..f5d787b62f 100644 --- a/plugins/connection/jail.py +++ b/plugins/connection/jail.py @@ -35,7 +35,6 @@ import os import os.path import subprocess import traceback -import ansible.constants as C from ansible.errors import AnsibleError from ansible.module_utils.six.moves import shlex_quote @@ -47,7 +46,7 @@ display = Display() class Connection(ConnectionBase): - ''' Local BSD Jail based connections ''' + """ Local BSD Jail based connections """ modified_jailname_key = 'conn_jail_name' @@ -90,20 +89,20 @@ class Connection(ConnectionBase): return to_text(stdout, errors='surrogate_or_strict').split() def _connect(self): - ''' connect to the jail; nothing to do here ''' + """ connect to the jail; nothing to do here """ super(Connection, self)._connect() if not self._connected: display.vvv(u"ESTABLISH JAIL CONNECTION FOR USER: {0}".format(self._play_context.remote_user), host=self.jail) self._connected = True def _buffered_exec_command(self, cmd, stdin=subprocess.PIPE): - ''' run a command on the jail. This is only needed for implementing + """ run a command on the jail. This is only needed for implementing put_file() get_file() so that we don't have to read the whole file into memory. compared to exec_command() it looses some niceties like being able to return the process's exit code immediately. - ''' + """ local_cmd = [self.jexec_cmd] set_env = '' @@ -123,16 +122,17 @@ class Connection(ConnectionBase): return p def exec_command(self, cmd, in_data=None, sudoable=False): - ''' run a command on the jail ''' + """ run a command on the jail """ super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable) p = self._buffered_exec_command(cmd) stdout, stderr = p.communicate(in_data) - return (p.returncode, stdout, stderr) + return p.returncode, stdout, stderr - def _prefix_login_path(self, remote_path): - ''' Make sure that we put files into a standard path + @staticmethod + def _prefix_login_path(remote_path): + """ Make sure that we put files into a standard path If a path is relative, then we need to choose where to put it. ssh chooses $HOME but we aren't guaranteed that a home dir will @@ -140,13 +140,13 @@ class Connection(ConnectionBase): This also happens to be the former default. Can revisit using $HOME instead if it's a problem - ''' + """ if not remote_path.startswith(os.path.sep): remote_path = os.path.join(os.path.sep, remote_path) return os.path.normpath(remote_path) def put_file(self, in_path, out_path): - ''' transfer a file from local to jail ''' + """ transfer a file from local to jail """ super(Connection, self).put_file(in_path, out_path) display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.jail) @@ -172,7 +172,7 @@ class Connection(ConnectionBase): raise AnsibleError("file or module does not exist at: %s" % in_path) def fetch_file(self, in_path, out_path): - ''' fetch a file from jail to local ''' + """ fetch a file from jail to local """ super(Connection, self).fetch_file(in_path, out_path) display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.jail) @@ -196,6 +196,6 @@ class Connection(ConnectionBase): raise AnsibleError("failed to transfer file %s to %s:\n%s\n%s" % (in_path, out_path, to_native(stdout), to_native(stderr))) def close(self): - ''' terminate the connection; nothing to do here ''' + """ terminate the connection; nothing to do here """ super(Connection, self).close() self._connected = False diff --git a/plugins/connection/lxc.py b/plugins/connection/lxc.py index 8de1acc35d..6512a87c6d 100644 --- a/plugins/connection/lxc.py +++ b/plugins/connection/lxc.py @@ -42,14 +42,13 @@ try: except ImportError: pass -from ansible import constants as C from ansible import errors from ansible.module_utils._text import to_bytes, to_native from ansible.plugins.connection import ConnectionBase class Connection(ConnectionBase): - ''' Local lxc based connections ''' + """ Local lxc based connections """ transport = 'community.general.lxc' has_pipelining = True @@ -62,7 +61,7 @@ class Connection(ConnectionBase): self.container = None def _connect(self): - ''' connect to the lxc; nothing to do here ''' + """ connect to the lxc; nothing to do here """ super(Connection, self)._connect() if not HAS_LIBLXC: @@ -77,7 +76,8 @@ class Connection(ConnectionBase): if self.container.state == "STOPPED": raise errors.AnsibleError("%s is not running" % self.container_name) - def _communicate(self, pid, in_data, stdin, stdout, stderr): + @staticmethod + def _communicate(pid, in_data, stdin, stdout, stderr): buf = {stdout: [], stderr: []} read_fds = [stdout, stderr] if in_data: @@ -111,7 +111,7 @@ class Connection(ConnectionBase): return fd def exec_command(self, cmd, in_data=None, sudoable=False): - ''' run a command on the chroot ''' + """ run a command on the chroot """ super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable) # python2-lxc needs bytes. python3-lxc needs text. diff --git a/plugins/connection/qubes.py b/plugins/connection/qubes.py index aa0075b674..d3f934b601 100644 --- a/plugins/connection/qubes.py +++ b/plugins/connection/qubes.py @@ -37,15 +37,9 @@ DOCUMENTATION = ''' # - name: hosts ''' -import shlex -import shutil - -import os -import base64 import subprocess -import ansible.constants as C -from ansible.module_utils._text import to_bytes, to_native +from ansible.module_utils._text import to_bytes from ansible.plugins.connection import ConnectionBase, ensure_connect from ansible.errors import AnsibleConnectionFailure from ansible.utils.display import Display diff --git a/plugins/connection/saltstack.py b/plugins/connection/saltstack.py index 6be7a79949..f8e3680aea 100644 --- a/plugins/connection/saltstack.py +++ b/plugins/connection/saltstack.py @@ -16,14 +16,11 @@ DOCUMENTATION = ''' - This allows you to use existing Saltstack infrastructure to connect to targets. ''' -import re import os -import pty -import codecs -import subprocess +import base64 -from ansible.module_utils._text import to_bytes, to_text -from ansible.module_utils.six.moves import cPickle +from ansible import errors +from ansible.plugins.connection import ConnectionBase HAVE_SALTSTACK = False try: @@ -32,13 +29,9 @@ try: except ImportError: pass -import os -from ansible import errors -from ansible.plugins.connection import ConnectionBase - class Connection(ConnectionBase): - ''' Salt-based connections ''' + """ Salt-based connections """ has_pipelining = False # while the name of the product is salt, naming that module salt cause @@ -58,29 +51,30 @@ class Connection(ConnectionBase): return self def exec_command(self, cmd, sudoable=False, in_data=None): - ''' run a command on the remote minion ''' + """ run a command on the remote minion """ super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable) if in_data: raise errors.AnsibleError("Internal Error: this module does not support optimized module pipelining") - self._display.vvv("EXEC %s" % (cmd), host=self.host) + self._display.vvv("EXEC %s" % cmd, host=self.host) # need to add 'true;' to work around https://github.com/saltstack/salt/issues/28077 res = self.client.cmd(self.host, 'cmd.exec_code_all', ['bash', 'true;' + cmd]) if self.host not in res: raise errors.AnsibleError("Minion %s didn't answer, check if salt-minion is running and the name is correct" % self.host) p = res[self.host] - return (p['retcode'], p['stdout'], p['stderr']) + return p['retcode'], p['stdout'], p['stderr'] - def _normalize_path(self, path, prefix): + @staticmethod + def _normalize_path(path, prefix): if not path.startswith(os.path.sep): path = os.path.join(os.path.sep, path) normpath = os.path.normpath(path) return os.path.join(prefix, normpath[1:]) def put_file(self, in_path, out_path): - ''' transfer a file from local to remote ''' + """ transfer a file from local to remote """ super(Connection, self).put_file(in_path, out_path) @@ -88,11 +82,11 @@ class Connection(ConnectionBase): self._display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.host) with open(in_path, 'rb') as in_fh: content = in_fh.read() - self.client.cmd(self.host, 'hashutil.base64_decodefile', [codecs.encode(content, 'base64'), out_path]) + self.client.cmd(self.host, 'hashutil.base64_decodefile', [base64.b64encode(content), out_path]) # TODO test it def fetch_file(self, in_path, out_path): - ''' fetch a file from remote to local ''' + """ fetch a file from remote to local """ super(Connection, self).fetch_file(in_path, out_path) @@ -102,5 +96,5 @@ class Connection(ConnectionBase): open(out_path, 'wb').write(content) def close(self): - ''' terminate the connection; nothing to do here ''' + """ terminate the connection; nothing to do here """ pass diff --git a/plugins/connection/zone.py b/plugins/connection/zone.py index 7a7a36331d..b101ec5cf3 100644 --- a/plugins/connection/zone.py +++ b/plugins/connection/zone.py @@ -31,7 +31,6 @@ import os.path import subprocess import traceback -from ansible import constants as C from ansible.errors import AnsibleError from ansible.module_utils.six.moves import shlex_quote from ansible.module_utils._text import to_bytes @@ -42,7 +41,7 @@ display = Display() class Connection(ConnectionBase): - ''' Local zone based connections ''' + """ Local zone based connections """ transport = 'community.general.zone' has_pipelining = True @@ -75,9 +74,9 @@ class Connection(ConnectionBase): stdout=subprocess.PIPE, stderr=subprocess.PIPE) zones = [] - for l in process.stdout.readlines(): + for line in process.stdout.readlines(): # 1:work:running:/zones/work:3126dc59-9a07-4829-cde9-a816e4c5040e:native:shared - s = l.split(':') + s = line.split(':') if s[1] != 'global': zones.append(s[1]) @@ -95,20 +94,20 @@ class Connection(ConnectionBase): return path + '/root' def _connect(self): - ''' connect to the zone; nothing to do here ''' + """ connect to the zone; nothing to do here """ super(Connection, self)._connect() if not self._connected: display.vvv("THIS IS A LOCAL ZONE DIR", host=self.zone) self._connected = True def _buffered_exec_command(self, cmd, stdin=subprocess.PIPE): - ''' run a command on the zone. This is only needed for implementing + """ run a command on the zone. This is only needed for implementing put_file() get_file() so that we don't have to read the whole file into memory. compared to exec_command() it looses some niceties like being able to return the process's exit code immediately. - ''' + """ # NOTE: zlogin invokes a shell (just like ssh does) so we do not pass # this through /bin/sh -c here. Instead it goes through the shell # that zlogin selects. @@ -122,16 +121,16 @@ class Connection(ConnectionBase): return p def exec_command(self, cmd, in_data=None, sudoable=False): - ''' run a command on the zone ''' + """ run a command on the zone """ super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable) p = self._buffered_exec_command(cmd) stdout, stderr = p.communicate(in_data) - return (p.returncode, stdout, stderr) + return p.returncode, stdout, stderr def _prefix_login_path(self, remote_path): - ''' Make sure that we put files into a standard path + """ Make sure that we put files into a standard path If a path is relative, then we need to choose where to put it. ssh chooses $HOME but we aren't guaranteed that a home dir will @@ -139,13 +138,13 @@ class Connection(ConnectionBase): This also happens to be the former default. Can revisit using $HOME instead if it's a problem - ''' + """ if not remote_path.startswith(os.path.sep): remote_path = os.path.join(os.path.sep, remote_path) return os.path.normpath(remote_path) def put_file(self, in_path, out_path): - ''' transfer a file from local to zone ''' + """ transfer a file from local to zone """ super(Connection, self).put_file(in_path, out_path) display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.zone) @@ -171,7 +170,7 @@ class Connection(ConnectionBase): raise AnsibleError("file or module does not exist at: %s" % in_path) def fetch_file(self, in_path, out_path): - ''' fetch a file from zone to local ''' + """ fetch a file from zone to local """ super(Connection, self).fetch_file(in_path, out_path) display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.zone) @@ -195,6 +194,6 @@ class Connection(ConnectionBase): raise AnsibleError("failed to transfer file %s to %s:\n%s\n%s" % (in_path, out_path, stdout, stderr)) def close(self): - ''' terminate the connection; nothing to do here ''' + """ terminate the connection; nothing to do here """ super(Connection, self).close() self._connected = False From 7753fa42192ff3b7e1ec57501644b087e6870ac0 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 17 May 2021 08:09:21 +0200 Subject: [PATCH 057/139] 1085 updating the hcl whitelist to include all supported options (#2495) (#2528) * 1085 updating the hcl whitelist to include all supported options * Update changelogs/fragments/1085-consul-acl-hcl-whitelist-update.yml Co-authored-by: Felix Fontein Co-authored-by: Dillon Gilmore Co-authored-by: Felix Fontein (cherry picked from commit 5b7751530819ce066f8edf899ef3ecd2d7791e6d) Co-authored-by: iridian <442359+iridian-ks@users.noreply.github.com> --- .../1085-consul-acl-hcl-whitelist-update.yml | 2 ++ .../modules/clustering/consul/consul_acl.py | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/1085-consul-acl-hcl-whitelist-update.yml diff --git a/changelogs/fragments/1085-consul-acl-hcl-whitelist-update.yml b/changelogs/fragments/1085-consul-acl-hcl-whitelist-update.yml new file mode 100644 index 0000000000..78db43da7d --- /dev/null +++ b/changelogs/fragments/1085-consul-acl-hcl-whitelist-update.yml @@ -0,0 +1,2 @@ +bugfixes: + - consul_acl - update the hcl allowlist to include all supported options (https://github.com/ansible-collections/community.general/pull/2495). diff --git a/plugins/modules/clustering/consul/consul_acl.py b/plugins/modules/clustering/consul/consul_acl.py index cb5395ed31..5a37ca0eb9 100644 --- a/plugins/modules/clustering/consul/consul_acl.py +++ b/plugins/modules/clustering/consul/consul_acl.py @@ -189,7 +189,24 @@ from collections import defaultdict from ansible.module_utils.basic import to_text, AnsibleModule -RULE_SCOPES = ["agent", "event", "key", "keyring", "node", "operator", "query", "service", "session"] +RULE_SCOPES = [ + "agent", + "agent_prefix", + "event", + "event_prefix", + "key", + "key_prefix", + "keyring", + "node", + "node_prefix", + "operator", + "query", + "query_prefix", + "service", + "service_prefix", + "session", + "session_prefix", +] MANAGEMENT_PARAMETER_NAME = "mgmt_token" HOST_PARAMETER_NAME = "host" From ec2e7cad3e644a5724beae8e79f0627c9b4c0caa Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 17 May 2021 08:09:48 +0200 Subject: [PATCH 058/139] Update influxdb_user.py Fixed Multiple No Privileges (#2499) (#2530) * Update influxdb_user.py Fixed Multiple No Privileges * Update influxdb_user.py Fixed line spaces * Update influxdb_user.py Fixed whitespace * Create 2499-influxdb_user-fix-multiple-no-privileges.yml Added changelog (cherry picked from commit ea200c9d8c35ac084a5f4841ff82558572d14ee3) Co-authored-by: sgalea87 <43749726+sgalea87@users.noreply.github.com> --- ...99-influxdb_user-fix-multiple-no-privileges.yml | 2 ++ plugins/modules/database/influxdb/influxdb_user.py | 14 +++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) create mode 100644 changelogs/fragments/2499-influxdb_user-fix-multiple-no-privileges.yml diff --git a/changelogs/fragments/2499-influxdb_user-fix-multiple-no-privileges.yml b/changelogs/fragments/2499-influxdb_user-fix-multiple-no-privileges.yml new file mode 100644 index 0000000000..d4575ea711 --- /dev/null +++ b/changelogs/fragments/2499-influxdb_user-fix-multiple-no-privileges.yml @@ -0,0 +1,2 @@ +bugfixes: + - influxdb_user - fix bug where an influxdb user has no privileges for 2 or more databases (https://github.com/ansible-collections/community.general/pull/2499). diff --git a/plugins/modules/database/influxdb/influxdb_user.py b/plugins/modules/database/influxdb/influxdb_user.py index e17e3753f2..8aec04533b 100644 --- a/plugins/modules/database/influxdb/influxdb_user.py +++ b/plugins/modules/database/influxdb/influxdb_user.py @@ -166,16 +166,16 @@ def set_user_grants(module, client, user_name, grants): try: current_grants = client.get_list_privileges(user_name) + parsed_grants = [] # Fix privileges wording for i, v in enumerate(current_grants): - if v['privilege'] == 'ALL PRIVILEGES': - v['privilege'] = 'ALL' - current_grants[i] = v - elif v['privilege'] == 'NO PRIVILEGES': - del(current_grants[i]) + if v['privilege'] != 'NO PRIVILEGES': + if v['privilege'] == 'ALL PRIVILEGES': + v['privilege'] = 'ALL' + parsed_grants.add(v) # check if the current grants are included in the desired ones - for current_grant in current_grants: + for current_grant in parsed_grants: if current_grant not in grants: if not module.check_mode: client.revoke_privilege(current_grant['privilege'], @@ -185,7 +185,7 @@ def set_user_grants(module, client, user_name, grants): # check if the desired grants are included in the current ones for grant in grants: - if grant not in current_grants: + if grant not in parsed_grants: if not module.check_mode: client.grant_privilege(grant['privilege'], grant['database'], From af85b6c20320af1284b942a3bc6fca2a0495c75a Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 17 May 2021 08:09:58 +0200 Subject: [PATCH 059/139] fix error when cache is disabled (#2518) (#2532) (cherry picked from commit 448b8cbcda019e1d89eb715dfb6fc2f754440613) Co-authored-by: Dennis Israelsson --- changelogs/fragments/2518-nmap-fix-cache-disabled.yml | 2 ++ plugins/inventory/nmap.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2518-nmap-fix-cache-disabled.yml diff --git a/changelogs/fragments/2518-nmap-fix-cache-disabled.yml b/changelogs/fragments/2518-nmap-fix-cache-disabled.yml new file mode 100644 index 0000000000..8f4680b6a6 --- /dev/null +++ b/changelogs/fragments/2518-nmap-fix-cache-disabled.yml @@ -0,0 +1,2 @@ +bugfixes: + - nmap inventory plugin - fix local variable error when cache is disabled (https://github.com/ansible-collections/community.general/issues/2512). diff --git a/plugins/inventory/nmap.py b/plugins/inventory/nmap.py index 687317abfa..39a6ff3a67 100644 --- a/plugins/inventory/nmap.py +++ b/plugins/inventory/nmap.py @@ -130,7 +130,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): # This occurs if the cache_key is not in the cache or if the cache_key expired, so the cache needs to be updated cache_needs_update = True - if cache_needs_update: + if not user_cache_setting or cache_needs_update: # setup command cmd = [self._nmap] if not self._options['ports']: @@ -207,6 +207,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): except Exception as e: raise AnsibleParserError("failed to parse %s: %s " % (to_native(path), to_native(e))) + if cache_needs_update: self._cache[cache_key] = results self._populate(results) From b699aaff7bc940c6feecb4520ae7e0831ad3158e Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 17 May 2021 08:27:25 +0200 Subject: [PATCH 060/139] Use --assumeyes with explicit yum call. (#2533) (#2535) (cherry picked from commit 2cc848fe1a32959d54b23afe2aa153c2fd79b35c) Co-authored-by: Felix Fontein --- tests/integration/targets/yum_versionlock/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/targets/yum_versionlock/tasks/main.yml b/tests/integration/targets/yum_versionlock/tasks/main.yml index dda5a11bf0..3ea170b145 100644 --- a/tests/integration/targets/yum_versionlock/tasks/main.yml +++ b/tests/integration/targets/yum_versionlock/tasks/main.yml @@ -24,7 +24,7 @@ register: lock_all_packages - name: Update all packages - command: yum update --setopt=obsoletes=0 + command: yum update --assumeyes --setopt=obsoletes=0 register: update_all_locked_packages changed_when: - '"No packages marked for update" not in update_all_locked_packages.stdout' From 42f28048a82dfa4ca31aac018721721308e5755f Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 17 May 2021 10:36:36 +0200 Subject: [PATCH 061/139] yum_versionlock: disable fedora34 integration test (#2536) (#2538) * Disable yum_versionlock integration test on Fedora 34 * Remove --assumeyes and add a comment regarding this * Update update task name (cherry picked from commit da7e4e1dc2306ae047cac87912f5b7c805ee2233) Co-authored-by: Amin Vakil --- tests/integration/targets/yum_versionlock/tasks/main.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/integration/targets/yum_versionlock/tasks/main.yml b/tests/integration/targets/yum_versionlock/tasks/main.yml index 3ea170b145..4084bdcb91 100644 --- a/tests/integration/targets/yum_versionlock/tasks/main.yml +++ b/tests/integration/targets/yum_versionlock/tasks/main.yml @@ -23,8 +23,9 @@ state: present register: lock_all_packages - - name: Update all packages - command: yum update --assumeyes --setopt=obsoletes=0 + # This should fail when it needs user interaction and missing -y is on purpose. + - name: Update all packages (not really) + command: yum update --setopt=obsoletes=0 register: update_all_locked_packages changed_when: - '"No packages marked for update" not in update_all_locked_packages.stdout' @@ -59,4 +60,4 @@ state: absent when: yum_versionlock_install is changed when: (ansible_distribution in ['CentOS', 'RedHat'] and ansible_distribution_major_version is version('7', '>=')) or - (ansible_distribution == 'Fedora') + (ansible_distribution == 'Fedora' and ansible_distribution_major_version is version('33', '<=')) From 38aa0ec8ad14f98beeb2f129f5bf30b4a0969cc5 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 17 May 2021 14:14:44 +0200 Subject: [PATCH 062/139] Add option missing to passwordstore lookup (#2500) (#2541) Add ability to ignore error on missing pass file to allow processing the output further via another filters (mainly the default filter) without updating the pass file itself. It also contains the option to create the pass file, like the option create=true does. Finally, it also allows to issue a warning only, if the pass file is not found. (cherry picked from commit 350380ba8c91030b69ec4fe2b087fb62ee82c389) Co-authored-by: Jan Baier <7996094+baierjan@users.noreply.github.com> --- ...asswordstore-add_option_ignore_missing.yml | 3 + plugins/lookup/passwordstore.py | 56 +++++++++++++++++-- .../lookup_passwordstore/tasks/tests.yml | 31 ++++++++++ 3 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/2500-passwordstore-add_option_ignore_missing.yml diff --git a/changelogs/fragments/2500-passwordstore-add_option_ignore_missing.yml b/changelogs/fragments/2500-passwordstore-add_option_ignore_missing.yml new file mode 100644 index 0000000000..6141ac7747 --- /dev/null +++ b/changelogs/fragments/2500-passwordstore-add_option_ignore_missing.yml @@ -0,0 +1,3 @@ +minor_changes: + - passwordstore lookup - add option ``missing`` to choose what to do if the password file is missing + (https://github.com/ansible-collections/community.general/pull/2500). diff --git a/plugins/lookup/passwordstore.py b/plugins/lookup/passwordstore.py index 79c69ed962..976dfb837e 100644 --- a/plugins/lookup/passwordstore.py +++ b/plugins/lookup/passwordstore.py @@ -25,9 +25,9 @@ DOCUMENTATION = ''' env: - name: PASSWORD_STORE_DIR create: - description: Create the password if it does not already exist. + description: Create the password if it does not already exist. Takes precedence over C(missing). type: bool - default: 'no' + default: false overwrite: description: Overwrite the password if it does already exist. type: bool @@ -60,6 +60,22 @@ DOCUMENTATION = ''' description: use alphanumeric characters. type: bool default: 'no' + missing: + description: + - List of preference about what to do if the password file is missing. + - If I(create=true), the value for this option is ignored and assumed to be C(create). + - If set to C(error), the lookup will error out if the passname does not exist. + - If set to C(create), the passname will be created with the provided length I(length) if it does not exist. + - If set to C(empty) or C(warn), will return a C(none) in case the passname does not exist. + When using C(lookup) and not C(query), this will be translated to an empty string. + version_added: 3.1.0 + type: str + default: error + choices: + - error + - warn + - empty + - create ''' EXAMPLES = """ # Debug is used for examples, BAD IDEA to show passwords on screen @@ -67,12 +83,28 @@ EXAMPLES = """ ansible.builtin.debug: msg: "{{ lookup('community.general.passwordstore', 'example/test')}}" +- name: Basic lookup. Warns if example/test does not exist and returns empty string + ansible.builtin.debug: + msg: "{{ lookup('community.general.passwordstore', 'example/test missing=warn')}}" + - name: Create pass with random 16 character password. If password exists just give the password ansible.builtin.debug: var: mypassword vars: mypassword: "{{ lookup('community.general.passwordstore', 'example/test create=true')}}" +- name: Create pass with random 16 character password. If password exists just give the password + ansible.builtin.debug: + var: mypassword + vars: + mypassword: "{{ lookup('community.general.passwordstore', 'example/test missing=create')}}" + +- name: Prints 'abc' if example/test does not exist, just give the password otherwise + ansible.builtin.debug: + var: mypassword + vars: + mypassword: "{{ lookup('community.general.passwordstore', 'example/test missing=empty') | default('abc', true) }}" + - name: Different size password ansible.builtin.debug: msg: "{{ lookup('community.general.passwordstore', 'example/test create=true length=42')}}" @@ -111,10 +143,13 @@ import yaml from distutils import util from ansible.errors import AnsibleError, AnsibleAssertionError from ansible.module_utils._text import to_bytes, to_native, to_text +from ansible.utils.display import Display from ansible.utils.encrypt import random_password from ansible.plugins.lookup import LookupBase from ansible import constants as C +display = Display() + # backhacked check_output with input for python 2.7 # http://stackoverflow.com/questions/10103551/passing-data-to-subprocess-check-output @@ -178,12 +213,17 @@ class LookupModule(LookupBase): self.paramvals[key] = util.strtobool(self.paramvals[key]) except (ValueError, AssertionError) as e: raise AnsibleError(e) + if self.paramvals['missing'] not in ['error', 'warn', 'create', 'empty']: + raise AnsibleError("{0} is not a valid option for missing".format(self.paramvals['missing'])) if not isinstance(self.paramvals['length'], int): if self.paramvals['length'].isdigit(): self.paramvals['length'] = int(self.paramvals['length']) else: raise AnsibleError("{0} is not a correct value for length".format(self.paramvals['length'])) + if self.paramvals['create']: + self.paramvals['missing'] = 'create' + # Collect pass environment variables from the plugin's parameters. self.env = os.environ.copy() @@ -224,9 +264,11 @@ class LookupModule(LookupBase): if e.returncode != 0 and 'not in the password store' in e.output: # if pass returns 1 and return string contains 'is not in the password store.' # We need to determine if this is valid or Error. - if not self.paramvals['create']: - raise AnsibleError('passname: {0} not found, use create=True'.format(self.passname)) + if self.paramvals['missing'] == 'error': + raise AnsibleError('passwordstore: passname {0} not found and missing=error is set'.format(self.passname)) else: + if self.paramvals['missing'] == 'warn': + display.warning('passwordstore: passname {0} not found'.format(self.passname)) return False else: raise AnsibleError(e) @@ -294,6 +336,7 @@ class LookupModule(LookupBase): 'userpass': '', 'length': 16, 'backup': False, + 'missing': 'error', } for term in terms: @@ -304,6 +347,9 @@ class LookupModule(LookupBase): else: result.append(self.get_passresult()) else: # password does not exist - if self.paramvals['create']: + if self.paramvals['missing'] == 'create': result.append(self.generate_password()) + else: + result.append(None) + return result diff --git a/tests/integration/targets/lookup_passwordstore/tasks/tests.yml b/tests/integration/targets/lookup_passwordstore/tasks/tests.yml index aba5457c0a..e69ba5e572 100644 --- a/tests/integration/targets/lookup_passwordstore/tasks/tests.yml +++ b/tests/integration/targets/lookup_passwordstore/tasks/tests.yml @@ -61,6 +61,37 @@ that: - readpass == newpass +- name: Create a password using missing=create + set_fact: + newpass: "{{ lookup('community.general.passwordstore', 'test-missing-create missing=create length=8') }}" + +- name: Fetch password from an existing file + set_fact: + readpass: "{{ lookup('community.general.passwordstore', 'test-missing-create') }}" + +- name: Verify password + assert: + that: + - readpass == newpass + +- name: Fetch password from existing file using missing=empty + set_fact: + readpass: "{{ lookup('community.general.passwordstore', 'test-missing-create missing=empty') }}" + +- name: Verify password + assert: + that: + - readpass == newpass + +- name: Fetch password from non-existing file using missing=empty + set_fact: + readpass: "{{ query('community.general.passwordstore', 'test-missing-pass missing=empty') }}" + +- name: Verify password + assert: + that: + - readpass == [ none ] + # As inserting multiline passwords on the commandline would require something # like expect, simply create it by using default gpg on a file with the correct # structure. From b78254fe240cfa99be688b58393cdb2215e5ed8d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 17 May 2021 18:02:13 +0000 Subject: [PATCH 063/139] zfs_delegate_admin: drop choices from permissions (#2540) (#2544) instead of whitelisting some subset of known existing permissions, just allow any string to be used as permissions. this way, any permission supported by the underlying zfs commands can be used, eg. 'bookmark', 'load-key', 'change-key' and all property permissions, which were missing from the choices list. (cherry picked from commit dc0a56141fd41c94ff7c79dc902f97255da295cb) Co-authored-by: Lauri Tirkkonen --- changelogs/fragments/2540-zfs-delegate-choices.yml | 2 ++ plugins/modules/storage/zfs/zfs_delegate_admin.py | 8 +++----- 2 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/2540-zfs-delegate-choices.yml diff --git a/changelogs/fragments/2540-zfs-delegate-choices.yml b/changelogs/fragments/2540-zfs-delegate-choices.yml new file mode 100644 index 0000000000..8e0138420c --- /dev/null +++ b/changelogs/fragments/2540-zfs-delegate-choices.yml @@ -0,0 +1,2 @@ +minor_changes: + - zfs_delegate_admin - drop choices from permissions, allowing any permission supported by the underlying zfs commands (https://github.com/ansible-collections/community.general/pull/2540). diff --git a/plugins/modules/storage/zfs/zfs_delegate_admin.py b/plugins/modules/storage/zfs/zfs_delegate_admin.py index 71225fa155..ead4041150 100644 --- a/plugins/modules/storage/zfs/zfs_delegate_admin.py +++ b/plugins/modules/storage/zfs/zfs_delegate_admin.py @@ -51,8 +51,9 @@ options: permissions: description: - The list of permission(s) to delegate (required if C(state) is C(present)). + - Supported permissions depend on the ZFS version in use. See for example + U(https://openzfs.github.io/openzfs-docs/man/8/zfs-allow.8.html) for OpenZFS. type: list - choices: [ allow, clone, create, destroy, diff, hold, mount, promote, readonly, receive, release, rename, rollback, send, share, snapshot, unallow ] elements: str local: description: @@ -248,10 +249,7 @@ def main(): users=dict(type='list', elements='str'), groups=dict(type='list', elements='str'), everyone=dict(type='bool', default=False), - permissions=dict(type='list', elements='str', - choices=['allow', 'clone', 'create', 'destroy', 'diff', 'hold', 'mount', 'promote', - 'readonly', 'receive', 'release', 'rename', 'rollback', 'send', 'share', - 'snapshot', 'unallow']), + permissions=dict(type='list', elements='str'), local=dict(type='bool'), descendents=dict(type='bool'), recursive=dict(type='bool', default=False), From b2e4485567b61dbf4ebe2ef1989ee64911355e9d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 17 May 2021 20:24:09 +0200 Subject: [PATCH 064/139] java_keystore: pass in secret to keytool via stdin (#2526) (#2545) * java_keystore: pass in secret to keytool via stdin * add changelog fragment (cherry picked from commit 2b1eff2783b6f6c8b6d4ef0552afc35d5eac9146) Co-authored-by: quidame --- .../2526-java_keystore-password-via-stdin.yml | 4 ++++ plugins/modules/system/java_keystore.py | 10 ++++------ .../unit/plugins/modules/system/test_java_keystore.py | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 changelogs/fragments/2526-java_keystore-password-via-stdin.yml diff --git a/changelogs/fragments/2526-java_keystore-password-via-stdin.yml b/changelogs/fragments/2526-java_keystore-password-via-stdin.yml new file mode 100644 index 0000000000..1e45e306af --- /dev/null +++ b/changelogs/fragments/2526-java_keystore-password-via-stdin.yml @@ -0,0 +1,4 @@ +--- +minor_changes: + - "java_keystore - replace envvar by stdin to pass secret to ``keytool`` + (https://github.com/ansible-collections/community.general/pull/2526)." diff --git a/plugins/modules/system/java_keystore.py b/plugins/modules/system/java_keystore.py index 78bcfb6af6..8293801f1b 100644 --- a/plugins/modules/system/java_keystore.py +++ b/plugins/modules/system/java_keystore.py @@ -290,11 +290,11 @@ class JavaKeystore: def read_stored_certificate_fingerprint(self): stored_certificate_fingerprint_cmd = [ - self.keytool_bin, "-list", "-alias", self.name, "-keystore", - self.keystore_path, "-storepass:env", "STOREPASS", "-v" + self.keytool_bin, "-list", "-alias", self.name, + "-keystore", self.keystore_path, "-v" ] (rc, stored_certificate_fingerprint_out, stored_certificate_fingerprint_err) = self.module.run_command( - stored_certificate_fingerprint_cmd, environ_update=dict(STOREPASS=self.password), check_rc=False) + stored_certificate_fingerprint_cmd, data=self.password, check_rc=False) if rc != 0: if "keytool error: java.lang.Exception: Alias <%s> does not exist" % self.name \ in stored_certificate_fingerprint_out: @@ -428,12 +428,10 @@ class JavaKeystore: "-srckeystore", keystore_p12_path, "-srcstoretype", "pkcs12", "-alias", self.name, - "-deststorepass:env", "STOREPASS", - "-srcstorepass:env", "STOREPASS", "-noprompt"] (rc, import_keystore_out, dummy) = self.module.run_command( - import_keystore_cmd, data=None, environ_update=dict(STOREPASS=self.password), check_rc=False + import_keystore_cmd, data='%s\n%s\n%s' % (self.password, self.password, self.password), check_rc=False ) if rc != 0: return self.module.fail_json(msg=import_keystore_out, cmd=import_keystore_cmd, rc=rc) diff --git a/tests/unit/plugins/modules/system/test_java_keystore.py b/tests/unit/plugins/modules/system/test_java_keystore.py index 5e99074c95..7d582a3e99 100644 --- a/tests/unit/plugins/modules/system/test_java_keystore.py +++ b/tests/unit/plugins/modules/system/test_java_keystore.py @@ -80,7 +80,7 @@ class TestCreateJavaKeystore(ModuleTestCase): 'cmd': ["keytool", "-importkeystore", "-destkeystore", "/path/to/keystore.jks", "-srckeystore", "/tmp/tmpgrzm2ah7", "-srcstoretype", "pkcs12", "-alias", "test", - "-deststorepass:env", "STOREPASS", "-srcstorepass:env", "STOREPASS", "-noprompt"], + "-noprompt"], 'msg': '', 'rc': 0 } @@ -183,7 +183,7 @@ class TestCreateJavaKeystore(ModuleTestCase): cmd=["keytool", "-importkeystore", "-destkeystore", "/path/to/keystore.jks", "-srckeystore", "/tmp/tmpgrzm2ah7", "-srcstoretype", "pkcs12", "-alias", "test", - "-deststorepass:env", "STOREPASS", "-srcstorepass:env", "STOREPASS", "-noprompt"], + "-noprompt"], msg='', rc=1 ) @@ -354,7 +354,7 @@ class TestCertChanged(ModuleTestCase): jks = JavaKeystore(module) jks.cert_changed() module.fail_json.assert_called_with( - cmd=["keytool", "-list", "-alias", "foo", "-keystore", "/path/to/keystore.jks", "-storepass:env", "STOREPASS", "-v"], + cmd=["keytool", "-list", "-alias", "foo", "-keystore", "/path/to/keystore.jks", "-v"], msg='', err='Oops', rc=1 From 1f7047e725587054b4a37245bf810714c0b0fbaf Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 17 May 2021 20:50:43 +0200 Subject: [PATCH 065/139] ModuleHelper - better mechanism for customizing "changed" behaviour (#2514) (#2546) * better mechanism for customizing "changed" behaviour * dont drink and code: silly mistake from late at night * added changelog fragment (cherry picked from commit 2a376642ddc8be103e57eb688da86bfb71bf790a) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- changelogs/fragments/2514-mh-improved-changed.yml | 2 ++ plugins/module_utils/mh/base.py | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2514-mh-improved-changed.yml diff --git a/changelogs/fragments/2514-mh-improved-changed.yml b/changelogs/fragments/2514-mh-improved-changed.yml new file mode 100644 index 0000000000..b540600130 --- /dev/null +++ b/changelogs/fragments/2514-mh-improved-changed.yml @@ -0,0 +1,2 @@ +minor_changes: + - ModuleHelper module utils - improved mechanism for customizing the calculation of ``changed`` (https://github.com/ansible-collections/community.general/pull/2514). diff --git a/plugins/module_utils/mh/base.py b/plugins/module_utils/mh/base.py index 2a2dd88f7b..e0de7f2fdd 100644 --- a/plugins/module_utils/mh/base.py +++ b/plugins/module_utils/mh/base.py @@ -33,9 +33,15 @@ class ModuleHelperBase(object): def __quit_module__(self): pass + def __changed__(self): + raise NotImplementedError() + @property def changed(self): - return self._changed + try: + return self.__changed__() + except NotImplementedError: + return self._changed @changed.setter def changed(self, value): From 6e56bae0f30dc6c35f50272531d3ff86eca80d25 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 17 May 2021 19:18:33 +0000 Subject: [PATCH 066/139] influxdb_user: allow creation of first user with auth enabled (#2364) (#2368) (#2548) * influxdb_user: allow creation of first user with auth enabled (#2364) * handle potential exceptions while parsing influxdb client error * fix changelog Co-authored-by: Felix Fontein * influxdb_user: use generic exceptions to be compatible with python 2.7 Co-authored-by: Felix Fontein (cherry picked from commit b89eb87ad6872dcfed1bd2a7969ba5ce091ddf9e) Co-authored-by: Xabier Napal --- .../2364-influxdb_user-first_user.yml | 5 ++++ .../database/influxdb/influxdb_user.py | 25 +++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/2364-influxdb_user-first_user.yml diff --git a/changelogs/fragments/2364-influxdb_user-first_user.yml b/changelogs/fragments/2364-influxdb_user-first_user.yml new file mode 100644 index 0000000000..905688643b --- /dev/null +++ b/changelogs/fragments/2364-influxdb_user-first_user.yml @@ -0,0 +1,5 @@ +bugfixes: + - influxdb_user - allow creation of admin users when InfluxDB authentication + is enabled but no other user exists on the database. In this scenario, + InfluxDB 1.x allows only ``CREATE USER`` queries and rejects any other query + (https://github.com/ansible-collections/community.general/issues/2364). diff --git a/plugins/modules/database/influxdb/influxdb_user.py b/plugins/modules/database/influxdb/influxdb_user.py index 8aec04533b..d9e6b58051 100644 --- a/plugins/modules/database/influxdb/influxdb_user.py +++ b/plugins/modules/database/influxdb/influxdb_user.py @@ -100,6 +100,8 @@ RETURN = r''' #only defaults ''' +import json + from ansible.module_utils.urls import ConnectionError from ansible.module_utils.basic import AnsibleModule from ansible.module_utils._text import to_native @@ -115,7 +117,7 @@ def find_user(module, client, user_name): if user['user'] == user_name: user_result = user break - except (ConnectionError, influx.exceptions.InfluxDBClientError) as e: + except ConnectionError as e: module.fail_json(msg=to_native(e)) return user_result @@ -198,6 +200,9 @@ def set_user_grants(module, client, user_name, grants): return changed +INFLUX_AUTH_FIRST_USER_REQUIRED = "error authorizing query: create admin user first or disable authentication" + + def main(): argument_spec = influx.InfluxDb.influxdb_argument_spec() argument_spec.update( @@ -219,7 +224,23 @@ def main(): grants = module.params['grants'] influxdb = influx.InfluxDb(module) client = influxdb.connect_to_influxdb() - user = find_user(module, client, user_name) + + user = None + try: + user = find_user(module, client, user_name) + except influx.exceptions.InfluxDBClientError as e: + if e.code == 403: + reason = None + try: + msg = json.loads(e.content) + reason = msg["error"] + except (KeyError, ValueError): + module.fail_json(msg=to_native(e)) + + if reason != INFLUX_AUTH_FIRST_USER_REQUIRED: + module.fail_json(msg=to_native(e)) + else: + module.fail_json(msg=to_native(e)) changed = False From de2feb2567b2f05530cf014ef07be630a72729ab Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 18 May 2021 06:36:02 +0200 Subject: [PATCH 067/139] ModuleHelper - cmd params now taken from self.vars instead of self.module.params (#2517) (#2549) * cmd params now taken from self.vars instead of self.module.params * added changelog fragment * Update changelogs/fragments/2517-cmd-params-from-vars.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit d24fc92466cc48d8dc436b80a2613635061b8f07) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- changelogs/fragments/2517-cmd-params-from-vars.yml | 2 ++ plugins/module_utils/mh/mixins/cmd.py | 6 +++--- plugins/modules/system/xfconf.py | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 changelogs/fragments/2517-cmd-params-from-vars.yml diff --git a/changelogs/fragments/2517-cmd-params-from-vars.yml b/changelogs/fragments/2517-cmd-params-from-vars.yml new file mode 100644 index 0000000000..95a2f7165d --- /dev/null +++ b/changelogs/fragments/2517-cmd-params-from-vars.yml @@ -0,0 +1,2 @@ +minor_changes: + - cmd (Module Helper) module utils - ``CmdMixin`` now pulls the value for ``run_command()`` params from ``self.vars``, as opposed to previously retrieving those from ``self.module.params`` (https://github.com/ansible-collections/community.general/pull/2517). diff --git a/plugins/module_utils/mh/mixins/cmd.py b/plugins/module_utils/mh/mixins/cmd.py index fc66638f69..eb7cc698cc 100644 --- a/plugins/module_utils/mh/mixins/cmd.py +++ b/plugins/module_utils/mh/mixins/cmd.py @@ -120,7 +120,7 @@ class CmdMixin(object): cmd_args[0] = self.module.get_bin_path(cmd_args[0], required=True) except ValueError: pass - param_list = params if params else self.module.params.keys() + param_list = params if params else self.vars.keys() for param in param_list: if isinstance(param, dict): @@ -131,9 +131,9 @@ class CmdMixin(object): fmt = find_format(_param) value = param[_param] elif isinstance(param, str): - if param in self.module.argument_spec: + if param in self.vars.keys(): fmt = find_format(param) - value = self.module.params[param] + value = self.vars[param] elif param in extra_params: fmt = find_format(param) value = extra_params[param] diff --git a/plugins/modules/system/xfconf.py b/plugins/modules/system/xfconf.py index f2975df050..dc560e7775 100644 --- a/plugins/modules/system/xfconf.py +++ b/plugins/modules/system/xfconf.py @@ -258,7 +258,7 @@ class XFConfProperty(CmdMixin, StateMixin, ModuleHelper): params = ['channel', 'property', {'create': True}] if self.vars.is_array: - params.append({'is_array': True}) + params.append('is_array') params.append({'values_and_types': (self.vars.value, value_type)}) if not self.module.check_mode: From d43764da79520b2fa11ddcf7db8e46526c332d36 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 18 May 2021 10:49:12 +0200 Subject: [PATCH 068/139] filesystem: revamp module (#2472) (#2550) * revamp filesystem module to prepare next steps * pass all commands to module.run_command() as lists * refactor grow() and grow_cmd() to not need to override them so much * refactor all existing get_fs_size() overrides to raise a ValueError if not able to parse command output and return an integer. * override MKFS_FORCE_FLAGS the same way for all fstypes that require it * improve documentation of limitations of the module regarding FreeBSD * fix indentation in DOCUMENTATION * add/update function/method docstrings * fix pylint hints filesystem: refactor integration tests * Include *reiserfs* and *swap* in tests. * Fix reiserfs related code and tests accordingly. * Replace "other fs" (unhandled by this module), from *swap* to *minix* (both mkswap and mkfs.minix being provided by util-linux). * Replace *dd* commands by *filesize* dedicated module. * Use FQCNs and name the tasks. * Update main tests conditionals. * add a changelog fragment * Apply suggestions from code review Co-authored-by: Felix Fontein * declare variables as lists when lists are needed * fix construction without useless conversion Co-authored-by: Felix Fontein (cherry picked from commit f6db0745fcfb59dc2dff26a1d86fc60b142b65d3) Co-authored-by: quidame --- .../2472_filesystem_module_revamp.yml | 9 + plugins/modules/system/filesystem.py | 296 ++++++++++-------- .../targets/filesystem/defaults/main.yml | 2 + .../filesystem/tasks/create_device.yml | 20 +- .../targets/filesystem/tasks/create_fs.yml | 69 ++-- .../targets/filesystem/tasks/main.yml | 50 +-- .../filesystem/tasks/overwrite_another_fs.yml | 37 ++- .../targets/filesystem/tasks/remove_fs.yml | 60 ++-- .../targets/filesystem/tasks/setup.yml | 179 +++++++---- 9 files changed, 434 insertions(+), 288 deletions(-) create mode 100644 changelogs/fragments/2472_filesystem_module_revamp.yml diff --git a/changelogs/fragments/2472_filesystem_module_revamp.yml b/changelogs/fragments/2472_filesystem_module_revamp.yml new file mode 100644 index 0000000000..691c861078 --- /dev/null +++ b/changelogs/fragments/2472_filesystem_module_revamp.yml @@ -0,0 +1,9 @@ +--- +minor_changes: + - "filesystem - cleanup and revamp module, tests and doc. Pass all commands to + ``module.run_command()`` as lists. Move the device-vs-mountpoint logic to + ``grow()`` method. Give to all ``get_fs_size()`` the same logic and error + handling. (https://github.com/ansible-collections/community.general/pull/2472)." +bugfixes: + - "filesystem - repair ``reiserfs`` fstype support after adding it to integration + tests (https://github.com/ansible-collections/community.general/pull/2472)." diff --git a/plugins/modules/system/filesystem.py b/plugins/modules/system/filesystem.py index 6944178da1..97fe2dc1ab 100644 --- a/plugins/modules/system/filesystem.py +++ b/plugins/modules/system/filesystem.py @@ -7,10 +7,11 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type + DOCUMENTATION = ''' --- author: -- Alexander Bulimov (@abulimov) + - Alexander Bulimov (@abulimov) module: filesystem short_description: Makes a filesystem description: @@ -18,13 +19,12 @@ description: options: state: description: - - If C(state=present), the filesystem is created if it doesn't already - exist, that is the default behaviour if I(state) is omitted. - - If C(state=absent), filesystem signatures on I(dev) are wiped if it - contains a filesystem (as known by C(blkid)). - - When C(state=absent), all other options but I(dev) are ignored, and the - module doesn't fail if the device I(dev) doesn't actually exist. - - C(state=absent) is not supported and will fail on FreeBSD systems. + - If C(state=present), the filesystem is created if it doesn't already + exist, that is the default behaviour if I(state) is omitted. + - If C(state=absent), filesystem signatures on I(dev) are wiped if it + contains a filesystem (as known by C(blkid)). + - When C(state=absent), all other options but I(dev) are ignored, and the + module doesn't fail if the device I(dev) doesn't actually exist. type: str choices: [ present, absent ] default: present @@ -32,48 +32,56 @@ options: fstype: choices: [ btrfs, ext2, ext3, ext4, ext4dev, f2fs, lvm, ocfs2, reiserfs, xfs, vfat, swap ] description: - - Filesystem type to be created. This option is required with - C(state=present) (or if I(state) is omitted). - - reiserfs support was added in 2.2. - - lvm support was added in 2.5. - - since 2.5, I(dev) can be an image file. - - vfat support was added in 2.5 - - ocfs2 support was added in 2.6 - - f2fs support was added in 2.7 - - swap support was added in 2.8 + - Filesystem type to be created. This option is required with + C(state=present) (or if I(state) is omitted). + - reiserfs support was added in 2.2. + - lvm support was added in 2.5. + - since 2.5, I(dev) can be an image file. + - vfat support was added in 2.5 + - ocfs2 support was added in 2.6 + - f2fs support was added in 2.7 + - swap support was added in 2.8 type: str aliases: [type] dev: description: - - Target path to device or image file. + - Target path to block device or regular file. + - On systems not using block devices but character devices instead (as + FreeBSD), this module only works when applying to regular files, aka + disk images. type: path required: yes aliases: [device] force: description: - - If C(yes), allows to create new filesystem on devices that already has filesystem. + - If C(yes), allows to create new filesystem on devices that already has filesystem. type: bool default: 'no' resizefs: description: - - If C(yes), if the block device and filesystem size differ, grow the filesystem into the space. - - Supported for C(ext2), C(ext3), C(ext4), C(ext4dev), C(f2fs), C(lvm), C(xfs) and C(vfat) filesystems. - Attempts to resize other filesystem types will fail. - - XFS Will only grow if mounted. Currently, the module is based on commands - from C(util-linux) package to perform operations, so resizing of XFS is - not supported on FreeBSD systems. - - vFAT will likely fail if fatresize < 1.04. + - If C(yes), if the block device and filesystem size differ, grow the filesystem into the space. + - Supported for C(ext2), C(ext3), C(ext4), C(ext4dev), C(f2fs), C(lvm), C(xfs) and C(vfat) filesystems. + Attempts to resize other filesystem types will fail. + - XFS Will only grow if mounted. Currently, the module is based on commands + from C(util-linux) package to perform operations, so resizing of XFS is + not supported on FreeBSD systems. + - vFAT will likely fail if fatresize < 1.04. type: bool default: 'no' opts: description: - - List of options to be passed to mkfs command. + - List of options to be passed to mkfs command. type: str requirements: - - Uses tools related to the I(fstype) (C(mkfs)) and C(blkid) command. When I(resizefs) is enabled, C(blockdev) command is required too. + - Uses tools related to the I(fstype) (C(mkfs)) and the C(blkid) command. + - When I(resizefs) is enabled, C(blockdev) command is required too. notes: - - Potential filesystem on I(dev) are checked using C(blkid), in case C(blkid) isn't able to detect an existing filesystem, - this filesystem is overwritten even if I(force) is C(no). + - Potential filesystem on I(dev) are checked using C(blkid). In case C(blkid) + isn't able to detect an existing filesystem, this filesystem is overwritten + even if I(force) is C(no). + - On FreeBSD systems, either C(e2fsprogs) or C(util-linux) packages provide + a C(blkid) command that is compatible with this module, when applied to + regular files. - This module supports I(check_mode). ''' @@ -102,6 +110,7 @@ import re import stat from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native class Device(object): @@ -114,13 +123,15 @@ class Device(object): statinfo = os.stat(self.path) if stat.S_ISBLK(statinfo.st_mode): blockdev_cmd = self.module.get_bin_path("blockdev", required=True) - dummy, devsize_in_bytes, dummy = self.module.run_command([blockdev_cmd, "--getsize64", self.path], check_rc=True) - return int(devsize_in_bytes) + dummy, out, dummy = self.module.run_command([blockdev_cmd, "--getsize64", self.path], check_rc=True) + devsize_in_bytes = int(out) elif os.path.isfile(self.path): - return os.path.getsize(self.path) + devsize_in_bytes = os.path.getsize(self.path) else: self.module.fail_json(changed=False, msg="Target device not supported: %s" % self) + return devsize_in_bytes + def get_mountpoint(self): """Return (first) mountpoint of device. Returns None when not mounted.""" cmd_findmnt = self.module.get_bin_path("findmnt", required=True) @@ -141,9 +152,12 @@ class Device(object): class Filesystem(object): - GROW = None MKFS = None - MKFS_FORCE_FLAGS = '' + MKFS_FORCE_FLAGS = [] + INFO = None + GROW = None + GROW_MAX_SPACE_FLAGS = [] + GROW_MOUNTPOINT_ONLY = False LANG_ENV = {'LANG': 'C', 'LC_ALL': 'C', 'LC_MESSAGES': 'C'} @@ -155,7 +169,11 @@ class Filesystem(object): return type(self).__name__ def get_fs_size(self, dev): - """ Return size in bytes of filesystem on device. Returns int """ + """Return size in bytes of filesystem on device (integer). + Should query the info with a per-fstype command that can access the + device whenever it is mounted or not, and parse the command output. + Parser must ensure to return an integer, or raise a ValueError. + """ raise NotImplementedError() def create(self, opts, dev): @@ -163,31 +181,27 @@ class Filesystem(object): return mkfs = self.module.get_bin_path(self.MKFS, required=True) - if opts is None: - cmd = "%s %s '%s'" % (mkfs, self.MKFS_FORCE_FLAGS, dev) - else: - cmd = "%s %s %s '%s'" % (mkfs, self.MKFS_FORCE_FLAGS, opts, dev) + cmd = [mkfs] + self.MKFS_FORCE_FLAGS + opts + [str(dev)] self.module.run_command(cmd, check_rc=True) def wipefs(self, dev): - if platform.system() == 'FreeBSD': - msg = "module param state=absent is currently not supported on this OS (FreeBSD)." - self.module.fail_json(msg=msg) - if self.module.check_mode: return # wipefs comes with util-linux package (as 'blockdev' & 'findmnt' above) - # so it is not supported on FreeBSD. Even the use of dd as a fallback is + # that is ported to FreeBSD. The use of dd as a portable fallback is # not doable here if it needs get_mountpoint() (to prevent corruption of - # a mounted filesystem), since 'findmnt' is not available on FreeBSD. + # a mounted filesystem), since 'findmnt' is not available on FreeBSD, + # even in util-linux port for this OS. wipefs = self.module.get_bin_path('wipefs', required=True) - cmd = [wipefs, "--all", dev.__str__()] + cmd = [wipefs, "--all", str(dev)] self.module.run_command(cmd, check_rc=True) - def grow_cmd(self, dev): - cmd = self.module.get_bin_path(self.GROW, required=True) - return [cmd, str(dev)] + def grow_cmd(self, target): + """Build and return the resizefs commandline as list.""" + cmdline = [self.module.get_bin_path(self.GROW, required=True)] + cmdline += self.GROW_MAX_SPACE_FLAGS + [target] + return cmdline def grow(self, dev): """Get dev and fs size and compare. Returns stdout of used command.""" @@ -196,31 +210,50 @@ class Filesystem(object): try: fssize_in_bytes = self.get_fs_size(dev) except NotImplementedError: - self.module.fail_json(changed=False, msg="module does not support resizing %s filesystem yet." % self.fstype) + self.module.fail_json(msg="module does not support resizing %s filesystem yet" % self.fstype) + except ValueError as err: + self.module.warn("unable to process %s output '%s'" % (self.INFO, to_native(err))) + self.module.fail_json(msg="unable to process %s output for %s" % (self.INFO, dev)) if not fssize_in_bytes < devsize_in_bytes: self.module.exit_json(changed=False, msg="%s filesystem is using the whole device %s" % (self.fstype, dev)) elif self.module.check_mode: - self.module.exit_json(changed=True, msg="Resizing filesystem %s on device %s" % (self.fstype, dev)) + self.module.exit_json(changed=True, msg="resizing filesystem %s on device %s" % (self.fstype, dev)) + + if self.GROW_MOUNTPOINT_ONLY: + mountpoint = dev.get_mountpoint() + if not mountpoint: + self.module.fail_json(msg="%s needs to be mounted for %s operations" % (dev, self.fstype)) + grow_target = mountpoint else: - dummy, out, dummy = self.module.run_command(self.grow_cmd(dev), check_rc=True) - return out + grow_target = str(dev) + + dummy, out, dummy = self.module.run_command(self.grow_cmd(grow_target), check_rc=True) + return out class Ext(Filesystem): - MKFS_FORCE_FLAGS = '-F' + MKFS_FORCE_FLAGS = ['-F'] + INFO = 'tune2fs' GROW = 'resize2fs' def get_fs_size(self, dev): - cmd = self.module.get_bin_path('tune2fs', required=True) - # Get Block count and Block size - dummy, size, dummy = self.module.run_command([cmd, '-l', str(dev)], check_rc=True, environ_update=self.LANG_ENV) - for line in size.splitlines(): + """Get Block count and Block size and return their product.""" + cmd = self.module.get_bin_path(self.INFO, required=True) + dummy, out, dummy = self.module.run_command([cmd, '-l', str(dev)], check_rc=True, environ_update=self.LANG_ENV) + + block_count = block_size = None + for line in out.splitlines(): if 'Block count:' in line: block_count = int(line.split(':')[1].strip()) elif 'Block size:' in line: block_size = int(line.split(':')[1].strip()) - return block_size * block_count + if None not in (block_size, block_count): + break + else: + raise ValueError(out) + + return block_size * block_count class Ext2(Ext): @@ -237,52 +270,46 @@ class Ext4(Ext): class XFS(Filesystem): MKFS = 'mkfs.xfs' - MKFS_FORCE_FLAGS = '-f' + MKFS_FORCE_FLAGS = ['-f'] + INFO = 'xfs_info' GROW = 'xfs_growfs' + GROW_MOUNTPOINT_ONLY = True def get_fs_size(self, dev): - cmd = self.module.get_bin_path('xfs_info', required=True) + """Get bsize and blocks and return their product.""" + cmdline = [self.module.get_bin_path(self.INFO, required=True)] + # Depending on the versions, xfs_info is able to get info from the + # device, whenever it is mounted or not, or only if unmounted, or + # only if mounted, or not at all. For any version until now, it is + # able to query info from the mountpoint. So try it first, and use + # device as the last resort: it may or may not work. mountpoint = dev.get_mountpoint() if mountpoint: - rc, out, err = self.module.run_command([cmd, str(mountpoint)], environ_update=self.LANG_ENV) + cmdline += [mountpoint] else: - # Recent GNU/Linux distros support access to unmounted XFS filesystems - rc, out, err = self.module.run_command([cmd, str(dev)], environ_update=self.LANG_ENV) - if rc != 0: - self.module.fail_json(msg="Error while attempting to query size of XFS filesystem: %s" % err) + cmdline += [str(dev)] + dummy, out, dummy = self.module.run_command(cmdline, check_rc=True, environ_update=self.LANG_ENV) + block_size = block_count = None for line in out.splitlines(): col = line.split('=') if col[0].strip() == 'data': - if col[1].strip() != 'bsize': - self.module.fail_json(msg='Unexpected output format from xfs_info (could not locate "bsize")') - if col[2].split()[1] != 'blocks': - self.module.fail_json(msg='Unexpected output format from xfs_info (could not locate "blocks")') - block_size = int(col[2].split()[0]) - block_count = int(col[3].split(',')[0]) - return block_size * block_count + if col[1].strip() == 'bsize': + block_size = int(col[2].split()[0]) + if col[2].split()[1] == 'blocks': + block_count = int(col[3].split(',')[0]) + if None not in (block_size, block_count): + break + else: + raise ValueError(out) - def grow_cmd(self, dev): - # Check first if growing is needed, and then if it is doable or not. - devsize_in_bytes = dev.size() - fssize_in_bytes = self.get_fs_size(dev) - if not fssize_in_bytes < devsize_in_bytes: - self.module.exit_json(changed=False, msg="%s filesystem is using the whole device %s" % (self.fstype, dev)) - - mountpoint = dev.get_mountpoint() - if not mountpoint: - # xfs filesystem needs to be mounted - self.module.fail_json(msg="%s needs to be mounted for xfs operations" % dev) - - cmd = self.module.get_bin_path(self.GROW, required=True) - - return [cmd, str(mountpoint)] + return block_size * block_count class Reiserfs(Filesystem): MKFS = 'mkfs.reiserfs' - MKFS_FORCE_FLAGS = '-f' + MKFS_FORCE_FLAGS = ['-q'] class Btrfs(Filesystem): @@ -290,7 +317,8 @@ class Btrfs(Filesystem): def __init__(self, module): super(Btrfs, self).__init__(module) - dummy, stdout, stderr = self.module.run_command('%s --version' % self.MKFS, check_rc=True) + mkfs = self.module.get_bin_path(self.MKFS, required=True) + dummy, stdout, stderr = self.module.run_command([mkfs, '--version'], check_rc=True) match = re.search(r" v([0-9.]+)", stdout) if not match: # v0.20-rc1 use stderr @@ -298,29 +326,27 @@ class Btrfs(Filesystem): if match: # v0.20-rc1 doesn't have --force parameter added in following version v3.12 if LooseVersion(match.group(1)) >= LooseVersion('3.12'): - self.MKFS_FORCE_FLAGS = '-f' - else: - self.MKFS_FORCE_FLAGS = '' + self.MKFS_FORCE_FLAGS = ['-f'] else: # assume version is greater or equal to 3.12 - self.MKFS_FORCE_FLAGS = '-f' + self.MKFS_FORCE_FLAGS = ['-f'] self.module.warn('Unable to identify mkfs.btrfs version (%r, %r)' % (stdout, stderr)) class Ocfs2(Filesystem): MKFS = 'mkfs.ocfs2' - MKFS_FORCE_FLAGS = '-Fx' + MKFS_FORCE_FLAGS = ['-Fx'] class F2fs(Filesystem): MKFS = 'mkfs.f2fs' + INFO = 'dump.f2fs' GROW = 'resize.f2fs' - @property - def MKFS_FORCE_FLAGS(self): + def __init__(self, module): + super(F2fs, self).__init__(module) mkfs = self.module.get_bin_path(self.MKFS, required=True) - cmd = "%s %s" % (mkfs, os.devnull) - dummy, out, dummy = self.module.run_command(cmd, check_rc=False, environ_update=self.LANG_ENV) + dummy, out, dummy = self.module.run_command([mkfs, os.devnull], check_rc=False, environ_update=self.LANG_ENV) # Looking for " F2FS-tools: mkfs.f2fs Ver: 1.10.0 (2018-01-30)" # mkfs.f2fs displays version since v1.2.0 match = re.search(r"F2FS-tools: mkfs.f2fs Ver: ([0-9.]+) \(", out) @@ -328,69 +354,73 @@ class F2fs(Filesystem): # Since 1.9.0, mkfs.f2fs check overwrite before make filesystem # before that version -f switch wasn't used if LooseVersion(match.group(1)) >= LooseVersion('1.9.0'): - return '-f' - - return '' + self.MKFS_FORCE_FLAGS = ['-f'] def get_fs_size(self, dev): - cmd = self.module.get_bin_path('dump.f2fs', required=True) - # Get sector count and sector size - dummy, dump, dummy = self.module.run_command([cmd, str(dev)], check_rc=True, environ_update=self.LANG_ENV) - sector_size = None - sector_count = None - for line in dump.splitlines(): + """Get sector size and total FS sectors and return their product.""" + cmd = self.module.get_bin_path(self.INFO, required=True) + dummy, out, dummy = self.module.run_command([cmd, str(dev)], check_rc=True, environ_update=self.LANG_ENV) + sector_size = sector_count = None + for line in out.splitlines(): if 'Info: sector size = ' in line: # expected: 'Info: sector size = 512' sector_size = int(line.split()[4]) elif 'Info: total FS sectors = ' in line: # expected: 'Info: total FS sectors = 102400 (50 MB)' sector_count = int(line.split()[5]) - if None not in (sector_size, sector_count): break else: - self.module.warn("Unable to process dump.f2fs output '%s'", '\n'.join(dump)) - self.module.fail_json(msg="Unable to process dump.f2fs output for %s" % dev) + raise ValueError(out) return sector_size * sector_count class VFAT(Filesystem): - if platform.system() == 'FreeBSD': - MKFS = "newfs_msdos" - else: - MKFS = 'mkfs.vfat' + INFO = 'fatresize' GROW = 'fatresize' + GROW_MAX_SPACE_FLAGS = ['-s', 'max'] + + def __init__(self, module): + super(VFAT, self).__init__(module) + if platform.system() == 'FreeBSD': + self.MKFS = 'newfs_msdos' + else: + self.MKFS = 'mkfs.vfat' def get_fs_size(self, dev): - cmd = self.module.get_bin_path(self.GROW, required=True) - dummy, output, dummy = self.module.run_command([cmd, '--info', str(dev)], check_rc=True, environ_update=self.LANG_ENV) - for line in output.splitlines()[1:]: + """Get and return size of filesystem, in bytes.""" + cmd = self.module.get_bin_path(self.INFO, required=True) + dummy, out, dummy = self.module.run_command([cmd, '--info', str(dev)], check_rc=True, environ_update=self.LANG_ENV) + fssize = None + for line in out.splitlines()[1:]: param, value = line.split(':', 1) if param.strip() == 'Size': - return int(value.strip()) - self.module.fail_json(msg="fatresize failed to provide filesystem size for %s" % dev) + fssize = int(value.strip()) + break + else: + raise ValueError(out) - def grow_cmd(self, dev): - cmd = self.module.get_bin_path(self.GROW) - return [cmd, "-s", str(dev.size()), str(dev.path)] + return fssize class LVM(Filesystem): MKFS = 'pvcreate' - MKFS_FORCE_FLAGS = '-f' + MKFS_FORCE_FLAGS = ['-f'] + INFO = 'pvs' GROW = 'pvresize' def get_fs_size(self, dev): - cmd = self.module.get_bin_path('pvs', required=True) + """Get and return PV size, in bytes.""" + cmd = self.module.get_bin_path(self.INFO, required=True) dummy, size, dummy = self.module.run_command([cmd, '--noheadings', '-o', 'pv_size', '--units', 'b', '--nosuffix', str(dev)], check_rc=True) - block_count = int(size) - return block_count + pv_size = int(size) + return pv_size class Swap(Filesystem): MKFS = 'mkswap' - MKFS_FORCE_FLAGS = '-f' + MKFS_FORCE_FLAGS = ['-f'] FILESYSTEMS = { @@ -439,6 +469,10 @@ def main(): force = module.params['force'] resizefs = module.params['resizefs'] + mkfs_opts = [] + if opts is not None: + mkfs_opts = opts.split() + changed = False if not os.path.exists(dev): @@ -451,7 +485,7 @@ def main(): dev = Device(module, dev) cmd = module.get_bin_path('blkid', required=True) - rc, raw_fs, err = module.run_command("%s -c /dev/null -o value -s TYPE %s" % (cmd, dev)) + rc, raw_fs, err = module.run_command([cmd, '-c', os.devnull, '-o', 'value', '-s', 'TYPE', str(dev)]) # In case blkid isn't able to identify an existing filesystem, device is considered as empty, # then this existing filesystem would be overwritten even if force isn't enabled. fs = raw_fs.strip() @@ -481,7 +515,7 @@ def main(): module.fail_json(msg="'%s' is already used as %s, use force=yes to overwrite" % (dev, fs), rc=rc, err=err) # create fs - filesystem.create(opts, dev) + filesystem.create(mkfs_opts, dev) changed = True elif fs: diff --git a/tests/integration/targets/filesystem/defaults/main.yml b/tests/integration/targets/filesystem/defaults/main.yml index 764b98b6ba..15ef85aa0e 100644 --- a/tests/integration/targets/filesystem/defaults/main.yml +++ b/tests/integration/targets/filesystem/defaults/main.yml @@ -17,7 +17,9 @@ tested_filesystems: ext2: {fssize: 10, grow: True} xfs: {fssize: 20, grow: False} # grow requires a mounted filesystem btrfs: {fssize: 150, grow: False} # grow not implemented + reiserfs: {fssize: 33, grow: False} # grow not implemented vfat: {fssize: 20, grow: True} ocfs2: {fssize: '{{ ocfs2_fssize }}', grow: False} # grow not implemented f2fs: {fssize: '{{ f2fs_fssize|default(60) }}', grow: 'f2fs_version is version("1.10.0", ">=")'} lvm: {fssize: 20, grow: True} + swap: {fssize: 10, grow: False} # grow not implemented diff --git a/tests/integration/targets/filesystem/tasks/create_device.yml b/tests/integration/targets/filesystem/tasks/create_device.yml index e49861e7ca..30fd62e33a 100644 --- a/tests/integration/targets/filesystem/tasks/create_device.yml +++ b/tests/integration/targets/filesystem/tasks/create_device.yml @@ -1,6 +1,9 @@ --- - name: 'Create a "disk" file' - command: 'dd if=/dev/zero of={{ image_file }} bs=1M count={{ fssize }}' + community.general.filesize: + path: '{{ image_file }}' + size: '{{ fssize }}M' + force: true - vars: dev: '{{ image_file }}' @@ -8,26 +11,29 @@ - when: fstype == 'lvm' block: - name: 'Create a loop device for LVM' - command: 'losetup --show -f {{ dev }}' + ansible.builtin.command: + cmd: 'losetup --show -f {{ dev }}' register: loop_device_cmd - - set_fact: + - name: 'Switch to loop device target for further tasks' + ansible.builtin.set_fact: dev: "{{ loop_device_cmd.stdout }}" - include_tasks: '{{ action }}.yml' always: - name: 'Detach loop device used for LVM' - command: 'losetup -d {{ dev }}' - args: + ansible.builtin.command: + cmd: 'losetup -d {{ dev }}' removes: '{{ dev }}' when: fstype == 'lvm' - name: 'Clean correct device for LVM' - set_fact: + ansible.builtin.set_fact: dev: '{{ image_file }}' when: fstype == 'lvm' - - file: + - name: 'Remove disk image file' + ansible.builtin.file: name: '{{ image_file }}' state: absent diff --git a/tests/integration/targets/filesystem/tasks/create_fs.yml b/tests/integration/targets/filesystem/tasks/create_fs.yml index 688a4462db..de1a9f18a0 100644 --- a/tests/integration/targets/filesystem/tasks/create_fs.yml +++ b/tests/integration/targets/filesystem/tasks/create_fs.yml @@ -1,43 +1,58 @@ -- name: filesystem creation - filesystem: +--- +- name: "Create filesystem" + community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' register: fs_result -- assert: +- name: "Assert that results are as expected" + ansible.builtin.assert: that: - 'fs_result is changed' - 'fs_result is success' -- command: 'blkid -c /dev/null -o value -s UUID {{ dev }}' +- name: "Get UUID of created filesystem" + ansible.builtin.command: + cmd: 'blkid -c /dev/null -o value -s UUID {{ dev }}' + changed_when: false register: uuid - name: "Check that filesystem isn't created if force isn't used" - filesystem: + community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' register: fs2_result -- command: 'blkid -c /dev/null -o value -s UUID {{ dev }}' +- name: "Get UUID of the filesystem" + ansible.builtin.command: + cmd: 'blkid -c /dev/null -o value -s UUID {{ dev }}' + changed_when: false register: uuid2 -- assert: +- name: "Assert that filesystem UUID is not changed" + ansible.builtin.assert: that: - - 'not (fs2_result is changed)' + - 'fs2_result is not changed' - 'fs2_result is success' - 'uuid.stdout == uuid2.stdout' -- name: Check that filesystem is recreated if force is used - filesystem: +- name: "Check that filesystem is recreated if force is used" + community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' force: yes register: fs3_result -- command: 'blkid -c /dev/null -o value -s UUID {{ dev }}' +- name: "Get UUID of the new filesystem" + ansible.builtin.command: + cmd: 'blkid -c /dev/null -o value -s UUID {{ dev }}' + changed_when: false register: uuid3 -- assert: +- name: "Assert that filesystem UUID is changed" + # libblkid gets no UUID at all for this fstype on FreeBSD + when: not (ansible_system == 'FreeBSD' and fstype == 'reiserfs') + ansible.builtin.assert: that: - 'fs3_result is changed' - 'fs3_result is success' @@ -46,24 +61,31 @@ - when: 'grow|bool and (fstype != "vfat" or resize_vfat)' block: - - name: increase fake device - shell: 'dd if=/dev/zero bs=1M count=1 >> {{ image_file }}' + - name: "Increase fake device" + community.general.filesize: + path: '{{ image_file }}' + size: '{{ fssize | int + 1 }}M' - - name: Resize loop device for LVM - command: losetup -c {{ dev }} + - name: "Resize loop device for LVM" + ansible.builtin.command: + cmd: 'losetup -c {{ dev }}' when: fstype == 'lvm' - - name: Expand filesystem - filesystem: + - name: "Expand filesystem" + community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' resizefs: yes register: fs4_result - - command: 'blkid -c /dev/null -o value -s UUID {{ dev }}' + - name: "Get UUID of the filesystem" + ansible.builtin.command: + cmd: 'blkid -c /dev/null -o value -s UUID {{ dev }}' + changed_when: false register: uuid4 - - assert: + - name: "Assert that filesystem UUID is not changed" + ansible.builtin.assert: that: - 'fs4_result is changed' - 'fs4_result is success' @@ -74,14 +96,15 @@ (fstype == "xfs" and ansible_system == "Linux" and ansible_distribution not in ["CentOS", "Ubuntu"]) block: - - name: Check that resizefs does nothing if device size is not changed - filesystem: + - name: "Check that resizefs does nothing if device size is not changed" + community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' resizefs: yes register: fs5_result - - assert: + - name: "Assert that the state did not change" + ansible.builtin.assert: that: - 'fs5_result is not changed' - 'fs5_result is succeeded' diff --git a/tests/integration/targets/filesystem/tasks/main.yml b/tests/integration/targets/filesystem/tasks/main.yml index 44e8c49f61..d836c8a15d 100644 --- a/tests/integration/targets/filesystem/tasks/main.yml +++ b/tests/integration/targets/filesystem/tasks/main.yml @@ -4,9 +4,9 @@ # and should not be used as examples of how to write Ansible roles # #################################################################### -- debug: +- ansible.builtin.debug: msg: '{{ role_name }}' -- debug: +- ansible.builtin.debug: msg: '{{ role_path|basename }}' - import_tasks: setup.yml @@ -27,29 +27,35 @@ grow: '{{ item.0.value.grow }}' action: '{{ item.1 }}' when: - - 'not (item.0.key == "btrfs" and ansible_system == "FreeBSD")' # btrfs not available on FreeBSD - # On Ubuntu trusty, blkid is unable to identify filesystem smaller than 256Mo, see - # https://www.kernel.org/pub/linux/utils/util-linux/v2.21/v2.21-ChangeLog - # https://anonscm.debian.org/cgit/collab-maint/pkg-util-linux.git/commit/?id=04f7020eadf31efc731558df92daa0a1c336c46c - - 'not (item.0.key == "btrfs" and (ansible_distribution == "Ubuntu" and ansible_distribution_release == "trusty"))' - - 'not (item.0.key == "btrfs" and (ansible_facts.os_family == "RedHat" and ansible_facts.distribution_major_version is version("8", ">=")))' - - 'not (item.0.key == "lvm" and ansible_system == "FreeBSD")' # LVM not available on FreeBSD - - 'not (item.0.key == "lvm" and ansible_virtualization_type in ["docker", "container", "containerd"])' # Tests use losetup which can not be used inside unprivileged container - - 'not (item.0.key == "ocfs2" and ansible_os_family != "Debian")' # ocfs2 only available on Debian based distributions - - 'not (item.0.key == "f2fs" and ansible_system == "FreeBSD")' - # f2fs-tools package not available with RHEL/CentOS - - 'not (item.0.key == "f2fs" and ansible_distribution in ["CentOS", "RedHat"])' - # On Ubuntu trusty, blkid (2.20.1) is unable to identify F2FS filesystem. blkid handles F2FS since v2.23, see: - # https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.23/v2.23-ReleaseNotes - - 'not (item.0.key == "f2fs" and ansible_distribution == "Ubuntu" and ansible_distribution_version is version("14.04", "<="))' - - 'not (item.1 == "overwrite_another_fs" and ansible_system == "FreeBSD")' + # FreeBSD limited support + # Not available: btrfs, lvm, f2fs, ocfs2 + # All BSD systems use swap fs, but only Linux needs mkswap + # Supported: ext2/3/4 (e2fsprogs), xfs (xfsprogs), reiserfs (progsreiserfs), vfat + - 'not (ansible_system == "FreeBSD" and item.0.key in ["btrfs", "f2fs", "swap", "lvm", "ocfs2"])' + # Available on FreeBSD but not on testbed (util-linux conflicts with e2fsprogs): wipefs, mkfs.minix + - 'not (ansible_system == "FreeBSD" and item.1 in ["overwrite_another_fs", "remove_fs"])' + + # Other limitations and corner cases + + # f2fs-tools and reiserfs-utils packages not available with RHEL/CentOS on CI + - 'not (ansible_distribution in ["CentOS", "RedHat"] and item.0.key in ["f2fs", "reiserfs"])' + - 'not (ansible_os_family == "RedHat" and ansible_distribution_major_version is version("8", ">=") and + item.0.key == "btrfs")' + # ocfs2 only available on Debian based distributions + - 'not (item.0.key == "ocfs2" and ansible_os_family != "Debian")' + # Tests use losetup which can not be used inside unprivileged container + - 'not (item.0.key == "lvm" and ansible_virtualization_type in ["docker", "container", "containerd"])' - - 'not (item.1 == "remove_fs" and ansible_system == "FreeBSD")' # util-linux not available on FreeBSD # On CentOS 6 shippable containers, wipefs seems unable to remove vfat signatures - - 'not (item.1 == "remove_fs" and item.0.key == "vfat" and ansible_distribution == "CentOS" and - ansible_distribution_version is version("7.0", "<"))' + - 'not (ansible_distribution == "CentOS" and ansible_distribution_version is version("7.0", "<") and + item.1 == "remove_fs" and item.0.key == "vfat")' + # On same systems, mkfs.minix (unhandled by the module) can't find the device/file + - 'not (ansible_distribution == "CentOS" and ansible_distribution_version is version("7.0", "<") and + item.1 == "overwrite_another_fs")' # The xfsprogs package on newer versions of OpenSUSE (15+) require Python 3, we skip this on our Python 2 container # OpenSUSE 42.3 Python2 and the other py3 containers are not affected so we will continue to run that - - 'not (item.0.key == "xfs" and ansible_os_family == "Suse" and ansible_python.version.major == 2 and ansible_distribution_major_version|int != 42)' + - 'not (ansible_os_family == "Suse" and ansible_distribution_major_version|int != 42 and + item.0.key == "xfs" and ansible_python.version.major == 2)' + loop: "{{ query('dict', tested_filesystems)|product(['create_fs', 'overwrite_another_fs', 'remove_fs'])|list }}" diff --git a/tests/integration/targets/filesystem/tasks/overwrite_another_fs.yml b/tests/integration/targets/filesystem/tasks/overwrite_another_fs.yml index 671d9b0bea..4bf92836bb 100644 --- a/tests/integration/targets/filesystem/tasks/overwrite_another_fs.yml +++ b/tests/integration/targets/filesystem/tasks/overwrite_another_fs.yml @@ -1,40 +1,55 @@ --- - name: 'Recreate "disk" file' - command: 'dd if=/dev/zero of={{ image_file }} bs=1M count={{ fssize }}' + community.general.filesize: + path: '{{ image_file }}' + size: '{{ fssize }}M' + force: true -- name: 'Create a swap filesystem' - command: 'mkswap {{ dev }}' +- name: 'Create a minix filesystem' + ansible.builtin.command: + cmd: 'mkfs.minix {{ dev }}' -- command: 'blkid -c /dev/null -o value -s UUID {{ dev }}' +- name: 'Get UUID of the new filesystem' + ansible.builtin.command: + cmd: 'blkid -c /dev/null -o value -s UUID {{ dev }}' + changed_when: false register: uuid - name: "Check that an existing filesystem (not handled by this module) isn't overwritten when force isn't used" - filesystem: + community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' register: fs_result ignore_errors: True -- command: 'blkid -c /dev/null -o value -s UUID {{ dev }}' +- name: 'Get UUID of the filesystem' + ansible.builtin.command: + cmd: 'blkid -c /dev/null -o value -s UUID {{ dev }}' + changed_when: false register: uuid2 -- assert: +- name: 'Assert that module failed and filesystem UUID is not changed' + ansible.builtin.assert: that: - 'fs_result is failed' - 'uuid.stdout == uuid2.stdout' - name: "Check that an existing filesystem (not handled by this module) is overwritten when force is used" - filesystem: + community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' force: yes register: fs_result2 -- command: 'blkid -c /dev/null -o value -s UUID {{ dev }}' +- name: 'Get UUID of the new filesystem' + ansible.builtin.command: + cmd: 'blkid -c /dev/null -o value -s UUID {{ dev }}' + changed_when: false register: uuid3 -- assert: +- name: 'Assert that module succeeded and filesystem UUID is changed' + ansible.builtin.assert: that: - - 'fs_result2 is successful' + - 'fs_result2 is success' - 'fs_result2 is changed' - 'uuid2.stdout != uuid3.stdout' diff --git a/tests/integration/targets/filesystem/tasks/remove_fs.yml b/tests/integration/targets/filesystem/tasks/remove_fs.yml index 7d1ca2a19c..338d439d60 100644 --- a/tests/integration/targets/filesystem/tasks/remove_fs.yml +++ b/tests/integration/targets/filesystem/tasks/remove_fs.yml @@ -1,98 +1,98 @@ --- # We assume 'create_fs' tests have passed. -- name: filesystem creation - filesystem: +- name: "Create filesystem" + community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' -- name: get filesystem UUID with 'blkid' - command: +- name: "Get filesystem UUID with 'blkid'" + ansible.builtin.command: cmd: 'blkid -c /dev/null -o value -s UUID {{ dev }}' changed_when: false register: blkid_ref -- name: Assert that a filesystem exists on top of the device - assert: +- name: "Assert that a filesystem exists on top of the device" + ansible.builtin.assert: that: - blkid_ref.stdout | length > 0 # Test check_mode first -- name: filesystem removal (check mode) - filesystem: +- name: "Remove filesystem (check mode)" + community.general.filesystem: dev: '{{ dev }}' state: absent register: wipefs check_mode: yes -- name: get filesystem UUID with 'blkid' (should remain the same) - command: +- name: "Get filesystem UUID with 'blkid' (should remain the same)" + ansible.builtin.command: cmd: 'blkid -c /dev/null -o value -s UUID {{ dev }}' changed_when: false register: blkid -- name: Assert that the state changed but the filesystem still exists - assert: +- name: "Assert that the state changed but the filesystem still exists" + ansible.builtin.assert: that: - wipefs is changed - blkid.stdout == blkid_ref.stdout # Do it -- name: filesystem removal - filesystem: +- name: "Remove filesystem" + community.general.filesystem: dev: '{{ dev }}' state: absent register: wipefs -- name: get filesystem UUID with 'blkid' (should be empty) - command: +- name: "Get filesystem UUID with 'blkid' (should be empty)" + ansible.builtin.command: cmd: 'blkid -c /dev/null -o value -s UUID {{ dev }}' changed_when: false failed_when: false register: blkid -- name: Assert that the state changed and the device has no filesystem - assert: +- name: "Assert that the state changed and the device has no filesystem" + ansible.builtin.assert: that: - wipefs is changed - blkid.stdout | length == 0 - blkid.rc == 2 # Do it again -- name: filesystem removal (idempotency) - filesystem: +- name: "Remove filesystem (idempotency)" + community.general.filesystem: dev: '{{ dev }}' state: absent register: wipefs -- name: Assert that the state did not change - assert: +- name: "Assert that the state did not change" + ansible.builtin.assert: that: - wipefs is not changed # and again -- name: filesystem removal (idempotency, check mode) - filesystem: +- name: "Remove filesystem (idempotency, check mode)" + community.general.filesystem: dev: '{{ dev }}' state: absent register: wipefs check_mode: yes -- name: Assert that the state did not change - assert: +- name: "Assert that the state did not change" + ansible.builtin.assert: that: - wipefs is not changed # By the way, test removal of a filesystem on unexistent device -- name: filesystem removal (unexistent device) - filesystem: +- name: "Remove filesystem (unexistent device)" + community.general.filesystem: dev: '/dev/unexistent_device' state: absent register: wipefs -- name: Assert that the state did not change - assert: +- name: "Assert that the state did not change" + ansible.builtin.assert: that: - wipefs is not changed diff --git a/tests/integration/targets/filesystem/tasks/setup.yml b/tests/integration/targets/filesystem/tasks/setup.yml index 82fe7c54e6..9ca4b983d0 100644 --- a/tests/integration/targets/filesystem/tasks/setup.yml +++ b/tests/integration/targets/filesystem/tasks/setup.yml @@ -1,6 +1,9 @@ --- -- name: install filesystem tools - package: +# By installing e2fsprogs on FreeBSD, we get a usable blkid command, but this +# package conflicts with util-linux, that provides blkid too, but also wipefs +# (required for filesystem state=absent). +- name: "Install filesystem tools" + ansible.builtin.package: name: '{{ item }}' state: present # xfsprogs on OpenSUSE requires Python 3, skip this for our newer Py2 OpenSUSE builds @@ -9,86 +12,134 @@ - e2fsprogs - xfsprogs -- block: - - name: install btrfs progs - package: - name: btrfs-progs - state: present - when: - - ansible_os_family != 'Suse' - - not (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('16.04', '<=')) - - ansible_system != "FreeBSD" - - not (ansible_facts.os_family == "RedHat" and ansible_facts.distribution_major_version is version('8', '>=')) +- name: "Install btrfs progs" + ansible.builtin.package: + name: btrfs-progs + state: present + when: + - ansible_os_family != 'Suse' + - not (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('16.04', '<=')) + - ansible_system != "FreeBSD" + - not (ansible_facts.os_family == "RedHat" and ansible_facts.distribution_major_version is version('8', '>=')) - - name: install btrfs progs (Ubuntu <= 16.04) - package: - name: btrfs-tools - state: present - when: ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('16.04', '<=') +- name: "Install btrfs tools (Ubuntu <= 16.04)" + ansible.builtin.package: + name: btrfs-tools + state: present + when: + - ansible_distribution == 'Ubuntu' + - ansible_distribution_version is version('16.04', '<=') - - name: install btrfs progs (OpenSuse) - package: - name: '{{ item }}' - state: present - when: ansible_os_family == 'Suse' - with_items: - - python{{ ansible_python.version.major }}-xml - - btrfsprogs +- name: "Install btrfs progs (OpenSuse)" + ansible.builtin.package: + name: '{{ item }}' + state: present + when: ansible_os_family == 'Suse' + with_items: + - python{{ ansible_python.version.major }}-xml + - btrfsprogs - - name: install ocfs2 (Debian) - package: - name: ocfs2-tools - state: present - when: ansible_os_family == 'Debian' +- name: "Install reiserfs utils (Fedora)" + ansible.builtin.package: + name: reiserfs-utils + state: present + when: + - ansible_distribution == 'Fedora' - - when: - - ansible_os_family != 'RedHat' or ansible_distribution == 'Fedora' - - ansible_distribution != 'Ubuntu' or ansible_distribution_version is version('16.04', '>=') - - ansible_system != "FreeBSD" - block: - - name: install f2fs - package: - name: f2fs-tools - state: present +- name: "Install reiserfs (OpenSuse)" + ansible.builtin.package: + name: reiserfs + state: present + when: + - ansible_os_family == 'Suse' - - name: fetch f2fs version - command: mkfs.f2fs /dev/null - ignore_errors: yes - register: mkfs_f2fs +- name: "Install reiserfs progs (Debian and more)" + ansible.builtin.package: + name: reiserfsprogs + state: present + when: + - ansible_system == 'Linux' + - ansible_os_family not in ['Suse', 'RedHat'] - - set_fact: - f2fs_version: '{{ mkfs_f2fs.stdout | regex_search("F2FS-tools: mkfs.f2fs Ver:.*") | regex_replace("F2FS-tools: mkfs.f2fs Ver: ([0-9.]+) .*", "\1") }}' +- name: "Install reiserfs progs (FreeBSD)" + ansible.builtin.package: + name: progsreiserfs + state: present + when: + - ansible_system == 'FreeBSD' - - name: install dosfstools and lvm2 (Linux) - package: - name: '{{ item }}' - with_items: - - dosfstools - - lvm2 - when: ansible_system == 'Linux' +- name: "Install ocfs2 (Debian)" + ansible.builtin.package: + name: ocfs2-tools + state: present + when: ansible_os_family == 'Debian' -- block: - - name: install fatresize - package: - name: fatresize - state: present - - command: fatresize --help - register: fatresize - - set_fact: - fatresize_version: '{{ fatresize.stdout_lines[0] | regex_search("[0-9]+\.[0-9]+\.[0-9]+") }}' +- name: "Install f2fs tools and get version" + when: + - ansible_os_family != 'RedHat' or ansible_distribution == 'Fedora' + - ansible_distribution != 'Ubuntu' or ansible_distribution_version is version('16.04', '>=') + - ansible_system != "FreeBSD" + block: + - name: "Install f2fs tools" + ansible.builtin.package: + name: f2fs-tools + state: present + + - name: "Fetch f2fs version" + ansible.builtin.command: + cmd: mkfs.f2fs /dev/null + changed_when: false + ignore_errors: true + register: mkfs_f2fs + + - name: "Record f2fs_version" + ansible.builtin.set_fact: + f2fs_version: '{{ mkfs_f2fs.stdout + | regex_search("F2FS-tools: mkfs.f2fs Ver:.*") + | regex_replace("F2FS-tools: mkfs.f2fs Ver: ([0-9.]+) .*", "\1") }}' + +- name: "Install dosfstools and lvm2 (Linux)" + ansible.builtin.package: + name: '{{ item }}' + with_items: + - dosfstools + - lvm2 + when: ansible_system == 'Linux' + +- name: "Install fatresize and get version" when: - ansible_system == 'Linux' - ansible_os_family != 'Suse' - ansible_os_family != 'RedHat' or (ansible_distribution == 'CentOS' and ansible_distribution_version is version('7.0', '==')) + block: + - name: "Install fatresize" + ansible.builtin.package: + name: fatresize + state: present -- command: mke2fs -V + - name: "Fetch fatresize version" + ansible.builtin.command: + cmd: fatresize --help + changed_when: false + register: fatresize + + - name: "Record fatresize_version" + ansible.builtin.set_fact: + fatresize_version: '{{ fatresize.stdout_lines[0] | regex_search("[0-9]+\.[0-9]+\.[0-9]+") }}' + +- name: "Fetch e2fsprogs version" + ansible.builtin.command: + cmd: mke2fs -V + changed_when: false register: mke2fs -- set_fact: +- name: "Record e2fsprogs_version" + ansible.builtin.set_fact: # mke2fs 1.43.6 (29-Aug-2017) e2fsprogs_version: '{{ mke2fs.stderr_lines[0] | regex_search("[0-9]{1,2}\.[0-9]{1,2}(\.[0-9]{1,2})?") }}' -- set_fact: +- name: "Set version-related facts to skip further tasks" + ansible.builtin.set_fact: # http://e2fsprogs.sourceforge.net/e2fsprogs-release.html#1.43 # Mke2fs no longer complains if the user tries to create a file system # using the entire block device. From f1dab6d4a798637627d181e4e710df446b88116e Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 18 May 2021 11:57:35 +0200 Subject: [PATCH 069/139] Prepare 3.1.0 release. --- changelogs/fragments/3.1.0.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/fragments/3.1.0.yml diff --git a/changelogs/fragments/3.1.0.yml b/changelogs/fragments/3.1.0.yml new file mode 100644 index 0000000000..c1cd23f095 --- /dev/null +++ b/changelogs/fragments/3.1.0.yml @@ -0,0 +1 @@ +release_summary: Regular feature and bugfix release. From 62043463f313c5305c4d3d626a6a6ac9aa444c56 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 18 May 2021 12:27:31 +0200 Subject: [PATCH 070/139] iptables_state: fix per-table initialization command (#2525) (#2553) * refactor initialize_from_null_state() * Use a more neutral command (iptables -L) to load per-table needed modules. * fix 'FutureWarning: Possible nested set at position ...' (re.sub) * fix pylints (module + action plugin) * unsubscriptable-object * superfluous-parens * consider-using-in * unused-variable * unused-import * no-else-break * cleanup other internal module_args if they exist * add changelog fragment * Apply suggestions from code review (changelog fragment) Co-authored-by: Felix Fontein * Remove useless plugin type in changelog fragment Co-authored-by: Amin Vakil Co-authored-by: Felix Fontein Co-authored-by: Amin Vakil (cherry picked from commit 2c1ab2d384cc44136e76a9177a7e87e4c7d1f96a) Co-authored-by: quidame --- ...ables_state-fix-initialization-command.yml | 6 +++ plugins/action/system/iptables_state.py | 19 ++++--- plugins/modules/system/iptables_state.py | 49 +++++++++---------- 3 files changed, 37 insertions(+), 37 deletions(-) create mode 100644 changelogs/fragments/2525-iptables_state-fix-initialization-command.yml diff --git a/changelogs/fragments/2525-iptables_state-fix-initialization-command.yml b/changelogs/fragments/2525-iptables_state-fix-initialization-command.yml new file mode 100644 index 0000000000..552c0b26ab --- /dev/null +++ b/changelogs/fragments/2525-iptables_state-fix-initialization-command.yml @@ -0,0 +1,6 @@ +--- +bugfixes: + - "iptables_state - fix initialization of iptables from null state when adressing + more than one table (https://github.com/ansible-collections/community.general/issues/2523)." + - "iptables_state - fix a 'FutureWarning' in a regex and do some basic code clean up + (https://github.com/ansible-collections/community.general/pull/2525)." diff --git a/plugins/action/system/iptables_state.py b/plugins/action/system/iptables_state.py index cc174b3bd7..96b6dc689c 100644 --- a/plugins/action/system/iptables_state.py +++ b/plugins/action/system/iptables_state.py @@ -7,7 +7,7 @@ __metaclass__ = type import time from ansible.plugins.action import ActionBase -from ansible.errors import AnsibleError, AnsibleActionFail, AnsibleConnectionFailure +from ansible.errors import AnsibleActionFail, AnsibleConnectionFailure from ansible.utils.vars import merge_hash from ansible.utils.display import Display @@ -46,7 +46,7 @@ class ActionModule(ActionBase): the async wrapper results (those with the ansible_job_id key). ''' # At least one iteration is required, even if timeout is 0. - for i in range(max(1, timeout)): + for dummy in range(max(1, timeout)): async_result = self._execute_module( module_name='ansible.builtin.async_status', module_args=module_args, @@ -76,7 +76,6 @@ class ActionModule(ActionBase): task_async = self._task.async_val check_mode = self._play_context.check_mode max_timeout = self._connection._play_context.timeout - module_name = self._task.action module_args = self._task.args if module_args.get('state', None) == 'restored': @@ -133,7 +132,7 @@ class ActionModule(ActionBase): # The module is aware to not process the main iptables-restore # command before finding (and deleting) the 'starter' cookie on # the host, so the previous query will not reach ssh timeout. - garbage = self._low_level_execute_command(starter_cmd, sudoable=self.DEFAULT_SUDOABLE) + dummy = self._low_level_execute_command(starter_cmd, sudoable=self.DEFAULT_SUDOABLE) # As the main command is not yet executed on the target, here # 'finished' means 'failed before main command be executed'. @@ -143,7 +142,7 @@ class ActionModule(ActionBase): except AttributeError: pass - for x in range(max_timeout): + for dummy in range(max_timeout): time.sleep(1) remaining_time -= 1 # - AnsibleConnectionFailure covers rejected requests (i.e. @@ -151,7 +150,7 @@ class ActionModule(ActionBase): # - ansible_timeout is able to cover dropped requests (due # to a rule or policy DROP) if not lower than async_val. try: - garbage = self._low_level_execute_command(confirm_cmd, sudoable=self.DEFAULT_SUDOABLE) + dummy = self._low_level_execute_command(confirm_cmd, sudoable=self.DEFAULT_SUDOABLE) break except AnsibleConnectionFailure: continue @@ -164,12 +163,12 @@ class ActionModule(ActionBase): del result[key] if result.get('invocation', {}).get('module_args'): - if '_timeout' in result['invocation']['module_args']: - del result['invocation']['module_args']['_back'] - del result['invocation']['module_args']['_timeout'] + for key in ('_back', '_timeout', '_async_dir', 'jid'): + if result['invocation']['module_args'].get(key): + del result['invocation']['module_args'][key] async_status_args['mode'] = 'cleanup' - garbage = self._execute_module( + dummy = self._execute_module( module_name='ansible.builtin.async_status', module_args=async_status_args, task_vars=task_vars, diff --git a/plugins/modules/system/iptables_state.py b/plugins/modules/system/iptables_state.py index 5647526819..326db862bc 100644 --- a/plugins/modules/system/iptables_state.py +++ b/plugins/modules/system/iptables_state.py @@ -232,7 +232,7 @@ import filecmp import shutil from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_bytes, to_native, to_text +from ansible.module_utils._text import to_bytes, to_native IPTABLES = dict( @@ -262,7 +262,7 @@ def read_state(b_path): lines = text.splitlines() while '' in lines: lines.remove('') - return (lines) + return lines def write_state(b_path, lines, changed): @@ -282,9 +282,9 @@ def write_state(b_path, lines, changed): if b_destdir and not os.path.exists(b_destdir) and not module.check_mode: try: os.makedirs(b_destdir) - except Exception as e: + except Exception as err: module.fail_json( - msg='Error creating %s. Error code: %s. Error description: %s' % (destdir, e[0], e[1]), + msg='Error creating %s: %s' % (destdir, to_native(err)), initial_state=lines) changed = True @@ -295,10 +295,10 @@ def write_state(b_path, lines, changed): if changed and not module.check_mode: try: shutil.copyfile(tmpfile, b_path) - except Exception as e: + except Exception as err: path = to_native(b_path, errors='surrogate_or_strict') module.fail_json( - msg='Error saving state into %s. Error code: %s. Error description: %s' % (path, e[0], e[1]), + msg='Error saving state into %s: %s' % (path, to_native(err)), initial_state=lines) return changed @@ -313,14 +313,11 @@ def initialize_from_null_state(initializer, initcommand, table): if table is None: table = 'filter' - tmpfd, tmpfile = tempfile.mkstemp() - with os.fdopen(tmpfd, 'w') as f: - f.write('*%s\nCOMMIT\n' % table) - - initializer.append(tmpfile) - (rc, out, err) = module.run_command(initializer, check_rc=True) + commandline = list(initializer) + commandline += ['-t', table] + (rc, out, err) = module.run_command(commandline, check_rc=True) (rc, out, err) = module.run_command(initcommand, check_rc=True) - return (rc, out, err) + return rc, out, err def filter_and_format_state(string): @@ -328,13 +325,13 @@ def filter_and_format_state(string): Remove timestamps to ensure idempotence between runs. Also remove counters by default. And return the result as a list. ''' - string = re.sub('((^|\n)# (Generated|Completed)[^\n]*) on [^\n]*', '\\1', string) + string = re.sub(r'((^|\n)# (Generated|Completed)[^\n]*) on [^\n]*', r'\1', string) if not module.params['counters']: - string = re.sub('[[][0-9]+:[0-9]+[]]', '[0:0]', string) + string = re.sub(r'\[[0-9]+:[0-9]+\]', r'[0:0]', string) lines = string.splitlines() while '' in lines: lines.remove('') - return (lines) + return lines def per_table_state(command, state): @@ -347,14 +344,14 @@ def per_table_state(command, state): COMMAND = list(command) if '*%s' % t in state.splitlines(): COMMAND.extend(['--table', t]) - (rc, out, err) = module.run_command(COMMAND, check_rc=True) - out = re.sub('(^|\n)(# Generated|# Completed|[*]%s|COMMIT)[^\n]*' % t, '', out) - out = re.sub(' *[[][0-9]+:[0-9]+[]] *', '', out) + 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 - return (tables) + return tables def main(): @@ -402,7 +399,7 @@ def main(): changed = False COMMANDARGS = [] INITCOMMAND = [bin_iptables_save] - INITIALIZER = [bin_iptables_restore] + INITIALIZER = [bin_iptables, '-L', '-n'] TESTCOMMAND = [bin_iptables_restore, '--test'] if counters: @@ -502,7 +499,7 @@ def main(): if _back is not None: b_back = to_bytes(_back, errors='surrogate_or_strict') - garbage = write_state(b_back, initref_state, changed) + dummy = write_state(b_back, initref_state, changed) BACKCOMMAND = list(MAINCOMMAND) BACKCOMMAND.append(_back) @@ -559,9 +556,7 @@ def main(): if os.path.exists(b_starter): os.remove(b_starter) break - else: - time.sleep(0.01) - continue + time.sleep(0.01) (rc, stdout, stderr) = module.run_command(MAINCOMMAND) if 'Another app is currently holding the xtables lock' in stderr: @@ -579,7 +574,7 @@ def main(): (rc, stdout, stderr) = module.run_command(SAVECOMMAND, check_rc=True) restored_state = filter_and_format_state(stdout) - if restored_state != initref_state and restored_state != initial_state: + if restored_state not in (initref_state, initial_state): if module.check_mode: changed = True else: @@ -609,7 +604,7 @@ def main(): # timeout # * task attribute 'poll' equals 0 # - for x in range(_timeout): + for dummy in range(_timeout): if os.path.exists(b_back): time.sleep(1) continue From 26c2876f5041886b0b475054198048aa44a5e573 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 18 May 2021 13:08:06 +0200 Subject: [PATCH 071/139] pacman: add 'executable' option to use an alternative pacman binary (#2524) (#2554) * Add 'bin' option to use an alternative pacman binary * Add changelog entry * Incorporate recommendations * Update plugins/modules/packaging/os/pacman.py * Apply suggestions from code review Co-authored-by: Felix Fontein (cherry picked from commit c4624d3ad8db66a3f7d21656fef8a8f60a907aeb) Co-authored-by: Andre Lehmann --- .../fragments/2524-pacman_add_bin_option.yml | 2 ++ plugins/modules/packaging/os/pacman.py | 26 ++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/2524-pacman_add_bin_option.yml diff --git a/changelogs/fragments/2524-pacman_add_bin_option.yml b/changelogs/fragments/2524-pacman_add_bin_option.yml new file mode 100644 index 0000000000..1a7c78f7ec --- /dev/null +++ b/changelogs/fragments/2524-pacman_add_bin_option.yml @@ -0,0 +1,2 @@ +minor_changes: + - pacman - add ``executable`` option to use an alternative pacman binary (https://github.com/ansible-collections/community.general/issues/2524). diff --git a/plugins/modules/packaging/os/pacman.py b/plugins/modules/packaging/os/pacman.py index b19528ba9e..859c90a6c4 100644 --- a/plugins/modules/packaging/os/pacman.py +++ b/plugins/modules/packaging/os/pacman.py @@ -44,6 +44,14 @@ options: default: no type: bool + executable: + description: + - Name of binary to use. This can either be C(pacman) or a pacman compatible AUR helper. + - Beware that AUR helpers might behave unexpectedly and are therefore not recommended. + default: pacman + type: str + version_added: 3.1.0 + extra_args: description: - Additional option to pass to pacman when enforcing C(state). @@ -79,8 +87,10 @@ options: type: str notes: - - When used with a `loop:` each package will be processed individually, - it is much more efficient to pass the list directly to the `name` option. + - When used with a C(loop:) each package will be processed individually, + it is much more efficient to pass the list directly to the I(name) option. + - To use an AUR helper (I(executable) option), a few extra setup steps might be required beforehand. + For example, a dedicated build user with permissions to install packages could be necessary. ''' RETURN = ''' @@ -109,6 +119,13 @@ EXAMPLES = ''' - ~/bar-1.0-1-any.pkg.tar.xz state: present +- name: Install package from AUR using a Pacman compatible AUR helper + community.general.pacman: + name: foo + state: present + executable: yay + extra_args: --builddir /var/cache/yay + - name: Upgrade package foo community.general.pacman: name: foo @@ -419,6 +436,7 @@ def main(): name=dict(type='list', elements='str', aliases=['pkg', 'package']), state=dict(type='str', default='present', choices=['present', 'installed', 'latest', 'absent', 'removed']), force=dict(type='bool', default=False), + executable=dict(type='str', default='pacman'), extra_args=dict(type='str', default=''), upgrade=dict(type='bool', default=False), upgrade_extra_args=dict(type='str', default=''), @@ -432,11 +450,13 @@ def main(): supports_check_mode=True, ) - pacman_path = module.get_bin_path('pacman', True) module.run_command_environ_update = dict(LC_ALL='C') p = module.params + # find pacman binary + pacman_path = module.get_bin_path(p['executable'], True) + # normalize the state parameter if p['state'] in ['present', 'installed']: p['state'] = 'present' From 658e95c5cacbb718c906ebd76bd878dd344c6ee6 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 18 May 2021 13:09:47 +0200 Subject: [PATCH 072/139] Release 3.1.0. --- CHANGELOG.rst | 89 ++++++++++++ changelogs/changelog.yaml | 132 ++++++++++++++++++ .../1085-consul-acl-hcl-whitelist-update.yml | 2 - .../fragments/2323-groupby_as_dict-filter.yml | 3 - ...dfish_config-skip-incorrect-attributes.yml | 4 - ...spotinst_aws_elastigroup-list-elements.yml | 2 - .../2364-influxdb_user-first_user.yml | 5 - ...uxdb_retention_policy-add-state-option.yml | 6 - .../2393-module_helper-breakdown.yml | 2 - .../fragments/2410-linode-improvements.yml | 5 - .../fragments/2417-nmcli_remove_dead_code.yml | 2 - ...450-gitlab_user-add_expires_at_option.yaml | 3 - .../2472_filesystem_module_revamp.yml | 9 -- ...85-java_keystore-ssl_backend-parameter.yml | 2 - ...fluxdb_user-fix-multiple-no-privileges.yml | 2 - ...asswordstore-add_option_ignore_missing.yml | 3 - .../fragments/2514-mh-improved-changed.yml | 2 - .../fragments/2517-cmd-params-from-vars.yml | 2 - .../2518-nmap-fix-cache-disabled.yml | 2 - .../fragments/2520-connection-refactors.yml | 9 -- .../fragments/2524-pacman_add_bin_option.yml | 2 - ...ables_state-fix-initialization-command.yml | 6 - .../2526-java_keystore-password-via-stdin.yml | 4 - .../fragments/2540-zfs-delegate-choices.yml | 2 - changelogs/fragments/3.1.0.yml | 1 - changelogs/fragments/deprecate-ipaddress.yml | 4 - changelogs/fragments/nios-deprecation.yml | 2 - 27 files changed, 221 insertions(+), 86 deletions(-) delete mode 100644 changelogs/fragments/1085-consul-acl-hcl-whitelist-update.yml delete mode 100644 changelogs/fragments/2323-groupby_as_dict-filter.yml delete mode 100644 changelogs/fragments/2334-redfish_config-skip-incorrect-attributes.yml delete mode 100644 changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml delete mode 100644 changelogs/fragments/2364-influxdb_user-first_user.yml delete mode 100644 changelogs/fragments/2383-influxdb_retention_policy-add-state-option.yml delete mode 100644 changelogs/fragments/2393-module_helper-breakdown.yml delete mode 100644 changelogs/fragments/2410-linode-improvements.yml delete mode 100644 changelogs/fragments/2417-nmcli_remove_dead_code.yml delete mode 100644 changelogs/fragments/2450-gitlab_user-add_expires_at_option.yaml delete mode 100644 changelogs/fragments/2472_filesystem_module_revamp.yml delete mode 100644 changelogs/fragments/2485-java_keystore-ssl_backend-parameter.yml delete mode 100644 changelogs/fragments/2499-influxdb_user-fix-multiple-no-privileges.yml delete mode 100644 changelogs/fragments/2500-passwordstore-add_option_ignore_missing.yml delete mode 100644 changelogs/fragments/2514-mh-improved-changed.yml delete mode 100644 changelogs/fragments/2517-cmd-params-from-vars.yml delete mode 100644 changelogs/fragments/2518-nmap-fix-cache-disabled.yml delete mode 100644 changelogs/fragments/2520-connection-refactors.yml delete mode 100644 changelogs/fragments/2524-pacman_add_bin_option.yml delete mode 100644 changelogs/fragments/2525-iptables_state-fix-initialization-command.yml delete mode 100644 changelogs/fragments/2526-java_keystore-password-via-stdin.yml delete mode 100644 changelogs/fragments/2540-zfs-delegate-choices.yml delete mode 100644 changelogs/fragments/3.1.0.yml delete mode 100644 changelogs/fragments/deprecate-ipaddress.yml delete mode 100644 changelogs/fragments/nios-deprecation.yml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ba15b4e7a4..5ae15a68d4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,95 @@ Community General Release Notes This changelog describes changes after version 2.0.0. +v3.1.0 +====== + +Release Summary +--------------- + +Regular feature and bugfix release. + +Minor Changes +------------- + +- ModuleHelper module utils - improved mechanism for customizing the calculation of ``changed`` (https://github.com/ansible-collections/community.general/pull/2514). +- chroot connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). +- cmd (Module Helper) module utils - ``CmdMixin`` now pulls the value for ``run_command()`` params from ``self.vars``, as opposed to previously retrieving those from ``self.module.params`` (https://github.com/ansible-collections/community.general/pull/2517). +- filesystem - cleanup and revamp module, tests and doc. Pass all commands to ``module.run_command()`` as lists. Move the device-vs-mountpoint logic to ``grow()`` method. Give to all ``get_fs_size()`` the same logic and error handling. (https://github.com/ansible-collections/community.general/pull/2472). +- funcd connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). +- gitlab_user - add ``expires_at`` option (https://github.com/ansible-collections/community.general/issues/2325). +- idrac_redfish_config - modified set_manager_attributes function to skip invalid attribute instead of returning. Added skipped attributes to output. Modified module exit to add warning variable (https://github.com/ansible-collections/community.general/issues/1995). +- influxdb_retention_policy - add ``state`` parameter with allowed values ``present`` and ``absent`` to support deletion of existing retention policies (https://github.com/ansible-collections/community.general/issues/2383). +- influxdb_retention_policy - simplify duration logic parsing (https://github.com/ansible-collections/community.general/pull/2385). +- iocage connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). +- jail connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). +- java_keystore - added ``ssl_backend`` parameter for using the cryptography library instead of the OpenSSL binary (https://github.com/ansible-collections/community.general/pull/2485). +- java_keystore - replace envvar by stdin to pass secret to ``keytool`` (https://github.com/ansible-collections/community.general/pull/2526). +- linode - added proper traceback when failing due to exceptions (https://github.com/ansible-collections/community.general/pull/2410). +- linode - parameter ``additional_disks`` is now validated as a list of dictionaries (https://github.com/ansible-collections/community.general/pull/2410). +- lxc connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). +- module_helper module utils - break down of the long file into smaller pieces (https://github.com/ansible-collections/community.general/pull/2393). +- nmcli - remove dead code, ``options`` never contains keys from ``param_alias`` (https://github.com/ansible-collections/community.general/pull/2417). +- pacman - add ``executable`` option to use an alternative pacman binary (https://github.com/ansible-collections/community.general/issues/2524). +- passwordstore lookup - add option ``missing`` to choose what to do if the password file is missing (https://github.com/ansible-collections/community.general/pull/2500). +- qubes connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). +- redfish_config - modified module exit to add warning variable (https://github.com/ansible-collections/community.general/issues/1995). +- redfish_utils module utils - modified set_bios_attributes function to skip invalid attribute instead of returning. Added skipped attributes to output (https://github.com/ansible-collections/community.general/issues/1995). +- saltstack connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). +- spotinst_aws_elastigroup - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2355). +- zfs_delegate_admin - drop choices from permissions, allowing any permission supported by the underlying zfs commands (https://github.com/ansible-collections/community.general/pull/2540). +- zone connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + +Deprecated Features +------------------- + +- The nios, nios_next_ip, nios_next_network lookup plugins, the nios documentation fragment, and the nios_host_record, nios_ptr_record, nios_mx_record, nios_fixed_address, nios_zone, nios_member, nios_a_record, nios_aaaa_record, nios_network, nios_dns_view, nios_txt_record, nios_naptr_record, nios_srv_record, nios_cname_record, nios_nsgroup, and nios_network_view module have been deprecated and will be removed from community.general 5.0.0. Please install the `infoblox.nios_modules `_ collection instead and use its plugins and modules (https://github.com/ansible-collections/community.general/pull/2458). +- The vendored copy of ``ipaddress`` will be removed in community.general 4.0.0. Please switch to ``ipaddress`` from the Python 3 standard library, or `from pypi `_, if your code relies on the vendored version of ``ipaddress`` (https://github.com/ansible-collections/community.general/pull/2459). +- linode - parameter ``backupsenabled`` is deprecated and will be removed in community.general 5.0.0 (https://github.com/ansible-collections/community.general/pull/2410). +- lxd inventory plugin - the plugin will require ``ipaddress`` installed when used with Python 2 from community.general 4.0.0 on. ``ipaddress`` is part of the Python 3 standard library, but can be installed for Python 2 from pypi (https://github.com/ansible-collections/community.general/pull/2459). +- scaleway_security_group_rule - the module will require ``ipaddress`` installed when used with Python 2 from community.general 4.0.0 on. ``ipaddress`` is part of the Python 3 standard library, but can be installed for Python 2 from pypi (https://github.com/ansible-collections/community.general/pull/2459). + +Bugfixes +-------- + +- consul_acl - update the hcl allowlist to include all supported options (https://github.com/ansible-collections/community.general/pull/2495). +- filesystem - repair ``reiserfs`` fstype support after adding it to integration tests (https://github.com/ansible-collections/community.general/pull/2472). +- influxdb_user - allow creation of admin users when InfluxDB authentication is enabled but no other user exists on the database. In this scenario, InfluxDB 1.x allows only ``CREATE USER`` queries and rejects any other query (https://github.com/ansible-collections/community.general/issues/2364). +- influxdb_user - fix bug where an influxdb user has no privileges for 2 or more databases (https://github.com/ansible-collections/community.general/pull/2499). +- iptables_state - fix a 'FutureWarning' in a regex and do some basic code clean up (https://github.com/ansible-collections/community.general/pull/2525). +- iptables_state - fix initialization of iptables from null state when adressing more than one table (https://github.com/ansible-collections/community.general/issues/2523). +- nmap inventory plugin - fix local variable error when cache is disabled (https://github.com/ansible-collections/community.general/issues/2512). + +New Plugins +----------- + +Filter +~~~~~~ + +- groupby_as_dict - Transform a sequence of dictionaries to a dictionary where the dictionaries are indexed by an attribute + +Lookup +~~~~~~ + +- dependent - Composes a list with nested elements of other lists or dicts which can depend on previous loop variables +- random_pet - Generates random pet names + +New Modules +----------- + +Cloud +~~~~~ + +misc +^^^^ + +- proxmox_nic - Management of a NIC of a Qemu(KVM) VM in a Proxmox VE cluster. + +Notification +~~~~~~~~~~~~ + +- discord - Send Discord messages + v3.0.2 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 600b51463b..b51e963768 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -1024,3 +1024,135 @@ releases: - 2454-detect_zfs_changed.yml - 3.0.2.yml release_date: '2021-05-11' + 3.1.0: + changes: + bugfixes: + - consul_acl - update the hcl allowlist to include all supported options (https://github.com/ansible-collections/community.general/pull/2495). + - filesystem - repair ``reiserfs`` fstype support after adding it to integration + tests (https://github.com/ansible-collections/community.general/pull/2472). + - influxdb_user - allow creation of admin users when InfluxDB authentication + is enabled but no other user exists on the database. In this scenario, InfluxDB + 1.x allows only ``CREATE USER`` queries and rejects any other query (https://github.com/ansible-collections/community.general/issues/2364). + - influxdb_user - fix bug where an influxdb user has no privileges for 2 or + more databases (https://github.com/ansible-collections/community.general/pull/2499). + - iptables_state - fix a 'FutureWarning' in a regex and do some basic code clean + up (https://github.com/ansible-collections/community.general/pull/2525). + - iptables_state - fix initialization of iptables from null state when adressing + more than one table (https://github.com/ansible-collections/community.general/issues/2523). + - nmap inventory plugin - fix local variable error when cache is disabled (https://github.com/ansible-collections/community.general/issues/2512). + deprecated_features: + - The nios, nios_next_ip, nios_next_network lookup plugins, the nios documentation + fragment, and the nios_host_record, nios_ptr_record, nios_mx_record, nios_fixed_address, + nios_zone, nios_member, nios_a_record, nios_aaaa_record, nios_network, nios_dns_view, + nios_txt_record, nios_naptr_record, nios_srv_record, nios_cname_record, nios_nsgroup, + and nios_network_view module have been deprecated and will be removed from + community.general 5.0.0. Please install the `infoblox.nios_modules `_ + collection instead and use its plugins and modules (https://github.com/ansible-collections/community.general/pull/2458). + - The vendored copy of ``ipaddress`` will be removed in community.general 4.0.0. + Please switch to ``ipaddress`` from the Python 3 standard library, or `from + pypi `_, if your code relies on the vendored + version of ``ipaddress`` (https://github.com/ansible-collections/community.general/pull/2459). + - linode - parameter ``backupsenabled`` is deprecated and will be removed in + community.general 5.0.0 (https://github.com/ansible-collections/community.general/pull/2410). + - lxd inventory plugin - the plugin will require ``ipaddress`` installed when + used with Python 2 from community.general 4.0.0 on. ``ipaddress`` is part + of the Python 3 standard library, but can be installed for Python 2 from pypi + (https://github.com/ansible-collections/community.general/pull/2459). + - scaleway_security_group_rule - the module will require ``ipaddress`` installed + when used with Python 2 from community.general 4.0.0 on. ``ipaddress`` is + part of the Python 3 standard library, but can be installed for Python 2 from + pypi (https://github.com/ansible-collections/community.general/pull/2459). + minor_changes: + - ModuleHelper module utils - improved mechanism for customizing the calculation + of ``changed`` (https://github.com/ansible-collections/community.general/pull/2514). + - chroot connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - cmd (Module Helper) module utils - ``CmdMixin`` now pulls the value for ``run_command()`` + params from ``self.vars``, as opposed to previously retrieving those from + ``self.module.params`` (https://github.com/ansible-collections/community.general/pull/2517). + - filesystem - cleanup and revamp module, tests and doc. Pass all commands to + ``module.run_command()`` as lists. Move the device-vs-mountpoint logic to + ``grow()`` method. Give to all ``get_fs_size()`` the same logic and error + handling. (https://github.com/ansible-collections/community.general/pull/2472). + - funcd connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - gitlab_user - add ``expires_at`` option (https://github.com/ansible-collections/community.general/issues/2325). + - idrac_redfish_config - modified set_manager_attributes function to skip invalid + attribute instead of returning. Added skipped attributes to output. Modified + module exit to add warning variable (https://github.com/ansible-collections/community.general/issues/1995). + - influxdb_retention_policy - add ``state`` parameter with allowed values ``present`` + and ``absent`` to support deletion of existing retention policies (https://github.com/ansible-collections/community.general/issues/2383). + - influxdb_retention_policy - simplify duration logic parsing (https://github.com/ansible-collections/community.general/pull/2385). + - iocage connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - jail connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - java_keystore - added ``ssl_backend`` parameter for using the cryptography + library instead of the OpenSSL binary (https://github.com/ansible-collections/community.general/pull/2485). + - java_keystore - replace envvar by stdin to pass secret to ``keytool`` (https://github.com/ansible-collections/community.general/pull/2526). + - linode - added proper traceback when failing due to exceptions (https://github.com/ansible-collections/community.general/pull/2410). + - linode - parameter ``additional_disks`` is now validated as a list of dictionaries + (https://github.com/ansible-collections/community.general/pull/2410). + - lxc connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - module_helper module utils - break down of the long file into smaller pieces + (https://github.com/ansible-collections/community.general/pull/2393). + - nmcli - remove dead code, ``options`` never contains keys from ``param_alias`` + (https://github.com/ansible-collections/community.general/pull/2417). + - pacman - add ``executable`` option to use an alternative pacman binary (https://github.com/ansible-collections/community.general/issues/2524). + - passwordstore lookup - add option ``missing`` to choose what to do if the + password file is missing (https://github.com/ansible-collections/community.general/pull/2500). + - qubes connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - redfish_config - modified module exit to add warning variable (https://github.com/ansible-collections/community.general/issues/1995). + - redfish_utils module utils - modified set_bios_attributes function to skip + invalid attribute instead of returning. Added skipped attributes to output + (https://github.com/ansible-collections/community.general/issues/1995). + - saltstack connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + - spotinst_aws_elastigroup - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2355). + - zfs_delegate_admin - drop choices from permissions, allowing any permission + supported by the underlying zfs commands (https://github.com/ansible-collections/community.general/pull/2540). + - zone connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). + release_summary: Regular feature and bugfix release. + fragments: + - 1085-consul-acl-hcl-whitelist-update.yml + - 2323-groupby_as_dict-filter.yml + - 2334-redfish_config-skip-incorrect-attributes.yml + - 2355-spotinst_aws_elastigroup-list-elements.yml + - 2364-influxdb_user-first_user.yml + - 2383-influxdb_retention_policy-add-state-option.yml + - 2393-module_helper-breakdown.yml + - 2410-linode-improvements.yml + - 2417-nmcli_remove_dead_code.yml + - 2450-gitlab_user-add_expires_at_option.yaml + - 2472_filesystem_module_revamp.yml + - 2485-java_keystore-ssl_backend-parameter.yml + - 2499-influxdb_user-fix-multiple-no-privileges.yml + - 2500-passwordstore-add_option_ignore_missing.yml + - 2514-mh-improved-changed.yml + - 2517-cmd-params-from-vars.yml + - 2518-nmap-fix-cache-disabled.yml + - 2520-connection-refactors.yml + - 2524-pacman_add_bin_option.yml + - 2525-iptables_state-fix-initialization-command.yml + - 2526-java_keystore-password-via-stdin.yml + - 2540-zfs-delegate-choices.yml + - 3.1.0.yml + - deprecate-ipaddress.yml + - nios-deprecation.yml + modules: + - description: Send Discord messages + name: discord + namespace: notification + - description: Management of a NIC of a Qemu(KVM) VM in a Proxmox VE cluster. + name: proxmox_nic + namespace: cloud.misc + plugins: + filter: + - description: Transform a sequence of dictionaries to a dictionary where the + dictionaries are indexed by an attribute + name: groupby_as_dict + namespace: null + lookup: + - description: Composes a list with nested elements of other lists or dicts + which can depend on previous loop variables + name: dependent + namespace: null + - description: Generates random pet names + name: random_pet + namespace: null + release_date: '2021-05-18' diff --git a/changelogs/fragments/1085-consul-acl-hcl-whitelist-update.yml b/changelogs/fragments/1085-consul-acl-hcl-whitelist-update.yml deleted file mode 100644 index 78db43da7d..0000000000 --- a/changelogs/fragments/1085-consul-acl-hcl-whitelist-update.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - consul_acl - update the hcl allowlist to include all supported options (https://github.com/ansible-collections/community.general/pull/2495). diff --git a/changelogs/fragments/2323-groupby_as_dict-filter.yml b/changelogs/fragments/2323-groupby_as_dict-filter.yml deleted file mode 100644 index e72f323a60..0000000000 --- a/changelogs/fragments/2323-groupby_as_dict-filter.yml +++ /dev/null @@ -1,3 +0,0 @@ -add plugin.filter: - - name: groupby_as_dict - description: Transform a sequence of dictionaries to a dictionary where the dictionaries are indexed by an attribute diff --git a/changelogs/fragments/2334-redfish_config-skip-incorrect-attributes.yml b/changelogs/fragments/2334-redfish_config-skip-incorrect-attributes.yml deleted file mode 100644 index 2e609c43fc..0000000000 --- a/changelogs/fragments/2334-redfish_config-skip-incorrect-attributes.yml +++ /dev/null @@ -1,4 +0,0 @@ -minor_changes: - - redfish_utils module utils - modified set_bios_attributes function to skip invalid attribute instead of returning. Added skipped attributes to output (https://github.com/ansible-collections/community.general/issues/1995). - - idrac_redfish_config - modified set_manager_attributes function to skip invalid attribute instead of returning. Added skipped attributes to output. Modified module exit to add warning variable (https://github.com/ansible-collections/community.general/issues/1995). - - redfish_config - modified module exit to add warning variable (https://github.com/ansible-collections/community.general/issues/1995). diff --git a/changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml b/changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml deleted file mode 100644 index 876b212690..0000000000 --- a/changelogs/fragments/2355-spotinst_aws_elastigroup-list-elements.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - spotinst_aws_elastigroup - elements of list parameters are now validated (https://github.com/ansible-collections/community.general/pull/2355). diff --git a/changelogs/fragments/2364-influxdb_user-first_user.yml b/changelogs/fragments/2364-influxdb_user-first_user.yml deleted file mode 100644 index 905688643b..0000000000 --- a/changelogs/fragments/2364-influxdb_user-first_user.yml +++ /dev/null @@ -1,5 +0,0 @@ -bugfixes: - - influxdb_user - allow creation of admin users when InfluxDB authentication - is enabled but no other user exists on the database. In this scenario, - InfluxDB 1.x allows only ``CREATE USER`` queries and rejects any other query - (https://github.com/ansible-collections/community.general/issues/2364). diff --git a/changelogs/fragments/2383-influxdb_retention_policy-add-state-option.yml b/changelogs/fragments/2383-influxdb_retention_policy-add-state-option.yml deleted file mode 100644 index b8e358848e..0000000000 --- a/changelogs/fragments/2383-influxdb_retention_policy-add-state-option.yml +++ /dev/null @@ -1,6 +0,0 @@ -minor_changes: - - influxdb_retention_policy - add ``state`` parameter with allowed values - ``present`` and ``absent`` to support deletion of existing retention policies - (https://github.com/ansible-collections/community.general/issues/2383). - - influxdb_retention_policy - simplify duration logic parsing - (https://github.com/ansible-collections/community.general/pull/2385). diff --git a/changelogs/fragments/2393-module_helper-breakdown.yml b/changelogs/fragments/2393-module_helper-breakdown.yml deleted file mode 100644 index 472a1c3569..0000000000 --- a/changelogs/fragments/2393-module_helper-breakdown.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - module_helper module utils - break down of the long file into smaller pieces (https://github.com/ansible-collections/community.general/pull/2393). diff --git a/changelogs/fragments/2410-linode-improvements.yml b/changelogs/fragments/2410-linode-improvements.yml deleted file mode 100644 index cdf8551b08..0000000000 --- a/changelogs/fragments/2410-linode-improvements.yml +++ /dev/null @@ -1,5 +0,0 @@ -deprecated_features: - - linode - parameter ``backupsenabled`` is deprecated and will be removed in community.general 5.0.0 (https://github.com/ansible-collections/community.general/pull/2410). -minor_changes: - - linode - added proper traceback when failing due to exceptions (https://github.com/ansible-collections/community.general/pull/2410). - - linode - parameter ``additional_disks`` is now validated as a list of dictionaries (https://github.com/ansible-collections/community.general/pull/2410). diff --git a/changelogs/fragments/2417-nmcli_remove_dead_code.yml b/changelogs/fragments/2417-nmcli_remove_dead_code.yml deleted file mode 100644 index 9d94c393fa..0000000000 --- a/changelogs/fragments/2417-nmcli_remove_dead_code.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - nmcli - remove dead code, ``options`` never contains keys from ``param_alias`` (https://github.com/ansible-collections/community.general/pull/2417). diff --git a/changelogs/fragments/2450-gitlab_user-add_expires_at_option.yaml b/changelogs/fragments/2450-gitlab_user-add_expires_at_option.yaml deleted file mode 100644 index 290e13847a..0000000000 --- a/changelogs/fragments/2450-gitlab_user-add_expires_at_option.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: - - gitlab_user - add ``expires_at`` option (https://github.com/ansible-collections/community.general/issues/2325). diff --git a/changelogs/fragments/2472_filesystem_module_revamp.yml b/changelogs/fragments/2472_filesystem_module_revamp.yml deleted file mode 100644 index 691c861078..0000000000 --- a/changelogs/fragments/2472_filesystem_module_revamp.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -minor_changes: - - "filesystem - cleanup and revamp module, tests and doc. Pass all commands to - ``module.run_command()`` as lists. Move the device-vs-mountpoint logic to - ``grow()`` method. Give to all ``get_fs_size()`` the same logic and error - handling. (https://github.com/ansible-collections/community.general/pull/2472)." -bugfixes: - - "filesystem - repair ``reiserfs`` fstype support after adding it to integration - tests (https://github.com/ansible-collections/community.general/pull/2472)." diff --git a/changelogs/fragments/2485-java_keystore-ssl_backend-parameter.yml b/changelogs/fragments/2485-java_keystore-ssl_backend-parameter.yml deleted file mode 100644 index b446476f82..0000000000 --- a/changelogs/fragments/2485-java_keystore-ssl_backend-parameter.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - java_keystore - added ``ssl_backend`` parameter for using the cryptography library instead of the OpenSSL binary (https://github.com/ansible-collections/community.general/pull/2485). diff --git a/changelogs/fragments/2499-influxdb_user-fix-multiple-no-privileges.yml b/changelogs/fragments/2499-influxdb_user-fix-multiple-no-privileges.yml deleted file mode 100644 index d4575ea711..0000000000 --- a/changelogs/fragments/2499-influxdb_user-fix-multiple-no-privileges.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - influxdb_user - fix bug where an influxdb user has no privileges for 2 or more databases (https://github.com/ansible-collections/community.general/pull/2499). diff --git a/changelogs/fragments/2500-passwordstore-add_option_ignore_missing.yml b/changelogs/fragments/2500-passwordstore-add_option_ignore_missing.yml deleted file mode 100644 index 6141ac7747..0000000000 --- a/changelogs/fragments/2500-passwordstore-add_option_ignore_missing.yml +++ /dev/null @@ -1,3 +0,0 @@ -minor_changes: - - passwordstore lookup - add option ``missing`` to choose what to do if the password file is missing - (https://github.com/ansible-collections/community.general/pull/2500). diff --git a/changelogs/fragments/2514-mh-improved-changed.yml b/changelogs/fragments/2514-mh-improved-changed.yml deleted file mode 100644 index b540600130..0000000000 --- a/changelogs/fragments/2514-mh-improved-changed.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - ModuleHelper module utils - improved mechanism for customizing the calculation of ``changed`` (https://github.com/ansible-collections/community.general/pull/2514). diff --git a/changelogs/fragments/2517-cmd-params-from-vars.yml b/changelogs/fragments/2517-cmd-params-from-vars.yml deleted file mode 100644 index 95a2f7165d..0000000000 --- a/changelogs/fragments/2517-cmd-params-from-vars.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - cmd (Module Helper) module utils - ``CmdMixin`` now pulls the value for ``run_command()`` params from ``self.vars``, as opposed to previously retrieving those from ``self.module.params`` (https://github.com/ansible-collections/community.general/pull/2517). diff --git a/changelogs/fragments/2518-nmap-fix-cache-disabled.yml b/changelogs/fragments/2518-nmap-fix-cache-disabled.yml deleted file mode 100644 index 8f4680b6a6..0000000000 --- a/changelogs/fragments/2518-nmap-fix-cache-disabled.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - nmap inventory plugin - fix local variable error when cache is disabled (https://github.com/ansible-collections/community.general/issues/2512). diff --git a/changelogs/fragments/2520-connection-refactors.yml b/changelogs/fragments/2520-connection-refactors.yml deleted file mode 100644 index 2e5c8273d7..0000000000 --- a/changelogs/fragments/2520-connection-refactors.yml +++ /dev/null @@ -1,9 +0,0 @@ -minor_changes: - - chroot connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). - - funcd connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). - - iocage connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). - - jail connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). - - lxc connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). - - qubes connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). - - saltstack connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). - - zone connection - minor refactor to make lints and IDEs happy (https://github.com/ansible-collections/community.general/pull/2520). diff --git a/changelogs/fragments/2524-pacman_add_bin_option.yml b/changelogs/fragments/2524-pacman_add_bin_option.yml deleted file mode 100644 index 1a7c78f7ec..0000000000 --- a/changelogs/fragments/2524-pacman_add_bin_option.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - pacman - add ``executable`` option to use an alternative pacman binary (https://github.com/ansible-collections/community.general/issues/2524). diff --git a/changelogs/fragments/2525-iptables_state-fix-initialization-command.yml b/changelogs/fragments/2525-iptables_state-fix-initialization-command.yml deleted file mode 100644 index 552c0b26ab..0000000000 --- a/changelogs/fragments/2525-iptables_state-fix-initialization-command.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -bugfixes: - - "iptables_state - fix initialization of iptables from null state when adressing - more than one table (https://github.com/ansible-collections/community.general/issues/2523)." - - "iptables_state - fix a 'FutureWarning' in a regex and do some basic code clean up - (https://github.com/ansible-collections/community.general/pull/2525)." diff --git a/changelogs/fragments/2526-java_keystore-password-via-stdin.yml b/changelogs/fragments/2526-java_keystore-password-via-stdin.yml deleted file mode 100644 index 1e45e306af..0000000000 --- a/changelogs/fragments/2526-java_keystore-password-via-stdin.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -minor_changes: - - "java_keystore - replace envvar by stdin to pass secret to ``keytool`` - (https://github.com/ansible-collections/community.general/pull/2526)." diff --git a/changelogs/fragments/2540-zfs-delegate-choices.yml b/changelogs/fragments/2540-zfs-delegate-choices.yml deleted file mode 100644 index 8e0138420c..0000000000 --- a/changelogs/fragments/2540-zfs-delegate-choices.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - zfs_delegate_admin - drop choices from permissions, allowing any permission supported by the underlying zfs commands (https://github.com/ansible-collections/community.general/pull/2540). diff --git a/changelogs/fragments/3.1.0.yml b/changelogs/fragments/3.1.0.yml deleted file mode 100644 index c1cd23f095..0000000000 --- a/changelogs/fragments/3.1.0.yml +++ /dev/null @@ -1 +0,0 @@ -release_summary: Regular feature and bugfix release. diff --git a/changelogs/fragments/deprecate-ipaddress.yml b/changelogs/fragments/deprecate-ipaddress.yml deleted file mode 100644 index 545a66c7f1..0000000000 --- a/changelogs/fragments/deprecate-ipaddress.yml +++ /dev/null @@ -1,4 +0,0 @@ -deprecated_features: -- "The vendored copy of ``ipaddress`` will be removed in community.general 4.0.0. Please switch to ``ipaddress`` from the Python 3 standard library, or `from pypi `_, if your code relies on the vendored version of ``ipaddress`` (https://github.com/ansible-collections/community.general/pull/2459)." -- "scaleway_security_group_rule - the module will require ``ipaddress`` installed when used with Python 2 from community.general 4.0.0 on. ``ipaddress`` is part of the Python 3 standard library, but can be installed for Python 2 from pypi (https://github.com/ansible-collections/community.general/pull/2459)." -- "lxd inventory plugin - the plugin will require ``ipaddress`` installed when used with Python 2 from community.general 4.0.0 on. ``ipaddress`` is part of the Python 3 standard library, but can be installed for Python 2 from pypi (https://github.com/ansible-collections/community.general/pull/2459)." diff --git a/changelogs/fragments/nios-deprecation.yml b/changelogs/fragments/nios-deprecation.yml deleted file mode 100644 index bcfc2b4128..0000000000 --- a/changelogs/fragments/nios-deprecation.yml +++ /dev/null @@ -1,2 +0,0 @@ -deprecated_features: -- "The nios, nios_next_ip, nios_next_network lookup plugins, the nios documentation fragment, and the nios_host_record, nios_ptr_record, nios_mx_record, nios_fixed_address, nios_zone, nios_member, nios_a_record, nios_aaaa_record, nios_network, nios_dns_view, nios_txt_record, nios_naptr_record, nios_srv_record, nios_cname_record, nios_nsgroup, and nios_network_view module have been deprecated and will be removed from community.general 5.0.0. Please install the `infoblox.nios_modules `_ collection instead and use its plugins and modules (https://github.com/ansible-collections/community.general/pull/2458)." From b25e0f360c6546577fd15c8f5005b8643fb27b96 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 18 May 2021 15:00:48 +0200 Subject: [PATCH 073/139] Next release will be 3.2.0. --- galaxy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galaxy.yml b/galaxy.yml index a4b4cad7e0..ba1969d712 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: community name: general -version: 3.1.0 +version: 3.2.0 readme: README.md authors: - Ansible (https://github.com/ansible) From 43e766dd448ed773b9ccb9e6df98ec68e7cd1a7f Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 19 May 2021 22:23:36 +0200 Subject: [PATCH 074/139] removed supporting code for testing module "nuage" - no longer exists here (#2559) (#2563) (cherry picked from commit 452a185a2364b6c404093a1d5c6a6efa0e092c18) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../prepare_nuage_tests/tasks/main.yml | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 tests/integration/targets/prepare_nuage_tests/tasks/main.yml diff --git a/tests/integration/targets/prepare_nuage_tests/tasks/main.yml b/tests/integration/targets/prepare_nuage_tests/tasks/main.yml deleted file mode 100644 index 2a902dc828..0000000000 --- a/tests/integration/targets/prepare_nuage_tests/tasks/main.yml +++ /dev/null @@ -1,24 +0,0 @@ -#################################################################### -# WARNING: These are designed specifically for Ansible tests # -# and should not be used as examples of how to write Ansible roles # -#################################################################### - -- block: - - name: Install Nuage VSD API Simulator - pip: - name: nuage-vsd-sim - - - name: Start Nuage VSD API Simulator - shell: "(cd /; nuage-vsd-sim >/dev/null 2>&1)" - async: 1800 - poll: 0 - - - name: Wait for API to be ready - uri: - url: http://localhost:5000 - register: api - delay: 3 - retries: 10 - until: api.status == 200 - - when: "ansible_python_version is version('2.7', '>=')" From fa477ebb356610a3dffdfe036ad8a321ce37c525 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 20 May 2021 20:11:08 +0200 Subject: [PATCH 075/139] ModuleHelper: CmdMixin custom function for processing cmd results (#2564) (#2565) * MH: custom function for processing cmd results * added changelog fragment * removed case of process_output being a str (cherry picked from commit 1403f5edccd34027b25dfda9fa61309e16b0f3d2) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- changelogs/fragments/2564-mh-cmd-process-output.yml | 2 ++ plugins/module_utils/mh/mixins/cmd.py | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/2564-mh-cmd-process-output.yml diff --git a/changelogs/fragments/2564-mh-cmd-process-output.yml b/changelogs/fragments/2564-mh-cmd-process-output.yml new file mode 100644 index 0000000000..717c0d7fbb --- /dev/null +++ b/changelogs/fragments/2564-mh-cmd-process-output.yml @@ -0,0 +1,2 @@ +minor_changes: + - module_helper module utils - method ``CmdMixin.run_command()`` now accepts ``process_output`` specifying a function to process the outcome of the underlying ``module.run_command()`` (https://github.com/ansible-collections/community.general/pull/2564). diff --git a/plugins/module_utils/mh/mixins/cmd.py b/plugins/module_utils/mh/mixins/cmd.py index eb7cc698cc..724708868e 100644 --- a/plugins/module_utils/mh/mixins/cmd.py +++ b/plugins/module_utils/mh/mixins/cmd.py @@ -152,7 +152,7 @@ class CmdMixin(object): def process_command_output(self, rc, out, err): return rc, out, err - def run_command(self, extra_params=None, params=None, *args, **kwargs): + def run_command(self, extra_params=None, params=None, process_output=None, *args, **kwargs): self.vars.cmd_args = self._calculate_args(extra_params, params) options = dict(self.run_command_fixed_options) env_update = dict(options.get('environ_update', {})) @@ -164,4 +164,9 @@ class CmdMixin(object): options.update(kwargs) rc, out, err = self.module.run_command(self.vars.cmd_args, *args, **options) self.update_output(rc=rc, stdout=out, stderr=err) - return self.process_command_output(rc, out, err) + if process_output is None: + _process = self.process_command_output + else: + _process = process_output + + return _process(rc, out, err) From fd8193e0bd217a5c14d370172ad9088b6312c9ea Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 20 May 2021 23:18:41 +0200 Subject: [PATCH 076/139] Add comment_visibility parameter for comment operation for jira module (#2556) (#2566) * Add comment_visibility parameter for comment operation for jira module Co-authored-by: felixfontein * Update plugins/modules/web_infrastructure/jira.py Co-authored-by: Felix Fontein * Update plugins/modules/web_infrastructure/jira.py Co-authored-by: Felix Fontein * addressed pep8 E711 * Added missing parameter. * params is not in use anymore. * It appears other modules are using options, where in documentation they use suboptions. Inconsistancy? * adjusted indentation * tweaked suboptions, fixed documentation * Added fragment * Update changelogs/fragments/2556-add-comment_visibility-parameter-for-comment-operation-of-jira-module.yml Co-authored-by: Felix Fontein * Update plugins/modules/web_infrastructure/jira.py Co-authored-by: Felix Fontein Co-authored-by: felixfontein (cherry picked from commit 7a169af0534d21142e2ddd5b89a882aedd2b6256) Co-authored-by: momcilo78 --- ...r-for-comment-operation-of-jira-module.yml | 2 + plugins/modules/web_infrastructure/jira.py | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 changelogs/fragments/2556-add-comment_visibility-parameter-for-comment-operation-of-jira-module.yml diff --git a/changelogs/fragments/2556-add-comment_visibility-parameter-for-comment-operation-of-jira-module.yml b/changelogs/fragments/2556-add-comment_visibility-parameter-for-comment-operation-of-jira-module.yml new file mode 100644 index 0000000000..e31fad744a --- /dev/null +++ b/changelogs/fragments/2556-add-comment_visibility-parameter-for-comment-operation-of-jira-module.yml @@ -0,0 +1,2 @@ +minor_changes: + - jira - add comment visibility parameter for comment operation (https://github.com/ansible-collections/community.general/pull/2556). diff --git a/plugins/modules/web_infrastructure/jira.py b/plugins/modules/web_infrastructure/jira.py index 6acf0c7f51..4c10974126 100644 --- a/plugins/modules/web_infrastructure/jira.py +++ b/plugins/modules/web_infrastructure/jira.py @@ -86,6 +86,25 @@ options: - The comment text to add. - Note that JIRA may not allow changing field values on specific transitions or states. + comment_visibility: + type: dict + description: + - Used to specify comment comment visibility. + - See U(https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-comments/#api-rest-api-2-issue-issueidorkey-comment-post) for details. + suboptions: + type: + description: + - Use type to specify which of the JIRA visibility restriction types will be used. + type: str + required: true + choices: [group, role] + value: + description: + - Use value to specify value corresponding to the type of visibility restriction. For example name of the group or role. + type: str + required: true + version_added: '3.2.0' + status: type: str required: false @@ -223,6 +242,18 @@ EXAMPLES = r""" operation: comment comment: A comment added by Ansible +- name: Comment on issue with restricted visibility + community.general.jira: + uri: '{{ server }}' + username: '{{ user }}' + password: '{{ pass }}' + issue: '{{ issue.meta.key }}' + operation: comment + comment: A comment added by Ansible + comment_visibility: + type: role + value: Developers + # Assign an existing issue using edit - name: Assign an issue using free-form fields community.general.jira: @@ -385,6 +416,10 @@ class JIRA(StateModuleHelper): issuetype=dict(type='str', ), issue=dict(type='str', aliases=['ticket']), comment=dict(type='str', ), + comment_visibility=dict(type='dict', options=dict( + type=dict(type='str', choices=['group', 'role'], required=True), + value=dict(type='str', required=True) + )), status=dict(type='str', ), assignee=dict(type='str', ), fields=dict(default={}, type='dict'), @@ -445,6 +480,10 @@ class JIRA(StateModuleHelper): data = { 'body': self.vars.comment } + # if comment_visibility is specified restrict visibility + if self.vars.comment_visibility is not None: + data['visibility'] = self.vars.comment_visibility + url = self.vars.restbase + '/issue/' + self.vars.issue + '/comment' self.vars.meta = self.post(url, data) From e3b47899c59a02c77fa9237556d9e88647b2f2f5 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 21 May 2021 19:44:08 +0200 Subject: [PATCH 077/139] Add missing author name (#2570) (#2576) Signed-off-by: Abhijeet Kasurde (cherry picked from commit 852e2405256b661a1a306a3e7656a60e7fba6803) Co-authored-by: Abhijeet Kasurde --- plugins/inventory/stackpath_compute.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/inventory/stackpath_compute.py b/plugins/inventory/stackpath_compute.py index fb879e869e..8e6b5bf953 100644 --- a/plugins/inventory/stackpath_compute.py +++ b/plugins/inventory/stackpath_compute.py @@ -10,6 +10,8 @@ DOCUMENTATION = ''' name: stackpath_compute short_description: StackPath Edge Computing inventory source version_added: 1.2.0 + author: + - UNKNOWN (@shayrybak) extends_documentation_fragment: - inventory_cache - constructed From 936dd283951a793144c4244c21cc3c12aef5265c Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 22 May 2021 13:46:32 +0200 Subject: [PATCH 078/139] java_cert - fix incorrect certificate alias on pkcs12 import (#2560) (#2581) * fix wrong certificate alias used when importing pkcs12, modify error output, stdout is more relevant than stderr * add changelog fragment * fix changelog fragment (cherry picked from commit 8f083d5d85ddf4f98aee8221bf4cb3c4a721e7d6) Co-authored-by: absynth76 <58172580+absynth76@users.noreply.github.com> --- .../2560-java_cert-pkcs12-alias-bugfix.yml | 2 + plugins/modules/system/java_cert.py | 4 +- .../targets/java_cert/tasks/state_change.yml | 138 ++++++++++++------ 3 files changed, 98 insertions(+), 46 deletions(-) create mode 100644 changelogs/fragments/2560-java_cert-pkcs12-alias-bugfix.yml diff --git a/changelogs/fragments/2560-java_cert-pkcs12-alias-bugfix.yml b/changelogs/fragments/2560-java_cert-pkcs12-alias-bugfix.yml new file mode 100644 index 0000000000..471962d74f --- /dev/null +++ b/changelogs/fragments/2560-java_cert-pkcs12-alias-bugfix.yml @@ -0,0 +1,2 @@ +bugfixes: + - "java_cert - fix issue with incorrect alias used on PKCS#12 certificate import (https://github.com/ansible-collections/community.general/pull/2560)." diff --git a/plugins/modules/system/java_cert.py b/plugins/modules/system/java_cert.py index ad56358034..1c507f9277 100644 --- a/plugins/modules/system/java_cert.py +++ b/plugins/modules/system/java_cert.py @@ -278,7 +278,7 @@ 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_err, + module.fail_json(msg="Internal module failure, cannot extract public certificate from pkcs12, error: %s" % export_stdout, rc=export_rc) with open(dest, 'w') as f: @@ -498,7 +498,7 @@ def main(): if pkcs12_path: # Extracting certificate with openssl - _export_public_cert_from_pkcs12(module, executable, pkcs12_path, cert_alias, pkcs12_pass, new_certificate) + _export_public_cert_from_pkcs12(module, executable, pkcs12_path, pkcs12_alias, pkcs12_pass, new_certificate) elif path: # Extracting the X509 digest is a bit easier. Keytool will print the PEM diff --git a/tests/integration/targets/java_cert/tasks/state_change.yml b/tests/integration/targets/java_cert/tasks/state_change.yml index 3c37fc6727..8cee41106f 100644 --- a/tests/integration/targets/java_cert/tasks/state_change.yml +++ b/tests/integration/targets/java_cert/tasks/state_change.yml @@ -4,52 +4,11 @@ args: creates: "{{ test_key_path }}" -- name: Create the test keystore - java_keystore: - name: placeholder - dest: "{{ test_keystore2_path }}" - password: "{{ test_keystore2_password }}" - private_key: "{{ lookup('file', '{{ test_key_path }}') }}" - certificate: "{{ lookup('file', '{{ test_cert_path }}') }}" - - name: Generate the self signed cert we will use for testing command: openssl req -x509 -newkey rsa:4096 -keyout '{{ test_key2_path }}' -out '{{ test_cert2_path }}' -days 365 -nodes -subj '/CN=localhost' args: creates: "{{ test_key2_path }}" -- name: | - Import the newly created certificate. This is our main test. - If the java_cert has been updated properly, then this task will report changed each time - since the module will be comparing the hash of the certificate instead of validating that the alias - simply exists - java_cert: - cert_alias: test_cert - cert_path: "{{ test_cert2_path }}" - keystore_path: "{{ test_keystore2_path }}" - keystore_pass: "{{ test_keystore2_password }}" - state: present - register: result_x509_changed - -- name: Verify the x509 status has changed - assert: - that: - - result_x509_changed is changed - -- name: | - We also want to make sure that the status doesnt change if we import the same cert - java_cert: - cert_alias: test_cert - cert_path: "{{ test_cert2_path }}" - keystore_path: "{{ test_keystore2_path }}" - keystore_pass: "{{ test_keystore2_password }}" - state: present - register: result_x509_succeeded - -- name: Verify the x509 status is ok - assert: - that: - - result_x509_succeeded is succeeded - - name: Create the pkcs12 archive from the test x509 cert command: > openssl pkcs12 @@ -70,6 +29,97 @@ -out {{ test_pkcs2_path }} -passout pass:"{{ test_keystore2_password }}" +- name: try to create the test keystore based on the just created pkcs12, keystore_create flag not enabled + java_cert: + cert_alias: test_pkcs12_cert + pkcs12_alias: test_pkcs12_cert + pkcs12_path: "{{ test_pkcs_path }}" + pkcs12_password: "{{ test_keystore2_password }}" + keystore_path: "{{ test_keystore2_path }}" + keystore_pass: "{{ test_keystore2_password }}" + ignore_errors: true + register: result_x509_changed + +- name: Verify the x509 status is failed + assert: + that: + - result_x509_changed is failed + +- name: Create the test keystore based on the just created pkcs12 + java_cert: + cert_alias: test_pkcs12_cert + pkcs12_alias: test_pkcs12_cert + pkcs12_path: "{{ test_pkcs_path }}" + pkcs12_password: "{{ test_keystore2_password }}" + keystore_path: "{{ test_keystore2_path }}" + keystore_pass: "{{ test_keystore2_password }}" + keystore_create: yes + +- name: try to import from pkcs12 a non existing alias + java_cert: + cert_alias: test_pkcs12_cert + pkcs12_alias: non_existing_alias + pkcs12_path: "{{ test_pkcs_path }}" + pkcs12_password: "{{ test_keystore2_password }}" + keystore_path: "{{ test_keystore2_path }}" + keystore_pass: "{{ test_keystore2_password }}" + keystore_create: yes + ignore_errors: yes + register: result_x509_changed + +- name: Verify the x509 status is failed + assert: + that: + - result_x509_changed is failed + +- name: import initial test certificate from file path + java_cert: + cert_alias: test_cert + cert_path: "{{ test_cert_path }}" + keystore_path: "{{ test_keystore2_path }}" + keystore_pass: "{{ test_keystore2_password }}" + keystore_create: yes + state: present + register: result_x509_changed + +- name: Verify the x509 status is changed + assert: + that: + - result_x509_changed is changed + +- name: | + Import the newly created certificate. This is our main test. + If the java_cert has been updated properly, then this task will report changed each time + since the module will be comparing the hash of the certificate instead of validating that the alias + simply exists + java_cert: + cert_alias: test_cert + cert_path: "{{ test_cert2_path }}" + keystore_path: "{{ test_keystore2_path }}" + keystore_pass: "{{ test_keystore2_password }}" + state: present + register: result_x509_changed + +- name: Verify the x509 status is changed + assert: + that: + - result_x509_changed is changed + +- name: | + We also want to make sure that the status doesnt change if we import the same cert + java_cert: + cert_alias: test_cert + cert_path: "{{ test_cert2_path }}" + keystore_path: "{{ test_keystore2_path }}" + keystore_pass: "{{ test_keystore2_password }}" + state: present + register: result_x509_succeeded + +- name: Verify the x509 status is ok + assert: + that: + - result_x509_succeeded is succeeded + - name: > Ensure the original pkcs12 cert is in the keystore java_cert: @@ -83,7 +133,7 @@ - name: | Perform the same test, but we will now be testing the pkcs12 functionality - If we add a different pkcs12 cert with the same alias, we should have a chnaged result, NOT the same + If we add a different pkcs12 cert with the same alias, we should have a changed result, NOT the same java_cert: cert_alias: test_pkcs12_cert pkcs12_alias: test_pkcs12_cert @@ -94,7 +144,7 @@ state: present register: result_pkcs12_changed -- name: Verify the pkcs12 status has changed +- name: Verify the pkcs12 status is changed assert: that: - result_pkcs12_changed is changed @@ -155,7 +205,7 @@ that: - result_x509_absent is changed -- name: Ensure we can remove the pkcs12 archive +- name: Ensure we can remove the certificate imported from pkcs12 archive java_cert: cert_alias: test_pkcs12_cert keystore_path: "{{ test_keystore2_path }}" From 4ef05a6483851faa9b3b88b4ffc6820ad754de4d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 22 May 2021 14:36:50 +0200 Subject: [PATCH 079/139] ovir4 inventory script (#2461) (#2583) * update configparser * changelog * handle multiple python version * Update changelogs/fragments/2461-ovirt4-fix-configparser.yml Co-authored-by: Felix Fontein * Update ovirt4.py Co-authored-by: Felix Fontein (cherry picked from commit 3100c32a00d6a350274884aba06afe51a71d5253) Co-authored-by: abikouo <79859644+abikouo@users.noreply.github.com> --- .../2461-ovirt4-fix-configparser.yml | 3 +++ scripts/inventory/ovirt4.py | 27 +++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 changelogs/fragments/2461-ovirt4-fix-configparser.yml diff --git a/changelogs/fragments/2461-ovirt4-fix-configparser.yml b/changelogs/fragments/2461-ovirt4-fix-configparser.yml new file mode 100644 index 0000000000..6e3845b21a --- /dev/null +++ b/changelogs/fragments/2461-ovirt4-fix-configparser.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - ovir4 inventory script - improve configparser creation to avoid crashes for options without values (https://github.com/ansible-collections/community.general/issues/674). diff --git a/scripts/inventory/ovirt4.py b/scripts/inventory/ovirt4.py index afff18dbdb..84b68a1258 100755 --- a/scripts/inventory/ovirt4.py +++ b/scripts/inventory/ovirt4.py @@ -56,6 +56,7 @@ import sys from collections import defaultdict from ansible.module_utils.six.moves import configparser +from ansible.module_utils.six import PY2 import json @@ -106,14 +107,24 @@ def create_connection(): config_path = os.environ.get('OVIRT_INI_PATH', default_path) # Create parser and add ovirt section if it doesn't exist: - config = configparser.SafeConfigParser( - defaults={ - 'ovirt_url': os.environ.get('OVIRT_URL'), - 'ovirt_username': os.environ.get('OVIRT_USERNAME'), - 'ovirt_password': os.environ.get('OVIRT_PASSWORD'), - 'ovirt_ca_file': os.environ.get('OVIRT_CAFILE', ''), - } - ) + if PY2: + config = configparser.SafeConfigParser( + defaults={ + 'ovirt_url': os.environ.get('OVIRT_URL'), + 'ovirt_username': os.environ.get('OVIRT_USERNAME'), + 'ovirt_password': os.environ.get('OVIRT_PASSWORD'), + 'ovirt_ca_file': os.environ.get('OVIRT_CAFILE', ''), + }, allow_no_value=True + ) + else: + config = configparser.ConfigParser( + defaults={ + 'ovirt_url': os.environ.get('OVIRT_URL'), + 'ovirt_username': os.environ.get('OVIRT_USERNAME'), + 'ovirt_password': os.environ.get('OVIRT_PASSWORD'), + 'ovirt_ca_file': os.environ.get('OVIRT_CAFILE', ''), + }, allow_no_value=True + ) if not config.has_section('ovirt'): config.add_section('ovirt') config.read(config_path) From 3a076fd5850a61358a392b744a19bddd8a80e386 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 22 May 2021 14:53:16 +0200 Subject: [PATCH 080/139] Massive adjustment in integration tests for changed and failed (#2577) (#2584) * Replaced ".changed ==" with "is [not] changed". Same for failed * Mr Quote refused to go (cherry picked from commit d7e55db99b331be30301b9d1f027be63504007be) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../targets/archive/tasks/main.yml | 16 ++++++------- .../targets/flatpak/tasks/check_mode.yml | 24 +++++++++---------- .../targets/flatpak/tasks/main.yml | 4 ++-- .../targets/flatpak/tasks/test.yml | 16 ++++++------- .../flatpak_remote/tasks/check_mode.yml | 12 +++++----- .../targets/flatpak_remote/tasks/main.yml | 4 ++-- .../targets/flatpak_remote/tasks/test.yml | 10 ++++---- .../git_config/tasks/get_set_no_state.yml | 4 ++-- .../tasks/get_set_state_present.yml | 4 ++-- .../precedence_between_unset_and_value.yml | 2 +- .../git_config/tasks/unset_check_mode.yml | 2 +- .../git_config/tasks/unset_no_value.yml | 2 +- .../targets/git_config/tasks/unset_value.yml | 2 +- .../targets/github_issue/tasks/main.yml | 10 ++++---- .../targets/hwc_ecs_instance/tasks/main.yml | 8 +++---- .../targets/hwc_evs_disk/tasks/main.yml | 10 ++++---- .../targets/hwc_network_vpc/tasks/main.yml | 8 +++---- .../targets/hwc_smn_topic/tasks/main.yml | 8 +++---- .../targets/hwc_vpc_eip/tasks/main.yml | 8 +++---- .../hwc_vpc_peering_connect/tasks/main.yml | 8 +++---- .../targets/hwc_vpc_port/tasks/main.yml | 8 +++---- .../targets/hwc_vpc_private_ip/tasks/main.yml | 8 +++---- .../targets/hwc_vpc_route/tasks/main.yml | 8 +++---- .../hwc_vpc_security_group/tasks/main.yml | 8 +++---- .../tasks/main.yml | 8 +++---- .../targets/hwc_vpc_subnet/tasks/main.yml | 8 +++---- .../targets/influxdb_user/tasks/tests.yml | 22 ++++++++--------- .../targets/ipify_facts/tasks/main.yml | 6 ++--- .../targets/iso_create/tasks/main.yml | 16 ++++++------- .../targets/iso_extract/tasks/tests.yml | 6 ++--- .../targets/one_host/tasks/main.yml | 2 +- .../test_buildah_synchronize/tasks/main.yml | 4 ++-- .../test-add-children-elements-unicode.yml | 4 ++-- .../xml/tasks/test-add-children-elements.yml | 4 ++-- .../test-add-children-from-groupvars.yml | 4 ++-- .../tasks/test-add-children-insertafter.yml | 4 ++-- .../tasks/test-add-children-insertbefore.yml | 4 ++-- ...t-add-children-with-attributes-unicode.yml | 4 ++-- .../test-add-children-with-attributes.yml | 4 ++-- .../xml/tasks/test-add-element-implicitly.yml | 2 +- .../test-add-namespaced-children-elements.yml | 6 ++--- .../xml/tasks/test-children-elements-xml.yml | 4 ++-- .../targets/xml/tasks/test-count-unicode.yml | 2 +- .../targets/xml/tasks/test-count.yml | 2 +- .../test-get-element-content-unicode.yml | 4 ++-- .../xml/tasks/test-get-element-content.yml | 4 ++-- .../test-mutually-exclusive-attributes.yml | 4 ++-- .../xml/tasks/test-pretty-print-only.yml | 4 ++-- .../targets/xml/tasks/test-pretty-print.yml | 4 ++-- .../tasks/test-remove-attribute-nochange.yml | 4 ++-- .../xml/tasks/test-remove-attribute.yml | 4 ++-- .../tasks/test-remove-element-nochange.yml | 4 ++-- .../targets/xml/tasks/test-remove-element.yml | 4 ++-- ...t-remove-namespaced-attribute-nochange.yml | 4 ++-- .../test-remove-namespaced-attribute.yml | 4 ++-- ...est-remove-namespaced-element-nochange.yml | 4 ++-- .../tasks/test-remove-namespaced-element.yml | 4 ++-- .../test-set-attribute-value-unicode.yml | 4 ++-- .../xml/tasks/test-set-attribute-value.yml | 4 ++-- .../test-set-children-elements-level.yml | 8 +++---- .../test-set-children-elements-unicode.yml | 8 +++---- .../xml/tasks/test-set-children-elements.yml | 8 +++---- .../tasks/test-set-element-value-empty.yml | 4 ++-- .../tasks/test-set-element-value-unicode.yml | 6 ++--- .../xml/tasks/test-set-element-value.yml | 6 ++--- .../test-set-namespaced-attribute-value.yml | 4 ++-- .../test-set-namespaced-children-elements.yml | 6 ++--- .../test-set-namespaced-element-value.yml | 6 ++--- .../targets/xml/tasks/test-xmlstring.yml | 14 +++++------ 69 files changed, 220 insertions(+), 220 deletions(-) diff --git a/tests/integration/targets/archive/tasks/main.yml b/tests/integration/targets/archive/tasks/main.yml index 19a1f6af0c..2267268715 100644 --- a/tests/integration/targets/archive/tasks/main.yml +++ b/tests/integration/targets/archive/tasks/main.yml @@ -174,7 +174,7 @@ - name: Test that the file modes were changed assert: that: - - "archive_02_gz_stat.changed == False " + - archive_02_gz_stat is not changed - "archive_02_gz_stat.stat.mode == '0600'" - "'archived' in archive_bz2_result_02" - "{{ archive_bz2_result_02['archived']| length}} == 3" @@ -199,7 +199,7 @@ - name: Test that the file modes were changed assert: that: - - "archive_02_zip_stat.changed == False" + - archive_02_zip_stat is not changed - "archive_02_zip_stat.stat.mode == '0600'" - "'archived' in archive_zip_result_02" - "{{ archive_zip_result_02['archived']| length}} == 3" @@ -224,7 +224,7 @@ - name: Test that the file modes were changed assert: that: - - "archive_02_bz2_stat.changed == False" + - archive_02_bz2_stat is not changed - "archive_02_bz2_stat.stat.mode == '0600'" - "'archived' in archive_bz2_result_02" - "{{ archive_bz2_result_02['archived']| length}} == 3" @@ -248,7 +248,7 @@ - name: Test that the file modes were changed assert: that: - - "archive_02_xz_stat.changed == False" + - archive_02_xz_stat is not changed - "archive_02_xz_stat.stat.mode == '0600'" - "'archived' in archive_xz_result_02" - "{{ archive_xz_result_02['archived']| length}} == 3" @@ -294,7 +294,7 @@ - name: Assert that nonascii tests succeeded assert: that: - - "nonascii_result_0.changed == true" + - nonascii_result_0 is changed - "nonascii_stat0.stat.exists == true" - name: remove nonascii test @@ -315,7 +315,7 @@ - name: Assert that nonascii tests succeeded assert: that: - - "nonascii_result_1.changed == true" + - nonascii_result_1 is changed - "nonascii_stat_1.stat.exists == true" - name: remove nonascii test @@ -336,7 +336,7 @@ - name: Assert that nonascii tests succeeded assert: that: - - "nonascii_result_1.changed == true" + - nonascii_result_1 is changed - "nonascii_stat_1.stat.exists == true" - name: remove nonascii test @@ -357,7 +357,7 @@ - name: Assert that nonascii tests succeeded assert: that: - - "nonascii_result_2.changed == true" + - nonascii_result_2 is changed - "nonascii_stat_2.stat.exists == true" - name: remove nonascii test diff --git a/tests/integration/targets/flatpak/tasks/check_mode.yml b/tests/integration/targets/flatpak/tasks/check_mode.yml index 065f10dfa7..3186fd2830 100644 --- a/tests/integration/targets/flatpak/tasks/check_mode.yml +++ b/tests/integration/targets/flatpak/tasks/check_mode.yml @@ -13,7 +13,7 @@ - name: Verify addition of absent flatpak test result (check mode) assert: that: - - "addition_result.changed == true" + - addition_result is changed msg: "Adding an absent flatpak shall mark module execution as changed" - name: Test non-existent idempotency of addition of absent flatpak (check mode) @@ -27,7 +27,7 @@ - name: Verify non-existent idempotency of addition of absent flatpak test result (check mode) assert: that: - - "double_addition_result.changed == true" + - double_addition_result is changed msg: | Adding an absent flatpak a second time shall still mark module execution as changed in check mode @@ -44,7 +44,7 @@ - name: Verify removal of absent flatpak test result (check mode) assert: that: - - "removal_result.changed == false" + - removal_result is not changed msg: "Removing an absent flatpak shall mark module execution as not changed" # state=present with url on absent flatpak @@ -60,7 +60,7 @@ - name: Verify addition of absent flatpak with url test result (check mode) assert: that: - - "url_addition_result.changed == true" + - url_addition_result is changed msg: "Adding an absent flatpak from URL shall mark module execution as changed" - name: Test non-existent idempotency of addition of absent flatpak with url (check mode) @@ -76,7 +76,7 @@ result (check mode) assert: that: - - "double_url_addition_result.changed == true" + - double_url_addition_result is changed msg: | Adding an absent flatpak from URL a second time shall still mark module execution as changed in check mode @@ -93,7 +93,7 @@ - name: Verify removal of absent flatpak with url test result (check mode) assert: that: - - "url_removal_result.changed == false" + - url_removal_result is not changed msg: "Removing an absent flatpak shall mark module execution as not changed" @@ -112,7 +112,7 @@ - name: Verify addition test result of present flatpak (check mode) assert: that: - - "addition_present_result.changed == false" + - addition_present_result is not changed msg: "Adding an present flatpak shall mark module execution as not changed" # state=absent on present flatpak @@ -127,7 +127,7 @@ - name: Verify removal of present flatpak test result (check mode) assert: that: - - "removal_present_result.changed == true" + - removal_present_result is changed msg: "Removing a present flatpak shall mark module execution as changed" - name: Test non-existent idempotency of removal (check mode) @@ -140,7 +140,7 @@ - name: Verify non-existent idempotency of removal (check mode) assert: that: - - "double_removal_present_result.changed == true" + - double_removal_present_result is changed msg: | Removing a present flatpak a second time shall still mark module execution as changed in check mode @@ -158,7 +158,7 @@ - name: Verify addition with url of present flatpak test result (check mode) assert: that: - - "url_addition_present_result.changed == false" + - url_addition_present_result is not changed msg: "Adding a present flatpak from URL shall mark module execution as not changed" # state=absent with url on present flatpak @@ -173,7 +173,7 @@ - name: Verify removal with url of present flatpak test result (check mode) assert: that: - - "url_removal_present_result.changed == true" + - url_removal_present_result is changed msg: "Removing an absent flatpak shall mark module execution as not changed" - name: Test non-existent idempotency of removal with url of present flatpak (check mode) @@ -189,5 +189,5 @@ flatpak test result (check mode) assert: that: - - "double_url_removal_present_result.changed == true" + - double_url_removal_present_result is changed msg: Removing an absent flatpak a second time shall still mark module execution as changed diff --git a/tests/integration/targets/flatpak/tasks/main.yml b/tests/integration/targets/flatpak/tasks/main.yml index 45f9ecd501..a1d1bda8a4 100644 --- a/tests/integration/targets/flatpak/tasks/main.yml +++ b/tests/integration/targets/flatpak/tasks/main.yml @@ -40,8 +40,8 @@ - name: Verify executable override test result assert: that: - - "executable_override_result.failed == true" - - "executable_override_result.changed == false" + - executable_override_result is failed + - executable_override_result is not changed msg: "Specifying non-existing executable shall fail module execution" - import_tasks: check_mode.yml diff --git a/tests/integration/targets/flatpak/tasks/test.yml b/tests/integration/targets/flatpak/tasks/test.yml index 20d864a84d..1e7d888bb5 100644 --- a/tests/integration/targets/flatpak/tasks/test.yml +++ b/tests/integration/targets/flatpak/tasks/test.yml @@ -11,7 +11,7 @@ - name: Verify addition test result - {{ method }} assert: that: - - "addition_result.changed == true" + - addition_result is changed msg: "state=present shall add flatpak when absent" - name: Test idempotency of addition - {{ method }} @@ -25,7 +25,7 @@ - name: Verify idempotency of addition test result - {{ method }} assert: that: - - "double_addition_result.changed == false" + - double_addition_result is not changed msg: "state=present shall not do anything when flatpak is already present" # state=absent @@ -40,7 +40,7 @@ - name: Verify removal test result - {{ method }} assert: that: - - "removal_result.changed == true" + - removal_result is changed msg: "state=absent shall remove flatpak when present" - name: Test idempotency of removal - {{ method }} @@ -53,7 +53,7 @@ - name: Verify idempotency of removal test result - {{ method }} assert: that: - - "double_removal_result.changed == false" + - double_removal_result is not changed msg: "state=absent shall not do anything when flatpak is not present" # state=present with url as name @@ -69,7 +69,7 @@ - name: Verify addition test result - {{ method }} assert: that: - - "url_addition_result.changed == true" + - url_addition_result is changed msg: "state=present with url as name shall add flatpak when absent" - name: Test idempotency of addition with url - {{ method }} @@ -83,7 +83,7 @@ - name: Verify idempotency of addition with url test result - {{ method }} assert: that: - - "double_url_addition_result.changed == false" + - double_url_addition_result is not changed msg: "state=present with url as name shall not do anything when flatpak is already present" # state=absent with url as name @@ -98,7 +98,7 @@ - name: Verify removal test result - {{ method }} assert: that: - - "url_removal_result.changed == true" + - url_removal_result is changed msg: "state=absent with url as name shall remove flatpak when present" - name: Test idempotency of removal with url - {{ method }} @@ -111,5 +111,5 @@ - name: Verify idempotency of removal with url test result - {{ method }} assert: that: - - "double_url_removal_result.changed == false" + - double_url_removal_result is not changed msg: "state=absent with url as name shall not do anything when flatpak is not present" diff --git a/tests/integration/targets/flatpak_remote/tasks/check_mode.yml b/tests/integration/targets/flatpak_remote/tasks/check_mode.yml index 7ce89a8c15..1f4def86d9 100644 --- a/tests/integration/targets/flatpak_remote/tasks/check_mode.yml +++ b/tests/integration/targets/flatpak_remote/tasks/check_mode.yml @@ -13,7 +13,7 @@ - name: Verify addition of absent flatpak remote test result (check mode) assert: that: - - "addition_result.changed == true" + - addition_result is changed msg: "Adding an absent flatpak remote shall mark module execution as changed" - name: Test non-existent idempotency of addition of absent flatpak remote (check mode) @@ -29,7 +29,7 @@ test result (check mode) assert: that: - - "double_addition_result.changed == true" + - double_addition_result is changed msg: | Adding an absent flatpak remote a second time shall still mark module execution as changed in check mode @@ -46,7 +46,7 @@ - name: Verify removal of absent flatpak remote test result (check mode) assert: that: - - "removal_result.changed == false" + - removal_result is not changed msg: "Removing an absent flatpak remote shall mark module execution as not changed" @@ -65,7 +65,7 @@ - name: Verify addition of present flatpak remote test result (check mode) assert: that: - - "addition_result.changed == false" + - addition_result is not changed msg: "Adding a present flatpak remote shall mark module execution as not changed" # state=absent @@ -80,7 +80,7 @@ - name: Verify removal of present flatpak remote test result (check mode) assert: that: - - "removal_result.changed == true" + - removal_result is changed msg: "Removing a present flatpak remote shall mark module execution as changed" - name: Test non-existent idempotency of removal of present flatpak remote (check mode) @@ -95,7 +95,7 @@ test result (check mode) assert: that: - - "double_removal_result.changed == true" + - double_removal_result is changed msg: | Removing a present flatpak remote a second time shall still mark module execution as changed in check mode diff --git a/tests/integration/targets/flatpak_remote/tasks/main.yml b/tests/integration/targets/flatpak_remote/tasks/main.yml index aa2219e181..91fa7262df 100644 --- a/tests/integration/targets/flatpak_remote/tasks/main.yml +++ b/tests/integration/targets/flatpak_remote/tasks/main.yml @@ -40,8 +40,8 @@ - name: Verify executable override test result assert: that: - - "executable_override_result.failed == true" - - "executable_override_result.changed == false" + - executable_override_result is failed + - executable_override_result is not changed msg: "Specifying non-existing executable shall fail module execution" - import_tasks: check_mode.yml diff --git a/tests/integration/targets/flatpak_remote/tasks/test.yml b/tests/integration/targets/flatpak_remote/tasks/test.yml index 9570f623a1..66c43649b4 100644 --- a/tests/integration/targets/flatpak_remote/tasks/test.yml +++ b/tests/integration/targets/flatpak_remote/tasks/test.yml @@ -11,7 +11,7 @@ - name: Verify addition test result - {{ method }} assert: that: - - "addition_result.changed == true" + - addition_result is changed msg: "state=present shall add flatpak when absent" - name: Test idempotency of addition - {{ method }} @@ -25,7 +25,7 @@ - name: Verify idempotency of addition test result - {{ method }} assert: that: - - "double_addition_result.changed == false" + - double_addition_result is not changed msg: "state=present shall not do anything when flatpak is already present" - name: Test updating remote url does not do anything - {{ method }} @@ -39,7 +39,7 @@ - name: Verify updating remote url does not do anything - {{ method }} assert: that: - - "url_update_result.changed == false" + - url_update_result is not changed msg: "Trying to update the URL of an existing flatpak remote shall not do anything" @@ -55,7 +55,7 @@ - name: Verify removal test result - {{ method }} assert: that: - - "removal_result.changed == true" + - removal_result is changed msg: "state=absent shall remove flatpak when present" - name: Test idempotency of removal - {{ method }} @@ -68,5 +68,5 @@ - name: Verify idempotency of removal test result - {{ method }} assert: that: - - "double_removal_result.changed == false" + - double_removal_result is not changed msg: "state=absent shall not do anything when flatpak is not present" diff --git a/tests/integration/targets/git_config/tasks/get_set_no_state.yml b/tests/integration/targets/git_config/tasks/get_set_no_state.yml index 149a9b2d93..7e9714a75e 100644 --- a/tests/integration/targets/git_config/tasks/get_set_no_state.yml +++ b/tests/integration/targets/git_config/tasks/get_set_no_state.yml @@ -17,9 +17,9 @@ - name: assert set changed and value is correct assert: that: - - set_result.changed == true + - set_result is changed - set_result.diff.before == "\n" - set_result.diff.after == option_value + "\n" - - get_result.changed == false + - get_result is not changed - get_result.config_value == option_value ... diff --git a/tests/integration/targets/git_config/tasks/get_set_state_present.yml b/tests/integration/targets/git_config/tasks/get_set_state_present.yml index 59f3c9c0ee..52d986d633 100644 --- a/tests/integration/targets/git_config/tasks/get_set_state_present.yml +++ b/tests/integration/targets/git_config/tasks/get_set_state_present.yml @@ -19,9 +19,9 @@ - name: assert set changed and value is correct with state=present assert: that: - - set_result.changed == true + - set_result is changed - set_result.diff.before == "\n" - set_result.diff.after == option_value + "\n" - - get_result.changed == false + - get_result is not changed - get_result.config_value == option_value ... diff --git a/tests/integration/targets/git_config/tasks/precedence_between_unset_and_value.yml b/tests/integration/targets/git_config/tasks/precedence_between_unset_and_value.yml index 24ef292015..9eb4ca4034 100644 --- a/tests/integration/targets/git_config/tasks/precedence_between_unset_and_value.yml +++ b/tests/integration/targets/git_config/tasks/precedence_between_unset_and_value.yml @@ -18,7 +18,7 @@ - name: assert unset changed and deleted value assert: that: - - unset_result.changed == true + - unset_result is changed - unset_result.diff.before == option_value + "\n" - unset_result.diff.after == "\n" - get_result.config_value == '' diff --git a/tests/integration/targets/git_config/tasks/unset_check_mode.yml b/tests/integration/targets/git_config/tasks/unset_check_mode.yml index c8fe00c0b7..43b9905373 100644 --- a/tests/integration/targets/git_config/tasks/unset_check_mode.yml +++ b/tests/integration/targets/git_config/tasks/unset_check_mode.yml @@ -18,7 +18,7 @@ - name: assert unset changed but dit not delete value assert: that: - - unset_result.changed == true + - unset_result is changed - unset_result.diff.before == option_value + "\n" - unset_result.diff.after == "\n" - get_result.config_value == option_value diff --git a/tests/integration/targets/git_config/tasks/unset_no_value.yml b/tests/integration/targets/git_config/tasks/unset_no_value.yml index 71568e3aa4..5fb6b6bcb6 100644 --- a/tests/integration/targets/git_config/tasks/unset_no_value.yml +++ b/tests/integration/targets/git_config/tasks/unset_no_value.yml @@ -17,7 +17,7 @@ - name: assert unsetting didn't change assert: that: - - unset_result.changed == false + - unset_result is not changed - unset_result.msg == 'no setting to unset' - get_result.config_value == '' ... diff --git a/tests/integration/targets/git_config/tasks/unset_value.yml b/tests/integration/targets/git_config/tasks/unset_value.yml index a2308156aa..6dda37736e 100644 --- a/tests/integration/targets/git_config/tasks/unset_value.yml +++ b/tests/integration/targets/git_config/tasks/unset_value.yml @@ -17,7 +17,7 @@ - name: assert unset changed and deleted value assert: that: - - unset_result.changed == true + - unset_result is changed - unset_result.diff.before == option_value + "\n" - unset_result.diff.after == "\n" - get_result.config_value == '' diff --git a/tests/integration/targets/github_issue/tasks/main.yml b/tests/integration/targets/github_issue/tasks/main.yml index 24266128ae..7731a7a955 100644 --- a/tests/integration/targets/github_issue/tasks/main.yml +++ b/tests/integration/targets/github_issue/tasks/main.yml @@ -18,8 +18,8 @@ - assert: that: - - "{{ get_status_0002.changed == True }}" - - "{{ get_status_0002.issue_status == 'closed' }}" + - get_status_0002 is changed + - get_status_0002.issue_status == 'closed' - name: Check if GitHub issue is closed or not github_issue: @@ -32,6 +32,6 @@ - assert: that: - - "{{ get_status_0003.changed == False }}" - - "{{ get_status_0003.failed == True }}" - - "{{ 'Failed' in get_status_0003.msg }}" + - get_status_0003 is not changed + - get_status_0003 is failed + - "'Failed' in get_status_0003.msg" diff --git a/tests/integration/targets/hwc_ecs_instance/tasks/main.yml b/tests/integration/targets/hwc_ecs_instance/tasks/main.yml index 8c8ea2eb3d..4d36c11286 100644 --- a/tests/integration/targets/hwc_ecs_instance/tasks/main.yml +++ b/tests/integration/targets/hwc_ecs_instance/tasks/main.yml @@ -167,8 +167,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #---------------------------------------------------------- - name: delete a instance (check mode) hwc_ecs_instance: @@ -277,8 +277,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #--------------------------------------------------------- # Post-test teardown - name: delete a disk diff --git a/tests/integration/targets/hwc_evs_disk/tasks/main.yml b/tests/integration/targets/hwc_evs_disk/tasks/main.yml index 79e67d0dc9..e2380450cd 100644 --- a/tests/integration/targets/hwc_evs_disk/tasks/main.yml +++ b/tests/integration/targets/hwc_evs_disk/tasks/main.yml @@ -50,8 +50,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #---------------------------------------------------------- - name: delete a disk (check mode) hwc_evs_disk: @@ -92,7 +92,7 @@ - name: assert changed is false assert: that: - - result.changed == false + - result is not changed # ---------------------------------------------------------------------------- - name: delete a disk that does not exist hwc_evs_disk: @@ -105,5 +105,5 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed diff --git a/tests/integration/targets/hwc_network_vpc/tasks/main.yml b/tests/integration/targets/hwc_network_vpc/tasks/main.yml index 5c01cf7ad8..e3b979d0b5 100644 --- a/tests/integration/targets/hwc_network_vpc/tasks/main.yml +++ b/tests/integration/targets/hwc_network_vpc/tasks/main.yml @@ -62,8 +62,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #---------------------------------------------------------- - name: delete a vpc hwc_network_vpc: @@ -97,5 +97,5 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed diff --git a/tests/integration/targets/hwc_smn_topic/tasks/main.yml b/tests/integration/targets/hwc_smn_topic/tasks/main.yml index 180f8fad3e..a9879aea54 100644 --- a/tests/integration/targets/hwc_smn_topic/tasks/main.yml +++ b/tests/integration/targets/hwc_smn_topic/tasks/main.yml @@ -44,8 +44,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #---------------------------------------------------------- - name: delete a smn topic hwc_smn_topic: @@ -77,5 +77,5 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed diff --git a/tests/integration/targets/hwc_vpc_eip/tasks/main.yml b/tests/integration/targets/hwc_vpc_eip/tasks/main.yml index 57de832418..bdf5d763a7 100644 --- a/tests/integration/targets/hwc_vpc_eip/tasks/main.yml +++ b/tests/integration/targets/hwc_vpc_eip/tasks/main.yml @@ -96,8 +96,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #---------------------------------------------------------- - name: delete a eip (check mode) hwc_vpc_eip: @@ -159,8 +159,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #--------------------------------------------------------- # Post-test teardown - name: delete a port diff --git a/tests/integration/targets/hwc_vpc_peering_connect/tasks/main.yml b/tests/integration/targets/hwc_vpc_peering_connect/tasks/main.yml index 2316a4b25c..cb6a15f750 100644 --- a/tests/integration/targets/hwc_vpc_peering_connect/tasks/main.yml +++ b/tests/integration/targets/hwc_vpc_peering_connect/tasks/main.yml @@ -78,8 +78,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #---------------------------------------------------------- - name: delete a peering connect (check mode) hwc_vpc_peering_connect: @@ -133,8 +133,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #--------------------------------------------------------- # Post-test teardown - name: delete a vpc diff --git a/tests/integration/targets/hwc_vpc_port/tasks/main.yml b/tests/integration/targets/hwc_vpc_port/tasks/main.yml index b7f28360c1..00f5ae8b2e 100644 --- a/tests/integration/targets/hwc_vpc_port/tasks/main.yml +++ b/tests/integration/targets/hwc_vpc_port/tasks/main.yml @@ -69,8 +69,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #---------------------------------------------------------- - name: delete a port (check mode) hwc_vpc_port: @@ -116,8 +116,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #--------------------------------------------------------- # Post-test teardown - name: delete a subnet diff --git a/tests/integration/targets/hwc_vpc_private_ip/tasks/main.yml b/tests/integration/targets/hwc_vpc_private_ip/tasks/main.yml index efd6765c80..5531d575f8 100644 --- a/tests/integration/targets/hwc_vpc_private_ip/tasks/main.yml +++ b/tests/integration/targets/hwc_vpc_private_ip/tasks/main.yml @@ -70,8 +70,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #---------------------------------------------------------- - name: delete a private ip (check mode) hwc_vpc_private_ip: @@ -117,8 +117,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #--------------------------------------------------------- # Post-test teardown - name: delete a subnet diff --git a/tests/integration/targets/hwc_vpc_route/tasks/main.yml b/tests/integration/targets/hwc_vpc_route/tasks/main.yml index b281000b7a..9c9c37e8c0 100644 --- a/tests/integration/targets/hwc_vpc_route/tasks/main.yml +++ b/tests/integration/targets/hwc_vpc_route/tasks/main.yml @@ -81,8 +81,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #---------------------------------------------------------- - name: delete a route (check mode) hwc_vpc_route: @@ -127,8 +127,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #--------------------------------------------------------- # Post-test teardown - name: delete a peering connect diff --git a/tests/integration/targets/hwc_vpc_security_group/tasks/main.yml b/tests/integration/targets/hwc_vpc_security_group/tasks/main.yml index 6b21f8b9a4..9f853ca8e7 100644 --- a/tests/integration/targets/hwc_vpc_security_group/tasks/main.yml +++ b/tests/integration/targets/hwc_vpc_security_group/tasks/main.yml @@ -51,8 +51,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #---------------------------------------------------------- - name: delete a security group (check mode) hwc_vpc_security_group: @@ -83,5 +83,5 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed diff --git a/tests/integration/targets/hwc_vpc_security_group_rule/tasks/main.yml b/tests/integration/targets/hwc_vpc_security_group_rule/tasks/main.yml index 2d774101bf..04213e7162 100644 --- a/tests/integration/targets/hwc_vpc_security_group_rule/tasks/main.yml +++ b/tests/integration/targets/hwc_vpc_security_group_rule/tasks/main.yml @@ -85,8 +85,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #---------------------------------------------------------- - name: delete a security group rule (check mode) hwc_vpc_security_group_rule: @@ -151,8 +151,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #--------------------------------------------------------- # Post-test teardown - name: delete a security group diff --git a/tests/integration/targets/hwc_vpc_subnet/tasks/main.yml b/tests/integration/targets/hwc_vpc_subnet/tasks/main.yml index 3b3cf65478..c16ff85241 100644 --- a/tests/integration/targets/hwc_vpc_subnet/tasks/main.yml +++ b/tests/integration/targets/hwc_vpc_subnet/tasks/main.yml @@ -77,8 +77,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #---------------------------------------------------------- - name: delete a subnet (check mode) hwc_vpc_subnet: @@ -136,8 +136,8 @@ - name: assert changed is false assert: that: - - result.failed == 0 - - result.changed == false + - result is not failed + - result is not changed #--------------------------------------------------------- # Post-test teardown - name: delete a vpc diff --git a/tests/integration/targets/influxdb_user/tasks/tests.yml b/tests/integration/targets/influxdb_user/tasks/tests.yml index b980e29094..ad3396642b 100644 --- a/tests/integration/targets/influxdb_user/tasks/tests.yml +++ b/tests/integration/targets/influxdb_user/tasks/tests.yml @@ -13,7 +13,7 @@ - name: Check that admin user adding succeeds with a change assert: that: - - add_admin_user.changed == true + - add_admin_user is changed - name: Test add admin user block: @@ -24,7 +24,7 @@ - name: Check that admin user adding succeeds with a change assert: that: - - add_admin_user.changed == true + - add_admin_user is changed - name: Test add admin user idempotence block: @@ -35,7 +35,7 @@ - name: Check that admin user adding succeeds without a change assert: that: - - add_admin_user.changed == false + - add_admin_user is not changed - name: Enable authentication and restart service block: @@ -58,7 +58,7 @@ - name: Check that adding user with enabled authentication succeeds with a change assert: that: - - add_user_with_auth_enabled.changed == true + - add_user_with_auth_enabled is changed - name: Test add user when authentication enabled block: @@ -69,7 +69,7 @@ - name: Check that adding user with enabled authentication succeeds with a change assert: that: - - add_user_with_auth_enabled.changed == true + - add_user_with_auth_enabled is changed - name: Test add user when authentication enabled idempotence block: @@ -80,7 +80,7 @@ - name: Check that adding same user succeeds without a change assert: that: - - same_user.changed == false + - same_user is not changed - name: Test change user password in check mode block: @@ -92,7 +92,7 @@ - name: Check that password changing succeeds with a change assert: that: - - change_password.changed == true + - change_password is changed - name: Test change user password block: @@ -103,7 +103,7 @@ - name: Check that password changing succeeds with a change assert: that: - - change_password.changed == true + - change_password is changed - name: Test remove user in check mode block: @@ -115,7 +115,7 @@ - name: Check that removing user succeeds with a change assert: that: - - remove_user.changed == true + - remove_user is changed - name: Test remove user block: @@ -126,7 +126,7 @@ - name: Check that removing user succeeds with a change assert: that: - - remove_user.changed == true + - remove_user is changed - name: Test remove user idempotence block: @@ -137,4 +137,4 @@ - name: Check that removing user succeeds without a change assert: that: - - remove_user.changed == false + - remove_user is not changed diff --git a/tests/integration/targets/ipify_facts/tasks/main.yml b/tests/integration/targets/ipify_facts/tasks/main.yml index 4fbd5ab696..7b620ff9ec 100644 --- a/tests/integration/targets/ipify_facts/tasks/main.yml +++ b/tests/integration/targets/ipify_facts/tasks/main.yml @@ -41,6 +41,6 @@ - name: check if task was successful assert: that: - - "{{ external_ip.changed == false }}" - - "{{ external_ip['ansible_facts'] is defined }}" - - "{{ external_ip['ansible_facts']['ipify_public_ip'] is defined }}" + - external_ip is not changed + - external_ip.ansible_facts is defined + - external_ip.ansible_facts.ipify_public_ip is defined diff --git a/tests/integration/targets/iso_create/tasks/main.yml b/tests/integration/targets/iso_create/tasks/main.yml index de46276743..4a0df3b818 100644 --- a/tests/integration/targets/iso_create/tasks/main.yml +++ b/tests/integration/targets/iso_create/tasks/main.yml @@ -35,7 +35,7 @@ - debug: var=iso_file - assert: that: - - iso_result.changed == True + - iso_result is changed - iso_file.stat.exists == False - name: Create iso file with a specified file @@ -54,7 +54,7 @@ - assert: that: - - iso_result.changed == True + - iso_result is changed - iso_file.stat.exists == True - name: Create iso file with a specified file and folder @@ -74,10 +74,10 @@ - assert: that: - - iso_result.changed == True + - iso_result is changed - iso_file.stat.exists == True -- name: Create iso file with volume identification string +- name: Create iso file with volume identification string iso_create: src_files: - "{{ role_path }}/files/test1.cfg" @@ -93,7 +93,7 @@ - assert: that: - - iso_result.changed == True + - iso_result is changed - iso_file.stat.exists == True - name: Create iso file with Rock Ridge extention @@ -112,7 +112,7 @@ - assert: that: - - iso_result.changed == True + - iso_result is changed - iso_file.stat.exists == True - name: Create iso file with Joliet extention @@ -131,7 +131,7 @@ - assert: that: - - iso_result.changed == True + - iso_result is changed - iso_file.stat.exists == True - name: Create iso file with UDF enabled @@ -150,5 +150,5 @@ - assert: that: - - iso_result.changed == True + - iso_result is changed - iso_file.stat.exists == True diff --git a/tests/integration/targets/iso_extract/tasks/tests.yml b/tests/integration/targets/iso_extract/tasks/tests.yml index f9182ba6ae..18f22422ce 100644 --- a/tests/integration/targets/iso_extract/tasks/tests.yml +++ b/tests/integration/targets/iso_extract/tasks/tests.yml @@ -28,7 +28,7 @@ - assert: that: - - iso_extract_test0 is changed == true + - iso_extract_test0 is changed - name: Extract the iso again iso_extract: @@ -42,11 +42,11 @@ - name: Test iso_extract_test0_again (normal mode) assert: that: - - iso_extract_test0_again is changed == false + - iso_extract_test0_again is not changed when: not in_check_mode - name: Test iso_extract_test0_again (check-mode) assert: that: - - iso_extract_test0_again is changed == true + - iso_extract_test0_again is changed when: in_check_mode diff --git a/tests/integration/targets/one_host/tasks/main.yml b/tests/integration/targets/one_host/tasks/main.yml index a3cea768af..7d38c2a890 100644 --- a/tests/integration/targets/one_host/tasks/main.yml +++ b/tests/integration/targets/one_host/tasks/main.yml @@ -177,7 +177,7 @@ - name: "assert test_{{test_number}} worked" assert: that: - - result.changed == false + - result is not changed # HOST DISABLEMENT diff --git a/tests/integration/targets/synchronize-buildah/roles/test_buildah_synchronize/tasks/main.yml b/tests/integration/targets/synchronize-buildah/roles/test_buildah_synchronize/tasks/main.yml index 92fd0830c4..a80e218921 100644 --- a/tests/integration/targets/synchronize-buildah/roles/test_buildah_synchronize/tasks/main.yml +++ b/tests/integration/targets/synchronize-buildah/roles/test_buildah_synchronize/tasks/main.yml @@ -40,7 +40,7 @@ - assert: that: - "'changed' in sync_result" - - "sync_result.changed == true" + - sync_result is changed - "'cmd' in sync_result" - "'rsync' in sync_result.cmd" - "'msg' in sync_result" @@ -63,7 +63,7 @@ - assert: that: - - "sync_result.changed == False" + - sync_result is not changed - name: cleanup old files file: diff --git a/tests/integration/targets/xml/tasks/test-add-children-elements-unicode.yml b/tests/integration/targets/xml/tasks/test-add-children-elements-unicode.yml index 8ad91501c3..d89c29ae27 100644 --- a/tests/integration/targets/xml/tasks/test-add-children-elements-unicode.yml +++ b/tests/integration/targets/xml/tasks/test-add-children-elements-unicode.yml @@ -24,6 +24,6 @@ - name: Test expected result assert: that: - - add_children_elements_unicode.changed == true - - comparison.changed == false # identical + - add_children_elements_unicode is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-add-children-elements-unicode.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-add-children-elements.yml b/tests/integration/targets/xml/tasks/test-add-children-elements.yml index 8d9b06866d..3c439c7ac2 100644 --- a/tests/integration/targets/xml/tasks/test-add-children-elements.yml +++ b/tests/integration/targets/xml/tasks/test-add-children-elements.yml @@ -24,6 +24,6 @@ - name: Test expected result assert: that: - - add_children_elements.changed == true - - comparison.changed == false # identical + - add_children_elements is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-add-children-elements.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-add-children-from-groupvars.yml b/tests/integration/targets/xml/tasks/test-add-children-from-groupvars.yml index e062de8d14..818fdf09b9 100644 --- a/tests/integration/targets/xml/tasks/test-add-children-from-groupvars.yml +++ b/tests/integration/targets/xml/tasks/test-add-children-from-groupvars.yml @@ -23,6 +23,6 @@ - name: Test expected result assert: that: - - add_children_from_groupvars.changed == true - - comparison.changed == false # identical + - add_children_from_groupvars is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-add-children-from-groupvars.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-add-children-insertafter.yml b/tests/integration/targets/xml/tasks/test-add-children-insertafter.yml index 2d42e2d54e..479052ebdd 100644 --- a/tests/integration/targets/xml/tasks/test-add-children-insertafter.yml +++ b/tests/integration/targets/xml/tasks/test-add-children-insertafter.yml @@ -28,5 +28,5 @@ - name: Test expected result assert: that: - - add_children_insertafter.changed == true - - comparison.changed == false # identical + - add_children_insertafter is changed + - comparison is not changed # identical diff --git a/tests/integration/targets/xml/tasks/test-add-children-insertbefore.yml b/tests/integration/targets/xml/tasks/test-add-children-insertbefore.yml index 8550f12cf7..9839d7cc91 100644 --- a/tests/integration/targets/xml/tasks/test-add-children-insertbefore.yml +++ b/tests/integration/targets/xml/tasks/test-add-children-insertbefore.yml @@ -28,5 +28,5 @@ - name: Test expected result assert: that: - - add_children_insertbefore.changed == true - - comparison.changed == false # identical + - add_children_insertbefore is changed + - comparison is not changed # identical diff --git a/tests/integration/targets/xml/tasks/test-add-children-with-attributes-unicode.yml b/tests/integration/targets/xml/tasks/test-add-children-with-attributes-unicode.yml index d4a2329f69..585157c970 100644 --- a/tests/integration/targets/xml/tasks/test-add-children-with-attributes-unicode.yml +++ b/tests/integration/targets/xml/tasks/test-add-children-with-attributes-unicode.yml @@ -26,6 +26,6 @@ - name: Test expected result assert: that: - - add_children_with_attributes_unicode.changed == true - - comparison.changed == false # identical + - add_children_with_attributes_unicode is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-add-children-with-attributes-unicode.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-add-children-with-attributes.yml b/tests/integration/targets/xml/tasks/test-add-children-with-attributes.yml index 91e92637fc..c3704801d9 100644 --- a/tests/integration/targets/xml/tasks/test-add-children-with-attributes.yml +++ b/tests/integration/targets/xml/tasks/test-add-children-with-attributes.yml @@ -29,7 +29,7 @@ - name: Test expected result assert: that: - - add_children_with_attributes.changed == true - - comparison.changed == false # identical + - add_children_with_attributes is changed + - comparison is not changed # identical when: lxml_predictable_attribute_order #command: diff -u {{ role_path }}/results/test-add-children-with-attributes.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-add-element-implicitly.yml b/tests/integration/targets/xml/tasks/test-add-element-implicitly.yml index db674ba4fc..6166cd46b9 100644 --- a/tests/integration/targets/xml/tasks/test-add-element-implicitly.yml +++ b/tests/integration/targets/xml/tasks/test-add-element-implicitly.yml @@ -108,7 +108,7 @@ - name: Test expected result assert: that: - - comparison.changed == false # identical + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-add-element-implicitly.yml /tmp/ansible-xml-beers-implicit.xml diff --git a/tests/integration/targets/xml/tasks/test-add-namespaced-children-elements.yml b/tests/integration/targets/xml/tasks/test-add-namespaced-children-elements.yml index 25eca47f5b..2cac73e65c 100644 --- a/tests/integration/targets/xml/tasks/test-add-namespaced-children-elements.yml +++ b/tests/integration/targets/xml/tasks/test-add-namespaced-children-elements.yml @@ -21,12 +21,12 @@ src: results/test-add-namespaced-children-elements.xml dest: /tmp/ansible-xml-namespaced-beers.xml check_mode: yes - diff: yes + diff: yes register: comparison - name: Test expected result assert: that: - - add_namespaced_children_elements.changed == true - - comparison.changed == false # identical + - add_namespaced_children_elements is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-add-namespaced-children-elements.xml /tmp/ansible-xml-namespaced-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-children-elements-xml.yml b/tests/integration/targets/xml/tasks/test-children-elements-xml.yml index e63100c47c..6b50d819c3 100644 --- a/tests/integration/targets/xml/tasks/test-children-elements-xml.yml +++ b/tests/integration/targets/xml/tasks/test-children-elements-xml.yml @@ -25,6 +25,6 @@ - name: Test expected result assert: that: - - children_elements.changed == true - - comparison.changed == false # identical + - children_elements is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-add-children-elements.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-count-unicode.yml b/tests/integration/targets/xml/tasks/test-count-unicode.yml index 47a806bf98..a9a462b5da 100644 --- a/tests/integration/targets/xml/tasks/test-count-unicode.yml +++ b/tests/integration/targets/xml/tasks/test-count-unicode.yml @@ -15,5 +15,5 @@ - name: Test expected result assert: that: - - beers.changed == false + - beers is not changed - beers.count == 2 diff --git a/tests/integration/targets/xml/tasks/test-count.yml b/tests/integration/targets/xml/tasks/test-count.yml index cbc97e323c..b8a21870f7 100644 --- a/tests/integration/targets/xml/tasks/test-count.yml +++ b/tests/integration/targets/xml/tasks/test-count.yml @@ -15,5 +15,5 @@ - name: Test expected result assert: that: - - beers.changed == false + - beers is not changed - beers.count == 3 diff --git a/tests/integration/targets/xml/tasks/test-get-element-content-unicode.yml b/tests/integration/targets/xml/tasks/test-get-element-content-unicode.yml index 73ae96674f..718f12d640 100644 --- a/tests/integration/targets/xml/tasks/test-get-element-content-unicode.yml +++ b/tests/integration/targets/xml/tasks/test-get-element-content-unicode.yml @@ -15,7 +15,7 @@ - name: Test expected result assert: that: - - get_element_attribute.changed == false + - get_element_attribute is not changed - get_element_attribute.matches[0]['rating'] is defined and get_element_attribute.matches[0]['rating']['subjective'] == 'да' - name: Get element text @@ -28,5 +28,5 @@ - name: Test expected result assert: that: - - get_element_text.changed == false + - get_element_text is not changed - get_element_text.matches[0]['rating'] == 'десять' diff --git a/tests/integration/targets/xml/tasks/test-get-element-content.yml b/tests/integration/targets/xml/tasks/test-get-element-content.yml index 4a40b42dcf..d38aa70d95 100644 --- a/tests/integration/targets/xml/tasks/test-get-element-content.yml +++ b/tests/integration/targets/xml/tasks/test-get-element-content.yml @@ -15,7 +15,7 @@ - name: Test expected result assert: that: - - get_element_attribute.changed == false + - get_element_attribute is not changed - get_element_attribute.matches[0]['rating'] is defined - get_element_attribute.matches[0]['rating']['subjective'] == 'true' @@ -43,5 +43,5 @@ - name: Test expected result assert: that: - - get_element_text.changed == false + - get_element_text is not changed - get_element_text.matches[0]['rating'] == '10' diff --git a/tests/integration/targets/xml/tasks/test-mutually-exclusive-attributes.yml b/tests/integration/targets/xml/tasks/test-mutually-exclusive-attributes.yml index 3f24b0ac84..07a71f9153 100644 --- a/tests/integration/targets/xml/tasks/test-mutually-exclusive-attributes.yml +++ b/tests/integration/targets/xml/tasks/test-mutually-exclusive-attributes.yml @@ -18,5 +18,5 @@ - name: Test expected result assert: that: - - module_output.changed == false - - module_output.failed == true + - module_output is not changed + - module_output is failed diff --git a/tests/integration/targets/xml/tasks/test-pretty-print-only.yml b/tests/integration/targets/xml/tasks/test-pretty-print-only.yml index 7c0f7d5fd6..16fcf629c5 100644 --- a/tests/integration/targets/xml/tasks/test-pretty-print-only.yml +++ b/tests/integration/targets/xml/tasks/test-pretty-print-only.yml @@ -24,6 +24,6 @@ - name: Test expected result assert: that: - - pretty_print_only.changed == true - - comparison.changed == false # identical + - pretty_print_only is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-pretty-print-only.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-pretty-print.yml b/tests/integration/targets/xml/tasks/test-pretty-print.yml index 88b618b25d..fd47ff3d82 100644 --- a/tests/integration/targets/xml/tasks/test-pretty-print.yml +++ b/tests/integration/targets/xml/tasks/test-pretty-print.yml @@ -25,6 +25,6 @@ - name: Test expected result assert: that: - - pretty_print.changed == true - - comparison.changed == false # identical + - pretty_print is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-pretty-print.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-remove-attribute-nochange.yml b/tests/integration/targets/xml/tasks/test-remove-attribute-nochange.yml index d09dee405c..fbd73237f1 100644 --- a/tests/integration/targets/xml/tasks/test-remove-attribute-nochange.yml +++ b/tests/integration/targets/xml/tasks/test-remove-attribute-nochange.yml @@ -23,6 +23,6 @@ - name: Test expected result assert: that: - - remove_attribute.changed == false - - comparison.changed == false # identical + - remove_attribute is not changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-remove-attribute.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-remove-attribute.yml b/tests/integration/targets/xml/tasks/test-remove-attribute.yml index 9aa395e666..52b5214213 100644 --- a/tests/integration/targets/xml/tasks/test-remove-attribute.yml +++ b/tests/integration/targets/xml/tasks/test-remove-attribute.yml @@ -23,6 +23,6 @@ - name: Test expected result assert: that: - - remove_attribute.changed == true - - comparison.changed == false # identical + - remove_attribute is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-remove-attribute.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-remove-element-nochange.yml b/tests/integration/targets/xml/tasks/test-remove-element-nochange.yml index 2debc80d51..e548bfabf8 100644 --- a/tests/integration/targets/xml/tasks/test-remove-element-nochange.yml +++ b/tests/integration/targets/xml/tasks/test-remove-element-nochange.yml @@ -23,6 +23,6 @@ - name: Test expected result assert: that: - - remove_element.changed == false - - comparison.changed == false # identical + - remove_element is not changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-remove-element.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-remove-element.yml b/tests/integration/targets/xml/tasks/test-remove-element.yml index f2e20ea220..092ca3e033 100644 --- a/tests/integration/targets/xml/tasks/test-remove-element.yml +++ b/tests/integration/targets/xml/tasks/test-remove-element.yml @@ -23,6 +23,6 @@ - name: Test expected result assert: that: - - remove_element.changed == true - - comparison.changed == false # identical + - remove_element is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-remove-element.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute-nochange.yml b/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute-nochange.yml index 291536d3bf..19c14dec8d 100644 --- a/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute-nochange.yml +++ b/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute-nochange.yml @@ -28,6 +28,6 @@ - name: Test expected result assert: that: - - remove_namespaced_attribute.changed == false - - comparison.changed == false # identical + - remove_namespaced_attribute is not changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-remove-namespaced-attribute.xml /tmp/ansible-xml-namespaced-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute.yml b/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute.yml index a7ccdac4e3..9e54911ba5 100644 --- a/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute.yml +++ b/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute.yml @@ -28,6 +28,6 @@ - name: Test expected result assert: that: - - remove_namespaced_attribute.changed == true - - comparison.changed == false # identical + - remove_namespaced_attribute is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-remove-namespaced-attribute.xml /tmp/ansible-xml-namespaced-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-remove-namespaced-element-nochange.yml b/tests/integration/targets/xml/tasks/test-remove-namespaced-element-nochange.yml index b1938e45b7..b96f2a7819 100644 --- a/tests/integration/targets/xml/tasks/test-remove-namespaced-element-nochange.yml +++ b/tests/integration/targets/xml/tasks/test-remove-namespaced-element-nochange.yml @@ -28,6 +28,6 @@ - name: Test expected result assert: that: - - remove_namespaced_element.changed == false - - comparison.changed == false # identical + - remove_namespaced_element is not changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-remove-element.xml /tmp/ansible-xml-namespaced-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-remove-namespaced-element.yml b/tests/integration/targets/xml/tasks/test-remove-namespaced-element.yml index be78af6803..660baa9840 100644 --- a/tests/integration/targets/xml/tasks/test-remove-namespaced-element.yml +++ b/tests/integration/targets/xml/tasks/test-remove-namespaced-element.yml @@ -28,6 +28,6 @@ - name: Test expected result assert: that: - - remove_namespaced_element.changed == true - - comparison.changed == false # identical + - remove_namespaced_element is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-remove-element.xml /tmp/ansible-xml-namespaced-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-set-attribute-value-unicode.yml b/tests/integration/targets/xml/tasks/test-set-attribute-value-unicode.yml index dabf72a1b7..b72d502f12 100644 --- a/tests/integration/targets/xml/tasks/test-set-attribute-value-unicode.yml +++ b/tests/integration/targets/xml/tasks/test-set-attribute-value-unicode.yml @@ -24,6 +24,6 @@ - name: Test expected result assert: that: - - set_attribute_value_unicode.changed == true - - comparison.changed == false # identical + - set_attribute_value_unicode is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-set-attribute-value-unicode.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-set-attribute-value.yml b/tests/integration/targets/xml/tasks/test-set-attribute-value.yml index 2aa39fe22f..6a2aa6c511 100644 --- a/tests/integration/targets/xml/tasks/test-set-attribute-value.yml +++ b/tests/integration/targets/xml/tasks/test-set-attribute-value.yml @@ -24,6 +24,6 @@ - name: Test expected result assert: that: - - set_attribute_value.changed == true - - comparison.changed == false # identical + - set_attribute_value is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-set-attribute-value.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-set-children-elements-level.yml b/tests/integration/targets/xml/tasks/test-set-children-elements-level.yml index 3e2c0adb6f..7fa926e879 100644 --- a/tests/integration/targets/xml/tasks/test-set-children-elements-level.yml +++ b/tests/integration/targets/xml/tasks/test-set-children-elements-level.yml @@ -47,8 +47,8 @@ - name: Test expected result assert: that: - - set_children_elements_level.changed == true - - comparison.changed == false # identical + - set_children_elements_level is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-set-children-elements-level.xml /tmp/ansible-xml-beers.xml @@ -70,5 +70,5 @@ - name: Test expected result assert: that: - - set_children_again.changed == false - - comparison.changed == false # identical + - set_children_again is not changed + - comparison is not changed # identical diff --git a/tests/integration/targets/xml/tasks/test-set-children-elements-unicode.yml b/tests/integration/targets/xml/tasks/test-set-children-elements-unicode.yml index 240b894ac7..3cc25cd999 100644 --- a/tests/integration/targets/xml/tasks/test-set-children-elements-unicode.yml +++ b/tests/integration/targets/xml/tasks/test-set-children-elements-unicode.yml @@ -25,8 +25,8 @@ - name: Test expected result assert: that: - - set_children_elements_unicode.changed == true - - comparison.changed == false # identical + - set_children_elements_unicode is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-set-children-elements-unicode.xml /tmp/ansible-xml-beers.xml @@ -41,6 +41,6 @@ - name: Test expected result assert: that: - - set_children_again.changed == false - - comparison.changed == false # identical + - set_children_again is not changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-set-children-elements-unicode.xml /tmp/ansible-xml-beers.xml 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 7b0f3247ad..7c305ead74 100644 --- a/tests/integration/targets/xml/tasks/test-set-children-elements.yml +++ b/tests/integration/targets/xml/tasks/test-set-children-elements.yml @@ -25,8 +25,8 @@ - name: Test expected result assert: that: - - set_children_elements.changed == true - - comparison.changed == false # identical + - 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 @@ -48,6 +48,6 @@ - name: Test expected result assert: that: - - set_children_again.changed == false - - comparison.changed == false # identical + - set_children_again is not changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-set-children-elements.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-set-element-value-empty.yml b/tests/integration/targets/xml/tasks/test-set-element-value-empty.yml index 5814803cb7..4575d5e75f 100644 --- a/tests/integration/targets/xml/tasks/test-set-element-value-empty.yml +++ b/tests/integration/targets/xml/tasks/test-set-element-value-empty.yml @@ -23,6 +23,6 @@ - name: Test expected result assert: that: - - set_element_value_empty.changed == true - - comparison.changed == false # identical + - set_element_value_empty is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-set-element-value-empty.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-set-element-value-unicode.yml b/tests/integration/targets/xml/tasks/test-set-element-value-unicode.yml index c3a40b7d93..139087fcd9 100644 --- a/tests/integration/targets/xml/tasks/test-set-element-value-unicode.yml +++ b/tests/integration/targets/xml/tasks/test-set-element-value-unicode.yml @@ -37,7 +37,7 @@ - name: Test expected result assert: that: - - set_element_first_run.changed == true - - set_element_second_run.changed == false - - comparison.changed == false # identical + - set_element_first_run is changed + - set_element_second_run is not changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-set-element-value-unicode.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-set-element-value.yml b/tests/integration/targets/xml/tasks/test-set-element-value.yml index dbd070f139..2f845e949b 100644 --- a/tests/integration/targets/xml/tasks/test-set-element-value.yml +++ b/tests/integration/targets/xml/tasks/test-set-element-value.yml @@ -37,7 +37,7 @@ - name: Test expected result assert: that: - - set_element_first_run.changed == true - - set_element_second_run.changed == false - - comparison.changed == false # identical + - set_element_first_run is changed + - set_element_second_run is not changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-set-element-value.xml /tmp/ansible-xml-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-set-namespaced-attribute-value.yml b/tests/integration/targets/xml/tasks/test-set-namespaced-attribute-value.yml index e0086efe3a..2ba83a8330 100644 --- a/tests/integration/targets/xml/tasks/test-set-namespaced-attribute-value.yml +++ b/tests/integration/targets/xml/tasks/test-set-namespaced-attribute-value.yml @@ -29,6 +29,6 @@ - name: Test expected result assert: that: - - set_namespaced_attribute_value.changed == true - - comparison.changed == false # identical + - set_namespaced_attribute_value is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-set-namespaced-attribute-value.xml /tmp/ansible-xml-namespaced-beers.xml diff --git a/tests/integration/targets/xml/tasks/test-set-namespaced-children-elements.yml b/tests/integration/targets/xml/tasks/test-set-namespaced-children-elements.yml index 8e66e70eeb..6204c8c74d 100644 --- a/tests/integration/targets/xml/tasks/test-set-namespaced-children-elements.yml +++ b/tests/integration/targets/xml/tasks/test-set-namespaced-children-elements.yml @@ -52,6 +52,6 @@ - name: Test expected result assert: that: - - set_children_again.changed == false # idempotency - - set_namespaced_attribute_value.changed == true - - comparison.changed == false # identical + - set_children_again is not changed # idempotency + - set_namespaced_attribute_value is changed + - comparison is not changed # identical diff --git a/tests/integration/targets/xml/tasks/test-set-namespaced-element-value.yml b/tests/integration/targets/xml/tasks/test-set-namespaced-element-value.yml index f77d7537e9..cf6a8a7eb0 100644 --- a/tests/integration/targets/xml/tasks/test-set-namespaced-element-value.yml +++ b/tests/integration/targets/xml/tasks/test-set-namespaced-element-value.yml @@ -41,6 +41,6 @@ - name: Test expected result assert: that: - - set_element_first_run.changed == true - - set_element_second_run.changed == false - - comparison.changed == false # identical + - set_element_first_run is changed + - set_element_second_run is not changed + - comparison is not changed # identical diff --git a/tests/integration/targets/xml/tasks/test-xmlstring.yml b/tests/integration/targets/xml/tasks/test-xmlstring.yml index 4620d984fa..82781fa94d 100644 --- a/tests/integration/targets/xml/tasks/test-xmlstring.yml +++ b/tests/integration/targets/xml/tasks/test-xmlstring.yml @@ -25,8 +25,8 @@ - name: Test expected result assert: that: - - xmlresponse.changed == false - - comparison.changed == false # identical + - xmlresponse is not changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-pretty-print-only.xml /tmp/ansible-xml-beers.xml @@ -49,8 +49,8 @@ - name: Test expected result assert: that: - - xmlresponse.changed == true - - comparison.changed == false # identical + - xmlresponse is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-pretty-print-only.xml /tmp/ansible-xml-beers.xml @@ -63,7 +63,7 @@ add_children: - beer: Old Rasputin register: xmlresponse_modification - + - name: Compare to expected result copy: content: '{{ xmlresponse_modification.xmlstring }}' @@ -76,6 +76,6 @@ - name: Test expected result assert: that: - - xmlresponse_modification.changed == true - - comparison.changed == false # identical + - xmlresponse_modification is changed + - comparison is not changed # identical #command: diff -u {{ role_path }}/results/test-pretty-print.xml /tmp/ansible-xml-beers.xml From c12be67a6906fdd1b8295035f57df6d9581e75d7 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 22 May 2021 22:42:02 +0200 Subject: [PATCH 081/139] ini_file - opening file as utf-8-sig (#2578) (#2591) * opening file as utf-8-sig * added changelog fragment * using io.open() * Update tests/integration/targets/ini_file/tasks/main.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit cc293f90a245aad5c2eae4b1c28b49101563b134) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../fragments/2578-ini-file-utf8-bom.yml | 2 ++ plugins/modules/files/ini_file.py | 3 +- .../targets/ini_file/tasks/main.yml | 34 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2578-ini-file-utf8-bom.yml diff --git a/changelogs/fragments/2578-ini-file-utf8-bom.yml b/changelogs/fragments/2578-ini-file-utf8-bom.yml new file mode 100644 index 0000000000..00640c0b23 --- /dev/null +++ b/changelogs/fragments/2578-ini-file-utf8-bom.yml @@ -0,0 +1,2 @@ +minor_changes: + - ini_file - opening file with encoding ``utf-8-sig`` (https://github.com/ansible-collections/community.general/issues/2189). diff --git a/plugins/modules/files/ini_file.py b/plugins/modules/files/ini_file.py index ac4c6d0cf3..ea857cefa9 100644 --- a/plugins/modules/files/ini_file.py +++ b/plugins/modules/files/ini_file.py @@ -104,6 +104,7 @@ EXAMPLES = r''' backup: yes ''' +import io import os import re import tempfile @@ -141,7 +142,7 @@ def do_ini(module, filename, section=None, option=None, value=None, os.makedirs(destpath) ini_lines = [] else: - with open(filename, 'r') as ini_file: + with io.open(filename, 'r', encoding="utf-8-sig") as ini_file: ini_lines = ini_file.readlines() if module._diff: diff --git a/tests/integration/targets/ini_file/tasks/main.yml b/tests/integration/targets/ini_file/tasks/main.yml index 2e84147c72..be5835669b 100644 --- a/tests/integration/targets/ini_file/tasks/main.yml +++ b/tests/integration/targets/ini_file/tasks/main.yml @@ -480,3 +480,37 @@ assert: that: - content15 == expected15 + +- name: Create starting ini file + copy: + # The content below is the following text file with BOM: + # [section1] + # var1=aaa + # var2=bbb + # [section2] + # var3=ccc + content: !!binary | + 77u/W3NlY3Rpb24xXQp2YXIxPWFhYQp2YXIyPWJiYgpbc2VjdGlvbjJdCnZhcjM9Y2NjCg== + dest: "{{ output_file }}" +- name: Test ini breakage + ini_file: + path: "{{ output_file }}" + section: section1 + option: var4 + value: 0 + +- name: read content from output file + slurp: + src: "{{ output_file }}" + register: output_content + +- name: set expected content and get current ini file content + set_fact: + expected16: "[section1]\nvar1=aaa\nvar2=bbb\nvar4 = 0\n[section2]\nvar3=ccc\n" + content16: "{{ output_content.content | b64decode }}" +- debug: + var: content16 +- name: Verify content of ini file is as expected + assert: + that: + - content16 == expected16 From 113e7cdfa09b03e7a965760d081f685348b2b7b9 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 24 May 2021 20:28:18 +0000 Subject: [PATCH 082/139] rhsm_release: Fix the issue that rhsm_release module considers 8, 7Client and 7Workstation as invalid releases (#2571) (#2606) * rhsm_release: Fix the issue that rhsm_release module considers 8, 7Client and 7Workstation as invalid releases. * Fix the unit test error: The new release_matcher could pass a wider range of patterns but that would not cause extra issue to the whole module. * Submit the changelog fragment. * Update changelogs/fragments/2571-rhsm_release-fix-release_matcher.yaml Co-authored-by: Amin Vakil Co-authored-by: Amin Vakil (cherry picked from commit 593d622438dd2a7aada0ccb762446df4ebb1a6ac) Co-authored-by: Tong He <68936428+unnecessary-username@users.noreply.github.com> --- .../fragments/2571-rhsm_release-fix-release_matcher.yaml | 2 ++ plugins/modules/packaging/os/rhsm_release.py | 6 +++--- .../unit/plugins/modules/packaging/os/test_rhsm_release.py | 5 ++--- 3 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/2571-rhsm_release-fix-release_matcher.yaml diff --git a/changelogs/fragments/2571-rhsm_release-fix-release_matcher.yaml b/changelogs/fragments/2571-rhsm_release-fix-release_matcher.yaml new file mode 100644 index 0000000000..764743303f --- /dev/null +++ b/changelogs/fragments/2571-rhsm_release-fix-release_matcher.yaml @@ -0,0 +1,2 @@ +bugfixes: + - rhsm_release - fix the issue that module considers 8, 7Client and 7Workstation as invalid releases (https://github.com/ansible-collections/community.general/pull/2571). diff --git a/plugins/modules/packaging/os/rhsm_release.py b/plugins/modules/packaging/os/rhsm_release.py index 22b280f1fc..a4d8f71197 100644 --- a/plugins/modules/packaging/os/rhsm_release.py +++ b/plugins/modules/packaging/os/rhsm_release.py @@ -56,9 +56,9 @@ from ansible.module_utils.basic import AnsibleModule import re -# Matches release-like values such as 7.2, 6.10, 10Server, -# but rejects unlikely values, like 100Server, 100.0, 1.100, etc. -release_matcher = re.compile(r'\b\d{1,2}(?:\.\d{1,2}|Server)\b') +# Matches release-like values such as 7.2, 5.10, 6Server, 8 +# but rejects unlikely values, like 100Server, 1.100, 7server etc. +release_matcher = re.compile(r'\b\d{1,2}(?:\.\d{1,2}|Server|Client|Workstation|)\b') def _sm_release(module, *args): diff --git a/tests/unit/plugins/modules/packaging/os/test_rhsm_release.py b/tests/unit/plugins/modules/packaging/os/test_rhsm_release.py index a75ec69448..98db6e2840 100644 --- a/tests/unit/plugins/modules/packaging/os/test_rhsm_release.py +++ b/tests/unit/plugins/modules/packaging/os/test_rhsm_release.py @@ -125,13 +125,12 @@ class RhsmRepositoryReleaseModuleTestCase(ModuleTestCase): def test_release_matcher(self): # throw a few values at the release matcher -- only sane_values should match - sane_values = ['1Server', '10Server', '1.10', '10.0'] + sane_values = ['1Server', '1Client', '10Server', '1.10', '10.0', '9'] insane_values = [ '6server', # lowercase 's' '100Server', # excessively long 'x' component - '100.0', # excessively long 'x' component - '6.100', # excessively long 'y' component '100.100', # excessively long 'x' and 'y' components + '+.-', # illegal characters ] matches = self.module.release_matcher.findall(' '.join(sane_values + insane_values)) From e19dffbf29e84a461ce7936ffd443c859bae02c6 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 25 May 2021 13:59:42 +0200 Subject: [PATCH 083/139] json_query, no more 'unknown type' errors (#2607) (#2613) Signed-off-by: Abhijeet Kasurde (cherry picked from commit d8713992209ccce44b884093967749249bca960f) Co-authored-by: Brian Coca --- changelogs/fragments/json_query_more_types.yml | 3 +++ plugins/filter/json_query.py | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/json_query_more_types.yml diff --git a/changelogs/fragments/json_query_more_types.yml b/changelogs/fragments/json_query_more_types.yml new file mode 100644 index 0000000000..4ac69b67c0 --- /dev/null +++ b/changelogs/fragments/json_query_more_types.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - json_query filter plugin - avoid 'unknown type' errors for more Ansible internal types (https://github.com/ansible-collections/community.general/pull/2607). diff --git a/plugins/filter/json_query.py b/plugins/filter/json_query.py index 972109a045..673cafa587 100644 --- a/plugins/filter/json_query.py +++ b/plugins/filter/json_query.py @@ -35,9 +35,11 @@ def json_query(data, expr): raise AnsibleError('You need to install "jmespath" prior to running ' 'json_query filter') - # Hack to handle Ansible String Types + # Hack to handle Ansible Unsafe text, AnsibleMapping and AnsibleSequence # See issue: https://github.com/ansible-collections/community.general/issues/320 jmespath.functions.REVERSE_TYPES_MAP['string'] = jmespath.functions.REVERSE_TYPES_MAP['string'] + ('AnsibleUnicode', 'AnsibleUnsafeText', ) + jmespath.functions.REVERSE_TYPES_MAP['array'] = jmespath.functions.REVERSE_TYPES_MAP['array'] + ('AnsibleSequence', ) + jmespath.functions.REVERSE_TYPES_MAP['object'] = jmespath.functions.REVERSE_TYPES_MAP['object'] + ('AnsibleMapping', ) try: return jmespath.search(expr, data) except jmespath.exceptions.JMESPathError as e: From 57bfbdc4078f8b6ba219f1bc7b8ec48bf489953f Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 25 May 2021 13:59:54 +0200 Subject: [PATCH 084/139] Use str() to get exception message (#2590) (#2611) (cherry picked from commit 63012eef82ad127e06e7a3e5a51eeb7a0f30a0c3) Co-authored-by: DasSkelett --- .../fragments/2590-netcup_dns-exception-no-message-attr.yml | 2 ++ plugins/modules/net_tools/netcup_dns.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2590-netcup_dns-exception-no-message-attr.yml diff --git a/changelogs/fragments/2590-netcup_dns-exception-no-message-attr.yml b/changelogs/fragments/2590-netcup_dns-exception-no-message-attr.yml new file mode 100644 index 0000000000..06cac9ad1b --- /dev/null +++ b/changelogs/fragments/2590-netcup_dns-exception-no-message-attr.yml @@ -0,0 +1,2 @@ +bugfixes: + - netcup_dns - use ``str(ex)`` instead of unreliable ``ex.message`` in exception handling to fix ``AttributeError`` in error cases (https://github.com/ansible-collections/community.general/pull/2590). diff --git a/plugins/modules/net_tools/netcup_dns.py b/plugins/modules/net_tools/netcup_dns.py index 5d63a5b38e..5ec5cbb246 100644 --- a/plugins/modules/net_tools/netcup_dns.py +++ b/plugins/modules/net_tools/netcup_dns.py @@ -255,7 +255,7 @@ def main(): has_changed = True except Exception as ex: - module.fail_json(msg=ex.message) + module.fail_json(msg=str(ex)) module.exit_json(changed=has_changed, result={"records": [record_data(r) for r in all_records]}) From 89b67a014bf98fd9e466d24ab2a7c18fab4d2a01 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 26 May 2021 07:22:03 +0200 Subject: [PATCH 085/139] jenkins_plugin: HTTP Error 405: Method Not Allowed on disable/enable plugin #2510 (#2511) (#2619) * define POST method for pluginManager api requests Jenkins makeEnable/makeDisable api requests requires to use POST method * add changelog fragment * fix my yoda lang thx to aminvakil Co-authored-by: Amin Vakil * update changelog fragment Co-authored-by: Felix Fontein Co-authored-by: Amin Vakil Co-authored-by: Felix Fontein (cherry picked from commit 6df3685d42f35147b73f08237b3dea73e8d36e9a) Co-authored-by: Alexander Moiseenko --- changelogs/fragments/2510-jenkins_plugin_use_post_method.yml | 2 ++ plugins/modules/web_infrastructure/jenkins_plugin.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2510-jenkins_plugin_use_post_method.yml diff --git a/changelogs/fragments/2510-jenkins_plugin_use_post_method.yml b/changelogs/fragments/2510-jenkins_plugin_use_post_method.yml new file mode 100644 index 0000000000..b310e27061 --- /dev/null +++ b/changelogs/fragments/2510-jenkins_plugin_use_post_method.yml @@ -0,0 +1,2 @@ +bugfixes: + - jenkins_plugin - use POST method for sending request to jenkins API when ``state`` option is one of ``enabled``, ``disabled``, ``pinned``, ``unpinned``, or ``absent`` (https://github.com/ansible-collections/community.general/issues/2510). diff --git a/plugins/modules/web_infrastructure/jenkins_plugin.py b/plugins/modules/web_infrastructure/jenkins_plugin.py index c9946023ac..be335fcfd3 100644 --- a/plugins/modules/web_infrastructure/jenkins_plugin.py +++ b/plugins/modules/web_infrastructure/jenkins_plugin.py @@ -696,7 +696,8 @@ class JenkinsPlugin(object): self._get_url_data( url, msg_status="Plugin not found. %s" % url, - msg_exception="%s has failed." % msg) + msg_exception="%s has failed." % msg, + method="POST") def main(): From 1a4814de5300a1aa3a70332fd136c675b25d99a9 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 26 May 2021 07:29:19 +0200 Subject: [PATCH 086/139] ini_file - added note in documentation for utf-8 bom (#2599) (#2620) * added note in documentation for utf-8 bom * Update plugins/modules/files/ini_file.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit aa74cf4d61b1e22e55ca1fa0b0d18744da493b4f) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- plugins/modules/files/ini_file.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/modules/files/ini_file.py b/plugins/modules/files/ini_file.py index ea857cefa9..d318d04d57 100644 --- a/plugins/modules/files/ini_file.py +++ b/plugins/modules/files/ini_file.py @@ -79,6 +79,7 @@ options: notes: - While it is possible to add an I(option) without specifying a I(value), this makes no sense. - As of Ansible 2.3, the I(dest) option has been changed to I(path) as default, but I(dest) still works as well. + - As of community.general 3.2.0, UTF-8 BOM markers are discarded when reading files. author: - Jan-Piet Mens (@jpmens) - Ales Nosek (@noseka1) From 057321c6c6a6320bc65c1d6614f7eb1ebce9bf72 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 26 May 2021 09:59:52 +0200 Subject: [PATCH 087/139] Add CONTRIBUTING.md (#2602) (#2626) * Initial file shamelessly copied from community.mysql * Add some notes on pull requests * Add CONTRIBUTING.md link to README.md * Add quick-start development guide link * Apply felixfontein's suggestions Co-authored-by: Felix Fontein * add note about rebasing and merge commits Co-authored-by: Felix Fontein * add note about easyfix and waiting_on_contributor tags Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit d0f8eac7fdf264ba04ce536d4de8b146dc3f86e4) Co-authored-by: Amin Vakil --- CONTRIBUTING.md | 32 ++++++++++++++++++++++++++++++++ README.md | 2 ++ 2 files changed, 34 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..959d363236 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,32 @@ +# Contributing + +We follow [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html) in all our contributions and interactions within this repository. + +If you are a committer, also refer to the [collection's committer guidelines](https://github.com/ansible-collections/community.general/blob/main/commit-rights.md). + +## Issue tracker + +Whether you are looking for an opportunity to contribute or you found a bug and already know how to solve it, please go to the [issue tracker](https://github.com/ansible-collections/community.general/issues). +There you can find feature ideas to implement, reports about bugs to solve, or submit an issue to discuss your idea before implementing it which can help choose a right direction at the beginning of your work and potentially save a lot of time and effort. +Also somebody may already have started discussing or working on implementing the same or a similar idea, +so you can cooperate to create a better solution together. + +* If you are interested in starting with an easy issue, look for [issues with an `easyfix` label](https://github.com/ansible-collections/community.general/labels/easyfix). +* Often issues that are waiting for contributors to pick up have [the `waiting_on_contributor` label](https://github.com/ansible-collections/community.general/labels/waiting_on_contributor). + +## Open pull requests + +Look through currently [open pull requests](https://github.com/ansible-collections/community.general/pulls). +You can help by reviewing them. Reviews help move pull requests to merge state. Some good pull requests cannot be merged only due to a lack of reviews. And it is always worth saying that good reviews are often more valuable than pull requests themselves. +Note that reviewing does not only mean code review, but also offering comments on new interfaces added to existing plugins/modules, interfaces of new plugins/modules, improving language (not everyone is a native english speaker), or testing bugfixes and new features! + +Also, consider taking up a valuable, reviewed, but abandoned pull request which you could politely ask the original authors to complete yourself. + +* Try committing your changes with an informative but short commit message. +* All commits of a pull request branch will be squashed into one commit at last. That does not mean you must have only one commit on your pull request, though! +* Please try not to force-push if it is not needed, so reviewers and other users looking at your pull request later can see the pull request commit history. +* Do not add merge commits to your PR. The bot will complain and you will have to rebase ([instructions for rebasing](https://docs.ansible.com/ansible/latest/dev_guide/developing_rebasing.html)) to remove them before your PR can be merged. To avoid that git automatically does merges during pulls, you can configure it to do rebases instead by running `git config pull.rebase true` inside the respository checkout. + +You can also read [our Quick-start development guide](https://github.com/ansible/community-docs/blob/main/create_pr_quick_start_guide.rst). + +If you find any inconsistencies or places in this document which can be improved, feel free to raise an issue or pull request to fix it. diff --git a/README.md b/README.md index f0881f9aee..1d31a87214 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,8 @@ export COLLECTIONS_PATH=$(pwd)/collections:$COLLECTIONS_PATH 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). + ### Running tests See [here](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections.html#testing-collections). From ed0636dc27e749bc1a766104957d0b5c18194a5d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 26 May 2021 10:00:02 +0200 Subject: [PATCH 088/139] redis cache - better parsing of connection uri (#2579) (#2622) * better parsing of connection uri * added changelog fragment * fixed tests for ansible 2.9 * Update tests/unit/plugins/cache/test_redis.py Co-authored-by: Felix Fontein * Update tests/unit/plugins/cache/test_redis.py Co-authored-by: Felix Fontein * Adjustments from PR * Update test_redis.py * Update test_redis.py * Update plugins/cache/redis.py Co-authored-by: Felix Fontein * Update plugins/cache/redis.py Co-authored-by: Felix Fontein * Update tests/unit/plugins/cache/test_redis.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 4764a5deba6b44c988ab21b1b8b2951e71b8499b) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- changelogs/fragments/2579-redis-cache-ipv6.yml | 2 ++ plugins/cache/redis.py | 14 ++++++++++++-- tests/unit/plugins/cache/test_redis.py | 15 ++++++++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/2579-redis-cache-ipv6.yml diff --git a/changelogs/fragments/2579-redis-cache-ipv6.yml b/changelogs/fragments/2579-redis-cache-ipv6.yml new file mode 100644 index 0000000000..aaa5e78b34 --- /dev/null +++ b/changelogs/fragments/2579-redis-cache-ipv6.yml @@ -0,0 +1,2 @@ +bugfixes: + - redis cache - improved connection string parsing (https://github.com/ansible-collections/community.general/issues/497). diff --git a/plugins/cache/redis.py b/plugins/cache/redis.py index 7a376d6d7c..6af7c731e4 100644 --- a/plugins/cache/redis.py +++ b/plugins/cache/redis.py @@ -61,6 +61,7 @@ DOCUMENTATION = ''' type: integer ''' +import re import time import json @@ -91,6 +92,8 @@ class CacheModule(BaseCacheModule): performance. """ _sentinel_service_name = None + re_url_conn = re.compile(r'^([^:]+|\[[^]]+\]):(\d+):(\d+)(?::(.*))?$') + re_sent_conn = re.compile(r'^(.*):(\d+)$') def __init__(self, *args, **kwargs): uri = '' @@ -130,11 +133,18 @@ class CacheModule(BaseCacheModule): self._db = self._get_sentinel_connection(uri, kw) # normal connection else: - connection = uri.split(':') + connection = self._parse_connection(self.re_url_conn, uri) self._db = StrictRedis(*connection, **kw) display.vv('Redis connection: %s' % self._db) + @staticmethod + def _parse_connection(re_patt, uri): + match = re_patt.match(uri) + if not match: + raise AnsibleError("Unable to parse connection string") + return match.groups() + def _get_sentinel_connection(self, uri, kw): """ get sentinel connection details from _uri @@ -158,7 +168,7 @@ class CacheModule(BaseCacheModule): except IndexError: pass # password is optional - sentinels = [tuple(shost.split(':')) for shost in connections] + sentinels = [self._parse_connection(self.re_sent_conn, shost) for shost in connections] display.vv('\nUsing redis sentinels: %s' % sentinels) scon = Sentinel(sentinels, **kw) try: diff --git a/tests/unit/plugins/cache/test_redis.py b/tests/unit/plugins/cache/test_redis.py index e665826769..ee7e1f7913 100644 --- a/tests/unit/plugins/cache/test_redis.py +++ b/tests/unit/plugins/cache/test_redis.py @@ -23,10 +23,23 @@ import pytest pytest.importorskip('redis') +from ansible import constants as C from ansible.plugins.loader import cache_loader +from ansible.release import __version__ as ansible_version from ansible_collections.community.general.plugins.cache.redis import CacheModule as RedisCache def test_redis_cachemodule(): # The _uri option is required for the redis plugin - assert isinstance(cache_loader.get('community.general.redis', **{'_uri': '127.0.0.1:6379:1'}), RedisCache) + connection = '127.0.0.1:6379:1' + if ansible_version.startswith('2.9.'): + C.CACHE_PLUGIN_CONNECTION = connection + assert isinstance(cache_loader.get('community.general.redis', **{'_uri': connection}), RedisCache) + + +def test_redis_cachemodule(): + # The _uri option is required for the redis plugin + connection = '[::1]:6379:1' + if ansible_version.startswith('2.9.'): + C.CACHE_PLUGIN_CONNECTION = connection + assert isinstance(cache_loader.get('community.general.redis', **{'_uri': connection}), RedisCache) From 0f0e9b2dca9b58438e6718332168741848db033f Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 26 May 2021 10:48:33 +0200 Subject: [PATCH 089/139] Use become test framework for sudosu tests. (#2629) (#2631) (cherry picked from commit 0b4a2bea01ef4f7a5d1f78e3f38f0d2b55955d39) Co-authored-by: Felix Fontein --- tests/unit/plugins/become/test_sudosu.py | 37 ++++++++++++++---------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/tests/unit/plugins/become/test_sudosu.py b/tests/unit/plugins/become/test_sudosu.py index 4e5c998f09..6adf200d8e 100644 --- a/tests/unit/plugins/become/test_sudosu.py +++ b/tests/unit/plugins/become/test_sudosu.py @@ -10,36 +10,41 @@ __metaclass__ = type import re from ansible import context -from ansible.playbook.play_context import PlayContext -from ansible.plugins.loader import become_loader + +from .helper import call_become_plugin def test_sudosu(mocker, parser, reset_cli_args): options = parser.parse_args([]) context._init_global_context(options) - play_context = PlayContext() default_cmd = "/bin/foo" default_exe = "/bin/bash" sudo_exe = 'sudo' sudo_flags = '-H -s -n' - cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) - assert cmd == default_cmd - success = 'BECOME-SUCCESS-.+?' - play_context.become = True - play_context.become_user = 'foo' - play_context.set_become_plugin(become_loader.get('community.general.sudosu')) - play_context.become_flags = sudo_flags - cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) - - assert (re.match("""%s %s su -l %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags, play_context.become_user, + task = { + 'become_user': 'foo', + 'become_method': 'community.general.sudosu', + 'become_flags': sudo_flags, + } + var_options = {} + cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe) + print(cmd) + assert (re.match("""%s %s su -l %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags, task['become_user'], default_exe, success, default_cmd), cmd) is not None) - play_context.become_pass = 'testpass' - cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) + task = { + 'become_user': 'foo', + 'become_method': 'community.general.sudosu', + 'become_flags': sudo_flags, + 'become_pass': 'testpass', + } + var_options = {} + cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe) + print(cmd) assert (re.match("""%s %s -p "%s" su -l %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags.replace('-n', ''), - r"\[sudo via ansible, key=.+?\] password:", play_context.become_user, + r"\[sudo via ansible, key=.+?\] password:", task['become_user'], default_exe, success, default_cmd), cmd) is not None) From 301fcc3b7e657c1b2d58d9892f14b54d89714eb8 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 27 May 2021 08:23:21 +0200 Subject: [PATCH 090/139] influxdb_user: Fix bug introduced by PR 2499 (#2614) (#2640) * Update influxdb_user.py Fixed function name * Create 2614-influxdb_user-fix-issue-introduced-in-PR#2499 Added changelog * Rename 2614-influxdb_user-fix-issue-introduced-in-PR#2499 to 2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml Fixed extension * Update changelogs/fragments/2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml Co-authored-by: Amin Vakil Co-authored-by: Amin Vakil (cherry picked from commit 4aa50962cb54b903c807b6a000cb41c28d4b1806) Co-authored-by: sgalea87 <43749726+sgalea87@users.noreply.github.com> --- .../2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml | 2 ++ plugins/modules/database/influxdb/influxdb_user.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml diff --git a/changelogs/fragments/2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml b/changelogs/fragments/2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml new file mode 100644 index 0000000000..dfae3f2bdf --- /dev/null +++ b/changelogs/fragments/2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml @@ -0,0 +1,2 @@ +bugfixes: + - influxdb_user - fix bug which removed current privileges instead of appending them to existing ones (https://github.com/ansible-collections/community.general/issues/2609, https://github.com/ansible-collections/community.general/pull/2614). diff --git a/plugins/modules/database/influxdb/influxdb_user.py b/plugins/modules/database/influxdb/influxdb_user.py index d9e6b58051..cb35ea7ce6 100644 --- a/plugins/modules/database/influxdb/influxdb_user.py +++ b/plugins/modules/database/influxdb/influxdb_user.py @@ -174,7 +174,7 @@ def set_user_grants(module, client, user_name, grants): if v['privilege'] != 'NO PRIVILEGES': if v['privilege'] == 'ALL PRIVILEGES': v['privilege'] = 'ALL' - parsed_grants.add(v) + parsed_grants.append(v) # check if the current grants are included in the desired ones for current_grant in parsed_grants: From 4f3de5658e125f8d68ba2c5d858bf7d54da4aad2 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 27 May 2021 08:25:49 +0200 Subject: [PATCH 091/139] Add one-liner lookup example (#2615) (#2638) * Add one-liner lookup example * Remove trailing whitespace * Update plugins/lookup/tss.py Co-authored-by: Felix Fontein * Update plugins/lookup/tss.py Co-authored-by: Amin Vakil Co-authored-by: Felix Fontein Co-authored-by: Amin Vakil (cherry picked from commit 26757edfb27b8d871963aae45e41eddf05a06775) Co-authored-by: Sylvia van Os --- plugins/lookup/tss.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/lookup/tss.py b/plugins/lookup/tss.py index 2c25532699..b7b7cd85e0 100644 --- a/plugins/lookup/tss.py +++ b/plugins/lookup/tss.py @@ -103,6 +103,14 @@ EXAMPLES = r""" | items2dict(key_name='slug', value_name='itemValue'))['password'] }} + +- hosts: localhost + vars: + secret_password: >- + {{ ((lookup('community.general.tss', 1) | from_json).get('items') | items2dict(key_name='slug', value_name='itemValue'))['password'] }}" + tasks: + - ansible.builtin.debug: + msg: the password is {{ secret_password }} """ from ansible.errors import AnsibleError, AnsibleOptionsError From c2429932910e1a83ddf333129bf9b6ba2079b46c Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 27 May 2021 08:28:45 +0200 Subject: [PATCH 092/139] Temporarily disable iptables_state tests. (#2641) (#2643) (cherry picked from commit b45298bc4355d0ab95ed37e0eade699b2b665289) Co-authored-by: Felix Fontein --- tests/integration/targets/iptables_state/aliases | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/targets/iptables_state/aliases b/tests/integration/targets/iptables_state/aliases index 3cac4af522..12765cec47 100644 --- a/tests/integration/targets/iptables_state/aliases +++ b/tests/integration/targets/iptables_state/aliases @@ -5,3 +5,4 @@ skip/freebsd # no iptables/netfilter (Linux specific) skip/osx # no iptables/netfilter (Linux specific) skip/macos # no iptables/netfilter (Linux specific) skip/aix # no iptables/netfilter (Linux specific) +disabled # FIXME From e6b84acd1e420b5c92a84ed2689ab5d963f80141 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 27 May 2021 07:16:36 +0000 Subject: [PATCH 093/139] fix a regression in initialization_from_null_state() (iptables-nft > 1.8.2) (#2604) (#2646) (cherry picked from commit 909e9fe9508804b2e18b755ef36060861cde5228) Co-authored-by: quidame --- plugins/modules/system/iptables_state.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/plugins/modules/system/iptables_state.py b/plugins/modules/system/iptables_state.py index 326db862bc..66ba2c9b20 100644 --- a/plugins/modules/system/iptables_state.py +++ b/plugins/modules/system/iptables_state.py @@ -304,7 +304,7 @@ def write_state(b_path, lines, changed): return changed -def initialize_from_null_state(initializer, initcommand, table): +def initialize_from_null_state(initializer, initcommand, fallbackcmd, table): ''' This ensures iptables-state output is suitable for iptables-restore to roll back to it, i.e. iptables-save output is not empty. This also works for the @@ -315,8 +315,14 @@ def initialize_from_null_state(initializer, initcommand, table): commandline = list(initializer) commandline += ['-t', table] - (rc, out, err) = module.run_command(commandline, check_rc=True) + dummy = module.run_command(commandline, check_rc=True) (rc, out, err) = module.run_command(initcommand, check_rc=True) + if '*%s' % table not in out.splitlines(): + # The last resort. + iptables_input = '*%s\n:OUTPUT ACCEPT\nCOMMIT\n' % table + dummy = module.run_command(fallbackcmd, data=iptables_input, check_rc=True) + (rc, out, err) = module.run_command(initcommand, check_rc=True) + return rc, out, err @@ -401,6 +407,7 @@ def main(): INITCOMMAND = [bin_iptables_save] INITIALIZER = [bin_iptables, '-L', '-n'] TESTCOMMAND = [bin_iptables_restore, '--test'] + FALLBACKCMD = [bin_iptables_restore] if counters: COMMANDARGS.append('--counters') @@ -425,6 +432,7 @@ def main(): INITIALIZER.extend(['--modprobe', modprobe]) INITCOMMAND.extend(['--modprobe', modprobe]) TESTCOMMAND.extend(['--modprobe', modprobe]) + FALLBACKCMD.extend(['--modprobe', modprobe]) SAVECOMMAND = list(COMMANDARGS) SAVECOMMAND.insert(0, bin_iptables_save) @@ -458,15 +466,15 @@ def main(): for t in TABLES: if '*%s' % t in state_to_restore: if len(stdout) == 0 or '*%s' % t not in stdout.splitlines(): - (rc, stdout, stderr) = initialize_from_null_state(INITIALIZER, INITCOMMAND, t) + (rc, stdout, stderr) = initialize_from_null_state(INITIALIZER, INITCOMMAND, FALLBACKCMD, t) elif len(stdout) == 0: - (rc, stdout, stderr) = initialize_from_null_state(INITIALIZER, INITCOMMAND, 'filter') + (rc, stdout, stderr) = initialize_from_null_state(INITIALIZER, INITCOMMAND, FALLBACKCMD, 'filter') elif state == 'restored' and '*%s' % table not in state_to_restore: module.fail_json(msg="Table %s to restore not defined in %s" % (table, path)) elif len(stdout) == 0 or '*%s' % table not in stdout.splitlines(): - (rc, stdout, stderr) = initialize_from_null_state(INITIALIZER, INITCOMMAND, table) + (rc, stdout, stderr) = initialize_from_null_state(INITIALIZER, INITCOMMAND, FALLBACKCMD, table) initial_state = filter_and_format_state(stdout) if initial_state is None: From 5b6866557156e6299b6482ce1283250362373767 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 27 May 2021 19:07:04 +0200 Subject: [PATCH 094/139] Add module hana_query to make SAP HANA administration easier. (#2623) (#2651) * new * move link * Apply suggestions from code review Co-authored-by: Felix Fontein * add more interesting return value in test * remove unused objects * removed unneeded function * extend test output * Update tests/unit/plugins/modules/database/saphana/test_hana_query.py Co-authored-by: Felix Fontein Co-authored-by: Rainer Leber Co-authored-by: Felix Fontein (cherry picked from commit b79969da68ddaa73cfabdb866f80ac7f414b9f62) Co-authored-by: rainerleber <39616583+rainerleber@users.noreply.github.com> --- .../modules/database/saphana/hana_query.py | 187 ++++++++++++++++++ plugins/modules/hana_query.py | 1 + .../modules/database/saphana/__init__.py | 0 .../database/saphana/test_hana_query.py | 66 +++++++ 4 files changed, 254 insertions(+) create mode 100644 plugins/modules/database/saphana/hana_query.py create mode 120000 plugins/modules/hana_query.py create mode 100644 tests/unit/plugins/modules/database/saphana/__init__.py create mode 100644 tests/unit/plugins/modules/database/saphana/test_hana_query.py diff --git a/plugins/modules/database/saphana/hana_query.py b/plugins/modules/database/saphana/hana_query.py new file mode 100644 index 0000000000..ab147ef3fe --- /dev/null +++ b/plugins/modules/database/saphana/hana_query.py @@ -0,0 +1,187 @@ +#!/usr/bin/python + +# Copyright: (c) 2021, Rainer Leber +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: hana_query +short_description: Execute SQL on HANA +version_added: 3.2.0 +description: This module executes SQL statements on HANA with hdbsql. +options: + sid: + description: The system ID. + type: str + required: true + instance: + description: The instance number. + type: str + required: true + user: + description: A dedicated username. Defaults to C(SYSTEM). + type: str + default: SYSTEM + password: + description: The password to connect to the database. + type: str + required: true + autocommit: + description: Autocommit the statement. + type: bool + default: true + host: + description: The Host IP address. The port can be defined as well. + type: str + database: + description: Define the database on which to connect. + type: str + encrypted: + description: Use encrypted connection. Defaults to C(false). + type: bool + default: false + filepath: + description: + - One or more files each containing one SQL query to run. + - Must be a string or list containing strings. + type: list + elements: path + query: + description: + - SQL query to run. + - Must be a string or list containing strings. Please note that if you supply a string, it will be split by commas (C(,)) to a list. + It is better to supply a one-element list instead to avoid mangled input. + type: list + elements: str +notes: + - Does not support C(check_mode). +author: + - Rainer Leber (@rainerleber) +''' + +EXAMPLES = r''' +- name: Simple select query + community.general.hana_query: + sid: "hdb" + instance: "01" + password: "Test123" + query: "select user_name from users" + +- name: Run several queries + community.general.hana_query: + sid: "hdb" + instance: "01" + password: "Test123" + query: + - "select user_name from users;" + - select * from SYSTEM; + host: "localhost" + autocommit: False + +- name: Run several queries from file + community.general.hana_query: + sid: "hdb" + instance: "01" + password: "Test123" + filepath: + - /tmp/HANA_CPU_UtilizationPerCore_2.00.020+.txt + - /tmp/HANA.txt + host: "localhost" +''' + +RETURN = r''' +query_result: + description: List containing results of all queries executed (one sublist for every query). + returned: on success + type: list + elements: list + sample: [[{"Column": "Value1"}, {"Column": "Value2"}], [{"Column": "Value1"}, {"Column": "Value2"}]] +''' + +import csv +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import StringIO +from ansible.module_utils._text import to_native + + +def csv_to_list(rawcsv): + reader_raw = csv.DictReader(StringIO(rawcsv)) + reader = [dict((k, v.strip()) for k, v in row.items()) for row in reader_raw] + return list(reader) + + +def main(): + module = AnsibleModule( + argument_spec=dict( + sid=dict(type='str', required=True), + instance=dict(type='str', required=True), + encrypted=dict(type='bool', required=False, default=False), + host=dict(type='str', required=False), + user=dict(type='str', required=False, default="SYSTEM"), + password=dict(type='str', required=True, no_log=True), + database=dict(type='str', required=False), + query=dict(type='list', elements='str', required=False), + filepath=dict(type='list', elements='path', required=False), + autocommit=dict(type='bool', required=False, default=True), + ), + required_one_of=[('query', 'filepath')], + supports_check_mode=False, + ) + rc, out, err, out_raw = [0, [], "", ""] + + params = module.params + + sid = (params['sid']).upper() + instance = params['instance'] + user = params['user'] + password = params['password'] + autocommit = params['autocommit'] + host = params['host'] + database = params['database'] + encrypted = params['encrypted'] + + filepath = params['filepath'] + query = params['query'] + + bin_path = "/usr/sap/{sid}/HDB{instance}/exe/hdbsql".format(sid=sid, instance=instance) + + try: + command = [module.get_bin_path(bin_path, required=True)] + except Exception as e: + module.fail_json(msg='Failed to find hdbsql at the expected path "{0}". Please check SID and instance number: "{1}"'.format(bin_path, to_native(e))) + + if encrypted is True: + command.extend(['-attemptencrypt']) + if autocommit is False: + command.extend(['-z']) + if host is not None: + command.extend(['-n', host]) + if database is not None: + command.extend(['-d', database]) + # -x Suppresses additional output, such as the number of selected rows in a result set. + command.extend(['-x', '-i', instance, '-u', user, '-p', password]) + + if filepath is not None: + command.extend(['-I']) + for p in filepath: + # makes a command like hdbsql -i 01 -u SYSTEM -p secret123# -I /tmp/HANA_CPU_UtilizationPerCore_2.00.020+.txt, + # iterates through files and append the output to var out. + query_command = command + [p] + (rc, out_raw, err) = module.run_command(query_command) + out.append(csv_to_list(out_raw)) + if query is not None: + for q in query: + # makes a command like hdbsql -i 01 -u SYSTEM -p secret123# "select user_name from users", + # iterates through multiple commands and append the output to var out. + query_command = command + [q] + (rc, out_raw, err) = module.run_command(query_command) + out.append(csv_to_list(out_raw)) + changed = True + + module.exit_json(changed=changed, rc=rc, query_result=out, stderr=err) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/hana_query.py b/plugins/modules/hana_query.py new file mode 120000 index 0000000000..ea869eb7a4 --- /dev/null +++ b/plugins/modules/hana_query.py @@ -0,0 +1 @@ +./database/saphana/hana_query.py \ No newline at end of file diff --git a/tests/unit/plugins/modules/database/saphana/__init__.py b/tests/unit/plugins/modules/database/saphana/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/unit/plugins/modules/database/saphana/test_hana_query.py b/tests/unit/plugins/modules/database/saphana/test_hana_query.py new file mode 100644 index 0000000000..4d158c028e --- /dev/null +++ b/tests/unit/plugins/modules/database/saphana/test_hana_query.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- + +# Copyright: (c) 2021, Rainer Leber (@rainerleber) +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +from ansible_collections.community.general.plugins.modules import hana_query +from ansible_collections.community.general.tests.unit.plugins.modules.utils import ( + AnsibleExitJson, + AnsibleFailJson, + ModuleTestCase, + set_module_args, +) +from ansible_collections.community.general.tests.unit.compat.mock import patch +from ansible.module_utils import basic + + +def get_bin_path(*args, **kwargs): + """Function to return path of hdbsql""" + return "/usr/sap/HDB/HDB01/exe/hdbsql" + + +class Testhana_query(ModuleTestCase): + """Main class for testing hana_query module.""" + + def setUp(self): + """Setup.""" + super(Testhana_query, self).setUp() + self.module = hana_query + self.mock_get_bin_path = patch.object(basic.AnsibleModule, 'get_bin_path', get_bin_path) + self.mock_get_bin_path.start() + self.addCleanup(self.mock_get_bin_path.stop) # ensure that the patching is 'undone' + + def tearDown(self): + """Teardown.""" + super(Testhana_query, self).tearDown() + + def test_without_required_parameters(self): + """Failure must occurs when all parameters are missing.""" + with self.assertRaises(AnsibleFailJson): + set_module_args({}) + self.module.main() + + def test_hana_query(self): + """Check that result is processed.""" + set_module_args({ + 'sid': "HDB", + 'instance': "01", + 'encrypted': False, + 'host': "localhost", + 'user': "SYSTEM", + 'password': "1234Qwer", + 'database': "HDB", + 'query': "SELECT * FROM users;" + }) + with patch.object(basic.AnsibleModule, 'run_command') as run_command: + run_command.return_value = 0, 'username,name\n testuser,test user \n myuser, my user \n', '' + with self.assertRaises(AnsibleExitJson) as result: + hana_query.main() + self.assertEqual(result.exception.args[0]['query_result'], [[ + {'username': 'testuser', 'name': 'test user'}, + {'username': 'myuser', 'name': 'my user'}, + ]]) + self.assertEqual(run_command.call_count, 1) From 928aeafe1d826154e2997b6e74584f61452cdbb5 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 27 May 2021 19:07:11 +0200 Subject: [PATCH 095/139] hana_query module: add a maintainer (#2647) (#2652) (cherry picked from commit dc793ea32b7246904c969eb1768fb5c8aef87990) Co-authored-by: Andrew Klychkov --- .github/BOTMETA.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index cdef437f90..994de0621f 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -347,6 +347,8 @@ files: $modules/database/mssql/mssql_db.py: maintainers: vedit Jmainguy kenichi-ogawa-1988 labels: mssql_db + $modules/database/saphana/hana_query.py: + maintainers: rainerleber $modules/database/vertica/: maintainers: dareko $modules/files/archive.py: From fb9730f75e2c4c400bd3d05843647d07a29cf2c1 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 27 May 2021 20:15:22 +0200 Subject: [PATCH 096/139] meta/runtime.yml and __init__.py cleanup (#2632) (#2653) * Remove superfluous __init__.py files. * Reformat and sort meta/runtime.yml. * The ovirt modules have been removed. * Add changelog entry. (cherry picked from commit 7cd96d963efe4e6bf7ac9080fdf933dc23664dcf) Co-authored-by: Felix Fontein --- changelogs/fragments/2632-cleanup.yml | 2 + meta/runtime.yml | 244 +++++++++--------- plugins/action/__init__.py | 0 plugins/become/__init__.py | 0 plugins/cache/__init__.py | 0 plugins/callback/__init__.py | 0 plugins/connection/__init__.py | 0 plugins/doc_fragments/__init__.py | 0 plugins/filter/__init__.py | 0 plugins/inventory/__init__.py | 0 plugins/lookup/__init__.py | 0 plugins/module_utils/__init__.py | 0 plugins/module_utils/identity/__init__.py | 0 .../identity/keycloak/__init__.py | 0 plugins/module_utils/mh/__init__.py | 0 plugins/module_utils/mh/mixins/__init__.py | 0 plugins/module_utils/net_tools/__init__.py | 0 .../module_utils/net_tools/nios/__init__.py | 0 .../net_tools/pritunl/__init__.py | 0 plugins/module_utils/oracle/__init__.py | 0 .../remote_management/__init__.py | 0 .../remote_management/lxca/__init__.py | 0 .../module_utils/source_control/__init__.py | 0 plugins/module_utils/storage/__init__.py | 0 plugins/module_utils/storage/emc/__init__.py | 0 .../module_utils/storage/hpe3par/__init__.py | 0 plugins/modules/__init__.py | 0 plugins/modules/net_tools/pritunl/__init__.py | 0 28 files changed, 118 insertions(+), 128 deletions(-) create mode 100644 changelogs/fragments/2632-cleanup.yml delete mode 100644 plugins/action/__init__.py delete mode 100644 plugins/become/__init__.py delete mode 100644 plugins/cache/__init__.py delete mode 100644 plugins/callback/__init__.py delete mode 100644 plugins/connection/__init__.py delete mode 100644 plugins/doc_fragments/__init__.py delete mode 100644 plugins/filter/__init__.py delete mode 100644 plugins/inventory/__init__.py delete mode 100644 plugins/lookup/__init__.py delete mode 100644 plugins/module_utils/__init__.py delete mode 100644 plugins/module_utils/identity/__init__.py delete mode 100644 plugins/module_utils/identity/keycloak/__init__.py delete mode 100644 plugins/module_utils/mh/__init__.py delete mode 100644 plugins/module_utils/mh/mixins/__init__.py delete mode 100644 plugins/module_utils/net_tools/__init__.py delete mode 100644 plugins/module_utils/net_tools/nios/__init__.py delete mode 100644 plugins/module_utils/net_tools/pritunl/__init__.py delete mode 100644 plugins/module_utils/oracle/__init__.py delete mode 100644 plugins/module_utils/remote_management/__init__.py delete mode 100644 plugins/module_utils/remote_management/lxca/__init__.py delete mode 100644 plugins/module_utils/source_control/__init__.py delete mode 100644 plugins/module_utils/storage/__init__.py delete mode 100644 plugins/module_utils/storage/emc/__init__.py delete mode 100644 plugins/module_utils/storage/hpe3par/__init__.py delete mode 100644 plugins/modules/__init__.py delete mode 100644 plugins/modules/net_tools/pritunl/__init__.py diff --git a/changelogs/fragments/2632-cleanup.yml b/changelogs/fragments/2632-cleanup.yml new file mode 100644 index 0000000000..def89de634 --- /dev/null +++ b/changelogs/fragments/2632-cleanup.yml @@ -0,0 +1,2 @@ +minor_changes: +- "Remove unnecessary ``__init__.py`` files from ``plugins/`` (https://github.com/ansible-collections/community.general/pull/2632)." diff --git a/meta/runtime.yml b/meta/runtime.yml index e5b59bc046..8b2a0c0ad6 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1,31 +1,5 @@ --- requires_ansible: '>=2.9.10' -action_groups: - ovirt: - - ovirt_affinity_label_facts - - ovirt_api_facts - - ovirt_cluster_facts - - ovirt_datacenter_facts - - ovirt_disk_facts - - ovirt_event_facts - - ovirt_external_provider_facts - - ovirt_group_facts - - ovirt_host_facts - - ovirt_host_storage_facts - - ovirt_network_facts - - ovirt_nic_facts - - ovirt_permission_facts - - ovirt_quota_facts - - ovirt_scheduling_policy_facts - - ovirt_snapshot_facts - - ovirt_storage_domain_facts - - ovirt_storage_template_facts - - ovirt_storage_vm_facts - - ovirt_tag_facts - - ovirt_template_facts - - ovirt_user_facts - - ovirt_vm_facts - - ovirt_vmpool_facts plugin_routing: connection: docker: @@ -40,15 +14,18 @@ plugin_routing: nios: deprecation: removal_version: 5.0.0 - warning_text: The community.general.nios lookup plugin has been deprecated. Please use infoblox.nios_modules.nios_lookup instead. + warning_text: The community.general.nios lookup plugin has been deprecated. + Please use infoblox.nios_modules.nios_lookup instead. nios_next_ip: deprecation: removal_version: 5.0.0 - warning_text: The community.general.nios_next_ip lookup plugin has been deprecated. Please use infoblox.nios_modules.nios_next_ip instead. + warning_text: The community.general.nios_next_ip lookup plugin has been deprecated. + Please use infoblox.nios_modules.nios_next_ip instead. nios_next_network: deprecation: removal_version: 5.0.0 - warning_text: The community.general.nios_next_network lookup plugin has been deprecated. Please use infoblox.nios_modules.nios_next_network instead. + warning_text: The community.general.nios_next_network lookup plugin has been + deprecated. Please use infoblox.nios_modules.nios_next_network instead. modules: ali_instance_facts: tombstone: @@ -153,11 +130,13 @@ plugin_routing: gcp_forwarding_rule: tombstone: removal_version: 2.0.0 - warning_text: Use google.cloud.gcp_compute_forwarding_rule or google.cloud.gcp_compute_global_forwarding_rule instead. + warning_text: Use google.cloud.gcp_compute_forwarding_rule or google.cloud.gcp_compute_global_forwarding_rule + instead. gcp_healthcheck: tombstone: removal_version: 2.0.0 - warning_text: Use google.cloud.gcp_compute_health_check, google.cloud.gcp_compute_http_health_check or google.cloud.gcp_compute_https_health_check instead. + warning_text: Use google.cloud.gcp_compute_health_check, google.cloud.gcp_compute_http_health_check + or google.cloud.gcp_compute_https_health_check instead. gcp_target_proxy: tombstone: removal_version: 2.0.0 @@ -168,37 +147,22 @@ plugin_routing: warning_text: Use google.cloud.gcp_compute_url_map instead. gcpubsub: redirect: community.google.gcpubsub - gcpubsub_info: - redirect: community.google.gcpubsub_info gcpubsub_facts: tombstone: removal_version: 3.0.0 warning_text: Use community.google.gcpubsub_info instead. + gcpubsub_info: + redirect: community.google.gcpubsub_info gcspanner: tombstone: removal_version: 2.0.0 - warning_text: Use google.cloud.gcp_spanner_database and/or google.cloud.gcp_spanner_instance instead. + warning_text: Use google.cloud.gcp_spanner_database and/or google.cloud.gcp_spanner_instance + instead. github_hooks: tombstone: removal_version: 2.0.0 - warning_text: Use community.general.github_webhook and community.general.github_webhook_info instead. - # Adding tombstones burns the old name, so we simply remove the entries: - # gluster_heal_info: - # tombstone: - # removal_version: 3.0.0 - # warning_text: The gluster modules have migrated to the gluster.gluster collection. Use gluster.gluster.gluster_heal_info instead. - # gluster_peer: - # tombstone: - # removal_version: 3.0.0 - # warning_text: The gluster modules have migrated to the gluster.gluster collection. Use gluster.gluster.gluster_peer instead. - # gluster_volume: - # tombstone: - # removal_version: 3.0.0 - # warning_text: The gluster modules have migrated to the gluster.gluster collection. Use gluster.gluster.gluster_volume instead. - # helm: - # tombstone: - # removal_version: 3.0.0 - # warning_text: Use community.kubernetes.helm instead. + warning_text: Use community.general.github_webhook and community.general.github_webhook_info + instead. hetzner_failover_ip: redirect: community.hrobot.failover_ip hetzner_failover_ip_info: @@ -246,11 +210,13 @@ plugin_routing: logicmonitor: tombstone: removal_version: 1.0.0 - warning_text: The logicmonitor_facts module is no longer maintained and the API used has been disabled in 2017. + warning_text: The logicmonitor_facts module is no longer maintained and the + API used has been disabled in 2017. logicmonitor_facts: tombstone: removal_version: 1.0.0 - warning_text: The logicmonitor_facts module is no longer maintained and the API used has been disabled in 2017. + warning_text: The logicmonitor_facts module is no longer maintained and the + API used has been disabled in 2017. memset_memstore_facts: tombstone: removal_version: 3.0.0 @@ -295,74 +261,90 @@ plugin_routing: tombstone: removal_version: 3.0.0 warning_text: Use netapp.ontap.na_ontap_info instead. - nios_a_record: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_a_record module has been deprecated. Please use infoblox.nios_modules.nios_a_record instead. - nios_aaaa_record: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_aaaa_record module has been deprecated. Please use infoblox.nios_modules.nios_aaaa_record instead. - nios_cname_record: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_cname_record module has been deprecated. Please use infoblox.nios_modules.nios_cname_record instead. - nios_dns_view: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_dns_view module has been deprecated. Please use infoblox.nios_modules.nios_dns_view instead. - nios_fixed_address: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_fixed_address module has been deprecated. Please use infoblox.nios_modules.nios_fixed_address instead. - nios_host_record: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_host_record module has been deprecated. Please use infoblox.nios_modules.nios_host_record instead. - nios_member: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_member module has been deprecated. Please use infoblox.nios_modules.nios_member instead. - nios_mx_record: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_mx_record module has been deprecated. Please use infoblox.nios_modules.nios_mx_record instead. - nios_naptr_record: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_naptr_record module has been deprecated. Please use infoblox.nios_modules.nios_naptr_record instead. - nios_network: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_network module has been deprecated. Please use infoblox.nios_modules.nios_network instead. - nios_network_view: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_network_view module has been deprecated. Please use infoblox.nios_modules.nios_network_view instead. - nios_nsgroup: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_nsgroup module has been deprecated. Please use infoblox.nios_modules.nios_nsgroup instead. - nios_ptr_record: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_ptr_record module has been deprecated. Please use infoblox.nios_modules.nios_ptr_record instead. - nios_srv_record: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_srv_record module has been deprecated. Please use infoblox.nios_modules.nios_srv_record instead. - nios_txt_record: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_txt_record module has been deprecated. Please use infoblox.nios_modules.nios_txt_record instead. - nios_zone: - deprecation: - removal_version: 5.0.0 - warning_text: The community.general.nios_zone module has been deprecated. Please use infoblox.nios_modules.nios_zone instead. nginx_status_facts: tombstone: removal_version: 3.0.0 warning_text: Use community.general.nginx_status_info instead. + nios_a_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_a_record module has been deprecated. + Please use infoblox.nios_modules.nios_a_record instead. + nios_aaaa_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_aaaa_record module has been deprecated. + Please use infoblox.nios_modules.nios_aaaa_record instead. + nios_cname_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_cname_record module has been deprecated. + Please use infoblox.nios_modules.nios_cname_record instead. + nios_dns_view: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_dns_view module has been deprecated. + Please use infoblox.nios_modules.nios_dns_view instead. + nios_fixed_address: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_fixed_address module has been deprecated. + Please use infoblox.nios_modules.nios_fixed_address instead. + nios_host_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_host_record module has been deprecated. + Please use infoblox.nios_modules.nios_host_record instead. + nios_member: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_member module has been deprecated. + Please use infoblox.nios_modules.nios_member instead. + nios_mx_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_mx_record module has been deprecated. + Please use infoblox.nios_modules.nios_mx_record instead. + nios_naptr_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_naptr_record module has been deprecated. + Please use infoblox.nios_modules.nios_naptr_record instead. + nios_network: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_network module has been deprecated. + Please use infoblox.nios_modules.nios_network instead. + nios_network_view: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_network_view module has been deprecated. + Please use infoblox.nios_modules.nios_network_view instead. + nios_nsgroup: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_nsgroup module has been deprecated. + Please use infoblox.nios_modules.nios_nsgroup instead. + nios_ptr_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_ptr_record module has been deprecated. + Please use infoblox.nios_modules.nios_ptr_record instead. + nios_srv_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_srv_record module has been deprecated. + Please use infoblox.nios_modules.nios_srv_record instead. + nios_txt_record: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_txt_record module has been deprecated. + Please use infoblox.nios_modules.nios_txt_record instead. + nios_zone: + deprecation: + removal_version: 5.0.0 + warning_text: The community.general.nios_zone module has been deprecated. + Please use infoblox.nios_modules.nios_zone instead. ome_device_info: redirect: dellemc.openmanage.ome_device_info one_image_facts: @@ -396,7 +378,8 @@ plugin_routing: oneview_logical_interconnect_group_facts: tombstone: removal_version: 3.0.0 - warning_text: Use community.general.oneview_logical_interconnect_group_info instead. + warning_text: Use community.general.oneview_logical_interconnect_group_info + instead. oneview_network_set_facts: tombstone: removal_version: 3.0.0 @@ -553,10 +536,10 @@ plugin_routing: redirect: community.postgresql.postgresql_table postgresql_tablespace: redirect: community.postgresql.postgresql_tablespace - postgresql_user_obj_stat_info: - redirect: community.postgresql.postgresql_user_obj_stat_info postgresql_user: redirect: community.postgresql.postgresql_user + postgresql_user_obj_stat_info: + redirect: community.postgresql.postgresql_user_obj_stat_info purefa_facts: tombstone: removal_version: 3.0.0 @@ -647,7 +630,8 @@ plugin_routing: nios: deprecation: removal_version: 5.0.0 - warning_text: The community.general.nios document fragment has been deprecated. Please use infoblox.nios_modules.nios instead. + warning_text: The community.general.nios document fragment has been deprecated. + Please use infoblox.nios_modules.nios instead. postgresql: redirect: community.postgresql.postgresql module_utils: @@ -668,26 +652,30 @@ plugin_routing: net_tools.nios.api: deprecation: removal_version: 5.0.0 - warning_text: The community.general.net_tools.nios.api module_utils has been deprecated. Please use infoblox.nios_modules.api instead. + warning_text: The community.general.net_tools.nios.api module_utils has been + deprecated. Please use infoblox.nios_modules.api instead. + postgresql: + redirect: community.postgresql.postgresql remote_management.dellemc.dellemc_idrac: redirect: dellemc.openmanage.dellemc_idrac remote_management.dellemc.ome: redirect: dellemc.openmanage.ome - postgresql: - redirect: community.postgresql.postgresql callback: actionable: tombstone: removal_version: 2.0.0 - warning_text: Use the 'default' callback plugin with 'display_skipped_hosts = no' and 'display_ok_hosts = no' options. + warning_text: Use the 'default' callback plugin with 'display_skipped_hosts + = no' and 'display_ok_hosts = no' options. full_skip: tombstone: removal_version: 2.0.0 - warning_text: Use the 'default' callback plugin with 'display_skipped_hosts = no' option. + warning_text: Use the 'default' callback plugin with 'display_skipped_hosts + = no' option. stderr: tombstone: removal_version: 2.0.0 - warning_text: Use the 'default' callback plugin with 'display_failed_stderr = yes' option. + warning_text: Use the 'default' callback plugin with 'display_failed_stderr + = yes' option. inventory: docker_machine: redirect: community.docker.docker_machine diff --git a/plugins/action/__init__.py b/plugins/action/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/become/__init__.py b/plugins/become/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/cache/__init__.py b/plugins/cache/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/callback/__init__.py b/plugins/callback/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/connection/__init__.py b/plugins/connection/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/doc_fragments/__init__.py b/plugins/doc_fragments/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/filter/__init__.py b/plugins/filter/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/inventory/__init__.py b/plugins/inventory/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/lookup/__init__.py b/plugins/lookup/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/__init__.py b/plugins/module_utils/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/identity/__init__.py b/plugins/module_utils/identity/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/identity/keycloak/__init__.py b/plugins/module_utils/identity/keycloak/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/mh/__init__.py b/plugins/module_utils/mh/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/mh/mixins/__init__.py b/plugins/module_utils/mh/mixins/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/net_tools/__init__.py b/plugins/module_utils/net_tools/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/net_tools/nios/__init__.py b/plugins/module_utils/net_tools/nios/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/net_tools/pritunl/__init__.py b/plugins/module_utils/net_tools/pritunl/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/oracle/__init__.py b/plugins/module_utils/oracle/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/remote_management/__init__.py b/plugins/module_utils/remote_management/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/remote_management/lxca/__init__.py b/plugins/module_utils/remote_management/lxca/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/source_control/__init__.py b/plugins/module_utils/source_control/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/storage/__init__.py b/plugins/module_utils/storage/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/storage/emc/__init__.py b/plugins/module_utils/storage/emc/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/module_utils/storage/hpe3par/__init__.py b/plugins/module_utils/storage/hpe3par/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/modules/__init__.py b/plugins/modules/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/modules/net_tools/pritunl/__init__.py b/plugins/modules/net_tools/pritunl/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 From 5a7d234d80fbfc1f0ef7aaa43045a81080df732f Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 27 May 2021 20:15:33 +0200 Subject: [PATCH 097/139] Terraform overwrite init (#2573) (#2654) * feat: implement overwrite_init option * chore: changelog (cherry picked from commit 285639a4f94e6000f61e8298e26589b39e5f8d8f) Co-authored-by: christophemorio <49184206+christophemorio@users.noreply.github.com> --- .../fragments/2573-terraform-overwrite-init.yml | 2 ++ plugins/modules/cloud/misc/terraform.py | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2573-terraform-overwrite-init.yml diff --git a/changelogs/fragments/2573-terraform-overwrite-init.yml b/changelogs/fragments/2573-terraform-overwrite-init.yml new file mode 100644 index 0000000000..f2dad6a7ee --- /dev/null +++ b/changelogs/fragments/2573-terraform-overwrite-init.yml @@ -0,0 +1,2 @@ +minor_changes: + - terraform - add option ``overwrite_init`` to skip init if exists (https://github.com/ansible-collections/community.general/pull/2573). diff --git a/plugins/modules/cloud/misc/terraform.py b/plugins/modules/cloud/misc/terraform.py index 0a4e41b5f0..9bf36c8c81 100644 --- a/plugins/modules/cloud/misc/terraform.py +++ b/plugins/modules/cloud/misc/terraform.py @@ -107,6 +107,12 @@ options: you intend to provision an entirely new Terraform deployment. default: false type: bool + overwrite_init: + description: + - Run init even if C(.terraform/terraform.tfstate) already exists in I(project_path). + default: true + type: bool + version_added: '3.2.0' backend_config: description: - A group of key-values to provide at init stage to the -backend-config parameter. @@ -348,6 +354,7 @@ def main(): backend_config=dict(type='dict', default=None), backend_config_files=dict(type='list', elements='path', default=None), init_reconfigure=dict(required=False, type='bool', default=False), + overwrite_init=dict(type='bool', default=True), ), required_if=[('state', 'planned', ['plan_file'])], supports_check_mode=True, @@ -367,6 +374,7 @@ def main(): backend_config = module.params.get('backend_config') backend_config_files = module.params.get('backend_config_files') init_reconfigure = module.params.get('init_reconfigure') + overwrite_init = module.params.get('overwrite_init') if bin_path is not None: command = [bin_path] @@ -383,7 +391,8 @@ def main(): APPLY_ARGS = ('apply', '-no-color', '-input=false', '-auto-approve') if force_init: - init_plugins(command[0], project_path, backend_config, backend_config_files, init_reconfigure, plugin_paths) + 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, plugin_paths) workspace_ctx = get_workspace_context(command[0], project_path) if workspace_ctx["current"] != workspace: From 0a676406b350909d3f3139f8450c7fd99cc246f1 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 27 May 2021 20:15:49 +0200 Subject: [PATCH 098/139] minor refactors on plugins/modules/cloud/misc (#2557) (#2660) * minor refactors on plugins/modules/cloud/misc * added changelog fragment * removed unreachable statement * Update plugins/modules/cloud/misc/terraform.py Co-authored-by: Felix Fontein * Update plugins/modules/cloud/misc/rhevm.py Co-authored-by: Felix Fontein * adjusted per PR comment Co-authored-by: Felix Fontein (cherry picked from commit 3afcf7e75db37d4c6e24bb4ef25999d95013d4e3) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../fragments/2557-cloud-misc-refactor.yml | 7 +++++ .../cloud/misc/cloud_init_data_facts.py | 4 +-- .../modules/cloud/misc/proxmox_group_info.py | 2 +- plugins/modules/cloud/misc/proxmox_kvm.py | 31 +++++++++---------- plugins/modules/cloud/misc/rhevm.py | 4 +-- plugins/modules/cloud/misc/serverless.py | 11 +++---- plugins/modules/cloud/misc/terraform.py | 2 +- 7 files changed, 32 insertions(+), 29 deletions(-) create mode 100644 changelogs/fragments/2557-cloud-misc-refactor.yml diff --git a/changelogs/fragments/2557-cloud-misc-refactor.yml b/changelogs/fragments/2557-cloud-misc-refactor.yml new file mode 100644 index 0000000000..82e56dc942 --- /dev/null +++ b/changelogs/fragments/2557-cloud-misc-refactor.yml @@ -0,0 +1,7 @@ +minor_changes: + - cloud_init_data_facts - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). + - proxmox_group_info - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). + - proxmox_kvm - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). + - rhevm - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). + - serverless - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). + - terraform - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). diff --git a/plugins/modules/cloud/misc/cloud_init_data_facts.py b/plugins/modules/cloud/misc/cloud_init_data_facts.py index 2efb90cfeb..5774fa6f39 100644 --- a/plugins/modules/cloud/misc/cloud_init_data_facts.py +++ b/plugins/modules/cloud/misc/cloud_init_data_facts.py @@ -88,7 +88,7 @@ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils._text import to_text -CLOUD_INIT_PATH = "/var/lib/cloud/data/" +CLOUD_INIT_PATH = "/var/lib/cloud/data" def gather_cloud_init_data_facts(module): @@ -100,7 +100,7 @@ def gather_cloud_init_data_facts(module): filter = module.params.get('filter') if filter is None or filter == i: res['cloud_init_data_facts'][i] = dict() - json_file = CLOUD_INIT_PATH + i + '.json' + json_file = os.path.join(CLOUD_INIT_PATH, i + '.json') if os.path.exists(json_file): f = open(json_file, 'rb') diff --git a/plugins/modules/cloud/misc/proxmox_group_info.py b/plugins/modules/cloud/misc/proxmox_group_info.py index bf88659656..3d60e7e214 100644 --- a/plugins/modules/cloud/misc/proxmox_group_info.py +++ b/plugins/modules/cloud/misc/proxmox_group_info.py @@ -95,7 +95,7 @@ class ProxmoxGroup: self.group = dict() # Data representation is not the same depending on API calls for k, v in group.items(): - if k == 'users' and type(v) == str: + if k == 'users' and isinstance(v, str): self.group['users'] = v.split(',') elif k == 'members': self.group['users'] = group['members'] diff --git a/plugins/modules/cloud/misc/proxmox_kvm.py b/plugins/modules/cloud/misc/proxmox_kvm.py index 2dcb1ab573..0ad75a45bd 100644 --- a/plugins/modules/cloud/misc/proxmox_kvm.py +++ b/plugins/modules/cloud/misc/proxmox_kvm.py @@ -808,23 +808,23 @@ def get_vminfo(module, proxmox, node, vmid, **kwargs): # Sanitize kwargs. Remove not defined args and ensure True and False converted to int. kwargs = dict((k, v) for k, v in kwargs.items() if v is not None) - # Convert all dict in kwargs to elements. For hostpci[n], ide[n], net[n], numa[n], parallel[n], sata[n], scsi[n], serial[n], virtio[n] + # Convert all dict in kwargs to elements. + # For hostpci[n], ide[n], net[n], numa[n], parallel[n], sata[n], scsi[n], serial[n], virtio[n] for k in list(kwargs.keys()): if isinstance(kwargs[k], dict): kwargs.update(kwargs[k]) del kwargs[k] # Split information by type + re_net = re.compile(r'net[0-9]') + re_dev = re.compile(r'(virtio|ide|scsi|sata)[0-9]') for k, v in kwargs.items(): - if re.match(r'net[0-9]', k) is not None: + if re_net.match(k): interface = k k = vm[k] k = re.search('=(.*?),', k).group(1) mac[interface] = k - if (re.match(r'virtio[0-9]', k) is not None or - re.match(r'ide[0-9]', k) is not None or - re.match(r'scsi[0-9]', k) is not None or - re.match(r'sata[0-9]', k) is not None): + elif re_dev.match(k): device = k k = vm[k] k = re.search('(.*?),', k).group(1) @@ -835,16 +835,13 @@ def get_vminfo(module, proxmox, node, vmid, **kwargs): results['vmid'] = int(vmid) -def settings(module, proxmox, vmid, node, name, **kwargs): +def settings(proxmox, vmid, node, **kwargs): proxmox_node = proxmox.nodes(node) # Sanitize kwargs. Remove not defined args and ensure True and False converted to int. kwargs = dict((k, v) for k, v in kwargs.items() if v is not None) - if proxmox_node.qemu(vmid).config.set(**kwargs) is None: - return True - else: - return False + return proxmox_node.qemu(vmid).config.set(**kwargs) is None def wait_for_task(module, proxmox, node, taskid): @@ -915,7 +912,8 @@ def create_vm(module, proxmox, vmid, newid, node, name, memory, cpu, cores, sock if 'pool' in kwargs: del kwargs['pool'] - # Convert all dict in kwargs to elements. For hostpci[n], ide[n], net[n], numa[n], parallel[n], sata[n], scsi[n], serial[n], virtio[n], ipconfig[n] + # Convert all dict in kwargs to elements. + # For hostpci[n], ide[n], net[n], numa[n], parallel[n], sata[n], scsi[n], serial[n], virtio[n], ipconfig[n] for k in list(kwargs.keys()): if isinstance(kwargs[k], dict): kwargs.update(kwargs[k]) @@ -938,8 +936,9 @@ def create_vm(module, proxmox, vmid, newid, node, name, memory, cpu, cores, sock # VM 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.match(r'^[a-z0-9_][a-z0-9_\-\+\.]*$', tag): + if not re_tag.match(tag): module.fail_json(msg='%s is not a valid tag' % tag) kwargs['tags'] = ",".join(kwargs['tags']) @@ -971,7 +970,7 @@ def create_vm(module, proxmox, vmid, newid, node, name, memory, cpu, cores, sock if not wait_for_task(module, proxmox, node, taskid): module.fail_json(msg='Reached timeout while waiting for creating VM. Last line in task before timeout: %s' % - proxmox_node.tasks(taskid).log.get()[:1]) + proxmox_node.tasks(taskid).log.get()[:1]) return False return True @@ -1209,14 +1208,14 @@ def main(): if delete is not None: try: - settings(module, proxmox, vmid, node, name, delete=delete) + settings(proxmox, vmid, node, delete=delete) module.exit_json(changed=True, vmid=vmid, msg="Settings has deleted on VM {0} with vmid {1}".format(name, vmid)) except Exception as e: module.fail_json(vmid=vmid, msg='Unable to delete settings on VM {0} with vmid {1}: '.format(name, vmid) + str(e)) if revert is not None: try: - settings(module, proxmox, vmid, node, name, revert=revert) + settings(proxmox, vmid, node, revert=revert) module.exit_json(changed=True, vmid=vmid, msg="Settings has reverted on VM {0} with vmid {1}".format(name, vmid)) except Exception as e: module.fail_json(vmid=vmid, msg='Unable to revert settings on VM {0} with vmid {1}: Maybe is not a pending task... '.format(name, vmid) + str(e)) diff --git a/plugins/modules/cloud/misc/rhevm.py b/plugins/modules/cloud/misc/rhevm.py index cc6c1252bf..77b40248b3 100644 --- a/plugins/modules/cloud/misc/rhevm.py +++ b/plugins/modules/cloud/misc/rhevm.py @@ -547,7 +547,7 @@ class RHEVConn(object): def set_Memory_Policy(self, name, memory_policy): VM = self.get_VM(name) - VM.memory_policy.guaranteed = int(int(memory_policy) * 1024 * 1024 * 1024) + VM.memory_policy.guaranteed = int(memory_policy) * 1024 * 1024 * 1024 try: VM.update() setMsg("The memory policy has been updated.") @@ -1260,7 +1260,7 @@ def core(module): r = RHEV(module) - state = module.params.get('state', 'present') + state = module.params.get('state') if state == 'ping': r.test() diff --git a/plugins/modules/cloud/misc/serverless.py b/plugins/modules/cloud/misc/serverless.py index 912d4226a8..1b2f8b62a6 100644 --- a/plugins/modules/cloud/misc/serverless.py +++ b/plugins/modules/cloud/misc/serverless.py @@ -139,16 +139,14 @@ from ansible.module_utils.basic import AnsibleModule def read_serverless_config(module): path = module.params.get('service_path') + full_path = os.path.join(path, 'serverless.yml') try: - with open(os.path.join(path, 'serverless.yml')) as sls_config: + with open(full_path) as sls_config: config = yaml.safe_load(sls_config.read()) return config except IOError as e: - module.fail_json(msg="Could not open serverless.yml in {0}. err: {1}".format(path, str(e))) - - module.fail_json(msg="Failed to open serverless config at {0}".format( - os.path.join(path, 'serverless.yml'))) + module.fail_json(msg="Could not open serverless.yml in {0}. err: {1}".format(full_path, str(e))) def get_service_name(module, stage): @@ -182,7 +180,6 @@ def main(): service_path = module.params.get('service_path') state = module.params.get('state') - functions = module.params.get('functions') region = module.params.get('region') stage = module.params.get('stage') deploy = module.params.get('deploy', True) @@ -193,7 +190,7 @@ def main(): if serverless_bin_path is not None: command = serverless_bin_path + " " else: - command = "serverless " + command = module.get_bin_path("serverless") + " " if state == 'present': command += 'deploy ' diff --git a/plugins/modules/cloud/misc/terraform.py b/plugins/modules/cloud/misc/terraform.py index 9bf36c8c81..8a34f9699b 100644 --- a/plugins/modules/cloud/misc/terraform.py +++ b/plugins/modules/cloud/misc/terraform.py @@ -233,7 +233,7 @@ def get_version(bin_path): def preflight_validation(bin_path, project_path, version, variables_args=None, plan_file=None): - if project_path in [None, ''] or '/' not in project_path: + if project_path is None or '/' not in project_path: module.fail_json(msg="Path for Terraform project can not be None or ''.") if not os.path.exists(bin_path): module.fail_json(msg="Path for Terraform binary '{0}' doesn't exist on this host - check the path and try again please.".format(bin_path)) From f7403a0b34f2a842745fe97f865c0f25d5e18a95 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 27 May 2021 20:16:50 +0200 Subject: [PATCH 099/139] random_string: a new lookup plugin (#2572) (#2659) New lookup plugin to generate random string based upon constraints. Signed-off-by: Abhijeet Kasurde (cherry picked from commit 43c12b82fa9cf63d2258565f1d62d5dc0a0075ff) Co-authored-by: Abhijeet Kasurde --- plugins/lookup/random_string.py | 220 ++++++++++++++++++ .../targets/lookup_random_string/aliases | 3 + .../targets/lookup_random_string/runme.sh | 6 + .../targets/lookup_random_string/test.yml | 48 ++++ 4 files changed, 277 insertions(+) create mode 100644 plugins/lookup/random_string.py create mode 100644 tests/integration/targets/lookup_random_string/aliases create mode 100755 tests/integration/targets/lookup_random_string/runme.sh create mode 100644 tests/integration/targets/lookup_random_string/test.yml diff --git a/plugins/lookup/random_string.py b/plugins/lookup/random_string.py new file mode 100644 index 0000000000..6a05cfd041 --- /dev/null +++ b/plugins/lookup/random_string.py @@ -0,0 +1,220 @@ +# -*- coding: utf-8 -*- +# Copyright: (c) 2021, Abhijeet Kasurde +# Copyright: (c) 2018, Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = r""" + name: random_string + author: + - Abhijeet Kasurde (@Akasurde) + short_description: Generates random string + version_added: '3.2.0' + description: + - Generates random string based upon the given constraints. + options: + length: + description: The length of the string. + default: 8 + type: int + upper: + description: + - Include uppercase letters in the string. + default: true + type: bool + lower: + description: + - Include lowercase letters in the string. + default: true + type: bool + numbers: + description: + - Include numbers in the string. + default: true + type: bool + special: + description: + - Include special characters in the string. + - Special characters are taken from Python standard library C(string). + See L(the documentation of string.punctuation,https://docs.python.org/3/library/string.html#string.punctuation) + for which characters will be used. + - The choice of special characters can be changed to setting I(override_special). + default: true + type: bool + min_numeric: + description: + - Minimum number of numeric characters in the string. + - If set, overrides I(numbers=false). + default: 0 + type: int + min_upper: + description: + - Minimum number of uppercase alphabets in the string. + - If set, overrides I(upper=false). + default: 0 + type: int + min_lower: + description: + - Minimum number of lowercase alphabets in the string. + - If set, overrides I(lower=false). + default: 0 + type: int + min_special: + description: + - Minimum number of special character in the string. + default: 0 + type: int + override_special: + description: + - Overide a list of special characters to use in the string. + - If set I(min_special) should be set to a non-default value. + type: str + override_all: + description: + - Override all values of I(numbers), I(upper), I(lower), and I(special) with + the given list of characters. + type: str + base64: + description: + - Returns base64 encoded string. + type: bool + default: false +""" + +EXAMPLES = r""" +- name: Generate random string + ansible.builtin.debug: + var: lookup('community.general.random_string') + # Example result: ['DeadBeeF'] + +- name: Generate random string with length 12 + ansible.builtin.debug: + var: lookup('community.general.random_string', length=12) + # Example result: ['Uan0hUiX5kVG'] + +- name: Generate base64 encoded random string + ansible.builtin.debug: + var: lookup('community.general.random_string', base64=True) + # Example result: ['NHZ6eWN5Qk0='] + +- name: Generate a random string with 1 lower, 1 upper, 1 number and 1 special char (atleast) + ansible.builtin.debug: + var: lookup('community.general.random_string', min_lower=1, min_upper=1, min_special=1, min_numeric=1) + # Example result: ['&Qw2|E[-'] + +- name: Generate a random string with all lower case characters + debug: + var: query('community.general.random_string', upper=false, numbers=false, special=false) + # Example result: ['exolxzyz'] + +- name: Generate random hexadecimal string + debug: + var: query('community.general.random_string', upper=false, lower=false, override_special=hex_chars, numbers=false) + vars: + hex_chars: '0123456789ABCDEF' + # Example result: ['D2A40737'] + +- name: Generate random hexadecimal string with override_all + debug: + var: query('community.general.random_string', override_all=hex_chars) + vars: + hex_chars: '0123456789ABCDEF' + # Example result: ['D2A40737'] +""" + +RETURN = r""" + _raw: + description: A one-element list containing a random string + type: list + elements: str +""" + +import base64 +import random +import string + +from ansible.errors import AnsibleLookupError +from ansible.plugins.lookup import LookupBase +from ansible.module_utils._text import to_bytes, to_text + + +class LookupModule(LookupBase): + @staticmethod + def get_random(random_generator, chars, length): + if not chars: + raise AnsibleLookupError( + "Available characters cannot be None, please change constraints" + ) + return "".join(random_generator.choice(chars) for dummy in range(length)) + + @staticmethod + def b64encode(string_value, encoding="utf-8"): + return to_text( + base64.b64encode( + to_bytes(string_value, encoding=encoding, errors="surrogate_or_strict") + ) + ) + + def run(self, terms, variables=None, **kwargs): + number_chars = string.digits + lower_chars = string.ascii_lowercase + upper_chars = string.ascii_uppercase + special_chars = string.punctuation + random_generator = random.SystemRandom() + + self.set_options(var_options=variables, direct=kwargs) + + length = self.get_option("length") + base64_flag = self.get_option("base64") + override_all = self.get_option("override_all") + values = "" + available_chars_set = "" + + if override_all: + # Override all the values + available_chars_set = override_all + else: + upper = self.get_option("upper") + lower = self.get_option("lower") + numbers = self.get_option("numbers") + special = self.get_option("special") + override_special = self.get_option("override_special") + + if override_special: + special_chars = override_special + + if upper: + available_chars_set += upper_chars + if lower: + available_chars_set += lower_chars + if numbers: + available_chars_set += number_chars + if special: + available_chars_set += special_chars + + mapping = { + "min_numeric": number_chars, + "min_lower": lower_chars, + "min_upper": upper_chars, + "min_special": special_chars, + } + + for m in mapping: + if self.get_option(m): + values += self.get_random(random_generator, mapping[m], self.get_option(m)) + + remaining_pass_len = length - len(values) + values += self.get_random(random_generator, available_chars_set, remaining_pass_len) + + # Get pseudo randomization + shuffled_values = list(values) + # Randomize the order + random.shuffle(shuffled_values) + + if base64_flag: + return [self.b64encode("".join(shuffled_values))] + + return ["".join(shuffled_values)] diff --git a/tests/integration/targets/lookup_random_string/aliases b/tests/integration/targets/lookup_random_string/aliases new file mode 100644 index 0000000000..bc987654d9 --- /dev/null +++ b/tests/integration/targets/lookup_random_string/aliases @@ -0,0 +1,3 @@ +shippable/posix/group2 +skip/aix +skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller diff --git a/tests/integration/targets/lookup_random_string/runme.sh b/tests/integration/targets/lookup_random_string/runme.sh new file mode 100755 index 0000000000..8ed6373823 --- /dev/null +++ b/tests/integration/targets/lookup_random_string/runme.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +set -eux + +ANSIBLE_ROLES_PATH=../ \ + ansible-playbook test.yml -v "$@" diff --git a/tests/integration/targets/lookup_random_string/test.yml b/tests/integration/targets/lookup_random_string/test.yml new file mode 100644 index 0000000000..52a572379b --- /dev/null +++ b/tests/integration/targets/lookup_random_string/test.yml @@ -0,0 +1,48 @@ +- hosts: localhost + gather_facts: no + tasks: + - name: Call plugin + set_fact: + result1: "{{ query('community.general.random_string') }}" + result2: "{{ query('community.general.random_string', length=0) }}" + result3: "{{ query('community.general.random_string', length=10) }}" + result4: "{{ query('community.general.random_string', length=-1) }}" + result5: "{{ query('community.general.random_string', override_special='_', min_special=1) }}" + result6: "{{ query('community.general.random_string', upper=false, special=false) }}" # lower case only + result7: "{{ query('community.general.random_string', lower=false) }}" # upper case only + result8: "{{ query('community.general.random_string', lower=false, upper=false, special=false) }}" # number only + result9: "{{ query('community.general.random_string', lower=false, upper=false, special=false, min_numeric=1, length=1) }}" # single digit only + result10: "{{ query('community.general.random_string', numbers=false, upper=false, special=false, min_lower=1, length=1) }}" # single lowercase character only + result11: "{{ query('community.general.random_string', base64=true, length=8) }}" + result12: "{{ query('community.general.random_string', upper=false, numbers=false, special=false) }}" # all lower case + result13: "{{ query('community.general.random_string', override_all='0', length=2) }}" + + - name: Raise error when impossible constraints are provided + set_fact: + impossible: "{{ query('community.general.random_string', upper=false, lower=false, special=false, numbers=false) }}" + ignore_errors: yes + register: impossible_result + + - name: Check results + assert: + that: + - result1[0] | length == 8 + - result2[0] | length == 0 + - result3[0] | length == 10 + - result4[0] | length == 0 + - result5[0] | length == 8 + - "'_' in result5[0]" + - result6[0] is lower + - result7[0] is upper + - result8[0] | regex_replace('^(\d+)$', '') == '' + - result9[0] | regex_replace('^(\d+)$', '') == '' + - result9[0] | length == 1 + - result10[0] | length == 1 + - result10[0] is lower + # if input string is not multiple of 3, base64 encoded string will be padded with = + - result11[0].endswith('=') + - result12[0] is lower + - result13[0] | length == 2 + - result13[0] == '00' + - impossible_result is failed + - "'Available characters cannot' in impossible_result.msg" From 3987b8a29131032af9aa787c04b76ce8d9bda989 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 27 May 2021 20:18:07 +0200 Subject: [PATCH 100/139] xml: Add an example for absent (#2644) (#2656) Element node can be deleted based upon the attribute value. Signed-off-by: Abhijeet Kasurde (cherry picked from commit 795125fec4d4b9875ea1c29a6ccd81c30432b4c7) Co-authored-by: Abhijeet Kasurde --- plugins/modules/files/xml.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/plugins/modules/files/xml.py b/plugins/modules/files/xml.py index f93c8e4dc4..e7c6ca3f1e 100644 --- a/plugins/modules/files/xml.py +++ b/plugins/modules/files/xml.py @@ -301,6 +301,23 @@ EXAMPLES = r''' - floor: Grog storage - construction_date: "1990" # Only strings are valid - building: Grog factory + +# Consider this XML for following example - +# +# +# +# part to remove +# +# +# part to keep +# +# + +- name: Delete element node based upon attribute + community.general.xml: + path: bar.xml + xpath: /config/element[@name='test1'] + state: absent ''' RETURN = r''' From 8f3043058ee92bd1220c434cd0e7459ccf959d19 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 27 May 2021 20:18:19 +0200 Subject: [PATCH 101/139] Fix drain example with correct wait values (#2603) (#2658) (cherry picked from commit 95794f31e34552628cd648d27672eadabe4154ec) Co-authored-by: Merouane Atig --- plugins/modules/net_tools/haproxy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/net_tools/haproxy.py b/plugins/modules/net_tools/haproxy.py index 8efb59ed2e..a3320b45c5 100644 --- a/plugins/modules/net_tools/haproxy.py +++ b/plugins/modules/net_tools/haproxy.py @@ -150,7 +150,7 @@ EXAMPLES = r''' backend: www wait: yes drain: yes - wait_interval: 1 + wait_interval: 60 wait_retries: 60 - name: Disable backend server in 'www' backend pool and drop open sessions to it From f33530dd61417bc11ba01dd3fa33fd6cc866f1cb Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 28 May 2021 06:49:01 +0200 Subject: [PATCH 102/139] Add extra docs tests (#2663) (#2665) * Add extra docs tests. * Linting. * Fix copy'n'paste error. (cherry picked from commit 14f13904d63dcffab2069b5be69ebe46a2945fef) Co-authored-by: Felix Fontein --- tests/sanity/extra/extra-docs.json | 10 ++++++++++ tests/sanity/extra/extra-docs.py | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tests/sanity/extra/extra-docs.json create mode 100755 tests/sanity/extra/extra-docs.py diff --git a/tests/sanity/extra/extra-docs.json b/tests/sanity/extra/extra-docs.json new file mode 100644 index 0000000000..a62ef37e63 --- /dev/null +++ b/tests/sanity/extra/extra-docs.json @@ -0,0 +1,10 @@ +{ + "include_symlinks": false, + "prefixes": [ + "docs/docsite/" + ], + "output": "path-line-column-message", + "requirements": [ + "antsibull" + ] +} diff --git a/tests/sanity/extra/extra-docs.py b/tests/sanity/extra/extra-docs.py new file mode 100755 index 0000000000..f4b7f59d3c --- /dev/null +++ b/tests/sanity/extra/extra-docs.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +"""Check extra collection docs with antsibull-lint.""" +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import sys +import subprocess + + +def main(): + """Main entry point.""" + if not os.path.isdir(os.path.join('docs', 'docsite')): + return + p = subprocess.run(['antsibull-lint', 'collection-docs', '.'], check=False) + if p.returncode not in (0, 3): + print('{0}:0:0: unexpected return code {1}'.format(sys.argv[0], p.returncode)) + + +if __name__ == '__main__': + main() From 0f8bb43723954ac66b3eba320494d633faf1c688 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 28 May 2021 07:29:02 +0200 Subject: [PATCH 103/139] Stop mentioning Freenode. We're on Libera.chat. (#2666) (#2669) (cherry picked from commit 14813a6287af016d2b1823ce8e29bc2cc1dd10e5) Co-authored-by: Felix Fontein --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1d31a87214..deab9071a7 100644 --- a/README.md +++ b/README.md @@ -60,10 +60,10 @@ See [here](https://docs.ansible.com/ansible/devel/dev_guide/developing_collectio We have a dedicated Working Group for Ansible development. -You can find other people interested on the following Freenode IRC channels - +You can find other people interested on the following [Libera.chat](https://libera.chat/) IRC channels - - `#ansible` - For general use questions and support. -- `#ansible-devel` - For discussions on developer topics and code related to features or bugs. -- `#ansible-community` - For discussions on community topics and community meetings. +- `#ansible-devel` - For discussions on developer topics and code related to features or bugs in ansible-core. +- `#ansible-community` - For discussions on community topics and community meetings, and for general development questions for community collections. For more information about communities, meetings and agendas see [Community Wiki](https://github.com/ansible/community/wiki/Community). From 3723e458d32b99b68e0d39ab26d9ee263c18ed8c Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 28 May 2021 13:24:44 +0200 Subject: [PATCH 104/139] composer: add composer_executable (#2650) (#2670) * composer: add composer_executable * Add changelog * Improve documentation thanks to felixfontein Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit c3cab7c68c4eb0d0f80d49356c8be52d0bb849ef) Co-authored-by: Amin Vakil --- .../2650-composer-add_composer_executable.yml | 3 +++ plugins/modules/packaging/language/composer.py | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/2650-composer-add_composer_executable.yml diff --git a/changelogs/fragments/2650-composer-add_composer_executable.yml b/changelogs/fragments/2650-composer-add_composer_executable.yml new file mode 100644 index 0000000000..b1cccc689c --- /dev/null +++ b/changelogs/fragments/2650-composer-add_composer_executable.yml @@ -0,0 +1,3 @@ +--- +minor_changes: + - composer - add ``composer_executable`` option (https://github.com/ansible-collections/community.general/issues/2649). diff --git a/plugins/modules/packaging/language/composer.py b/plugins/modules/packaging/language/composer.py index 64157cb685..86fe7bdea3 100644 --- a/plugins/modules/packaging/language/composer.py +++ b/plugins/modules/packaging/language/composer.py @@ -117,9 +117,14 @@ options: default: false type: bool aliases: [ ignore-platform-reqs ] + composer_executable: + type: path + description: + - Path to composer executable on the remote host, if composer is not in C(PATH) or a custom composer is needed. + version_added: 3.2.0 requirements: - php - - composer installed in bin path (recommended /usr/local/bin) + - composer installed in bin path (recommended /usr/local/bin) or specified in I(composer_executable) notes: - Default options that are always appended in each execution are --no-ansi, --no-interaction and --no-progress if available. - We received reports about issues on macOS if composer was installed by Homebrew. Please use the official install method to avoid issues. @@ -187,7 +192,11 @@ def composer_command(module, command, arguments="", options=None, global_command else: php_path = module.params['executable'] - composer_path = module.get_bin_path("composer", True, ["/usr/local/bin"]) + if module.params['composer_executable'] is None: + composer_path = module.get_bin_path("composer", True, ["/usr/local/bin"]) + else: + composer_path = module.params['composer_executable'] + cmd = "%s %s %s %s %s %s" % (php_path, composer_path, "global" if global_command else "", command, " ".join(options), arguments) return module.run_command(cmd) @@ -231,6 +240,7 @@ def main(): ignore_platform_reqs=dict( default=False, type="bool", aliases=["ignore-platform-reqs"], deprecated_aliases=[dict(name='ignore-platform-reqs', version='5.0.0', collection_name='community.general')]), + composer_executable=dict(type="path"), ), required_if=[('global_command', False, ['working_dir'])], supports_check_mode=True From 6b215e3a9c731285e95963ff9c7d1b51f5cd8724 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 29 May 2021 10:50:11 +0200 Subject: [PATCH 105/139] proxmox_kvm - Fixed vmid result when VM with name exists (#2648) (#2674) * Fixed vmid result when VM with name exists * Adding changelog fragment (cherry picked from commit b281d3d699433a0e0dda7d6db01d22855a2a4cd5) Co-authored-by: Ajpantuso --- changelogs/fragments/2648-proxmox_kvm-fix-vmid-return-value.yml | 2 ++ plugins/modules/cloud/misc/proxmox_kvm.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2648-proxmox_kvm-fix-vmid-return-value.yml diff --git a/changelogs/fragments/2648-proxmox_kvm-fix-vmid-return-value.yml b/changelogs/fragments/2648-proxmox_kvm-fix-vmid-return-value.yml new file mode 100644 index 0000000000..7971fc24eb --- /dev/null +++ b/changelogs/fragments/2648-proxmox_kvm-fix-vmid-return-value.yml @@ -0,0 +1,2 @@ +bugfixes: + - proxmox_kvm - fixed ``vmid`` return value when VM with ``name`` already exists (https://github.com/ansible-collections/community.general/issues/2648). diff --git a/plugins/modules/cloud/misc/proxmox_kvm.py b/plugins/modules/cloud/misc/proxmox_kvm.py index 0ad75a45bd..a664279e57 100644 --- a/plugins/modules/cloud/misc/proxmox_kvm.py +++ b/plugins/modules/cloud/misc/proxmox_kvm.py @@ -1225,7 +1225,7 @@ def main(): if get_vm(proxmox, vmid) and not (update or clone): module.exit_json(changed=False, vmid=vmid, msg="VM with vmid <%s> already exists" % vmid) elif get_vmid(proxmox, name) and not (update or clone): - module.exit_json(changed=False, vmid=vmid, msg="VM with name <%s> already exists" % name) + module.exit_json(changed=False, vmid=get_vmid(proxmox, name)[0], msg="VM with name <%s> already exists" % name) elif not (node, name): module.fail_json(msg='node, name is mandatory for creating/updating vm') elif not node_check(proxmox, node): From 7483f71d31bc64738ba1850b0d46505cad430b8e Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 29 May 2021 13:58:03 +0200 Subject: [PATCH 106/139] iptables_state: fix broken query of `async_status` result (#2671) (#2676) * use get() rather than querying the key directly * add a changelog fragment * re-enable CI tests * Update changelog fragment Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit f09c39b71e84eb15481a9c2b4fd08beabfb17cff) Co-authored-by: quidame --- .../2671-fix-broken-query-of-async_status-result.yml | 6 ++++++ plugins/action/system/iptables_state.py | 2 +- tests/integration/targets/iptables_state/aliases | 1 - 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/2671-fix-broken-query-of-async_status-result.yml diff --git a/changelogs/fragments/2671-fix-broken-query-of-async_status-result.yml b/changelogs/fragments/2671-fix-broken-query-of-async_status-result.yml new file mode 100644 index 0000000000..993caaa323 --- /dev/null +++ b/changelogs/fragments/2671-fix-broken-query-of-async_status-result.yml @@ -0,0 +1,6 @@ +--- +bugfixes: + - "iptables_state - fix a broken query of ``async_status`` result + with current ansible-core development version + (https://github.com/ansible-collections/community.general/issues/2627, + https://github.com/ansible-collections/community.general/pull/2671)." diff --git a/plugins/action/system/iptables_state.py b/plugins/action/system/iptables_state.py index 96b6dc689c..887f3f47f9 100644 --- a/plugins/action/system/iptables_state.py +++ b/plugins/action/system/iptables_state.py @@ -52,7 +52,7 @@ class ActionModule(ActionBase): module_args=module_args, task_vars=task_vars, wrap_async=False) - if async_result['finished'] == 1: + if async_result.get('finished', 0) == 1: break time.sleep(min(1, timeout)) diff --git a/tests/integration/targets/iptables_state/aliases b/tests/integration/targets/iptables_state/aliases index 12765cec47..3cac4af522 100644 --- a/tests/integration/targets/iptables_state/aliases +++ b/tests/integration/targets/iptables_state/aliases @@ -5,4 +5,3 @@ skip/freebsd # no iptables/netfilter (Linux specific) skip/osx # no iptables/netfilter (Linux specific) skip/macos # no iptables/netfilter (Linux specific) skip/aix # no iptables/netfilter (Linux specific) -disabled # FIXME From 6590f5e0827bae182bee77e823e41a4c5236d9b9 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 29 May 2021 17:08:56 +0200 Subject: [PATCH 107/139] Fixed sanity checks for cloud/online/ modules (#2677) (#2679) * fixed validation-modules for plugins/modules/cloud/online/online_server_info.py * fixed validation-modules for plugins/modules/cloud/online/online_user_info.py * sanity fix (cherry picked from commit bef3c04d1c7dfaf87d00f3777dd844c1e09e2a99) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- plugins/modules/cloud/online/online_server_info.py | 8 +++++--- plugins/modules/cloud/online/online_user_info.py | 9 ++++----- tests/sanity/ignore-2.10.txt | 2 -- tests/sanity/ignore-2.11.txt | 2 -- tests/sanity/ignore-2.12.txt | 2 -- tests/sanity/ignore-2.9.txt | 2 -- 6 files changed, 9 insertions(+), 16 deletions(-) diff --git a/plugins/modules/cloud/online/online_server_info.py b/plugins/modules/cloud/online/online_server_info.py index f0e73aea16..f33a44d30f 100644 --- a/plugins/modules/cloud/online/online_server_info.py +++ b/plugins/modules/cloud/online/online_server_info.py @@ -32,11 +32,13 @@ EXAMPLES = r''' ''' RETURN = r''' ---- online_server_info: - description: Response from Online API + description: + - Response from Online API. + - "For more details please refer to: U(https://console.online.net/en/api/)." returned: success - type: complex + type: list + elements: dict sample: "online_server_info": [ { diff --git a/plugins/modules/cloud/online/online_user_info.py b/plugins/modules/cloud/online/online_user_info.py index 093a2c687f..4125ccb63d 100644 --- a/plugins/modules/cloud/online/online_user_info.py +++ b/plugins/modules/cloud/online/online_user_info.py @@ -7,7 +7,6 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type DOCUMENTATION = r''' ---- module: online_user_info short_description: Gather information about Online user. description: @@ -16,7 +15,6 @@ author: - "Remy Leone (@sieben)" extends_documentation_fragment: - community.general.online - ''' EXAMPLES = r''' @@ -29,11 +27,12 @@ EXAMPLES = r''' ''' RETURN = r''' ---- online_user_info: - description: Response from Online API + description: + - Response from Online API. + - "For more details please refer to: U(https://console.online.net/en/api/)." returned: success - type: complex + type: dict sample: "online_user_info": { "company": "foobar LLC", diff --git a/tests/sanity/ignore-2.10.txt b/tests/sanity/ignore-2.10.txt index 7af6144507..24caa4199d 100644 --- a/tests/sanity/ignore-2.10.txt +++ b/tests/sanity/ignore-2.10.txt @@ -6,8 +6,6 @@ plugins/module_utils/_mount.py metaclass-boilerplate plugins/modules/cloud/lxc/lxc_container.py use-argspec-type-path plugins/modules/cloud/lxc/lxc_container.py validate-modules:use-run-command-not-popen plugins/modules/cloud/misc/rhevm.py validate-modules:parameter-state-invalid-choice -plugins/modules/cloud/online/online_server_info.py validate-modules:return-syntax-error -plugins/modules/cloud/online/online_user_info.py validate-modules:return-syntax-error plugins/modules/cloud/rackspace/rax.py use-argspec-type-path # fix needed plugins/modules/cloud/rackspace/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/cloud/rackspace/rax_files_objects.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 1df87b7e33..b5f0a66859 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -5,8 +5,6 @@ plugins/module_utils/_mount.py metaclass-boilerplate plugins/modules/cloud/lxc/lxc_container.py use-argspec-type-path plugins/modules/cloud/lxc/lxc_container.py validate-modules:use-run-command-not-popen plugins/modules/cloud/misc/rhevm.py validate-modules:parameter-state-invalid-choice -plugins/modules/cloud/online/online_server_info.py validate-modules:return-syntax-error -plugins/modules/cloud/online/online_user_info.py validate-modules:return-syntax-error plugins/modules/cloud/rackspace/rax.py use-argspec-type-path # fix needed plugins/modules/cloud/rackspace/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/cloud/rackspace/rax_files_objects.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index c111c750a8..bde8427875 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -5,8 +5,6 @@ plugins/module_utils/_mount.py metaclass-boilerplate plugins/modules/cloud/lxc/lxc_container.py use-argspec-type-path plugins/modules/cloud/lxc/lxc_container.py validate-modules:use-run-command-not-popen plugins/modules/cloud/misc/rhevm.py validate-modules:parameter-state-invalid-choice -plugins/modules/cloud/online/online_server_info.py validate-modules:return-syntax-error -plugins/modules/cloud/online/online_user_info.py validate-modules:return-syntax-error plugins/modules/cloud/rackspace/rax.py use-argspec-type-path # fix needed plugins/modules/cloud/rackspace/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/cloud/rackspace/rax_files_objects.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.9.txt b/tests/sanity/ignore-2.9.txt index 68ceade157..569afe1207 100644 --- a/tests/sanity/ignore-2.9.txt +++ b/tests/sanity/ignore-2.9.txt @@ -5,8 +5,6 @@ plugins/module_utils/_mount.py future-import-boilerplate plugins/module_utils/_mount.py metaclass-boilerplate plugins/modules/cloud/lxc/lxc_container.py use-argspec-type-path plugins/modules/cloud/lxc/lxc_container.py validate-modules:use-run-command-not-popen -plugins/modules/cloud/online/online_server_info.py validate-modules:return-syntax-error -plugins/modules/cloud/online/online_user_info.py validate-modules:return-syntax-error plugins/modules/cloud/rackspace/rax.py use-argspec-type-path plugins/modules/cloud/rackspace/rax_files_objects.py use-argspec-type-path plugins/modules/cloud/rackspace/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values From e74ea7c8b8d139300c2a52a40c4c980da686750d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 31 May 2021 08:16:40 +0200 Subject: [PATCH 108/139] archive - Adding exclusion_patterns option (#2616) (#2686) * Adding exclusion_patterns option * Adding changelog fragment and Python 2.6 compatability * Minor refactoring for readability * Removing unneccessary conditional * Applying initial review suggestions * Adding missed review suggestion (cherry picked from commit b6c0cc0b610e8a23d4b8c7353475fce0f4315947) Co-authored-by: Ajpantuso --- ...2616-archive-exclusion_patterns-option.yml | 2 + plugins/modules/files/archive.py | 105 ++++++++++++++---- .../targets/archive/tasks/main.yml | 13 +++ 3 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 changelogs/fragments/2616-archive-exclusion_patterns-option.yml diff --git a/changelogs/fragments/2616-archive-exclusion_patterns-option.yml b/changelogs/fragments/2616-archive-exclusion_patterns-option.yml new file mode 100644 index 0000000000..86ef806b63 --- /dev/null +++ b/changelogs/fragments/2616-archive-exclusion_patterns-option.yml @@ -0,0 +1,2 @@ +minor_changes: + - archive - added ``exclusion_patterns`` option to exclude files or subdirectories from archives (https://github.com/ansible-collections/community.general/pull/2616). diff --git a/plugins/modules/files/archive.py b/plugins/modules/files/archive.py index 8b8088dae1..8d4afa58a5 100644 --- a/plugins/modules/files/archive.py +++ b/plugins/modules/files/archive.py @@ -41,8 +41,16 @@ options: exclude_path: description: - Remote absolute path, glob, or list of paths or globs for the file or files to exclude from I(path) list and glob expansion. + - Use I(exclusion_patterns) to instead exclude files or subdirectories below any of the paths from the I(path) list. type: list elements: path + exclusion_patterns: + description: + - Glob style patterns to exclude files or directories from the resulting archive. + - This differs from I(exclude_path) which applies only to the source paths from I(path). + type: list + elements: path + version_added: 3.2.0 force_archive: description: - Allows you to force the module to treat this as an archive even if only a single file is specified. @@ -163,6 +171,8 @@ import re import shutil import tarfile import zipfile +from fnmatch import fnmatch +from sys import version_info from traceback import format_exc from ansible.module_utils.basic import AnsibleModule, missing_required_lib @@ -186,6 +196,8 @@ else: LZMA_IMP_ERR = format_exc() HAS_LZMA = False +PY27 = version_info[0:2] >= (2, 7) + def to_b(s): return to_bytes(s, errors='surrogate_or_strict') @@ -214,6 +226,59 @@ def expand_paths(paths): return expanded_path, is_globby +def matches_exclusion_patterns(path, exclusion_patterns): + return any(fnmatch(path, p) for p in exclusion_patterns) + + +def get_filter(exclusion_patterns, format): + def zip_filter(path): + return matches_exclusion_patterns(path, exclusion_patterns) + + def tar_filter(tarinfo): + return None if matches_exclusion_patterns(tarinfo.name, exclusion_patterns) else tarinfo + + return zip_filter if format == 'zip' or not PY27 else tar_filter + + +def get_archive_contains(format): + def archive_contains(archive, name): + try: + if format == 'zip': + archive.getinfo(name) + else: + archive.getmember(name) + except KeyError: + return False + + return True + + return archive_contains + + +def get_add_to_archive(format, filter): + def add_to_zip_archive(archive_file, path, archive_name): + try: + if not filter(path): + archive_file.write(path, archive_name) + except Exception as e: + return e + + return None + + def add_to_tar_archive(archive_file, path, archive_name): + try: + if PY27: + archive_file.add(path, archive_name, recursive=False, filter=filter) + else: + archive_file.add(path, archive_name, recursive=False, exclude=filter) + except Exception as e: + return e + + return None + + return add_to_zip_archive if format == 'zip' else add_to_tar_archive + + def main(): module = AnsibleModule( argument_spec=dict( @@ -221,6 +286,7 @@ def main(): format=dict(type='str', default='gz', choices=['bz2', 'gz', 'tar', 'xz', 'zip']), dest=dict(type='path'), exclude_path=dict(type='list', elements='path'), + exclusion_patterns=dict(type='list', elements='path'), force_archive=dict(type='bool', default=False), remove=dict(type='bool', default=False), ), @@ -242,6 +308,8 @@ def main(): changed = False state = 'absent' + exclusion_patterns = params['exclusion_patterns'] or [] + # Simple or archive file compression (inapplicable with 'zip' since it's always an archive) b_successes = [] @@ -262,6 +330,10 @@ def main(): # Only attempt to expand the exclude paths if it exists b_expanded_exclude_paths = expand_paths(exclude_paths)[0] if exclude_paths else [] + filter = get_filter(exclusion_patterns, fmt) + archive_contains = get_archive_contains(fmt) + add_to_archive = get_add_to_archive(fmt, filter) + # Only try to determine if we are working with an archive or not if we haven't set archive to true if not force_archive: # If we actually matched multiple files or TRIED to, then @@ -384,38 +456,31 @@ def main(): n_fullpath = to_na(b_fullpath) n_arcname = to_native(b_match_root.sub(b'', b_fullpath), errors='surrogate_or_strict') - try: - if fmt == 'zip': - arcfile.write(n_fullpath, n_arcname) - else: - arcfile.add(n_fullpath, n_arcname, recursive=False) - - except Exception as e: - errors.append('%s: %s' % (n_fullpath, to_native(e))) + err = add_to_archive(arcfile, n_fullpath, n_arcname) + if err: + errors.append('%s: %s' % (n_fullpath, to_native(err))) for b_filename in b_filenames: b_fullpath = b_dirpath + b_filename n_fullpath = to_na(b_fullpath) n_arcname = to_n(b_match_root.sub(b'', b_fullpath)) - try: - if fmt == 'zip': - arcfile.write(n_fullpath, n_arcname) - else: - arcfile.add(n_fullpath, n_arcname, recursive=False) + err = add_to_archive(arcfile, n_fullpath, n_arcname) + if err: + errors.append('Adding %s: %s' % (to_native(b_path), to_native(err))) + if archive_contains(arcfile, n_arcname): b_successes.append(b_fullpath) - except Exception as e: - errors.append('Adding %s: %s' % (to_native(b_path), to_native(e))) else: path = to_na(b_path) arcname = to_n(b_match_root.sub(b'', b_path)) - if fmt == 'zip': - arcfile.write(path, arcname) - else: - arcfile.add(path, arcname, recursive=False) - b_successes.append(b_path) + err = add_to_archive(arcfile, path, arcname) + if err: + errors.append('Adding %s: %s' % (to_native(b_path), to_native(err))) + + if archive_contains(arcfile, arcname): + b_successes.append(b_path) except Exception as e: expanded_fmt = 'zip' if fmt == 'zip' else ('tar.' + fmt) diff --git a/tests/integration/targets/archive/tasks/main.yml b/tests/integration/targets/archive/tasks/main.yml index 2267268715..761f9eb7b8 100644 --- a/tests/integration/targets/archive/tasks/main.yml +++ b/tests/integration/targets/archive/tasks/main.yml @@ -363,6 +363,19 @@ - name: remove nonascii test file: path="{{ output_dir }}/test-archive-nonascii-くらとみ.zip" state=absent +- name: Test exclusion_patterns option + archive: + path: "{{ output_dir }}/*.txt" + dest: "{{ output_dir }}/test-archive-exclustion-patterns.tgz" + exclusion_patterns: b?r.* + register: exclusion_patterns_result + +- name: Assert that exclusion_patterns only archives included files + assert: + that: + - exclusion_patterns_result is changed + - "'bar.txt' not in exclusion_patterns_result.archived" + - name: Remove backports.lzma if previously installed (pip) pip: name=backports.lzma state=absent when: backports_lzma_pip is changed From b1a4a0ff217afb851049409db90c007360463aef Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 1 Jun 2021 20:38:12 +0200 Subject: [PATCH 109/139] Add filter docs (#2680) (#2687) * Began with filter docs. * Add more filters. * Add time unit filters. * Add TOC and filters to create identifiers. * Add more filters. * Add documentation from ansible/ansible for json_query and random_mac. * Update docs/docsite/rst/filter_guide.rst Co-authored-by: Abhijeet Kasurde Co-authored-by: Abhijeet Kasurde (cherry picked from commit 3516acf8d402de721887cd10e16293d747fbb29e) Co-authored-by: Felix Fontein --- docs/docsite/extra-docs.yml | 5 + docs/docsite/rst/filter_guide.rst | 753 ++++++++++++++++++++++++++++++ 2 files changed, 758 insertions(+) create mode 100644 docs/docsite/extra-docs.yml create mode 100644 docs/docsite/rst/filter_guide.rst diff --git a/docs/docsite/extra-docs.yml b/docs/docsite/extra-docs.yml new file mode 100644 index 0000000000..22ae7b58f5 --- /dev/null +++ b/docs/docsite/extra-docs.yml @@ -0,0 +1,5 @@ +--- +sections: + - title: Guides + toctree: + - filter_guide diff --git a/docs/docsite/rst/filter_guide.rst b/docs/docsite/rst/filter_guide.rst new file mode 100644 index 0000000000..201b275aae --- /dev/null +++ b/docs/docsite/rst/filter_guide.rst @@ -0,0 +1,753 @@ +.. _ansible_collections.community.general.docsite.filter_guide: + +community.general Filter Guide +============================== + +The :ref:`community.general collection ` offers several useful filter plugins. + +.. contents:: Topics + +Paths +----- + +The ``path_join`` filter has been added in ansible-base 2.10. If you want to use this filter, but also need to support Ansible 2.9, you can use ``community.general``'s ``path_join`` shim, ``community.general.path_join``. This filter redirects to ``path_join`` for ansible-base 2.10 and ansible-core 2.11 or newer, and re-implements the filter for Ansible 2.9. + +.. code-block:: yaml+jinja + + # ansible-base 2.10 or newer: + path: {{ ('/etc', path, 'subdir', file) | path_join }} + + # Also works with Ansible 2.9: + path: {{ ('/etc', path, 'subdir', file) | community.general.path_join }} + +.. versionadded:: 3.0.0 + +Abstract transformations +------------------------ + +Dictionaries +^^^^^^^^^^^^ + +You can use the ``dict_kv`` filter to create a single-entry dictionary with ``value | community.general.dict_kv(key)``: + +.. code-block:: yaml+jinja + + - name: Create a single-entry dictionary + debug: + msg: "{{ myvar | community.general.dict_kv('thatsmyvar') }}" + vars: + myvar: myvalue + + - name: Create a list of dictionaries where the 'server' field is taken from a list + debug: + msg: >- + {{ myservers | map('community.general.dict_kv', 'server') + | map('combine', common_config) }} + vars: + common_config: + type: host + database: all + myservers: + - server1 + - server2 + +This produces: + +.. code-block:: ansible-output + + TASK [Create a single-entry dictionary] ************************************************** + ok: [localhost] => { + "msg": { + "thatsmyvar": "myvalue" + } + } + + TASK [Create a list of dictionaries where the 'server' field is taken from a list] ******* + ok: [localhost] => { + "msg": [ + { + "database": "all", + "server": "server1", + "type": "host" + }, + { + "database": "all", + "server": "server2", + "type": "host" + } + ] + } + +.. versionadded:: 2.0.0 + +If you need to convert a list of key-value pairs to a dictionary, you can use the ``dict`` function. Unfortunately, this function cannot be used with ``map``. For this, the ``community.general.dict`` filter can be used: + +.. code-block:: yaml+jinja + + - name: Create a dictionary with the dict function + debug: + msg: "{{ dict([[1, 2], ['a', 'b']]) }}" + + - name: Create a dictionary with the community.general.dict filter + debug: + msg: "{{ [[1, 2], ['a', 'b']] | community.general.dict }}" + + - name: Create a list of dictionaries with map and the community.general.dict filter + debug: + msg: >- + {{ values | map('zip', ['k1', 'k2', 'k3']) + | map('map', 'reverse') + | map('community.general.dict') }} + vars: + values: + - - foo + - 23 + - a + - - bar + - 42 + - b + +This produces: + +.. code-block:: ansible-output + + TASK [Create a dictionary with the dict function] **************************************** + ok: [localhost] => { + "msg": { + "1": 2, + "a": "b" + } + } + + TASK [Create a dictionary with the community.general.dict filter] ************************ + ok: [localhost] => { + "msg": { + "1": 2, + "a": "b" + } + } + + TASK [Create a list of dictionaries with map and the community.general.dict filter] ****** + ok: [localhost] => { + "msg": [ + { + "k1": "foo", + "k2": 23, + "k3": "a" + }, + { + "k1": "bar", + "k2": 42, + "k3": "b" + } + ] + } + +.. versionadded:: 3.0.0 + +Grouping +^^^^^^^^ + +If you have a list of dictionaries, the Jinja2 ``groupby`` filter allows to group the list by an attribute. This results in a list of ``(grouper, list)`` namedtuples, where ``list`` contains all dictionaries where the selected attribute equals ``grouper``. If you know that for every ``grouper``, there will be a most one entry in that list, you can use the ``community.general.groupby_as_dict`` filter to convert the original list into a dictionary which maps ``grouper`` to the corresponding dictionary. + +One example is ``ansible_facts.mounts``, which is a list of dictionaries where each has one ``device`` element to indicate the device which is mounted. Therefore, ``ansible_facts.mounts | community.general.groupby_as_dict('device')`` is a dictionary mapping a device to the mount information: + +.. code-block:: yaml+jinja + + - name: Output mount facts grouped by device name + debug: + var: ansible_facts.mounts | community.general.groupby_as_dict('device') + + - name: Output mount facts grouped by mount point + debug: + var: ansible_facts.mounts | community.general.groupby_as_dict('mount') + +This produces: + +.. code-block:: ansible-output + + TASK [Output mount facts grouped by device name] ****************************************** + ok: [localhost] => { + "ansible_facts.mounts | community.general.groupby_as_dict('device')": { + "/dev/sda1": { + "block_available": 2000, + "block_size": 4096, + "block_total": 2345, + "block_used": 345, + "device": "/dev/sda1", + "fstype": "ext4", + "inode_available": 500, + "inode_total": 512, + "inode_used": 12, + "mount": "/boot", + "options": "rw,relatime,data=ordered", + "size_available": 56821, + "size_total": 543210, + "uuid": "ab31cade-d9c1-484d-8482-8a4cbee5241a" + }, + "/dev/sda2": { + "block_available": 1234, + "block_size": 4096, + "block_total": 12345, + "block_used": 11111, + "device": "/dev/sda2", + "fstype": "ext4", + "inode_available": 1111, + "inode_total": 1234, + "inode_used": 123, + "mount": "/", + "options": "rw,relatime", + "size_available": 42143, + "size_total": 543210, + "uuid": "abcdef01-2345-6789-0abc-def012345678" + } + } + } + + TASK [Output mount facts grouped by mount point] ****************************************** + ok: [localhost] => { + "ansible_facts.mounts | community.general.groupby_as_dict('mount')": { + "/": { + "block_available": 1234, + "block_size": 4096, + "block_total": 12345, + "block_used": 11111, + "device": "/dev/sda2", + "fstype": "ext4", + "inode_available": 1111, + "inode_total": 1234, + "inode_used": 123, + "mount": "/", + "options": "rw,relatime", + "size_available": 42143, + "size_total": 543210, + "uuid": "bdf50b7d-4859-40af-8665-c637ee7a7808" + }, + "/boot": { + "block_available": 2000, + "block_size": 4096, + "block_total": 2345, + "block_used": 345, + "device": "/dev/sda1", + "fstype": "ext4", + "inode_available": 500, + "inode_total": 512, + "inode_used": 12, + "mount": "/boot", + "options": "rw,relatime,data=ordered", + "size_available": 56821, + "size_total": 543210, + "uuid": "ab31cade-d9c1-484d-8482-8a4cbee5241a" + } + } + } + +.. versionadded: 3.0.0 + +Merging lists of dictionaries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you have two lists of dictionaries and want to combine them into a list of merged dictionaries, where two dictionaries are merged if they coincide in one attribute, you can use the ``lists_mergeby`` filter. + +.. code-block:: yaml+jinja + + - name: Merge two lists by common attribute 'name' + debug: + var: list1 | community.general.lists_mergeby(list2, 'name') + vars: + list1: + - name: foo + extra: true + - name: bar + extra: false + - name: meh + extra: true + list2: + - name: foo + path: /foo + - name: baz + path: /bazzz + +This produces: + +.. code-block:: ansible-output + + TASK [Merge two lists by common attribute 'name'] **************************************** + ok: [localhost] => { + "list1 | community.general.lists_mergeby(list2, 'name')": [ + { + "extra": false, + "name": "bar" + }, + { + "name": "baz", + "path": "/bazzz" + }, + { + "extra": true, + "name": "foo", + "path": "/foo" + }, + { + "extra": true, + "name": "meh" + } + ] + } + +.. versionadded: 2.0.0 + +Working with times +------------------ + +The ``to_time_unit`` filter allows to convert times from a human-readable string to a unit. For example, ``'4h 30min 12second' | community.general.to_time_unit('hour')`` gives the number of hours that correspond to 4 hours, 30 minutes and 12 seconds. + +There are shorthands to directly convert to various units, like ``to_hours``, ``to_minutes``, ``to_seconds``, and so on. The following table lists all units that can be used: + +.. list-table:: Units + :widths: 25 25 25 25 + :header-rows: 1 + + * - Unit name + - Unit value in seconds + - Unit strings for filter + - Shorthand filter + * - Millisecond + - 1/1000 second + - ``ms``, ``millisecond``, ``milliseconds``, ``msec``, ``msecs``, ``msecond``, ``mseconds`` + - ``to_milliseconds`` + * - Second + - 1 second + - ``s``, ``sec``, ``secs``, ``second``, ``seconds`` + - ``to_seconds`` + * - Minute + - 60 seconds + - ``m``, ``min``, ``mins``, ``minute``, ``minutes`` + - ``to_minutes`` + * - Hour + - 60*60 seconds + - ``h``, ``hour``, ``hours`` + - ``to_hours`` + * - Day + - 24*60*60 seconds + - ``d``, ``day``, ``days`` + - ``to_days`` + * - Week + - 7*24*60*60 seconds + - ``w``, ``week``, ``weeks`` + - ``to_weeks`` + * - Month + - 30*24*60*60 seconds + - ``mo``, ``month``, ``months`` + - ``to_months`` + * - Year + - 365*24*60*60 seconds + - ``y``, ``year``, ``years`` + - ``to_years`` + +Note that months and years are using a simplified representation: a month is 30 days, and a year is 365 days. If you need different definitions of months or years, you can pass them as keyword arguments. For example, if you want a year to be 365.25 days, and a month to be 30.5 days, you can write ``'11months 4' | community.general.to_years(year=365.25, month=30.5)``. These keyword arguments can be specified to ``to_time_unit`` and to all shorthand filters. + +.. code-block:: yaml+jinja + + - name: Convert string to seconds + debug: + msg: "{{ '30h 20m 10s 123ms' | community.general.to_time_unit('seconds') }}" + + - name: Convert string to hours + debug: + msg: "{{ '30h 20m 10s 123ms' | community.general.to_hours }}" + + - name: Convert string to years (using 365.25 days == 1 year) + debug: + msg: "{{ '400d 15h' | community.general.to_years(year=365.25) }}" + +This produces: + +.. code-block:: ansible-output + + TASK [Convert string to seconds] ********************************************************** + ok: [localhost] => { + "msg": "109210.123" + } + + TASK [Convert string to hours] ************************************************************ + ok: [localhost] => { + "msg": "30.336145277778" + } + + TASK [Convert string to years (using 365.25 days == 1 year)] ****************************** + ok: [localhost] => { + "msg": "1.096851471595" + } + +.. versionadded: 0.2.0 + +Working with versions +--------------------- + +If you need to sort a list of version numbers, the Jinja ``sort`` filter is problematic. Since it sorts lexicographically, ``2.10`` will come before ``2.9``. To treat version numbers correctly, you can use the ``version_sort`` filter: + +.. code-block:: yaml+jinja + + - name: Sort list by version number + debug: + var: ansible_versions | community.general.version_sort + vars: + ansible_versions: + - '2.8.0' + - '2.11.0' + - '2.7.0' + - '2.10.0' + - '2.9.0' + +This produces: + +.. code-block:: ansible-output + + TASK [Sort list by version number] ******************************************************** + ok: [localhost] => { + "ansible_versions | community.general.version_sort": [ + "2.7.0", + "2.8.0", + "2.9.0", + "2.10.0", + "2.11.0" + ] + } + +.. versionadded: 2.2.0 + +Creating identifiers +-------------------- + +The following filters allow to create identifiers. + +Hashids +^^^^^^^ + +`Hashids `_ allow to convert sequences of integers to short unique string identifiers. This filter needs the `hashids Python library `_ installed on the controller. + +.. code-block:: yaml+jinja + + - name: "Create hashid" + debug: + msg: "{{ [1234, 5, 6] | community.general.hashids_encode }}" + + - name: "Decode hashid" + debug: + msg: "{{ 'jm2Cytn' | community.general.hashids_decode }}" + +This produces: + +.. code-block:: ansible-output + + TASK [Create hashid] ********************************************************************** + ok: [localhost] => { + "msg": "jm2Cytn" + } + + TASK [Decode hashid] ********************************************************************** + ok: [localhost] => { + "msg": [ + 1234, + 5, + 6 + ] + } + +The hashids filters accept keyword arguments to allow fine-tuning the hashids generated: + +:salt: String to use as salt when hashing. +:alphabet: String of 16 or more unique characters to produce a hash. +:min_length: Minimum length of hash produced. + +.. versionadded: 3.0.0 + +Random MACs +^^^^^^^^^^^ + +You can use the ``random_mac`` filter to complete a partial `MAC address `_ to a random 6-byte MAC address. + +.. code-block:: yaml+jinja + + - name: "Create a random MAC starting with ff:" + debug: + msg: "{{ 'FF' | community.general.random_mac }}" + + - name: "Create a random MAC starting with 00:11:22:" + debug: + msg: "{{ '00:11:22' | community.general.random_mac }}" + +This produces: + +.. code-block:: ansible-output + + TASK [Create a random MAC starting with ff:] ********************************************** + ok: [localhost] => { + "msg": "ff:69:d3:78:7f:b4" + } + + TASK [Create a random MAC starting with 00:11:22:] **************************************** + ok: [localhost] => { + "msg": "00:11:22:71:5d:3b" + } + +You can also initialize the random number generator from a seed to create random-but-idempotent MAC addresses: + +.. code-block:: yaml+jinja + + "{{ '52:54:00' | community.general.random_mac(seed=inventory_hostname) }}" + +Conversions +----------- + +Parsing CSV files +^^^^^^^^^^^^^^^^^ + +Ansible offers the :ref:`community.general.read_csv module ` to read CSV files. Sometimes you need to convert strings to CSV files instead. For this, the ``from_csv`` filter exists. + +.. code-block:: yaml+jinja + + - name: "Parse CSV from string" + debug: + msg: "{{ csv_string | community.general.from_csv }}" + vars: + csv_string: | + foo,bar,baz + 1,2,3 + you,this,then + +This produces: + +.. code-block:: ansible-output + + TASK [Parse CSV from string] ************************************************************** + ok: [localhost] => { + "msg": [ + { + "bar": "2", + "baz": "3", + "foo": "1" + }, + { + "bar": "this", + "baz": "then", + "foo": "you" + } + ] + } + +The ``from_csv`` filter has several keyword arguments to control its behavior: + +:dialect: Dialect of the CSV file. Default is ``excel``. Other possible choices are ``excel-tab`` and ``unix``. If one of ``delimiter``, ``skipinitialspace`` or ``strict`` is specified, ``dialect`` is ignored. +:fieldnames: A set of column names to use. If not provided, the first line of the CSV is assumed to contain the column names. +:delimiter: Sets the delimiter to use. Default depends on the dialect used. +:skipinitialspace: Set to ``true`` to ignore space directly after the delimiter. Default depends on the dialect used (usually ``false``). +:strict: Set to ``true`` to error out on invalid CSV input. + +.. versionadded: 3.0.0 + +Converting to JSON +^^^^^^^^^^^^^^^^^^ + +`JC `_ is a CLI tool and Python library which allows to interpret output of various CLI programs as JSON. It is also available as a filter in community.general. This filter needs the `jc Python library `_ installed on the controller. + +.. code-block:: yaml+jinja + + - name: Run 'ls' to list files in / + command: ls / + register: result + + - name: Parse the ls output + debug: + msg: "{{ result.stdout | community.general.jc('ls') }}" + +This produces: + +.. code-block:: ansible-output + + TASK [Run 'ls' to list files in /] ******************************************************** + changed: [localhost] + + TASK [Parse the ls output] **************************************************************** + ok: [localhost] => { + "msg": [ + { + "filename": "bin" + }, + { + "filename": "boot" + }, + { + "filename": "dev" + }, + { + "filename": "etc" + }, + { + "filename": "home" + }, + { + "filename": "lib" + }, + { + "filename": "proc" + }, + { + "filename": "root" + }, + { + "filename": "run" + }, + { + "filename": "tmp" + } + ] + } + +.. versionadded: 2.0.0 + +.. _ansible_collections.community.general.docsite.json_query_filter: + +Selecting JSON data: JSON queries +--------------------------------- + +To select a single element or a data subset from a complex data structure in JSON format (for example, Ansible facts), use the ``json_query`` filter. The ``json_query`` filter lets you query a complex JSON structure and iterate over it using a loop structure. + +.. note:: You must manually install the **jmespath** dependency on the Ansible controller before using this filter. This filter is built upon **jmespath**, and you can use the same syntax. For examples, see `jmespath examples `_. + +Consider this data structure: + +.. code-block:: yaml+jinja + + { + "domain_definition": { + "domain": { + "cluster": [ + { + "name": "cluster1" + }, + { + "name": "cluster2" + } + ], + "server": [ + { + "name": "server11", + "cluster": "cluster1", + "port": "8080" + }, + { + "name": "server12", + "cluster": "cluster1", + "port": "8090" + }, + { + "name": "server21", + "cluster": "cluster2", + "port": "9080" + }, + { + "name": "server22", + "cluster": "cluster2", + "port": "9090" + } + ], + "library": [ + { + "name": "lib1", + "target": "cluster1" + }, + { + "name": "lib2", + "target": "cluster2" + } + ] + } + } + } + +To extract all clusters from this structure, you can use the following query: + +.. code-block:: yaml+jinja + + - name: Display all cluster names + ansible.builtin.debug: + var: item + loop: "{{ domain_definition | community.general.json_query('domain.cluster[*].name') }}" + +To extract all server names: + +.. code-block:: yaml+jinja + + - name: Display all server names + ansible.builtin.debug: + var: item + loop: "{{ domain_definition | community.general.json_query('domain.server[*].name') }}" + +To extract ports from cluster1: + +.. code-block:: yaml+jinja + + - name: Display all ports from cluster1 + ansible.builtin.debug: + var: item + loop: "{{ domain_definition | community.general.json_query(server_name_cluster1_query) }}" + vars: + server_name_cluster1_query: "domain.server[?cluster=='cluster1'].port" + +.. note:: You can use a variable to make the query more readable. + +To print out the ports from cluster1 in a comma separated string: + +.. code-block:: yaml+jinja + + - name: Display all ports from cluster1 as a string + ansible.builtin.debug: + msg: "{{ domain_definition | community.general.json_query('domain.server[?cluster==`cluster1`].port') | join(', ') }}" + +.. note:: In the example above, quoting literals using backticks avoids escaping quotes and maintains readability. + +You can use YAML `single quote escaping `_: + +.. code-block:: yaml+jinja + + - name: Display all ports from cluster1 + ansible.builtin.debug: + var: item + loop: "{{ domain_definition | community.general.json_query('domain.server[?cluster==''cluster1''].port') }}" + +.. note:: Escaping single quotes within single quotes in YAML is done by doubling the single quote. + +To get a hash map with all ports and names of a cluster: + +.. code-block:: yaml+jinja + + - name: Display all server ports and names from cluster1 + ansible.builtin.debug: + var: item + loop: "{{ domain_definition | community.general.json_query(server_name_cluster1_query) }}" + vars: + server_name_cluster1_query: "domain.server[?cluster=='cluster2'].{name: name, port: port}" + +To extract ports from all clusters with name starting with 'server1': + +.. code-block:: yaml+jinja + + - name: Display all ports from cluster1 + ansible.builtin.debug: + msg: "{{ domain_definition | to_json | from_json | community.general.json_query(server_name_query) }}" + vars: + server_name_query: "domain.server[?starts_with(name,'server1')].port" + +To extract ports from all clusters with name containing 'server1': + +.. code-block:: yaml+jinja + + - name: Display all ports from cluster1 + ansible.builtin.debug: + msg: "{{ domain_definition | to_json | from_json | community.general.json_query(server_name_query) }}" + vars: + server_name_query: "domain.server[?contains(name,'server1')].port" + +.. note:: while using ``starts_with`` and ``contains``, you have to use `` to_json | from_json `` filter for correct parsing of data structure. From 4e1bf2d4ba6b7de849936e8dc02a05b9397f7bdd Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 1 Jun 2021 22:17:19 +0200 Subject: [PATCH 110/139] nmcli: new arguments to ignore automatic dns servers and gateways (#2635) (#2689) * nmcli: new arguments to ignore automatic dns servers and gateways Closes #1087 * Add changelog fragment * Address review comments (cherry picked from commit 1ad85849afa9a4c2d89678deecb7513edbee6164) Co-authored-by: Chih-Hsuan Yen --- .../2635-nmcli-add-ignore-auto-arguments.yml | 2 + plugins/modules/net_tools/nmcli.py | 42 ++++++++++++++++++- .../plugins/modules/net_tools/test_nmcli.py | 32 ++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2635-nmcli-add-ignore-auto-arguments.yml diff --git a/changelogs/fragments/2635-nmcli-add-ignore-auto-arguments.yml b/changelogs/fragments/2635-nmcli-add-ignore-auto-arguments.yml new file mode 100644 index 0000000000..e75ceb6a1b --- /dev/null +++ b/changelogs/fragments/2635-nmcli-add-ignore-auto-arguments.yml @@ -0,0 +1,2 @@ +minor_changes: + - nmcli - add new options to ignore automatic DNS servers and gateways (https://github.com/ansible-collections/community.general/issues/1087). diff --git a/plugins/modules/net_tools/nmcli.py b/plugins/modules/net_tools/nmcli.py index 929d88c654..399d15267a 100644 --- a/plugins/modules/net_tools/nmcli.py +++ b/plugins/modules/net_tools/nmcli.py @@ -77,6 +77,12 @@ options: - Use the format C(192.0.2.1). - This parameter is mutually_exclusive with never_default4 parameter. type: str + gw4_ignore_auto: + description: + - Ignore automatically configured IPv4 routes. + type: bool + default: false + version_added: 3.2.0 routes4: description: - The list of ipv4 routes. @@ -107,6 +113,12 @@ options: - A list of DNS search domains. elements: str type: list + dns4_ignore_auto: + description: + - Ignore automatically configured IPv4 name servers. + type: bool + default: false + version_added: 3.2.0 method4: description: - Configuration method to be used for IPv4. @@ -125,6 +137,12 @@ options: - The IPv6 gateway for this interface. - Use the format C(2001:db8::1). type: str + gw6_ignore_auto: + description: + - Ignore automatically configured IPv6 routes. + type: bool + default: false + version_added: 3.2.0 dns6: description: - A list of up to 3 dns servers. @@ -136,6 +154,12 @@ options: - A list of DNS search domains. elements: str type: list + dns6_ignore_auto: + description: + - Ignore automatically configured IPv6 name servers. + type: bool + default: false + version_added: 3.2.0 method6: description: - Configuration method to be used for IPv6 @@ -648,16 +672,20 @@ class Nmcli(object): self.type = module.params['type'] self.ip4 = module.params['ip4'] self.gw4 = module.params['gw4'] + self.gw4_ignore_auto = module.params['gw4_ignore_auto'] self.routes4 = module.params['routes4'] self.route_metric4 = module.params['route_metric4'] self.never_default4 = module.params['never_default4'] self.dns4 = module.params['dns4'] self.dns4_search = module.params['dns4_search'] + self.dns4_ignore_auto = module.params['dns4_ignore_auto'] self.method4 = module.params['method4'] self.ip6 = module.params['ip6'] self.gw6 = module.params['gw6'] + self.gw6_ignore_auto = module.params['gw6_ignore_auto'] self.dns6 = module.params['dns6'] self.dns6_search = module.params['dns6_search'] + self.dns6_ignore_auto = module.params['dns6_ignore_auto'] self.method6 = module.params['method6'] self.mtu = module.params['mtu'] self.stp = module.params['stp'] @@ -729,7 +757,9 @@ class Nmcli(object): 'ipv4.dhcp-client-id': self.dhcp_client_id, 'ipv4.dns': self.dns4, 'ipv4.dns-search': self.dns4_search, + 'ipv4.ignore-auto-dns': self.dns4_ignore_auto, 'ipv4.gateway': self.gw4, + 'ipv4.ignore-auto-routes': self.gw4_ignore_auto, 'ipv4.routes': self.routes4, 'ipv4.route-metric': self.route_metric4, 'ipv4.never-default': self.never_default4, @@ -737,7 +767,9 @@ class Nmcli(object): 'ipv6.addresses': self.ip6, 'ipv6.dns': self.dns6, 'ipv6.dns-search': self.dns6_search, + 'ipv6.ignore-auto-dns': self.dns6_ignore_auto, 'ipv6.gateway': self.gw6, + 'ipv6.ignore-auto-routes': self.gw6_ignore_auto, 'ipv6.method': self.ipv6_method, }) @@ -900,7 +932,11 @@ class Nmcli(object): if setting in ('bridge.stp', 'bridge-port.hairpin-mode', 'connection.autoconnect', - 'ipv4.never-default'): + 'ipv4.never-default', + 'ipv4.ignore-auto-dns', + 'ipv4.ignore-auto-routes', + 'ipv6.ignore-auto-dns', + 'ipv6.ignore-auto-routes'): return bool elif setting in ('ipv4.dns', 'ipv4.dns-search', @@ -1116,17 +1152,21 @@ def main(): ]), ip4=dict(type='str'), gw4=dict(type='str'), + gw4_ignore_auto=dict(type='bool', default=False), routes4=dict(type='list', elements='str'), route_metric4=dict(type='int'), never_default4=dict(type='bool', default=False), dns4=dict(type='list', elements='str'), dns4_search=dict(type='list', elements='str'), + dns4_ignore_auto=dict(type='bool', default=False), method4=dict(type='str', choices=['auto', 'link-local', 'manual', 'shared', 'disabled']), dhcp_client_id=dict(type='str'), ip6=dict(type='str'), gw6=dict(type='str'), + gw6_ignore_auto=dict(type='bool', default=False), dns6=dict(type='list', elements='str'), dns6_search=dict(type='list', elements='str'), + dns6_ignore_auto=dict(type='bool', default=False), method6=dict(type='str', choices=['ignore', 'auto', 'dhcp', 'link-local', 'manual', 'shared']), # Bond Specific vars mode=dict(type='str', default='balance-rr', diff --git a/tests/unit/plugins/modules/net_tools/test_nmcli.py b/tests/unit/plugins/modules/net_tools/test_nmcli.py index dceb5e5f3f..5b3f96937b 100644 --- a/tests/unit/plugins/modules/net_tools/test_nmcli.py +++ b/tests/unit/plugins/modules/net_tools/test_nmcli.py @@ -95,8 +95,12 @@ connection.autoconnect: yes ipv4.method: manual ipv4.addresses: 10.10.10.10/24 ipv4.gateway: 10.10.10.1 +ipv4.ignore-auto-dns: no +ipv4.ignore-auto-routes: no ipv4.never-default: no ipv6.method: auto +ipv6.ignore-auto-dns: no +ipv6.ignore-auto-routes: no """ TESTCASE_GENERIC_DNS4_SEARCH = [ @@ -120,10 +124,14 @@ connection.autoconnect: yes ipv4.method: manual ipv4.addresses: 10.10.10.10/24 ipv4.gateway: 10.10.10.1 +ipv4.ignore-auto-dns: no +ipv4.ignore-auto-routes: no ipv4.never-default: no ipv4.dns-search: search.redhat.com ipv6.dns-search: search6.redhat.com ipv6.method: auto +ipv6.ignore-auto-dns: no +ipv6.ignore-auto-routes: no """ TESTCASE_GENERIC_ZONE = [ @@ -147,8 +155,12 @@ connection.zone: external ipv4.method: manual ipv4.addresses: 10.10.10.10/24 ipv4.gateway: 10.10.10.1 +ipv4.ignore-auto-dns: no +ipv4.ignore-auto-routes: no ipv4.never-default: no ipv6.method: auto +ipv6.ignore-auto-dns: no +ipv6.ignore-auto-routes: no """ TESTCASE_BOND = [ @@ -172,8 +184,12 @@ connection.autoconnect: yes ipv4.method: manual ipv4.addresses: 10.10.10.10/24 ipv4.gateway: 10.10.10.1 +ipv4.ignore-auto-dns: no +ipv4.ignore-auto-routes: no ipv4.never-default: no ipv6.method: auto +ipv6.ignore-auto-dns: no +ipv6.ignore-auto-routes: no bond.options: mode=active-backup,primary=non_existent_primary """ @@ -199,8 +215,12 @@ connection.autoconnect: yes ipv4.method: manual ipv4.addresses: 10.10.10.10/24 ipv4.gateway: 10.10.10.1 +ipv4.ignore-auto-dns: no +ipv4.ignore-auto-routes: no ipv4.never-default: no ipv6.method: auto +ipv6.ignore-auto-dns: no +ipv6.ignore-auto-routes: no bridge.mac-address: 52:54:00:AB:CD:EF bridge.stp: yes bridge.max-age: 100 @@ -252,8 +272,12 @@ connection.autoconnect: yes ipv4.method: manual ipv4.addresses: 10.10.10.10/24 ipv4.gateway: 10.10.10.1 +ipv4.ignore-auto-dns: no +ipv4.ignore-auto-routes: no ipv4.never-default: no ipv6.method: auto +ipv6.ignore-auto-dns: no +ipv6.ignore-auto-routes: no vlan.id: 10 """ @@ -343,8 +367,12 @@ connection.autoconnect: yes 802-3-ethernet.mtu: auto ipv4.method: auto ipv4.dhcp-client-id: 00:11:22:AA:BB:CC:DD +ipv4.ignore-auto-dns: no +ipv4.ignore-auto-routes: no ipv4.never-default: no ipv6.method: auto +ipv6.ignore-auto-dns: no +ipv6.ignore-auto-routes: no """ TESTCASE_ETHERNET_STATIC = [ @@ -368,9 +396,13 @@ connection.autoconnect: yes ipv4.method: manual ipv4.addresses: 10.10.10.10/24 ipv4.gateway: 10.10.10.1 +ipv4.ignore-auto-dns: no +ipv4.ignore-auto-routes: no ipv4.never-default: no ipv4.dns: 1.1.1.1,8.8.8.8 ipv6.method: auto +ipv6.ignore-auto-dns: no +ipv6.ignore-auto-routes: no """ From 2edadb42fb1eb7f7ba864f4aac73c6a5f9469839 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 1 Jun 2021 22:23:08 +0200 Subject: [PATCH 111/139] Added SHA1 option to maven_artifact (#2662) (#2690) * Added SHA1 option * Add changelog fragment * Update plugins/modules/packaging/language/maven_artifact.py Co-authored-by: Felix Fontein * Update plugins/modules/packaging/language/maven_artifact.py Co-authored-by: Felix Fontein * Combined hash functions Co-authored-by: Felix Fontein * Update plugins/modules/packaging/language/maven_artifact.py Co-authored-by: Felix Fontein * Update plugins/modules/packaging/language/maven_artifact.py Co-authored-by: Felix Fontein * Removed unused functions (rolled into _local_checksum) * Update changelogs/fragments/2661-maven_artifact-add-sha1-option.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit ca1506fb267d2592ebc6e1fc5df87024ac98ce80) Co-authored-by: Gene Gotimer --- .../2661-maven_artifact-add-sha1-option.yml | 2 + .../packaging/language/maven_artifact.py | 72 +++++++++++-------- 2 files changed, 46 insertions(+), 28 deletions(-) create mode 100644 changelogs/fragments/2661-maven_artifact-add-sha1-option.yml diff --git a/changelogs/fragments/2661-maven_artifact-add-sha1-option.yml b/changelogs/fragments/2661-maven_artifact-add-sha1-option.yml new file mode 100644 index 0000000000..827942200b --- /dev/null +++ b/changelogs/fragments/2661-maven_artifact-add-sha1-option.yml @@ -0,0 +1,2 @@ +minor_changes: + - maven_artifact - added ``checksum_alg`` option to support SHA1 checksums in order to support FIPS systems (https://github.com/ansible-collections/community.general/pull/2662). diff --git a/plugins/modules/packaging/language/maven_artifact.py b/plugins/modules/packaging/language/maven_artifact.py index 50b808f57a..83833b0480 100644 --- a/plugins/modules/packaging/language/maven_artifact.py +++ b/plugins/modules/packaging/language/maven_artifact.py @@ -129,10 +129,10 @@ options: verify_checksum: type: str description: - - If C(never), the md5 checksum will never be downloaded and verified. - - If C(download), the md5 checksum will be downloaded and verified only after artifact download. This is the default. - - If C(change), the md5 checksum will be downloaded and verified if the destination already exist, - to verify if they are identical. This was the behaviour before 2.6. Since it downloads the md5 before (maybe) + - If C(never), the MD5/SHA1 checksum will never be downloaded and verified. + - If C(download), the MD5/SHA1 checksum will be downloaded and verified only after artifact download. This is the default. + - If C(change), the MD5/SHA1 checksum will be downloaded and verified if the destination already exist, + to verify if they are identical. This was the behaviour before 2.6. Since it downloads the checksum before (maybe) downloading the artifact, and since some repository software, when acting as a proxy/cache, return a 404 error if the artifact has not been cached yet, it may fail unexpectedly. If you still need it, you should consider using C(always) instead - if you deal with a checksum, it is better to @@ -141,6 +141,15 @@ options: required: false default: 'download' choices: ['never', 'download', 'change', 'always'] + checksum_alg: + type: str + description: + - If C(md5), checksums will use the MD5 algorithm. This is the default. + - If C(sha1), checksums will use the SHA1 algorithm. This can be used on systems configured to use + FIPS-compliant algorithms, since MD5 will be blocked on such systems. + default: 'md5' + choices: ['md5', 'sha1'] + version_added: 3.2.0 directory_mode: type: str description: @@ -507,7 +516,7 @@ class MavenDownloader: raise ValueError(failmsg + " because of " + info['msg'] + "for URL " + url_to_use) return None - def download(self, tmpdir, artifact, verify_download, filename=None): + def download(self, tmpdir, artifact, verify_download, filename=None, checksum_alg='md5'): if (not artifact.version and not artifact.version_by_spec) or artifact.version == "latest": artifact = Artifact(artifact.group_id, artifact.artifact_id, self.find_latest_version_available(artifact), None, artifact.classifier, artifact.extension) @@ -528,11 +537,11 @@ class MavenDownloader: shutil.copyfileobj(response, f) if verify_download: - invalid_md5 = self.is_invalid_md5(tempname, url) - if invalid_md5: + invalid_checksum = self.is_invalid_checksum(tempname, url, checksum_alg) + if invalid_checksum: # if verify_change was set, the previous file would be deleted os.remove(tempname) - return invalid_md5 + return invalid_checksum except Exception as e: os.remove(tempname) raise e @@ -541,40 +550,45 @@ class MavenDownloader: shutil.move(tempname, artifact.get_filename(filename)) return None - def is_invalid_md5(self, file, remote_url): + def is_invalid_checksum(self, file, remote_url, checksum_alg='md5'): if os.path.exists(file): - local_md5 = self._local_md5(file) + local_checksum = self._local_checksum(checksum_alg, file) if self.local: parsed_url = urlparse(remote_url) - remote_md5 = self._local_md5(parsed_url.path) + remote_checksum = self._local_checksum(checksum_alg, parsed_url.path) else: try: - remote_md5 = to_text(self._getContent(remote_url + '.md5', "Failed to retrieve MD5", False), errors='strict') + remote_checksum = to_text(self._getContent(remote_url + '.' + checksum_alg, "Failed to retrieve checksum", False), errors='strict') except UnicodeError as e: - return "Cannot retrieve a valid md5 from %s: %s" % (remote_url, to_native(e)) - if(not remote_md5): - return "Cannot find md5 from " + remote_url + return "Cannot retrieve a valid %s checksum from %s: %s" % (checksum_alg, remote_url, to_native(e)) + if not remote_checksum: + return "Cannot find %s checksum from %s" % (checksum_alg, remote_url) try: - # Check if remote md5 only contains md5 or md5 + filename - _remote_md5 = remote_md5.split(None)[0] - remote_md5 = _remote_md5 - # remote_md5 is empty so we continue and keep original md5 string - # This should not happen since we check for remote_md5 before + # Check if remote checksum only contains md5/sha1 or md5/sha1 + filename + _remote_checksum = remote_checksum.split(None)[0] + remote_checksum = _remote_checksum + # remote_checksum is empty so we continue and keep original checksum string + # This should not happen since we check for remote_checksum before except IndexError: pass - if local_md5.lower() == remote_md5.lower(): + if local_checksum.lower() == remote_checksum.lower(): return None else: - return "Checksum does not match: we computed " + local_md5 + " but the repository states " + remote_md5 + return "Checksum does not match: we computed " + local_checksum + " but the repository states " + remote_checksum return "Path does not exist: " + file - def _local_md5(self, file): - md5 = hashlib.md5() + def _local_checksum(self, checksum_alg, file): + if checksum_alg.lower() == 'md5': + hash = hashlib.md5() + elif checksum_alg.lower() == 'sha1': + hash = hashlib.sha1() + else: + raise ValueError("Unknown checksum_alg %s" % checksum_alg) with io.open(file, 'rb') as f: for chunk in iter(lambda: f.read(8192), b''): - md5.update(chunk) - return md5.hexdigest() + hash.update(chunk) + return hash.hexdigest() def main(): @@ -599,6 +613,7 @@ def main(): client_key=dict(type="path", required=False), keep_name=dict(required=False, default=False, type='bool'), verify_checksum=dict(required=False, default='download', choices=['never', 'download', 'change', 'always']), + checksum_alg=dict(required=False, default='md5', choices=['md5', 'sha1']), directory_mode=dict(type='str'), ), add_file_common_args=True, @@ -639,6 +654,7 @@ def main(): verify_checksum = module.params["verify_checksum"] verify_download = verify_checksum in ['download', 'always'] verify_change = verify_checksum in ['change', 'always'] + checksum_alg = module.params["checksum_alg"] downloader = MavenDownloader(module, repository_url, local, headers) @@ -683,12 +699,12 @@ def main(): b_dest = to_bytes(dest, errors='surrogate_or_strict') - if os.path.lexists(b_dest) and ((not verify_change) or not downloader.is_invalid_md5(dest, downloader.find_uri_for_artifact(artifact))): + if os.path.lexists(b_dest) and ((not verify_change) or not downloader.is_invalid_checksum(dest, downloader.find_uri_for_artifact(artifact), checksum_alg)): prev_state = "present" if prev_state == "absent": try: - download_error = downloader.download(module.tmpdir, artifact, verify_download, b_dest) + download_error = downloader.download(module.tmpdir, artifact, verify_download, b_dest, checksum_alg) if download_error is None: changed = True else: From 297b50fb96bb48a158e375febe71acb97626a2f7 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 3 Jun 2021 22:14:59 +0200 Subject: [PATCH 112/139] keycloak_realm.py: Fix the `ssl_required` parameter according to the API (#2693) (#2699) * keycloak_realm.py: Fix the `ssl_required` parameter according to the API The `ssl_required` parameter is a string and must be one of 'all', 'external' or 'none'. Passing a bool will make the server return a 500. * fixup! keycloak_realm.py: Fix the `ssl_required` parameter according to the API * Update changelogs/fragments/keycloak_realm_ssl_required.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit efbda2389d02dbefd887bac505b320c100b66b1a) Co-authored-by: Benjamin Schubert --- changelogs/fragments/keycloak_realm_ssl_required.yml | 3 +++ plugins/modules/identity/keycloak/keycloak_realm.py | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/keycloak_realm_ssl_required.yml diff --git a/changelogs/fragments/keycloak_realm_ssl_required.yml b/changelogs/fragments/keycloak_realm_ssl_required.yml new file mode 100644 index 0000000000..7476612e2f --- /dev/null +++ b/changelogs/fragments/keycloak_realm_ssl_required.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - keycloak_realm - ``ssl_required`` changed from a boolean type to accept the strings ``none``, ``external`` or ``all``. This is not a breaking change since the module always failed when a boolean was supplied (https://github.com/ansible-collections/community.general/pull/2693). diff --git a/plugins/modules/identity/keycloak/keycloak_realm.py b/plugins/modules/identity/keycloak/keycloak_realm.py index 7e80bd3d3d..cacbc11d2e 100644 --- a/plugins/modules/identity/keycloak/keycloak_realm.py +++ b/plugins/modules/identity/keycloak/keycloak_realm.py @@ -439,9 +439,10 @@ options: ssl_required: description: - The realm ssl required option. + choices: ['all', 'external', 'none'] aliases: - sslRequired - type: bool + type: str sso_session_idle_timeout: description: - The realm sso session idle timeout. @@ -657,7 +658,7 @@ def main(): reset_password_allowed=dict(type='bool', aliases=['resetPasswordAllowed']), revoke_refresh_token=dict(type='bool', aliases=['revokeRefreshToken']), smtp_server=dict(type='dict', aliases=['smtpServer']), - ssl_required=dict(type='bool', aliases=['sslRequired']), + ssl_required=dict(choices=["external", "all", "none"], aliases=['sslRequired']), sso_session_idle_timeout=dict(type='int', aliases=['ssoSessionIdleTimeout']), sso_session_idle_timeout_remember_me=dict(type='int', aliases=['ssoSessionIdleTimeoutRememberMe']), sso_session_max_lifespan=dict(type='int', aliases=['ssoSessionMaxLifespan']), From 65805e2dd60876ab186edeaeff16769f744c5a70 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 3 Jun 2021 22:17:50 +0200 Subject: [PATCH 113/139] keycloak_realm.py: Mark 'reset_password_allowed' as no_log=False (#2694) (#2698) * keycloak_realm.py: Mark 'reset_password_allowed' as no_log=False This value is not sensitive but Ansible will complain about it otherwise * fixup! keycloak_realm.py: Mark 'reset_password_allowed' as no_log=False * Apply all suggestions from code review Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit fe5717c1aa1deab9ac487a2903c725ac2ac2cb27) Co-authored-by: Benjamin Schubert --- changelogs/fragments/keycloak-realm-no-log-password-reset.yml | 2 ++ plugins/modules/identity/keycloak/keycloak_realm.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/keycloak-realm-no-log-password-reset.yml diff --git a/changelogs/fragments/keycloak-realm-no-log-password-reset.yml b/changelogs/fragments/keycloak-realm-no-log-password-reset.yml new file mode 100644 index 0000000000..104bf4179b --- /dev/null +++ b/changelogs/fragments/keycloak-realm-no-log-password-reset.yml @@ -0,0 +1,2 @@ +bugfixes: + - keycloak_realm - remove warning that ``reset_password_allowed`` needs to be marked as ``no_log`` (https://github.com/ansible-collections/community.general/pull/2694). diff --git a/plugins/modules/identity/keycloak/keycloak_realm.py b/plugins/modules/identity/keycloak/keycloak_realm.py index cacbc11d2e..95f79704ef 100644 --- a/plugins/modules/identity/keycloak/keycloak_realm.py +++ b/plugins/modules/identity/keycloak/keycloak_realm.py @@ -655,7 +655,7 @@ def main(): registration_flow=dict(type='str', aliases=['registrationFlow']), remember_me=dict(type='bool', aliases=['rememberMe']), reset_credentials_flow=dict(type='str', aliases=['resetCredentialsFlow']), - reset_password_allowed=dict(type='bool', aliases=['resetPasswordAllowed']), + reset_password_allowed=dict(type='bool', aliases=['resetPasswordAllowed'], no_log=False), revoke_refresh_token=dict(type='bool', aliases=['revokeRefreshToken']), smtp_server=dict(type='dict', aliases=['smtpServer']), ssl_required=dict(choices=["external", "all", "none"], aliases=['sslRequired']), From 3b893ec4216d500b14749e22543f69d0dd1f861f Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 4 Jun 2021 04:40:31 +0000 Subject: [PATCH 114/139] BOTMETA.yml: remove myself from zypper_repository (#2701) (#2703) (cherry picked from commit d93bc039b274d1af837fa7fe869956a3be1d878c) Co-authored-by: Matthias Vogelgesang --- .github/BOTMETA.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 994de0621f..a3fb8e1f35 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -717,8 +717,9 @@ files: labels: zypper ignore: dirtyharrycallahan robinro $modules/packaging/os/zypper_repository.py: - maintainers: $team_suse matze + maintainers: $team_suse labels: zypper + ignore: matze $modules/remote_management/cobbler/: maintainers: dagwieers $modules/remote_management/hpilo/: From 6faface39e6678bb055b4631484b57f12591b820 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 4 Jun 2021 07:36:29 +0200 Subject: [PATCH 115/139] add module pacman_key (#778) (#2704) * add module pacman_key * add symlink and fix documentation for pacman_key * documentation fix for pacman_key * improve logic around user input * Update plugins/modules/packaging/os/pacman_key.py Co-authored-by: Andrew Klychkov * Update plugins/modules/packaging/os/pacman_key.py Co-authored-by: Andrew Klychkov * Update plugins/modules/packaging/os/pacman_key.py Co-authored-by: Andrew Klychkov * Update plugins/modules/packaging/os/pacman_key.py Co-authored-by: Andrew Klychkov * Update plugins/modules/packaging/os/pacman_key.py Co-authored-by: Andrew Klychkov * Update plugins/modules/packaging/os/pacman_key.py Co-authored-by: Andrew Klychkov * Update plugins/modules/packaging/os/pacman_key.py Co-authored-by: Andrew Klychkov * Update plugins/modules/packaging/os/pacman_key.py Co-authored-by: Andrew Klychkov * Update plugins/modules/packaging/os/pacman_key.py Co-authored-by: Andrew Klychkov * Update plugins/modules/packaging/os/pacman_key.py Co-authored-by: Andrew Klychkov * Improve parameter checking required_one_of=[] is neat. Co-authored-by: Alexei Znamensky * Revert "Improve parameter checking" This reverts commit 044b0cbc854744480ad1e17753e33f0371c7d0eb. * Simplify a bunch of code. * fix typos pointed out by yan12125 * replaced manual checks with required-if invocation * added default keyring to documentation * some initial tests * updated metadata * refactored to make sanity tests pass * refactor to make sanity tests pass ... part deux * refactor: simplify run_command invocations * test: cover check-mode and some normal operation * docs: fix grammatical errors * rip out fingerprint code a full length (40 characters) key ID is equivalent to the fingerprint. * refactor tests, add a couple more * test: added testcase for method: data * Update plugins/modules/packaging/os/pacman_key.py Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> * docs: correct yaml boolean type Co-authored-by: Felix Fontein Co-authored-by: Andrew Klychkov Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> Co-authored-by: Felix Fontein (cherry picked from commit 5ddf0041ecc733ed6f1f6ab938af584683c6e862) Co-authored-by: George Rawlinson --- plugins/modules/packaging/os/pacman_key.py | 314 ++++++++++ plugins/modules/pacman_key.py | 1 + .../modules/packaging/os/test_pacman_key.py | 576 ++++++++++++++++++ 3 files changed, 891 insertions(+) create mode 100644 plugins/modules/packaging/os/pacman_key.py create mode 120000 plugins/modules/pacman_key.py create mode 100644 tests/unit/plugins/modules/packaging/os/test_pacman_key.py diff --git a/plugins/modules/packaging/os/pacman_key.py b/plugins/modules/packaging/os/pacman_key.py new file mode 100644 index 0000000000..85896c211d --- /dev/null +++ b/plugins/modules/packaging/os/pacman_key.py @@ -0,0 +1,314 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: (c) 2019, George Rawlinson +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: pacman_key +author: +- George Rawlinson (@grawlinson) +version_added: "3.2.0" +short_description: Manage pacman's list of trusted keys +description: +- Add or remove gpg keys from the pacman keyring. +notes: +- Use full-length key ID (40 characters). +- Keys will be verified when using I(data), I(file), or I(url) unless I(verify) is overridden. +- Keys will be locally signed after being imported into the keyring. +- If the key ID exists in the keyring, the key will not be added unless I(force_update) is specified. +- I(data), I(file), I(url), and I(keyserver) are mutually exclusive. +- Supports C(check_mode). +requirements: +- gpg +- pacman-key +options: + id: + description: + - The 40 character identifier of the key. + - Including this allows check mode to correctly report the changed state. + - Do not specify a subkey ID, instead specify the primary key ID. + required: true + type: str + data: + description: + - The keyfile contents to add to the keyring. + - Must be of C(PGP PUBLIC KEY BLOCK) type. + type: str + file: + description: + - The path to a keyfile on the remote server to add to the keyring. + - Remote file must be of C(PGP PUBLIC KEY BLOCK) type. + type: path + url: + description: + - The URL to retrieve keyfile from. + - Remote file must be of C(PGP PUBLIC KEY BLOCK) type. + type: str + keyserver: + description: + - The keyserver used to retrieve key from. + type: str + verify: + description: + - Whether or not to verify the keyfile's key ID against specified key ID. + type: bool + default: true + force_update: + description: + - This forces the key to be updated if it already exists in the keyring. + type: bool + default: false + keyring: + description: + - The full path to the keyring folder on the remote server. + - If not specified, module will use pacman's default (C(/etc/pacman.d/gnupg)). + - Useful if the remote system requires an alternative gnupg directory. + type: path + default: /etc/pacman.d/gnupg + state: + description: + - Ensures that the key is present (added) or absent (revoked). + default: present + choices: [ absent, present ] + type: str +''' + +EXAMPLES = ''' +- name: Import a key via local file + community.general.pacman_key: + data: "{{ lookup('file', 'keyfile.asc') }}" + state: present + +- name: Import a key via remote file + community.general.pacman_key: + file: /tmp/keyfile.asc + state: present + +- name: Import a key via url + community.general.pacman_key: + id: 01234567890ABCDE01234567890ABCDE12345678 + url: https://domain.tld/keys/keyfile.asc + state: present + +- name: Import a key via keyserver + community.general.pacman_key: + id: 01234567890ABCDE01234567890ABCDE12345678 + keyserver: keyserver.domain.tld + +- name: Import a key into an alternative keyring + community.general.pacman_key: + id: 01234567890ABCDE01234567890ABCDE12345678 + file: /tmp/keyfile.asc + keyring: /etc/pacman.d/gnupg-alternative + +- name: Remove a key from the keyring + community.general.pacman_key: + id: 01234567890ABCDE01234567890ABCDE12345678 + state: absent +''' + +RETURN = r''' # ''' + +import os.path +import tempfile +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.urls import fetch_url +from ansible.module_utils._text import to_native + + +class PacmanKey(object): + def __init__(self, module): + self.module = module + # obtain binary paths for gpg & pacman-key + self.gpg = module.get_bin_path('gpg', required=True) + self.pacman_key = module.get_bin_path('pacman-key', required=True) + + # obtain module parameters + keyid = module.params['id'] + url = module.params['url'] + data = module.params['data'] + file = module.params['file'] + keyserver = module.params['keyserver'] + verify = module.params['verify'] + force_update = module.params['force_update'] + keyring = module.params['keyring'] + state = module.params['state'] + self.keylength = 40 + + # sanitise key ID & check if key exists in the keyring + keyid = self.sanitise_keyid(keyid) + key_present = self.key_in_keyring(keyring, keyid) + + # check mode + if module.check_mode: + if state == "present": + changed = (key_present and force_update) or not key_present + module.exit_json(changed=changed) + elif state == "absent": + if key_present: + module.exit_json(changed=True) + module.exit_json(changed=False) + + if state == "present": + if key_present and not force_update: + module.exit_json(changed=False) + + if data: + file = self.save_key(data) + self.add_key(keyring, file, keyid, verify) + module.exit_json(changed=True) + elif file: + self.add_key(keyring, file, keyid, verify) + module.exit_json(changed=True) + elif url: + data = self.fetch_key(url) + file = self.save_key(data) + self.add_key(keyring, file, keyid, verify) + module.exit_json(changed=True) + elif keyserver: + self.recv_key(keyring, keyid, keyserver) + module.exit_json(changed=True) + elif state == "absent": + if key_present: + self.remove_key(keyring, keyid) + module.exit_json(changed=True) + module.exit_json(changed=False) + + def is_hexadecimal(self, string): + """Check if a given string is valid hexadecimal""" + try: + int(string, 16) + except ValueError: + return False + return True + + def sanitise_keyid(self, keyid): + """Sanitise given key ID. + + Strips whitespace, uppercases all characters, and strips leading `0X`. + """ + sanitised_keyid = keyid.strip().upper().replace(' ', '').replace('0X', '') + if len(sanitised_keyid) != self.keylength: + self.module.fail_json(msg="key ID is not full-length: %s" % sanitised_keyid) + if not self.is_hexadecimal(sanitised_keyid): + self.module.fail_json(msg="key ID is not hexadecimal: %s" % sanitised_keyid) + return sanitised_keyid + + def fetch_key(self, url): + """Downloads a key from url""" + response, info = fetch_url(self.module, url) + if info['status'] != 200: + self.module.fail_json(msg="failed to fetch key at %s, error was %s" % (url, info['msg'])) + return to_native(response.read()) + + def recv_key(self, keyring, keyid, keyserver): + """Receives key via keyserver""" + cmd = [self.pacman_key, '--gpgdir', keyring, '--keyserver', keyserver, '--recv-keys', keyid] + self.module.run_command(cmd, check_rc=True) + self.lsign_key(keyring, keyid) + + def lsign_key(self, keyring, keyid): + """Locally sign key""" + cmd = [self.pacman_key, '--gpgdir', keyring] + self.module.run_command(cmd + ['--lsign-key', keyid], check_rc=True) + + def save_key(self, data): + "Saves key data to a temporary file" + tmpfd, tmpname = tempfile.mkstemp() + self.module.add_cleanup_file(tmpname) + tmpfile = os.fdopen(tmpfd, "w") + tmpfile.write(data) + tmpfile.close() + return tmpname + + def add_key(self, keyring, keyfile, keyid, verify): + """Add key to pacman's keyring""" + if verify: + self.verify_keyfile(keyfile, keyid) + cmd = [self.pacman_key, '--gpgdir', keyring, '--add', keyfile] + self.module.run_command(cmd, check_rc=True) + self.lsign_key(keyring, keyid) + + def remove_key(self, keyring, keyid): + """Remove key from pacman's keyring""" + cmd = [self.pacman_key, '--gpgdir', keyring, '--delete', keyid] + self.module.run_command(cmd, check_rc=True) + + def verify_keyfile(self, keyfile, keyid): + """Verify that keyfile matches the specified key ID""" + if keyfile is None: + self.module.fail_json(msg="expected a key, got none") + elif keyid is None: + self.module.fail_json(msg="expected a key ID, got none") + + rc, stdout, stderr = self.module.run_command( + [ + self.gpg, + '--with-colons', + '--with-fingerprint', + '--batch', + '--no-tty', + '--show-keys', + keyfile + ], + check_rc=True, + ) + + extracted_keyid = None + for line in stdout.splitlines(): + if line.startswith('fpr:'): + extracted_keyid = line.split(':')[9] + break + + if extracted_keyid != keyid: + self.module.fail_json(msg="key ID does not match. expected %s, got %s" % (keyid, extracted_keyid)) + + def key_in_keyring(self, keyring, keyid): + "Check if the key ID is in pacman's keyring" + rc, stdout, stderr = self.module.run_command( + [ + self.gpg, + '--with-colons', + '--batch', + '--no-tty', + '--no-default-keyring', + '--keyring=%s/pubring.gpg' % keyring, + '--list-keys', keyid + ], + check_rc=False, + ) + if rc != 0: + if stderr.find("No public key") >= 0: + return False + else: + self.module.fail_json(msg="gpg returned an error: %s" % stderr) + return True + + +def main(): + module = AnsibleModule( + argument_spec=dict( + id=dict(type='str', required=True), + data=dict(type='str'), + file=dict(type='path'), + url=dict(type='str'), + keyserver=dict(type='str'), + verify=dict(type='bool', default=True), + force_update=dict(type='bool', default=False), + keyring=dict(type='path', default='/etc/pacman.d/gnupg'), + state=dict(type='str', default='present', choices=['absent', 'present']), + ), + supports_check_mode=True, + mutually_exclusive=(('data', 'file', 'url', 'keyserver'),), + required_if=[('state', 'present', ('data', 'file', 'url', 'keyserver'), True)], + ) + PacmanKey(module) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/pacman_key.py b/plugins/modules/pacman_key.py new file mode 120000 index 0000000000..ac0f448232 --- /dev/null +++ b/plugins/modules/pacman_key.py @@ -0,0 +1 @@ +packaging/os/pacman_key.py \ No newline at end of file diff --git a/tests/unit/plugins/modules/packaging/os/test_pacman_key.py b/tests/unit/plugins/modules/packaging/os/test_pacman_key.py new file mode 100644 index 0000000000..757fee4e87 --- /dev/null +++ b/tests/unit/plugins/modules/packaging/os/test_pacman_key.py @@ -0,0 +1,576 @@ +# Copyright: (c) 2019, George Rawlinson +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.community.general.plugins.modules.packaging.os import pacman_key +import pytest +import json + +# path used for mocking get_bin_path() +MOCK_BIN_PATH = '/mocked/path' + +# Key ID used for tests +TESTING_KEYID = '14F26682D0916CDD81E37B6D61B7B526D98F0353' +TESTING_KEYFILE_PATH = '/tmp/pubkey.asc' + +# gpg --{show,list}-key output (key present) +GPG_SHOWKEY_OUTPUT = '''tru::1:1616373715:0:3:1:5 +pub:-:4096:1:61B7B526D98F0353:1437155332:::-:::scSC::::::23::0: +fpr:::::::::14F26682D0916CDD81E37B6D61B7B526D98F0353: +uid:-::::1437155332::E57D1F9BFF3B404F9F30333629369B08DF5E2161::Mozilla Software Releases ::::::::::0: +sub:e:4096:1:1C69C4E55E9905DB:1437155572:1500227572:::::s::::::23: +fpr:::::::::F2EF4E6E6AE75B95F11F1EB51C69C4E55E9905DB: +sub:e:4096:1:BBBEBDBB24C6F355:1498143157:1561215157:::::s::::::23: +fpr:::::::::DCEAC5D96135B91C4EA672ABBBBEBDBB24C6F355: +sub:e:4096:1:F1A6668FBB7D572E:1559247338:1622319338:::::s::::::23: +fpr:::::::::097B313077AE62A02F84DA4DF1A6668FBB7D572E:''' + +# gpg --{show,list}-key output (key absent) +GPG_NOKEY_OUTPUT = '''gpg: error reading key: No public key +tru::1:1616373715:0:3:1:5''' + +# pacman-key output (successful invocation) +PACMAN_KEY_SUCCESS = '''==> Updating trust database... +gpg: next trustdb check due at 2021-08-02''' + +# expected command for gpg --list-keys KEYID +RUN_CMD_LISTKEYS = [ + MOCK_BIN_PATH, + '--with-colons', + '--batch', + '--no-tty', + '--no-default-keyring', + '--keyring=/etc/pacman.d/gnupg/pubring.gpg', + '--list-keys', + TESTING_KEYID, +] + +# expected command for gpg --show-keys KEYFILE +RUN_CMD_SHOW_KEYFILE = [ + MOCK_BIN_PATH, + '--with-colons', + '--with-fingerprint', + '--batch', + '--no-tty', + '--show-keys', + TESTING_KEYFILE_PATH, +] + +# expected command for pacman-key --lsign-key KEYID +RUN_CMD_LSIGN_KEY = [ + MOCK_BIN_PATH, + '--gpgdir', + '/etc/pacman.d/gnupg', + '--lsign-key', + TESTING_KEYID, +] + + +TESTCASES = [ + # + # invalid user input + # + # state: present, id: absent + [ + { + 'state': 'present', + }, + { + 'id': 'param_missing_id', + 'msg': 'missing required arguments: id', + 'failed': True, + }, + ], + # state: present, required parameters: missing + [ + { + 'state': 'present', + 'id': '0xDOESNTMATTER', + }, + { + 'id': 'param_missing_method', + 'msg': 'state is present but any of the following are missing: data, file, url, keyserver', + 'failed': True, + }, + ], + # state: present, id: invalid (not full-length) + [ + { + 'id': '0xDOESNTMATTER', + 'data': 'FAKEDATA', + }, + { + 'id': 'param_id_not_full', + 'msg': 'key ID is not full-length: DOESNTMATTER', + 'failed': True, + }, + ], + # state: present, id: invalid (not hexadecimal) + [ + { + 'state': 'present', + 'id': '01234567890ABCDE01234567890ABCDE1234567M', + 'data': 'FAKEDATA', + }, + { + 'id': 'param_id_not_hex', + 'msg': 'key ID is not hexadecimal: 01234567890ABCDE01234567890ABCDE1234567M', + 'failed': True, + }, + ], + # state: absent, id: absent + [ + { + 'state': 'absent', + }, + { + 'id': 'param_absent_state_missing_id', + 'msg': 'missing required arguments: id', + 'failed': True, + }, + ], + # + # check mode + # + # state & key present + [ + { + 'state': 'present', + 'id': TESTING_KEYID, + 'data': 'FAKEDATA', + '_ansible_check_mode': True, + }, + { + 'id': 'checkmode_state_and_key_present', + 'run_command.calls': [ + ( + RUN_CMD_LISTKEYS, + {'check_rc': False}, + ( + 0, + GPG_SHOWKEY_OUTPUT, + '', + ), + ), + ], + 'changed': False, + }, + ], + # state present, key absent + [ + { + 'state': 'present', + 'id': TESTING_KEYID, + 'data': 'FAKEDATA', + '_ansible_check_mode': True, + }, + { + 'id': 'checkmode_state_present_key_absent', + 'run_command.calls': [ + ( + RUN_CMD_LISTKEYS, + {'check_rc': False}, + ( + 2, + '', + GPG_NOKEY_OUTPUT, + ), + ), + ], + 'changed': True, + }, + ], + # state & key absent + [ + { + 'state': 'absent', + 'id': TESTING_KEYID, + '_ansible_check_mode': True, + }, + { + 'id': 'checkmode_state_and_key_absent', + 'run_command.calls': [ + ( + RUN_CMD_LISTKEYS, + {'check_rc': False}, + ( + 2, + '', + GPG_NOKEY_OUTPUT, + ), + ), + ], + 'changed': False, + }, + ], + # state absent, key present + [ + { + 'state': 'absent', + 'id': TESTING_KEYID, + '_ansible_check_mode': True, + }, + { + 'id': 'check_mode_state_absent_key_present', + 'run_command.calls': [ + ( + RUN_CMD_LISTKEYS, + {'check_rc': False}, + ( + 0, + GPG_SHOWKEY_OUTPUT, + '', + ), + ), + ], + 'changed': True, + }, + ], + # + # normal operation + # + # state & key present + [ + { + 'state': 'present', + 'id': TESTING_KEYID, + 'data': 'FAKEDATA', + }, + { + 'id': 'state_and_key_present', + 'run_command.calls': [ + ( + RUN_CMD_LISTKEYS, + {'check_rc': False}, + ( + 0, + GPG_SHOWKEY_OUTPUT, + '', + ), + ), + ], + 'changed': False, + }, + ], + # state absent, key present + [ + { + 'state': 'absent', + 'id': TESTING_KEYID, + }, + { + 'id': 'state_absent_key_present', + 'run_command.calls': [ + ( + RUN_CMD_LISTKEYS, + {'check_rc': False}, + ( + 0, + GPG_SHOWKEY_OUTPUT, + '', + ), + ), + ( + [ + MOCK_BIN_PATH, + '--gpgdir', + '/etc/pacman.d/gnupg', + '--delete', + TESTING_KEYID, + ], + {'check_rc': True}, + ( + 0, + PACMAN_KEY_SUCCESS, + '', + ), + ), + ], + 'changed': True, + }, + ], + # state & key absent + [ + { + 'state': 'absent', + 'id': TESTING_KEYID, + }, + { + 'id': 'state_and_key_absent', + 'run_command.calls': [ + ( + RUN_CMD_LISTKEYS, + {'check_rc': False}, + ( + 2, + '', + GPG_NOKEY_OUTPUT, + ), + ), + ], + 'changed': False, + }, + ], + # state: present, key: absent, method: file + [ + { + 'state': 'present', + 'id': TESTING_KEYID, + 'file': TESTING_KEYFILE_PATH, + }, + { + 'id': 'state_present_key_absent_method_file', + 'run_command.calls': [ + ( + RUN_CMD_LISTKEYS, + {'check_rc': False}, + ( + 2, + '', + GPG_NOKEY_OUTPUT, + ), + ), + ( + RUN_CMD_SHOW_KEYFILE, + {'check_rc': True}, + ( + 0, + GPG_SHOWKEY_OUTPUT, + '', + ), + ), + ( + [ + MOCK_BIN_PATH, + '--gpgdir', + '/etc/pacman.d/gnupg', + '--add', + '/tmp/pubkey.asc', + ], + {'check_rc': True}, + ( + 0, + PACMAN_KEY_SUCCESS, + '', + ), + ), + ( + RUN_CMD_LSIGN_KEY, + {'check_rc': True}, + ( + 0, + PACMAN_KEY_SUCCESS, + '', + ), + ), + ], + 'changed': True, + }, + ], + # state: present, key: absent, method: file + # failure: keyid & keyfile don't match + [ + { + 'state': 'present', + 'id': TESTING_KEYID, + 'file': TESTING_KEYFILE_PATH, + }, + { + 'id': 'state_present_key_absent_verify_failed', + 'msg': 'key ID does not match. expected 14F26682D0916CDD81E37B6D61B7B526D98F0353, got 14F26682D0916CDD81E37B6D61B7B526D98F0354', + 'run_command.calls': [ + ( + RUN_CMD_LISTKEYS, + {'check_rc': False}, + ( + 2, + '', + GPG_NOKEY_OUTPUT, + ), + ), + ( + RUN_CMD_SHOW_KEYFILE, + {'check_rc': True}, + ( + 0, + GPG_SHOWKEY_OUTPUT.replace('61B7B526D98F0353', '61B7B526D98F0354'), + '', + ), + ), + ], + 'failed': True, + }, + ], + # state: present, key: absent, method: keyserver + [ + { + 'state': 'present', + 'id': TESTING_KEYID, + 'keyserver': 'pgp.mit.edu', + }, + { + 'id': 'state_present_key_absent_method_keyserver', + 'run_command.calls': [ + ( + RUN_CMD_LISTKEYS, + {'check_rc': False}, + ( + 2, + '', + GPG_NOKEY_OUTPUT, + ), + ), + ( + [ + MOCK_BIN_PATH, + '--gpgdir', + '/etc/pacman.d/gnupg', + '--keyserver', + 'pgp.mit.edu', + '--recv-keys', + TESTING_KEYID, + ], + {'check_rc': True}, + ( + 0, + ''' +gpg: key 0x61B7B526D98F0353: 32 signatures not checked due to missing keys +gpg: key 0x61B7B526D98F0353: public key "Mozilla Software Releases " imported +gpg: marginals needed: 3 completes needed: 1 trust model: pgp +gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u +gpg: Total number processed: 1 +gpg: imported: 1 +''', + '', + ), + ), + ( + RUN_CMD_LSIGN_KEY, + {'check_rc': True}, + ( + 0, + PACMAN_KEY_SUCCESS, + '', + ), + ), + ], + 'changed': True, + }, + ], + # state: present, key: absent, method: data + [ + { + 'state': 'present', + 'id': TESTING_KEYID, + 'data': 'PGP_DATA', + }, + { + 'id': 'state_present_key_absent_method_data', + 'run_command.calls': [ + ( + RUN_CMD_LISTKEYS, + {'check_rc': False}, + ( + 2, + '', + GPG_NOKEY_OUTPUT, + ), + ), + ( + RUN_CMD_SHOW_KEYFILE, + {'check_rc': True}, + ( + 0, + GPG_SHOWKEY_OUTPUT, + '', + ), + ), + ( + [ + MOCK_BIN_PATH, + '--gpgdir', + '/etc/pacman.d/gnupg', + '--add', + '/tmp/pubkey.asc', + ], + {'check_rc': True}, + ( + 0, + PACMAN_KEY_SUCCESS, + '', + ), + ), + ( + RUN_CMD_LSIGN_KEY, + {'check_rc': True}, + ( + 0, + PACMAN_KEY_SUCCESS, + '', + ), + ), + ], + 'save_key_output': TESTING_KEYFILE_PATH, + 'changed': True, + }, + ], +] + + +@pytest.fixture +def patch_get_bin_path(mocker): + get_bin_path = mocker.patch.object( + AnsibleModule, + 'get_bin_path', + return_value=MOCK_BIN_PATH, + ) + + +@pytest.mark.parametrize( + 'patch_ansible_module, expected', + TESTCASES, + ids=[item[1]['id'] for item in TESTCASES], + indirect=['patch_ansible_module'] +) +@pytest.mark.usefixtures('patch_ansible_module') +def test_operation(mocker, capfd, patch_get_bin_path, expected): + # patch run_command invocations with mock data + if 'run_command.calls' in expected: + mock_run_command = mocker.patch.object( + AnsibleModule, + 'run_command', + side_effect=[item[2] for item in expected['run_command.calls']], + ) + + # patch save_key invocations with mock data + if 'save_key_output' in expected: + mock_save_key = mocker.patch.object( + pacman_key.PacmanKey, + 'save_key', + return_value=expected['save_key_output'], + ) + + # invoke module + with pytest.raises(SystemExit): + pacman_key.main() + + # capture std{out,err} + out, err = capfd.readouterr() + results = json.loads(out) + + # assertion time! + if 'msg' in expected: + assert results['msg'] == expected['msg'] + if 'changed' in expected: + assert results['changed'] == expected['changed'] + if 'failed' in expected: + assert results['failed'] == expected['failed'] + + if 'run_command.calls' in expected: + assert AnsibleModule.run_command.call_count == len(expected['run_command.calls']) + call_args_list = [(item[0][0], item[1]) for item in AnsibleModule.run_command.call_args_list] + expected_call_args_list = [(item[0], item[1]) for item in expected['run_command.calls']] + assert call_args_list == expected_call_args_list From 6549e41ab80e5806d017efea9e06e26158aec94d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 4 Jun 2021 07:55:41 +0200 Subject: [PATCH 116/139] Add module sapcar_extract to make SAP administration easier. (#2596) (#2705) * add sapcar * integrate test * test integration * Revert "integrate test" This reverts commit 17cbff4f0227e4c27e1e25671d993823559d94bd. * add requiered * change test * change binary * test * add bin bath * change future * change download logic * change logic * sanity * Apply suggestions from code review Co-authored-by: Felix Fontein * add url and error handling * sanity * Apply suggestions from code review Co-authored-by: Andrew Klychkov * Apply suggestions from code review Co-authored-by: Felix Fontein * cleanup and fixes * sanity * add sec library * add description * remove blanks * sanity * Apply suggestions from code review Co-authored-by: Felix Fontein Co-authored-by: Rainer Leber Co-authored-by: Felix Fontein Co-authored-by: Andrew Klychkov (cherry picked from commit a4f46b881ac4596ff32e8581df4c794301dacd6e) Co-authored-by: rainerleber <39616583+rainerleber@users.noreply.github.com> --- plugins/modules/files/sapcar_extract.py | 219 ++++++++++++++++++ plugins/modules/sapcar_extract.py | 1 + tests/unit/plugins/modules/files/__init__.py | 0 .../modules/files/test_sapcar_extract.py | 53 +++++ 4 files changed, 273 insertions(+) create mode 100644 plugins/modules/files/sapcar_extract.py create mode 120000 plugins/modules/sapcar_extract.py create mode 100644 tests/unit/plugins/modules/files/__init__.py create mode 100644 tests/unit/plugins/modules/files/test_sapcar_extract.py diff --git a/plugins/modules/files/sapcar_extract.py b/plugins/modules/files/sapcar_extract.py new file mode 100644 index 0000000000..db0f5f9ea8 --- /dev/null +++ b/plugins/modules/files/sapcar_extract.py @@ -0,0 +1,219 @@ +#!/usr/bin/python + +# Copyright: (c) 2021, Rainer Leber +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: sapcar_extract +short_description: Manages SAP SAPCAR archives +version_added: "3.2.0" +description: + - Provides support for unpacking C(sar)/C(car) files with the SAPCAR binary from SAP and pulling + information back into Ansible. +options: + path: + description: The path to the SAR/CAR file. + type: path + required: true + dest: + description: + - The destination where SAPCAR extracts the SAR file. Missing folders will be created. + If this parameter is not provided it will unpack in the same folder as the SAR file. + type: path + binary_path: + description: + - The path to the SAPCAR binary, for example, C(/home/dummy/sapcar) or C(https://myserver/SAPCAR). + If this parameter is not provided the module will look in C(PATH). + type: path + signature: + description: + - If C(true) the signature will be extracted. + default: false + type: bool + security_library: + description: + - The path to the security library, for example, C(/usr/sap/hostctrl/exe/libsapcrytp.so), for signature operations. + type: path + manifest: + description: + - The name of the manifest. + default: "SIGNATURE.SMF" + type: str + remove: + description: + - If C(true) the SAR/CAR file will be removed. B(This should be used with caution!) + default: false + type: bool +author: + - Rainer Leber (@RainerLeber) +notes: + - Always returns C(changed=true) in C(check_mode). +''' + +EXAMPLES = """ +- name: Extract SAR file + community.general.sapcar_extract: + path: "~/source/hana.sar" + +- name: Extract SAR file with destination + community.general.sapcar_extract: + path: "~/source/hana.sar" + dest: "~/test/" + +- name: Extract SAR file with destination and download from webserver can be a fileshare as well + community.general.sapcar_extract: + path: "~/source/hana.sar" + dest: "~/dest/" + binary_path: "https://myserver/SAPCAR" + +- name: Extract SAR file and delete SAR after extract + community.general.sapcar_extract: + path: "~/source/hana.sar" + remove: true + +- name: Extract SAR file with manifest + community.general.sapcar_extract: + path: "~/source/hana.sar" + signature: true + +- name: Extract SAR file with manifest and rename it + community.general.sapcar_extract: + path: "~/source/hana.sar" + manifest: "MyNewSignature.SMF" + signature: true +""" + +import os +from tempfile import NamedTemporaryFile +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.urls import open_url +from ansible.module_utils._text import to_native + + +def get_list_of_files(dir_name): + # create a list of file and directories + # names in the given directory + list_of_file = os.listdir(dir_name) + allFiles = list() + # Iterate over all the entries + for entry in list_of_file: + # Create full path + fullPath = os.path.join(dir_name, entry) + # If entry is a directory then get the list of files in this directory + if os.path.isdir(fullPath): + allFiles = allFiles + [fullPath] + allFiles = allFiles + get_list_of_files(fullPath) + else: + allFiles.append(fullPath) + return allFiles + + +def download_SAPCAR(binary_path, module): + bin_path = None + # download sapcar binary if url is provided otherwise path is returned + if binary_path is not None: + if binary_path.startswith('https://') or binary_path.startswith('http://'): + random_file = NamedTemporaryFile(delete=False) + with open_url(binary_path) as response: + with random_file as out_file: + data = response.read() + out_file.write(data) + os.chmod(out_file.name, 0o700) + bin_path = out_file.name + module.add_cleanup_file(bin_path) + else: + bin_path = binary_path + return bin_path + + +def check_if_present(command, path, dest, signature, manifest, module): + # manipuliating output from SAR file for compare with already extracted files + iter_command = [command, '-tvf', path] + sar_out = module.run_command(iter_command)[1] + sar_raw = sar_out.split("\n")[1:] + if dest[-1] != "/": + dest = dest + "/" + sar_files = [dest + x.split(" ")[-1] for x in sar_raw if x] + # remove any SIGNATURE.SMF from list because it will not unpacked if signature is false + if not signature: + sar_files = [item for item in sar_files if '.SMF' not in item] + # if signature is renamed manipulate files in list of sar file for compare. + if manifest != "SIGNATURE.SMF": + sar_files = [item for item in sar_files if '.SMF' not in item] + sar_files = sar_files + [manifest] + # get extracted files if present + files_extracted = get_list_of_files(dest) + # compare extracted files with files in sar file + present = all(elem in files_extracted for elem in sar_files) + return present + + +def main(): + module = AnsibleModule( + argument_spec=dict( + path=dict(type='path', required=True), + dest=dict(type='path'), + binary_path=dict(type='path'), + signature=dict(type='bool', default=False), + security_library=dict(type='path'), + manifest=dict(type='str', default="SIGNATURE.SMF"), + remove=dict(type='bool', default=False), + ), + supports_check_mode=True, + ) + rc, out, err = [0, "", ""] + params = module.params + check_mode = module.check_mode + + path = params['path'] + dest = params['dest'] + signature = params['signature'] + security_library = params['security_library'] + manifest = params['manifest'] + remove = params['remove'] + + bin_path = download_SAPCAR(params['binary_path'], module) + + if dest is None: + dest_head_tail = os.path.split(path) + dest = dest_head_tail[0] + '/' + else: + if not os.path.exists(dest): + os.makedirs(dest, 0o755) + + if bin_path is not None: + command = [module.get_bin_path(bin_path, required=True)] + else: + try: + command = [module.get_bin_path('sapcar', required=True)] + except Exception as e: + module.fail_json(msg='Failed to find SAPCAR at the expected path or URL "{0}". Please check whether it is available: {1}' + .format(bin_path, to_native(e))) + + present = check_if_present(command[0], path, dest, signature, manifest, module) + + if not present: + command.extend(['-xvf', path, '-R', dest]) + if security_library: + command.extend(['-L', security_library]) + if signature: + command.extend(['-manifest', manifest]) + if not check_mode: + (rc, out, err) = module.run_command(command, check_rc=True) + changed = True + else: + changed = False + out = "allready unpacked" + + if remove: + os.remove(path) + + module.exit_json(changed=changed, message=rc, stdout=out, + stderr=err, command=' '.join(command)) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/sapcar_extract.py b/plugins/modules/sapcar_extract.py new file mode 120000 index 0000000000..7bb47b10c1 --- /dev/null +++ b/plugins/modules/sapcar_extract.py @@ -0,0 +1 @@ +./files/sapcar_extract.py \ No newline at end of file diff --git a/tests/unit/plugins/modules/files/__init__.py b/tests/unit/plugins/modules/files/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/unit/plugins/modules/files/test_sapcar_extract.py b/tests/unit/plugins/modules/files/test_sapcar_extract.py new file mode 100644 index 0000000000..05946e8217 --- /dev/null +++ b/tests/unit/plugins/modules/files/test_sapcar_extract.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright: (c) 2021, Rainer Leber (@rainerleber) +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +from ansible_collections.community.general.plugins.modules.files import sapcar_extract +from ansible_collections.community.general.tests.unit.plugins.modules.utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase, set_module_args +from ansible_collections.community.general.tests.unit.compat.mock import patch +from ansible.module_utils import basic + + +def get_bin_path(*args, **kwargs): + """Function to return path of SAPCAR""" + return "/tmp/sapcar" + + +class Testsapcar_extract(ModuleTestCase): + """Main class for testing sapcar_extract module.""" + + def setUp(self): + """Setup.""" + super(Testsapcar_extract, self).setUp() + self.module = sapcar_extract + self.mock_get_bin_path = patch.object(basic.AnsibleModule, 'get_bin_path', get_bin_path) + self.mock_get_bin_path.start() + self.addCleanup(self.mock_get_bin_path.stop) # ensure that the patching is 'undone' + + def tearDown(self): + """Teardown.""" + super(Testsapcar_extract, self).tearDown() + + def test_without_required_parameters(self): + """Failure must occurs when all parameters are missing.""" + with self.assertRaises(AnsibleFailJson): + set_module_args({}) + self.module.main() + + def test_sapcar_extract(self): + """Check that result is changed.""" + set_module_args({ + 'path': "/tmp/HANA_CLIENT_REV2_00_053_00_LINUX_X86_64.SAR", + 'dest': "/tmp/test2", + 'binary_path': "/tmp/sapcar" + }) + with patch.object(basic.AnsibleModule, 'run_command') as run_command: + run_command.return_value = 0, '', '' # successful execution, no output + with self.assertRaises(AnsibleExitJson) as result: + sapcar_extract.main() + self.assertTrue(result.exception.args[0]['changed']) + self.assertEqual(run_command.call_count, 1) From 635d4f2138eedb464945b00f809860b7dc8bd5be Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 4 Jun 2021 10:24:55 +0200 Subject: [PATCH 117/139] Fix spurious test errors. (#2709) (#2710) (cherry picked from commit 2e8746a8aadc1af2ddc5a9e140851a9c0cf27092) Co-authored-by: Felix Fontein --- tests/integration/targets/lookup_random_string/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/targets/lookup_random_string/test.yml b/tests/integration/targets/lookup_random_string/test.yml index 52a572379b..edbf9fd035 100644 --- a/tests/integration/targets/lookup_random_string/test.yml +++ b/tests/integration/targets/lookup_random_string/test.yml @@ -9,7 +9,7 @@ result4: "{{ query('community.general.random_string', length=-1) }}" result5: "{{ query('community.general.random_string', override_special='_', min_special=1) }}" result6: "{{ query('community.general.random_string', upper=false, special=false) }}" # lower case only - result7: "{{ query('community.general.random_string', lower=false) }}" # upper case only + result7: "{{ query('community.general.random_string', lower=false, special=false) }}" # upper case only result8: "{{ query('community.general.random_string', lower=false, upper=false, special=false) }}" # number only result9: "{{ query('community.general.random_string', lower=false, upper=false, special=false, min_numeric=1, length=1) }}" # single digit only result10: "{{ query('community.general.random_string', numbers=false, upper=false, special=false, min_lower=1, length=1) }}" # single lowercase character only From 9ade4f6dd69e1708d5405663200be649741f899d Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Fri, 4 Jun 2021 10:38:04 +0200 Subject: [PATCH 118/139] Announce script removal. (#2697) --- changelogs/fragments/script-removal.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/script-removal.yml diff --git a/changelogs/fragments/script-removal.yml b/changelogs/fragments/script-removal.yml new file mode 100644 index 0000000000..4328fef555 --- /dev/null +++ b/changelogs/fragments/script-removal.yml @@ -0,0 +1,2 @@ +deprecated_features: +- "All inventory and vault scripts will be removed from community.general. If you are referencing them, please update your references to the new `contrib-scripts GitHub repository `_ so your workflow will not break once community.general 4.0.0 is released (https://github.com/ansible-collections/community.general/pull/2697)." From b2b65c431b7d0260c1cbe345f81b4dc207428985 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 4 Jun 2021 11:13:22 +0200 Subject: [PATCH 119/139] Fix action plugin BOTMETA entries. (#2707) (#2714) (cherry picked from commit 4396ec9631065ad85154f272193e58d289f21876) Co-authored-by: Felix Fontein --- .github/BOTMETA.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index a3fb8e1f35..b7709fbf6f 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -6,12 +6,9 @@ files: support: community $actions: labels: action - $actions/aireos.py: - labels: aireos cisco networking - $actions/ironware.py: - maintainers: paulquack - labels: ironware networking - $actions/shutdown.py: + $actions/system/iptables_state.py: + maintainers: quidame + $actions/system/shutdown.py: maintainers: nitzmahone samdoran aminvakil $becomes/: labels: become @@ -848,6 +845,8 @@ files: labels: interfaces_file $modules/system/iptables_state.py: maintainers: quidame + $modules/system/shutdown.py: + maintainers: nitzmahone samdoran aminvakil $modules/system/java_cert.py: maintainers: haad absynth76 $modules/system/java_keystore.py: From e30b91cb8d8e19734f3c73a5dd9e029399c4e47a Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 4 Jun 2021 11:13:32 +0200 Subject: [PATCH 120/139] Add new module/plugin maintainers to BOTMETA. (#2708) (#2712) (cherry picked from commit d49783280e9a3ba1df47ed999e3e8ec05b7206d0) Co-authored-by: Felix Fontein --- .github/BOTMETA.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index b7709fbf6f..74b53db418 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -117,6 +117,8 @@ files: $lookups/nios: maintainers: $team_networking sganesh-infoblox labels: infoblox networking + $lookups/random_string.py: + maintainers: Akasurde $module_utils/: labels: module_utils $module_utils/gitlab.py: @@ -649,6 +651,9 @@ files: maintainers: elasticdog indrajitr tchernomax labels: pacman ignore: elasticdog + $modules/packaging/os/pacman_key.py: + maintainers: grawlinson + labels: pacman $modules/packaging/os/pkgin.py: maintainers: $team_solaris L2G jasperla szinck martinm82 labels: pkgin solaris From d4a33433b4d9175a00212daeda994e47439dac7e Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Fri, 4 Jun 2021 12:37:04 +0200 Subject: [PATCH 121/139] Mention removal version more prominently. --- changelogs/fragments/script-removal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/fragments/script-removal.yml b/changelogs/fragments/script-removal.yml index 4328fef555..be17f6ad65 100644 --- a/changelogs/fragments/script-removal.yml +++ b/changelogs/fragments/script-removal.yml @@ -1,2 +1,2 @@ deprecated_features: -- "All inventory and vault scripts will be removed from community.general. If you are referencing them, please update your references to the new `contrib-scripts GitHub repository `_ so your workflow will not break once community.general 4.0.0 is released (https://github.com/ansible-collections/community.general/pull/2697)." +- "All inventory and vault scripts will be removed from community.general in version 4.0.0. If you are referencing them, please update your references to the new `contrib-scripts GitHub repository `_ so your workflow will not break once community.general 4.0.0 is released (https://github.com/ansible-collections/community.general/pull/2697)." From 4b07d45b7e59502bdc433c6b84503aae0930adfd Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 4 Jun 2021 21:12:40 +0200 Subject: [PATCH 122/139] Fix repeated word in description of fs_type (#2717) (#2719) (cherry picked from commit a343756e6f3a9ed24f1cb3c16a97dfbae2273bf3) Co-authored-by: Alex Willmer --- plugins/modules/system/parted.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/system/parted.py b/plugins/modules/system/parted.py index bbb8c1408b..3796cfc40b 100644 --- a/plugins/modules/system/parted.py +++ b/plugins/modules/system/parted.py @@ -100,7 +100,7 @@ options: fs_type: description: - If specified and the partition does not exist, will set filesystem type to given partition. - - Parameter optional, but see notes below about negative negative C(part_start) values. + - Parameter optional, but see notes below about negative C(part_start) values. type: str version_added: '0.2.0' resize: From eb4d7a41998f39fb6f008ab849514f46fd6a4a77 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 4 Jun 2021 21:12:53 +0200 Subject: [PATCH 123/139] Terraform: ensure workspace is reset to current value (#2634) (#2720) * fix: ensure workspace is reset to current value * chore: linter * chore: changelog (cherry picked from commit c49a384a6522dd9d9b80fd7810df9a8b829e5127) Co-authored-by: christophemorio <49184206+christophemorio@users.noreply.github.com> --- changelogs/fragments/2634-terraform-switch-workspace.yml | 2 ++ plugins/modules/cloud/misc/terraform.py | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2634-terraform-switch-workspace.yml diff --git a/changelogs/fragments/2634-terraform-switch-workspace.yml b/changelogs/fragments/2634-terraform-switch-workspace.yml new file mode 100644 index 0000000000..247447b3a8 --- /dev/null +++ b/changelogs/fragments/2634-terraform-switch-workspace.yml @@ -0,0 +1,2 @@ +bugfixes: + - terraform - ensure the workspace is set back to its previous value when the apply fails (https://github.com/ansible-collections/community.general/pull/2634). diff --git a/plugins/modules/cloud/misc/terraform.py b/plugins/modules/cloud/misc/terraform.py index 8a34f9699b..86521ed264 100644 --- a/plugins/modules/cloud/misc/terraform.py +++ b/plugins/modules/cloud/misc/terraform.py @@ -447,7 +447,14 @@ def main(): command.append(plan_file) if needs_application and not module.check_mode and not state == 'planned': - rc, out, err = module.run_command(command, check_rc=True, cwd=project_path) + rc, out, err = module.run_command(command, check_rc=False, cwd=project_path) + if rc != 0: + if workspace_ctx["current"] != workspace: + select_workspace(command[0], project_path, workspace_ctx["current"]) + module.fail_json(msg=err.rstrip(), rc=rc, stdout=out, + stdout_lines=out.splitlines(), stderr=err, + stderr_lines=err.splitlines(), + cmd=' '.join(command)) # checks out to decide if changes were made during execution if ' 0 added, 0 changed' not in out and not state == "absent" or ' 0 destroyed' not in out: changed = True From 321fb6c9740dce6c4a4e8a6bb91df20b1e3ec83d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 5 Jun 2021 18:03:14 +0200 Subject: [PATCH 124/139] Reduce stormssh searches based on host (#2568) (#2724) * Reduce stormssh searches based on host Due to the stormssh searches in the whole config values, we need to reduce the search results based on the full matching of the hosts * Removed whitespaces in the blank line * Added changelog fragment and tests for the fix. * Added newline at the end of the changelog fragment * Added newline at the end of the tests * Fixed bug with name in tests * Changed assertion for the existing host * Update changelogs/fragments/2568-ssh_config-reduce-stormssh-searches-based-on-host.yml Co-authored-by: Felix Fontein * Adjusted tests * New line at the end of the tests Co-authored-by: Anton Nikolaev Co-authored-by: Felix Fontein (cherry picked from commit 1a4af9bfc34e417d65e0eb81990d0f023a03c606) Co-authored-by: Anton Nikolaev --- ...reduce-stormssh-searches-based-on-host.yml | 2 ++ plugins/modules/system/ssh_config.py | 2 ++ .../targets/ssh_config/tasks/main.yml | 36 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 changelogs/fragments/2568-ssh_config-reduce-stormssh-searches-based-on-host.yml diff --git a/changelogs/fragments/2568-ssh_config-reduce-stormssh-searches-based-on-host.yml b/changelogs/fragments/2568-ssh_config-reduce-stormssh-searches-based-on-host.yml new file mode 100644 index 0000000000..2f3e400e7e --- /dev/null +++ b/changelogs/fragments/2568-ssh_config-reduce-stormssh-searches-based-on-host.yml @@ -0,0 +1,2 @@ +bugfixes: + - ssh_config - reduce stormssh searches based on host (https://github.com/ansible-collections/community.general/pull/2568/). diff --git a/plugins/modules/system/ssh_config.py b/plugins/modules/system/ssh_config.py index 943f6b44fc..be177baaaf 100644 --- a/plugins/modules/system/ssh_config.py +++ b/plugins/modules/system/ssh_config.py @@ -209,6 +209,8 @@ class SSHConfig(): hosts_removed = [] hosts_added = [] + hosts_result = [host for host in hosts_result if host['host'] == self.host] + if hosts_result: for host in hosts_result: if state == 'absent': diff --git a/tests/integration/targets/ssh_config/tasks/main.yml b/tests/integration/targets/ssh_config/tasks/main.yml index 12f277b455..bd5acc9e04 100644 --- a/tests/integration/targets/ssh_config/tasks/main.yml +++ b/tests/integration/targets/ssh_config/tasks/main.yml @@ -183,3 +183,39 @@ that: - not mut_ex.changed - "'parameters are mutually exclusive' in mut_ex.msg" + +- name: Add a full name host + community.general.ssh_config: + ssh_config_file: "{{ ssh_config_test }}" + host: "full_name" + hostname: full_name.com + identity_file: '{{ ssh_private_key }}' + port: '2223' + state: present + register: full_name + +- name: Check if changes are made + assert: + that: + - full_name is changed + - full_name.hosts_added == ["full_name"] + - full_name.hosts_changed == [] + - full_name.hosts_removed == [] + +- name: Add a host with name which is contained in full name host + community.general.ssh_config: + ssh_config_file: "{{ ssh_config_test }}" + host: "full" + hostname: full.com + identity_file: '{{ ssh_private_key }}' + port: '2223' + state: present + register: short_name + +- name: Check that short name host is added and full name host is not updated + assert: + that: + - short_name is changed + - short_name.hosts_added == ["full"] + - short_name.hosts_changed == [] + - short_name.hosts_removed == [] From 4cba1e60d97099b6cef40eb4ee05e81f4b8d766e Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 5 Jun 2021 23:03:53 +0200 Subject: [PATCH 125/139] Wire token param into consul_api #2124 (#2126) (#2726) * Wire token param into consul_api #2124 * Update changelogs/fragments/2124-consul_kv-pass-token.yml Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> * #2124 renamed release fragment to match pr, removed parse_params. * putting look back in, do some linting #2124 * try more linting * linting * try overwriting defaults in parse_params with get_option vals, instead of removing that function completely. * Revert "back to start, from 2nd approach: allow keyword arguments via parse_params for compatibility." This reverts commit 748be8e366d46b43cc63b740cb78cde519274342. * Revert " linting" This reverts commit 1d57374c3e539a2cb640bf1482496d80f654b7d8. * Revert " try more linting" This reverts commit 91c8d06e6af442bd130859a64afbf5d558528e74. * Revert "putting look back in, do some linting #2124" This reverts commit 87eeec71803929f08e2dbfc1bfa3c76c79ea55d0. * Revert " #2124 renamed release fragment to match pr, removed parse_params." This reverts commit d2869b2f22ad64d84945ed91145de5b52bff2676. * Revert "Update changelogs/fragments/2124-consul_kv-pass-token.yml" This reverts commit c50b1cf9d4a53fbbfaa8332ba3a7acca33909f09. * Revert "Wire token param into consul_api #2124" This reverts commit b60b6433a8000459b40c4fdcee1da4fe436729a9. * minimal chnages for this PR relative to current upstream. * superfluous newline in changlog fragment. Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> (cherry picked from commit 0e6d70697c57889c7af66757dd501f38422cf0b8) Co-authored-by: fkuep --- changelogs/fragments/2126-consul_kv-pass-token.yml | 4 ++++ plugins/lookup/consul_kv.py | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 changelogs/fragments/2126-consul_kv-pass-token.yml diff --git a/changelogs/fragments/2126-consul_kv-pass-token.yml b/changelogs/fragments/2126-consul_kv-pass-token.yml new file mode 100644 index 0000000000..a60fd2efcd --- /dev/null +++ b/changelogs/fragments/2126-consul_kv-pass-token.yml @@ -0,0 +1,4 @@ +--- +bugfixes: + - consul_kv lookup plugin - allow to set ``recurse``, ``index``, ``datacenter`` and ``token`` as keyword arguments + (https://github.com/ansible-collections/community.general/issues/2124). diff --git a/plugins/lookup/consul_kv.py b/plugins/lookup/consul_kv.py index 7ba7e5ac90..d567b7f687 100644 --- a/plugins/lookup/consul_kv.py +++ b/plugins/lookup/consul_kv.py @@ -171,10 +171,10 @@ class LookupModule(LookupBase): paramvals = { 'key': params[0], - 'token': None, - 'recurse': False, - 'index': None, - 'datacenter': None + 'token': self.get_option('token'), + 'recurse': self.get_option('recurse'), + 'index': self.get_option('index'), + 'datacenter': self.get_option('datacenter') } # parameters specified? From 94c368f7df82c683ffcfa8ac7c45702e9e67bfa3 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sat, 5 Jun 2021 23:04:03 +0200 Subject: [PATCH 126/139] open_iscsi: allow same target selected portals login and override (#2684) (#2727) * fix: include portal and port for logged on check * refactor: remove extra space * fix: allow None portal and port on target_loggedon test * add auto_portal_startup argument * fix: change param name for automatic_portal * add changelog fragment * refactor: Update changelogs/fragments/2684-open_iscsi-single-target-multiple-portal-overrides.yml Co-authored-by: Felix Fontein * add version added info to auto_portal_startup arg * add example for auto_portal_startup * fix: remove alias for auto_portal form arg_spec as well * refactor: elaborate in fragment changelogs Elaborate change Co-authored-by: Amin Vakil * open_iscsi: elaborate changelog fragment * Update plugins/modules/system/open_iscsi.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein Co-authored-by: Amin Vakil (cherry picked from commit 9d8bea9d36c1896ce7fff26bbed175ad7b96d601) Co-authored-by: The Binary --- ...ingle-target-multiple-portal-overrides.yml | 3 + plugins/modules/system/open_iscsi.py | 67 +++++++++++++++++-- 2 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/2684-open_iscsi-single-target-multiple-portal-overrides.yml diff --git a/changelogs/fragments/2684-open_iscsi-single-target-multiple-portal-overrides.yml b/changelogs/fragments/2684-open_iscsi-single-target-multiple-portal-overrides.yml new file mode 100644 index 0000000000..cb14a08ba0 --- /dev/null +++ b/changelogs/fragments/2684-open_iscsi-single-target-multiple-portal-overrides.yml @@ -0,0 +1,3 @@ +minor_changes: + - open_iscsi - also consider ``portal`` and ``port`` to check if already logged in or not (https://github.com/ansible-collections/community.general/issues/2683). + - open_iscsi - add ``auto_portal_startup`` parameter to allow ``node.startup`` setting per portal (https://github.com/ansible-collections/community.general/issues/2685). diff --git a/plugins/modules/system/open_iscsi.py b/plugins/modules/system/open_iscsi.py index 222bb82f3d..570925f6a4 100644 --- a/plugins/modules/system/open_iscsi.py +++ b/plugins/modules/system/open_iscsi.py @@ -57,6 +57,11 @@ options: - Whether the target node should be automatically connected at startup. type: bool aliases: [ automatic ] + auto_portal_startup: + description: + - Whether the target node portal should be automatically connected at startup. + type: bool + version_added: 3.2.0 discover: description: - Whether the list of target nodes on the portal should be @@ -102,10 +107,18 @@ EXAMPLES = r''' community.general.open_iscsi: login: no target: iqn.1986-03.com.sun:02:f8c1f9e0-c3ec-ec84-c9c9-8bfb0cd5de3d + +- name: Override and disable automatic portal login on specific portal + community.general.open_iscsi: + login: false + portal: 10.1.1.250 + auto_portal_startup: false + target: iqn.1986-03.com.sun:02:f8c1f9e0-c3ec-ec84-c9c9-8bfb0cd5de3d ''' import glob import os +import re import socket import time @@ -158,12 +171,18 @@ def iscsi_discover(module, portal, port): module.fail_json(cmd=cmd, rc=rc, msg=err) -def target_loggedon(module, target): +def target_loggedon(module, target, portal=None, port=None): cmd = '%s --mode session' % iscsiadm_cmd (rc, out, err) = module.run_command(cmd) + if portal is None: + portal = "" + if port is None: + port = "" + if rc == 0: - return target in out + search_re = "%s:%s.*%s" % (re.escape(portal), port, re.escape(target)) + return re.search(search_re, out) is not None elif rc == 21: return False else: @@ -219,8 +238,14 @@ def target_device_node(module, target): return devdisks -def target_isauto(module, target): +def target_isauto(module, target, portal=None, port=None): cmd = '%s --mode node --targetname %s' % (iscsiadm_cmd, target) + + if portal is not None: + if port is not None: + portal = '%s:%s' % (portal, port) + cmd = '%s --portal %s' % (cmd, portal) + (rc, out, err) = module.run_command(cmd) if rc == 0: @@ -233,16 +258,28 @@ def target_isauto(module, target): module.fail_json(cmd=cmd, rc=rc, msg=err) -def target_setauto(module, target): +def target_setauto(module, target, portal=None, port=None): cmd = '%s --mode node --targetname %s --op=update --name node.startup --value automatic' % (iscsiadm_cmd, target) + + if portal is not None: + if port is not None: + portal = '%s:%s' % (portal, port) + cmd = '%s --portal %s' % (cmd, portal) + (rc, out, err) = module.run_command(cmd) if rc > 0: module.fail_json(cmd=cmd, rc=rc, msg=err) -def target_setmanual(module, target): +def target_setmanual(module, target, portal=None, port=None): cmd = '%s --mode node --targetname %s --op=update --name node.startup --value manual' % (iscsiadm_cmd, target) + + if portal is not None: + if port is not None: + portal = '%s:%s' % (portal, port) + cmd = '%s --portal %s' % (cmd, portal) + (rc, out, err) = module.run_command(cmd) if rc > 0: @@ -265,6 +302,7 @@ def main(): # actions login=dict(type='bool', aliases=['state']), auto_node_startup=dict(type='bool', aliases=['automatic']), + auto_portal_startup=dict(type='bool'), discover=dict(type='bool', default=False), show_nodes=dict(type='bool', default=False), ), @@ -288,6 +326,7 @@ def main(): port = module.params['port'] login = module.params['login'] automatic = module.params['auto_node_startup'] + automatic_portal = module.params['auto_portal_startup'] discover = module.params['discover'] show_nodes = module.params['show_nodes'] @@ -333,7 +372,7 @@ def main(): result['nodes'] = nodes if login is not None: - loggedon = target_loggedon(module, target) + loggedon = target_loggedon(module, target, portal, port) if (login and loggedon) or (not login and not loggedon): result['changed'] |= False if login: @@ -368,6 +407,22 @@ def main(): result['changed'] |= True result['automatic_changed'] = True + if automatic_portal is not None: + isauto = target_isauto(module, target, portal, port) + if (automatic_portal and isauto) or (not automatic_portal and not isauto): + result['changed'] |= False + result['automatic_portal_changed'] = False + elif not check: + if automatic_portal: + target_setauto(module, target, portal, port) + else: + target_setmanual(module, target, portal, port) + result['changed'] |= True + result['automatic_portal_changed'] = True + else: + result['changed'] |= True + result['automatic_portal_changed'] = True + module.exit_json(**result) From 6570dfeb7d1427a13c4ce7c676092a739999ffa4 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 6 Jun 2021 18:10:29 +0200 Subject: [PATCH 127/139] iptables_state: fix async status call (-> action plugin) (#2711) (#2729) * fix call to async_status (-> action plugin) * add changelog fragment * Apply suggestions from code review Co-authored-by: Felix Fontein * rename a local variable for readability Co-authored-by: Felix Fontein (cherry picked from commit 463c576a67acdd101ecc1d181ad184742a22bcaa) Co-authored-by: quidame --- ...-iptables_state-2700-async_status-call.yml | 4 +++ plugins/action/system/iptables_state.py | 28 +++++++++++-------- 2 files changed, 20 insertions(+), 12 deletions(-) create mode 100644 changelogs/fragments/2711-fix-iptables_state-2700-async_status-call.yml diff --git a/changelogs/fragments/2711-fix-iptables_state-2700-async_status-call.yml b/changelogs/fragments/2711-fix-iptables_state-2700-async_status-call.yml new file mode 100644 index 0000000000..8f94cf5178 --- /dev/null +++ b/changelogs/fragments/2711-fix-iptables_state-2700-async_status-call.yml @@ -0,0 +1,4 @@ +--- +bugfixes: + - "iptables_state - call ``async_status`` action plugin rather than its module + (https://github.com/ansible-collections/community.general/issues/2700)." diff --git a/plugins/action/system/iptables_state.py b/plugins/action/system/iptables_state.py index 887f3f47f9..6884e77713 100644 --- a/plugins/action/system/iptables_state.py +++ b/plugins/action/system/iptables_state.py @@ -40,18 +40,26 @@ class ActionModule(ActionBase): "(=%s) to 0, and 'async' (=%s) to a value >2 and not greater than " "'ansible_timeout' (=%s) (recommended).") - def _async_result(self, module_args, task_vars, timeout): + def _async_result(self, async_status_args, task_vars, timeout): ''' Retrieve results of the asynchonous task, and display them in place of the async wrapper results (those with the ansible_job_id key). ''' + async_status = self._task.copy() + async_status.args = async_status_args + async_status.action = 'ansible.builtin.async_status' + async_status.async_val = 0 + async_action = self._shared_loader_obj.action_loader.get( + async_status.action, task=async_status, connection=self._connection, + play_context=self._play_context, loader=self._loader, templar=self._templar, + shared_loader_obj=self._shared_loader_obj) + + if async_status.args['mode'] == 'cleanup': + return async_action.run(task_vars=task_vars) + # At least one iteration is required, even if timeout is 0. for dummy in range(max(1, timeout)): - async_result = self._execute_module( - module_name='ansible.builtin.async_status', - module_args=module_args, - task_vars=task_vars, - wrap_async=False) + async_result = async_action.run(task_vars=task_vars) if async_result.get('finished', 0) == 1: break time.sleep(min(1, timeout)) @@ -106,7 +114,7 @@ class ActionModule(ActionBase): # longer on the controller); and set a backup file path. module_args['_timeout'] = task_async module_args['_back'] = '%s/iptables.state' % async_dir - async_status_args = dict(_async_dir=async_dir) + async_status_args = dict(mode='status') confirm_cmd = 'rm -f %s' % module_args['_back'] starter_cmd = 'touch %s.starter' % module_args['_back'] remaining_time = max(task_async, max_timeout) @@ -168,11 +176,7 @@ class ActionModule(ActionBase): del result['invocation']['module_args'][key] async_status_args['mode'] = 'cleanup' - dummy = self._execute_module( - module_name='ansible.builtin.async_status', - module_args=async_status_args, - task_vars=task_vars, - wrap_async=False) + dummy = self._async_result(async_status_args, task_vars, 0) if not wrap_async: # remove a temporary path we created From 4545d1c91e0c46442b973eaecb3953cf4462659a Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 7 Jun 2021 08:17:04 +0200 Subject: [PATCH 128/139] Bugfix + sanity checks for stacki_host (#2681) (#2733) * fixed validation-modules for plugins/modules/remote_management/stacki/stacki_host.py * sanity fix * added changelog fragment * extra fix to the documentation * Update plugins/modules/remote_management/stacki/stacki_host.py Co-authored-by: Felix Fontein * Update plugins/modules/remote_management/stacki/stacki_host.py Co-authored-by: Felix Fontein * rollback params Co-authored-by: Felix Fontein (cherry picked from commit f74b83663bcc1f6269a2bb56ba646f24f6218578) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .../fragments/2681-stacki-host-bugfix.yml | 4 + .../remote_management/stacki/stacki_host.py | 84 +++++++++++-------- tests/sanity/ignore-2.10.txt | 3 - tests/sanity/ignore-2.11.txt | 3 - tests/sanity/ignore-2.12.txt | 3 - tests/sanity/ignore-2.9.txt | 3 - 6 files changed, 54 insertions(+), 46 deletions(-) create mode 100644 changelogs/fragments/2681-stacki-host-bugfix.yml diff --git a/changelogs/fragments/2681-stacki-host-bugfix.yml b/changelogs/fragments/2681-stacki-host-bugfix.yml new file mode 100644 index 0000000000..3403bfbfbe --- /dev/null +++ b/changelogs/fragments/2681-stacki-host-bugfix.yml @@ -0,0 +1,4 @@ +bugfixes: + - stacki_host - when adding a new server, ``rack`` and ``rank`` must be passed, and network parameters are optional (https://github.com/ansible-collections/community.general/pull/2681). +minor_changes: + - stacki_host - minor refactoring (https://github.com/ansible-collections/community.general/pull/2681). diff --git a/plugins/modules/remote_management/stacki/stacki_host.py b/plugins/modules/remote_management/stacki/stacki_host.py index 8bdc0f82f6..fda0c5d318 100644 --- a/plugins/modules/remote_management/stacki/stacki_host.py +++ b/plugins/modules/remote_management/stacki/stacki_host.py @@ -12,46 +12,48 @@ DOCUMENTATION = ''' module: stacki_host short_description: Add or remove host to stacki front-end description: - - Use this module to add or remove hosts to a stacki front-end via API. - - U(https://github.com/StackIQ/stacki) + - Use this module to add or remove hosts to a stacki front-end via API. + - Information on stacki can be found at U(https://github.com/StackIQ/stacki). options: name: description: - - Name of the host to be added to Stacki. + - Name of the host to be added to Stacki. required: True type: str stacki_user: description: - - Username for authenticating with Stacki API, but if not - specified, the environment variable C(stacki_user) is used instead. + - Username for authenticating with Stacki API, but if not specified, the environment variable C(stacki_user) is used instead. required: True type: str stacki_password: description: - - Password for authenticating with Stacki API, but if not + - Password for authenticating with Stacki API, but if not specified, the environment variable C(stacki_password) is used instead. required: True type: str stacki_endpoint: description: - - URL for the Stacki API Endpoint. + - URL for the Stacki API Endpoint. required: True type: str prim_intf_mac: description: - - MAC Address for the primary PXE boot network interface. + - MAC Address for the primary PXE boot network interface. + - Currently not used by the module. type: str prim_intf_ip: description: - - IP Address for the primary network interface. + - IP Address for the primary network interface. + - Currently not used by the module. type: str prim_intf: description: - - Name of the primary network interface. + - Name of the primary network interface. + - Currently not used by the module. type: str force_install: description: - - Set value to True to force node into install state if it already exists in stacki. + - Set value to C(true) to force node into install state if it already exists in stacki. type: bool default: no state: @@ -59,6 +61,30 @@ options: - Set value to the desired state for the specified host. type: str choices: [ absent, present ] + default: present + appliance: + description: + - Applicance to be used in host creation. + - Required if I(state) is C(present) and host does not yet exist. + type: str + default: backend + rack: + description: + - Rack to be used in host creation. + - Required if I(state) is C(present) and host does not yet exist. + type: int + rank: + description: + - Rank to be used in host creation. + - In Stacki terminology, the rank is the position of the machine in a rack. + - Required if I(state) is C(present) and host does not yet exist. + type: int + network: + description: + - Network to be configured in the host. + - Currently not used by the module. + type: str + default: private author: - Hugh Ma (@bbyhuy) ''' @@ -128,7 +154,7 @@ class StackiHost(object): 'PASSWORD': module.params['stacki_password']} # Get Initial CSRF - cred_a = self.do_request(self.module, self.endpoint, method="GET") + cred_a = self.do_request(self.endpoint, method="GET") cookie_a = cred_a.headers.get('Set-Cookie').split(';') init_csrftoken = None for c in cookie_a: @@ -145,8 +171,7 @@ class StackiHost(object): login_endpoint = self.endpoint + "/login" # Get Final CSRF and Session ID - login_req = self.do_request(self.module, login_endpoint, headers=header, - payload=urlencode(auth_creds), method='POST') + login_req = self.do_request(login_endpoint, headers=header, payload=urlencode(auth_creds), method='POST') cookie_f = login_req.headers.get('Set-Cookie').split(';') csrftoken = None @@ -163,8 +188,8 @@ class StackiHost(object): 'Content-type': 'application/json', 'Cookie': login_req.headers.get('Set-Cookie')} - def do_request(self, module, url, payload=None, headers=None, method=None): - res, info = fetch_url(module, url, data=payload, headers=headers, method=method) + def do_request(self, url, payload=None, headers=None, method=None): + res, info = fetch_url(self.module, url, data=payload, headers=headers, method=method) if info['status'] != 200: self.module.fail_json(changed=False, msg=info['msg']) @@ -172,24 +197,16 @@ class StackiHost(object): return res def stack_check_host(self): - res = self.do_request(self.module, self.endpoint, payload=json.dumps({"cmd": "list host"}), headers=self.header, method="POST") - - if self.hostname in res.read(): - return True - else: - return False + res = self.do_request(self.endpoint, payload=json.dumps({"cmd": "list host"}), headers=self.header, method="POST") + return self.hostname in res.read() def stack_sync(self): - self.do_request(self.module, self.endpoint, payload=json.dumps({"cmd": "sync config"}), headers=self.header, method="POST") - self.do_request(self.module, self.endpoint, payload=json.dumps({"cmd": "sync host config"}), headers=self.header, method="POST") + self.do_request(self.endpoint, payload=json.dumps({"cmd": "sync config"}), headers=self.header, method="POST") + self.do_request(self.endpoint, payload=json.dumps({"cmd": "sync host config"}), headers=self.header, method="POST") def stack_force_install(self, result): - data = dict() - changed = False - - data['cmd'] = "set host boot {0} action=install" \ - .format(self.hostname) - self.do_request(self.module, self.endpoint, payload=json.dumps(data), headers=self.header, method="POST") + data = {'cmd': "set host boot {0} action=install".format(self.hostname)} + self.do_request(self.endpoint, payload=json.dumps(data), headers=self.header, method="POST") changed = True self.stack_sync() @@ -203,7 +220,7 @@ class StackiHost(object): data['cmd'] = "add host {0} rack={1} rank={2} appliance={3}"\ .format(self.hostname, self.rack, self.rank, self.appliance) - self.do_request(self.module, self.endpoint, payload=json.dumps(data), headers=self.header, method="POST") + self.do_request(self.endpoint, payload=json.dumps(data), headers=self.header, method="POST") self.stack_sync() @@ -215,7 +232,7 @@ class StackiHost(object): data['cmd'] = "remove host {0}"\ .format(self.hostname) - self.do_request(self.module, self.endpoint, payload=json.dumps(data), headers=self.header, method="POST") + self.do_request(self.endpoint, payload=json.dumps(data), headers=self.header, method="POST") self.stack_sync() @@ -258,8 +275,7 @@ def main(): .format(module.params['name']) # Otherwise, state is present, but host doesn't exists, require more params to add host elif module.params['state'] == 'present' and not host_exists: - for param in ['appliance', 'prim_intf', - 'prim_intf_ip', 'network', 'prim_intf_mac']: + for param in ['appliance', 'rack', 'rank', 'prim_intf', 'prim_intf_ip', 'network', 'prim_intf_mac']: if not module.params[param]: missing_params.append(param) if len(missing_params) > 0: # @FIXME replace with required_if diff --git a/tests/sanity/ignore-2.10.txt b/tests/sanity/ignore-2.10.txt index 24caa4199d..d4ab945043 100644 --- a/tests/sanity/ignore-2.10.txt +++ b/tests/sanity/ignore-2.10.txt @@ -48,9 +48,6 @@ plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:undocumented-parameter # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_tags.py validate-modules:parameter-state-invalid-choice -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:doc-default-does-not-match-spec -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:parameter-type-not-in-doc -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:undocumented-parameter plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-invalid plugins/modules/system/gconftool2.py validate-modules:parameter-state-invalid-choice plugins/modules/system/iptables_state.py validate-modules:undocumented-parameter diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index b5f0a66859..9795211211 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -47,9 +47,6 @@ plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:undocumented-parameter # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_tags.py validate-modules:parameter-state-invalid-choice -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:doc-default-does-not-match-spec -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:parameter-type-not-in-doc -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:undocumented-parameter plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-invalid plugins/modules/system/gconftool2.py validate-modules:parameter-state-invalid-choice plugins/modules/system/iptables_state.py validate-modules:undocumented-parameter diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index bde8427875..efa12cda04 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -47,9 +47,6 @@ plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:undocumented-parameter # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_tags.py validate-modules:parameter-state-invalid-choice -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:doc-default-does-not-match-spec -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:parameter-type-not-in-doc -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:undocumented-parameter plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-invalid plugins/modules/system/gconftool2.py validate-modules:parameter-state-invalid-choice plugins/modules/system/iptables_state.py validate-modules:undocumented-parameter diff --git a/tests/sanity/ignore-2.9.txt b/tests/sanity/ignore-2.9.txt index 569afe1207..e00cee8b52 100644 --- a/tests/sanity/ignore-2.9.txt +++ b/tests/sanity/ignore-2.9.txt @@ -38,9 +38,6 @@ plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:doc-missing-type # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:parameter-type-not-in-doc # missing docs on suboptions plugins/modules/remote_management/manageiq/manageiq_provider.py validate-modules:undocumented-parameter # missing docs on suboptions -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:doc-default-does-not-match-spec -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:parameter-type-not-in-doc -plugins/modules/remote_management/stacki/stacki_host.py validate-modules:undocumented-parameter plugins/modules/net_tools/nios/nios_a_record.py validate-modules:deprecation-mismatch plugins/modules/net_tools/nios/nios_a_record.py validate-modules:invalid-documentation plugins/modules/net_tools/nios/nios_aaaa_record.py validate-modules:deprecation-mismatch From 46781d9fd17b62b4b0c0bc7ab2daafdca57170bd Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 7 Jun 2021 13:27:30 +0200 Subject: [PATCH 129/139] [PR #2731/6a41fba2 backport][stable-3] ModuleHelper - also uses LC_ALL to force language (#2736) * ModuleHelper - also uses LC_ALL to force language (#2731) * also uses LC_ALL to force language * adjusted test_xfconf and test_cpanm * added changelog fragment * Update changelogs/fragments/2731-mh-cmd-locale.yml Co-authored-by: Felix Fontein * adjusted chglog frag per PR Co-authored-by: Felix Fontein (cherry picked from commit 6a41fba2f89c4b2f0d63b5b3b34b5b649101dde1) * snap revamp hasn't been backported yet. Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> Co-authored-by: Felix Fontein --- changelogs/fragments/2731-mh-cmd-locale.yml | 4 +++ plugins/module_utils/mh/mixins/cmd.py | 9 ++++-- .../modules/packaging/language/test_cpanm.py | 26 ++++++++-------- .../plugins/modules/system/test_xfconf.py | 30 +++++++++---------- 4 files changed, 38 insertions(+), 31 deletions(-) create mode 100644 changelogs/fragments/2731-mh-cmd-locale.yml diff --git a/changelogs/fragments/2731-mh-cmd-locale.yml b/changelogs/fragments/2731-mh-cmd-locale.yml new file mode 100644 index 0000000000..b917493f4c --- /dev/null +++ b/changelogs/fragments/2731-mh-cmd-locale.yml @@ -0,0 +1,4 @@ +bugfixes: + - module_helper module utils - ``CmdMixin`` must also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/pull/2731). + - xfconf - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/issues/2715). + - cpanm - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/pull/2731). diff --git a/plugins/module_utils/mh/mixins/cmd.py b/plugins/module_utils/mh/mixins/cmd.py index 724708868e..0367b6173c 100644 --- a/plugins/module_utils/mh/mixins/cmd.py +++ b/plugins/module_utils/mh/mixins/cmd.py @@ -155,13 +155,16 @@ class CmdMixin(object): def run_command(self, extra_params=None, params=None, process_output=None, *args, **kwargs): self.vars.cmd_args = self._calculate_args(extra_params, params) options = dict(self.run_command_fixed_options) - env_update = dict(options.get('environ_update', {})) options['check_rc'] = options.get('check_rc', self.check_rc) + options.update(kwargs) + env_update = dict(options.get('environ_update', {})) if self.force_lang: - env_update.update({'LANGUAGE': self.force_lang}) + env_update.update({ + 'LANGUAGE': self.force_lang, + 'LC_ALL': self.force_lang, + }) self.update_output(force_lang=self.force_lang) options['environ_update'] = env_update - options.update(kwargs) rc, out, err = self.module.run_command(self.vars.cmd_args, *args, **options) self.update_output(rc=rc, stdout=out, stderr=err) if process_output is None: diff --git a/tests/unit/plugins/modules/packaging/language/test_cpanm.py b/tests/unit/plugins/modules/packaging/language/test_cpanm.py index fd52fc1cc9..10a2955019 100644 --- a/tests/unit/plugins/modules/packaging/language/test_cpanm.py +++ b/tests/unit/plugins/modules/packaging/language/test_cpanm.py @@ -38,7 +38,7 @@ TEST_CASES = [ ), ( ['/testbin/cpanm', 'Dancer'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err ), ], @@ -65,7 +65,7 @@ TEST_CASES = [ 'id': 'install_dancer', 'run_command.calls': [( ['/testbin/cpanm', 'Dancer'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -77,7 +77,7 @@ TEST_CASES = [ 'id': 'install_distribution_file_compatibility', 'run_command.calls': [( ['/testbin/cpanm', 'MIYAGAWA/Plack-0.99_05.tar.gz'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -89,7 +89,7 @@ TEST_CASES = [ 'id': 'install_distribution_file', 'run_command.calls': [( ['/testbin/cpanm', 'MIYAGAWA/Plack-0.99_05.tar.gz'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -101,7 +101,7 @@ TEST_CASES = [ 'id': 'install_into_locallib', 'run_command.calls': [( ['/testbin/cpanm', '--local-lib', '/srv/webapps/my_app/extlib', 'Dancer'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -113,7 +113,7 @@ TEST_CASES = [ 'id': 'install_from_local_directory', 'run_command.calls': [( ['/testbin/cpanm', '/srv/webapps/my_app/src/'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -125,7 +125,7 @@ TEST_CASES = [ 'id': 'install_into_locallib_no_unit_testing', 'run_command.calls': [( ['/testbin/cpanm', '--notest', '--local-lib', '/srv/webapps/my_app/extlib', 'Dancer'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -137,7 +137,7 @@ TEST_CASES = [ 'id': 'install_from_mirror', 'run_command.calls': [( ['/testbin/cpanm', '--mirror', 'http://cpan.cpantesters.org/', 'Dancer'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -158,7 +158,7 @@ TEST_CASES = [ 'id': 'install_minversion_implicit', 'run_command.calls': [( ['/testbin/cpanm', 'Dancer~1.0'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -170,7 +170,7 @@ TEST_CASES = [ 'id': 'install_minversion_explicit', 'run_command.calls': [( ['/testbin/cpanm', 'Dancer~1.5'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -182,7 +182,7 @@ TEST_CASES = [ 'id': 'install_specific_version', 'run_command.calls': [( ['/testbin/cpanm', 'Dancer@1.7'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -215,7 +215,7 @@ TEST_CASES = [ 'id': 'install_specific_version_from_git_url_explicit', 'run_command.calls': [( ['/testbin/cpanm', 'git://github.com/plack/Plack.git@1.7'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, @@ -228,7 +228,7 @@ TEST_CASES = [ 'id': 'install_specific_version_from_git_url_implicit', 'run_command.calls': [( ['/testbin/cpanm', 'git://github.com/plack/Plack.git@2.5'], - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': True}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': True}, (0, '', '',), # output rc, out, err )], 'changed': True, diff --git a/tests/unit/plugins/modules/system/test_xfconf.py b/tests/unit/plugins/modules/system/test_xfconf.py index dee387bd7d..d8c9a30a9a 100644 --- a/tests/unit/plugins/modules/system/test_xfconf.py +++ b/tests/unit/plugins/modules/system/test_xfconf.py @@ -49,7 +49,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '100\n', '',), ), @@ -69,7 +69,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/i_dont_exist'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (1, '', 'Property "/general/i_dont_exist" does not exist on channel "xfwm4".\n',), ), @@ -89,7 +89,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, 'Value is an array with 3 items:\n\nMain\nWork\nTmp\n', '',), ), @@ -109,7 +109,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/use_compositing'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, 'true', '',), ), @@ -129,7 +129,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/use_compositing'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, 'false', '',), ), @@ -155,7 +155,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '100\n', '',), ), @@ -164,7 +164,7 @@ TEST_CASES = [ ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity', '--create', '--type', 'int', '--set', '90'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '', '',), ), @@ -190,7 +190,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '90\n', '',), ), @@ -199,7 +199,7 @@ TEST_CASES = [ ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/inactive_opacity', '--create', '--type', 'int', '--set', '90'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '', '',), ), @@ -225,7 +225,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, 'Value is an array with 3 items:\n\nMain\nWork\nTmp\n', '',), ), @@ -235,7 +235,7 @@ TEST_CASES = [ '--create', '--force-array', '--type', 'string', '--set', 'A', '--type', 'string', '--set', 'B', '--type', 'string', '--set', 'C'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '', '',), ), @@ -261,7 +261,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, 'Value is an array with 3 items:\n\nA\nB\nC\n', '',), ), @@ -271,7 +271,7 @@ TEST_CASES = [ '--create', '--force-array', '--type', 'string', '--set', 'A', '--type', 'string', '--set', 'B', '--type', 'string', '--set', 'C'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '', '',), ), @@ -295,7 +295,7 @@ TEST_CASES = [ # Calling of following command will be asserted ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, 'Value is an array with 3 items:\n\nA\nB\nC\n', '',), ), @@ -304,7 +304,7 @@ TEST_CASES = [ ['/testbin/xfconf-query', '--channel', 'xfwm4', '--property', '/general/workspace_names', '--reset'], # Was return code checked? - {'environ_update': {'LANGUAGE': 'C'}, 'check_rc': False}, + {'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False}, # Mock of returned code, stdout and stderr (0, '', '',), ), From 55682c52dfe0e788caea9d58e21339f736cb8864 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 7 Jun 2021 16:01:30 +0200 Subject: [PATCH 130/139] Add aminvakil to committers (#2739) (#2742) (cherry picked from commit 1e34df7ca05c729b29dd27d45d1fa68b0bc87640) Co-authored-by: Amin Vakil --- commit-rights.md | 1 + 1 file changed, 1 insertion(+) diff --git a/commit-rights.md b/commit-rights.md index d10bea9af7..7aae8617fb 100644 --- a/commit-rights.md +++ b/commit-rights.md @@ -67,6 +67,7 @@ Individuals who have been asked to become a part of this group have generally be | Name | GitHub ID | IRC Nick | Other | | ------------------- | -------------------- | ------------------ | -------------------- | +| Amin Vakil | aminvakil | aminvakil | | | Andrew Klychkov | andersson007 | andersson007_ | | | Felix Fontein | felixfontein | felixfontein | | | John R Barker | gundalow | gundalow | | From d25352dc06e0604259130c33f1d6b44b148c0473 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 7 Jun 2021 17:02:17 +0200 Subject: [PATCH 131/139] Remove aminvakil from supershipit section as it is not needed anymore (#2743) (#2746) (cherry picked from commit 7c3f2ae4af4d3d16f6c9ef58d5eab499499ee7c9) Co-authored-by: Amin Vakil --- .github/BOTMETA.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 74b53db418..6727373e85 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -1,7 +1,7 @@ automerge: true files: plugins/: - supershipit: aminvakil russoz + supershipit: russoz changelogs/fragments/: support: community $actions: From 42a1318fe309f321fec1f0c11571b14c582f43fc Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 7 Jun 2021 21:39:17 +0200 Subject: [PATCH 132/139] Re-enable flatpak_remote tests (#2747) (#2749) * Automate test repo creation, re-enable flatpak_remote tests. * Linting. * Another try. (cherry picked from commit 4c50f1add7e23b231afe6b80c8536ab4427b4005) Co-authored-by: Felix Fontein --- .../targets/flatpak_remote/aliases | 1 - .../setup_flatpak_remote/create-repo.sh | 51 ++++++++++++++++++ .../setup_flatpak_remote/files/repo.tar.xz | Bin 15496 -> 5524 bytes 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100755 tests/integration/targets/setup_flatpak_remote/create-repo.sh diff --git a/tests/integration/targets/flatpak_remote/aliases b/tests/integration/targets/flatpak_remote/aliases index 3623baa5c2..39291d435b 100644 --- a/tests/integration/targets/flatpak_remote/aliases +++ b/tests/integration/targets/flatpak_remote/aliases @@ -6,4 +6,3 @@ skip/osx skip/macos skip/rhel needs/root -disabled # FIXME diff --git a/tests/integration/targets/setup_flatpak_remote/create-repo.sh b/tests/integration/targets/setup_flatpak_remote/create-repo.sh new file mode 100755 index 0000000000..1b09bb7956 --- /dev/null +++ b/tests/integration/targets/setup_flatpak_remote/create-repo.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +set -eux + +flatpak install -y --system flathub org.freedesktop.Platform//1.6 org.freedesktop.Sdk//1.6 + +echo $'#!/bin/sh\necho hello world' > hello.sh + +export NUM=1 +flatpak build-init appdir$NUM com.dummy.App$NUM org.freedesktop.Sdk org.freedesktop.Platform 1.6; +flatpak build appdir$NUM mkdir /app/bin; +flatpak build appdir$NUM install --mode=750 hello.sh /app/bin; +flatpak build-finish --command=hello.sh appdir$NUM + +flatpak build-export repo appdir$NUM stable + +mkdir -p gpg +chmod 0700 gpg +gpg --homedir gpg --batch --passphrase '' --quick-gen-key test@dummy.com future-default default 10y + +KEY_ID=$(gpg --homedir=gpg --list-keys --with-colons test@dummy.com | grep fpr: | head -1 | cut -d ':' -f 10) + +gpg --homedir=gpg --export "${KEY_ID}" > dummy-repo.gpg + +BASE64_PUBLIC_KEY=$(base64 dummy-repo.gpg | tr -d '\n') + +cat > repo/com.dummy.App1.flatpakref < repo/dummy-repo.flatpakrepo <IAKH+ooF000E$*0e?f03iVu0001VFXf})@BbB4T>v>5N@un}Hi1L#y~)Z- z{84!W3f)Esb7jq5>fDNTXAtbJtFLh#1{z_@XdBbYO#I_6ejX}{k|qPV5*F#tV*(KZ z&8y&v@-_@%O$~^*VQ2&(ntw~=X4{`14ln0V8gAs7B)fP}6FAt~Kb*`}cin_F`PjKM z=gDE4I1`vmQzegt`_V-)uy0DRn8>u3#F{_S@Q?#j3Pf@d^@SuYQthQu*4bx}Wxgr^ zpzQnk7-!^ooWgD}Y<{Z)25({OuU|9(2RU`Q#t(Nms*UWhQUf?8R&lYuSf-byBX0K8 z^I}P z;jsPqKwt(94>NX^omDYN6iLjF8^%Fq74AggLtsy+E4;4W#LVx|OUJ_~rkBr=I9G`S z-`lF>zkaJh8c8uPIv7!1R#=VKn4$v5FVtOAT~e-|DG}P7pu?u zg2?4<^6J^x4!h7r^PhZef;GY0o&cgx`7rh$+7fCPFWMF3s{tZp9=q<`0M;3wj#_1g zy)AF_+45$2ZeN7&sq;gF7CAoR3TC{{A3kUkG`e@pmB_i|#|gx}R%AMZmCD*tQpM$A zmFmu|SZA0^w?;w2^J#7(!b+rZ$z`H1_w}(oKbr6?5#;6I*|C;sURHR-b#HK0GgHwl zWlO4wdEbX1D|5Dcj7=Qurtcf#d@UCH2{rv6(9o2ArZcO^C#+^h0?!I+spQj?8~88n z&E4e>R8^&N7+DMiqM6PD31Wv0giL;`XN??_@^TLV4hsB_WSOq_+c>H2$Dzqflv>9< zh9V#;-2)ZRNP$CY1HLx8Cx$ODMd$i>V~Lai-_=C*H-nB$WV7w4_|_RdZxY=@`)PU9 zGU-R&Fm5PR*l=QSUedJi+q~F%qp&wRE~3tnSu#;tV>1kSB#HCAD|;^tLzOsOObfGC zxl)v7r8Kf`JlpPMyfI81Mv@JKh+8vmq_9c@{#q=-N;#Y-+4)mJ77tr#mrvm(XFmSP zG`G5J9L|fhqonikigA&LzgIIzkD0JRwG!tEUQDZ}LZ|#5Ual6Xaun6M+(HDC&+jiB zxRa*KG2+)q*k=l9wu2EZW|NN;6w^HoI>w-V*1+BB&9amec?NGnkvXq>&?V<0S79xs zE);IWKN6$<=AHej%3g*(e+_xcmwPhy$}qM#E#@F{P)$5H9+(}YyEW0ZG;nQX00+iN zlwO}I{>mXc^=^Y1-~obpGtoH%Sg8VHbMnK%bcKXdHdNlomWIl)pzNw;A8lK?zqCL$ zNtth-_+Epfbrx87EX;Qr527&3oF#4}aE}OWga@2=Ygo`4h3Y^~>!X^knst8lFS%W5 z22|-1!ABSJyfe!9gP2T9@aCFHh_E-a`8#UE-nKN8K4Lw8PgF5GHLGhpl%DwU3GWAP zb)mCUGrJ1spZEsCe>(_RS+yylRnFv0&(HZPqRJiW{T9=KHLS>_%NoQ>AjypKmy>(K zStvuAI*Zm{SABkrITglicDPv7B=GyQ>NkIV*#NS+VqdSyXmh*i{Giej9qux%*V4!v z04}f5;K6g%G(3;;FrbnT{Vlj~6@tey6YDC&(V_B1$QFNs87L<@XGuRxb z-rW@&t@xrgkZjqx%OVI!>_M>rt9_fwcs-qXQM@YqO~2H@>&AFrl^o0=9KMF&+7hz8 zm9Z0~y=WvtQFC@A4HYGmx0;`V`j zTBirBrULceJufTw9S0oQrlQkQqL4U~0>5<_BHQxuNcybgxl+KdM;RrG>B_c1s)bSoOGy?7`dzpWg+m83c_Bfe}_G zs~{p8wWo+@hwfLuI(xH@T?B%SsJ~n@;DL)@45ldz@biq=qp>{HHsq0s`InRO9bUdOPHf1S(2GBdtU}U`lXj+^OaaJ0#?cIX zz`a_1oZoGHeOnV%cz?|}Ux!?f|BWlg`mh%HY&oR|SzSM*%ToXmZz^C-H2~|!G3&`d zCzie=S>qD)_I?rZJ#|kd6V&+zn{H`5&L{S%Bod&aajrBb!)rj#Xs~5!G zp(wBu%!MMS?AkiP;grvxR|8?)kmt33Ks3^UqR*k(HGaA1apho-VQ-xRYL`*9PsVQ* zgU=Tzp-Ab0@PL%xh?tv)VOvoR%C=YDQrO`Fh~-V^Gg1Am90nf<$hXh$Mj&A`=pj>y zBXH6u+B1j{O~Vxn)sMPc8YQ5@K?48f!TheWcJnpl#Kdl+zNEIal0C0Xxx*ay&BGTt zvJv?!ox`mJ2UfORJJr84*kW2)s;aizuM35WS7&vHCw{<)N>KpncOw%vC$e2I!T>HE z;hHcWk1BUPTsSh_eym-mFuSvZaS;o`j@#x|qz6gkPwEso`$pi&OqTtHJNMOyPYOY38xFB-B}fwBm;0_?4Ml@bxI6QfTp>DJr-^F%|W_ z$-Wlx_;e(f1)dO8QR&45;N*QG-c)lB-2)7qR9vsd*c(}Yp@Jf2nV38Y3W=}J^`9Xj z4^|H>om2DJ(AfpN96L<`CEV)e(`iQ>DemWjW z?#hsDws>z8($(!8fOwYzV|Q^~@ixxn#8TOMTj;{`7Ldq?z2;shLNYtuY?zsJ`8tJ>aXJ5j0S z95)Rb9qy4F`v;^O_Y)*9M+qOq=lX`2v?C+SZkuxNydCv@w$`OWJH43g%4!lk& zNEo2_0s;9TWv_KVzRWhB2Ntq-Xo$j9DB{AwI_{ac@FK$0Qjp|iDZC6+DAFbO-q&!W z9JWT6;p*bW#@Cmiceiq%R)QY|FOBs#3++h4b*o)4u*L^zDzolJbHB(k0dE3?6_-O% z7-;9MqjJs?r_{nm`Ve6AxTvebCYENAxyCW){#(NeH}OZa`;g1*+bVLLFzAHB|D-Bn z!&(K|XeU~^-&Y{a#(j+58(5j~ zLjy#sI4fG4xQ^X_kbH@F#sn}1!;X)2ykHi9Jc;`A34k%vE14LeTJF{G!4Ji4?=wR- z)zjB5K8bajhY%D+T|1S3fN#zt-?FPFOh}pCVrr6 zLTI^gc?vM+d%#YhHQbeZxy-NXZF;C!_oRTgHKSK$Q_i#ex>VZ#>|sc?EPYD?LI#1E zcN(_#74PgUZ)dY`{>3M{@8q@Kp?k1FwB^2l;-~(+A!BfIC4r|?y~l9}juyA2H!gXc zTrJt&h767*t{P?16$BU?g@U+X4XU622arWnyi9bWh1h~F4bjM%yWc*SR0g^_L0|Cx zry_hh3|iWe>UOV_PGS-w!U{Qou~SgKg3phkt06Pe&Z(lGvJ0%rrEzd8*_N{U-7w?m zGE%LF={|x#?(XU5_u{|zRAPuBYDdOfd9~rXcTN2OtliPE$`jdGDLDNHbzXBzGh
  • hitUvXK$sVWTuHQ4`ZdY6WW&L~ zYrr|UGRP5;Nk&K=A2@&o4^{3P!YbP$DR$8*fgz^$Sh1*c?`S(CY4dUUb9om`0^=(hr*Ce&t{Yz$ihlP(i21%ghcqYblmS!V)?*#g4GUc%yqbWw{q1EfU96 zdoUIg(;!t*YXS&P+ETGQ7(}uXNHx5qNdp#Hx)B2o6bgEIb#`ISwH203$fl`Qb1*w8`e`gB{_gynce{ znS8HH0?~yJro9En)?SFWZJC*b%Fvhh%OB7QjMOL9w*(-bFv?tLYogb}Jp6=hzY5rX z?7M`G$X;7JH)FIV&1&Brw(oot0Q^U?K2zJyz&+smc9-F6oS63gQp=36sY*D2xWZ>F zg7$w^{|SQy1o?Y9o%?D!Zix2U>s==f$i}meb-24lJQC*VpKu^3`Q#_GFkN(MW!Ybh z;=JF10DQ1ofCk~}{axu`@Q7TW6SP*i3jw6T*A{*zTwokFZi`oMbVj<_)}Xk36vi|x zKnsnf&pCxuvj;dc=59GwcagEJ9;;#uXs%TpKp+N?lF=RGED=EWet5#4$fiA|z_#p* zDDs0^=ISWtn=}DH7UbDn&`)$%x{t08%}FrW$b4G@9?{mEu~b~p4^r>ZL4+O<^Q zmWlBiQw+J1h|j%WUg;L-5wgiJ=nm)iEM>W06V*1yVI7rY^~0x~&!d=3nUl{gI4{MV zz{aoZ3`dP7q7{j+#B8hwedfY5r-n7`N8l4_12d1GeXQ!~GIK_)wTC0@6?g-b`B|lq2bG-zEloEM#*Y&L z>iQ{;vHn+)Q5IkmswrfxFf>0Hcf5c;#lq`U5DK5@QZ$xL_P)KksR+k449)S}RcT`3 zJ55QKuecH|_`LmTb$1nrdBjsKYJ>X?1=~Ldqaj@_k1A{!`qcnM9DxOzRjRZ$Gue$^ zKz)<LSF(d)Q0N`7h)2otJhEf+5ejV9Whz*;U%qDS zt!lPdMwT3{&pgHhh*}cnO$VoLYDLG;dkBFazn;HN^G=pPX|&& z`V(cM@h`Phy4B$m(G{apx$P@({_U4>E8Y>2+M)c?uO87t{wifMT1UloIoWeD)hB^= zFO2o1-z8`^O=PW1lyG$kt+EBo`AjbCs_N9QhRkW7K73AO-T6XVHPpVHeb~JhW0qKr zRkaP0XpQac_8d48VgHO4$-X_c9oM4h=WMmwCp|UYRHi0LK4F8HR3BA*>6ZsKZEFaZ zI7@6sqGB1x`6Wk^m6RgWy?l5DIu#0YJL&LVd*Ek_H_O;4Duo=^hH*OpHLstavsX5} za)|yUF{mUbR2do&rEK2-YWR4}6Mrn_q{3&RJ6g4PG_!pp#H3S$7x^y%nWeZw;Mwxy z2>Wa#Q((X*uxZKtlj?bxGlD>XMSo{^(n(q=)p#hSiN?stSFuvg!%px*vF-_oWE7_& z=^fo<7l_9=OvK$LGdGZO=<4tiGJ}tGYA4JSz{JLVGcm%62fajWhb+`0Ezbw+2uDZ_ z=`6RLzWT#dX3gKoYE$EXm_JK_!mwVwBN=!?H?4++G9*&csKyne*_VwXSq9#E1~s~F zMIi85_ukPN(T+_}kR2-9k#W*;r8n|SyDzP+b{?0njVMSb!wV%(ZkHTv2`vCv>5N@un}Hi1L#v;q3XE)^E@g)ZgXNF&=H-HakA{z?!OsX)+L=0K`5`#q1FO)| z@QO`e$oR3lw&+4zR2Fe{GDco>H`7iqBNOnV7teHb6Cx<1 z>&?~pmcoQ>3F1}g!1ago(bX6G(FrG%P8{pcIOF-xo_l?yTiKNM7as!Z8&PN*zkoZq zRfv_0BOT6xNqO-DT)?XgX3Hr_afav-8UCX=pDeZvpS|y&_CbTSHU3^Mqu{K#a#T6B zv6qsHt`nNV3v_vf;%pW}b!CM?r~+(D)v~F9oL?c;AfhZla*q}_51k=3T8I~`bTg%q zB8Kw8JEF&~hK1yEGLS)MA$U>hBkH(#$p@zHr(tIo4f4p(AUZr!-1T8dJ5)$~AOI4r zW9^M9Qbgeb_ObTL4>f^sT0QmORdL|eGO$f(AFS?hN}lrs!|di&@vdDFno_+LqVea_ zr24t2x`|&>OC*)UIpfkJ%B`zTXWW9(VXi_gpeU}!?f}HsU$nngar$hOm6pVc%&!J1 z9vRkQ8Reqem-8mN(8FcoeDU5o(r?#OxjYBWacRXpj@BCAm0`_+0xhih(lbAY0_>FrNoa!%Df448ZQtUTI1G zXP&^XUT(}}D4Bg&%o!w<3O;RX+K1vM*q>JNIkO#s>fbT0hOL>_+VvLdb@pRvfC~c0?)kd59 zQ73a#H&@Rp|1;IYrLP=M82GE~c3EK9#S)~Djz>cMMeKc_ti8U@N`4(bt+(`0K#$KfJ|F$RC*=F+UB9Zsl z0n2|(7&YcQrLmkoNj`IOMofpTqLLL4=%Az;>ZQ( zYe8(VMEZua0oT@ihvqxv9xyr1zV)G|ky;0D02OPp@;hNt(h2xA?o02Z7rP(F*SH>% zQ4AwTZU^hAa_i{ah31bJ#IXysyY zX@>R#q*el}uUGBnRDsxzPW?fn2*H}VhLGt6bVL!~I;<#U={?)k!3XVQJM2QTJ}>j_ zU%cL^u9hB{=(Nu{sfQ3Vk`+RE6-9m1AgK`Q&;#%X?R_k|IiFKkp2=h9J*e2GiBvbB8?K2D z1614QF6@zGK^exO1Tx?MKzw2)qZU{dbRUsctI>`t6_y;-k#zlzXs^VLmU9O^kCOT` z-djjy<~z1`sgr|vL*Q`}@RL3t6pJeLi1Et0Pt8?(v+gRg~a7DHw^sxW&V8sffy zM$03@D=5FP#{27Qs|dj39B1$2C!}G$BW^pqpqE<}xDax$wJ>%Wti4kahv0}u(G=Z5 z^AEH}i*F0OMCq7Q@M$xVocH%0m@ zlQA0~IcF16`Rz33DTpycuj+>*Z8!%dL&H207h ziRTl7xfSN?D!?6fGiDIJ`-}M{Z^=QF0hwtxuJbswYImvEb`^O>0`Ln(TJW#Szp>#T z3@RwV6K|SdpsdGYcJF&`E6<2$%UVqPmA<^&dF!$(@R=b-ZsH&VkBs^5Bn1_rmmf2Y zGE|JT>%^v~DwTc_v!MMm5r@b&8sc-fpE^nQssvZ$+NL_QK&d0XQ;^>Lc1$gki???{YOC z0+m_yqN54p5G3sQ=@5DU^K>FH7^x!+5m;DUzVyj`LDv*Me_97$P8k>! z_fI2iVgXe?5!Jt=c9*>zG0s~cU)BP+mc*D7@jX~u)tzlC3||n)E!*&Ez8rob2Te*+ zMUhZ2*}+Clxnwl`bj6z5q*=5^pIa;9dG{Yp%uLG)>~utH!dI5NFq#o5*|5n-%w38{<5cU$J;*F_3vz*s{x%%g zh{gF|46k^2Gu1!qdfT>lCrhhYk%Qn{rc>MQBp}SL*5iw0yeBwKKM1ffNYh~*l5Svl z#+4J76h@8_k|X75=IL31->W}0-v!th*Jb7wE;~B{r?N=7dwesU1p6|*^>Rr&0b7c^ zs8Dt}1edPcwzfkL>9*Q(mc)r_f39f#-xqn%F$iHaHJle3df?^cj!;4;!Z|(Z)PHN! zSXOMsvjI+t5|f?w99Xi{`N+4$t4ikr*2d5JvAmQB1+TNRhFXH|b_vdf233{!jb;sx zBD4x3>pWRQ&5LtkXMUDmk7EG@HDxJ42d1IB{In~H4l5}I&ssd`l7!Q9I4$dc znM}Q*I%DQ``Ipnj_Y^h!|7{|iAyy=5VI(4yL+_ldy)pnbZO5GXxlqdTeV-|!?mKBM z0f+AK*G$x!h4eipvk-r4gsl|F*vHsEiu&N0i6wtCJl@ik{Dh=N3FfNSA2 zGg4mmpM)X$DDQ>%gEY4gB+B&YG)sK#d4hS*av}5!ApJ;H7C6V|cuSs_rOgWCaV=t~ z#22B9k(a93vaA@QmD~A@#|MaPNWS30<=>Yn$(hzu=kF$qvNm?NO399rdp&anluXtO z0oSFyYz!ynhAWIFV{z+sFaB$6RGj)xJ0>$S6=A9}ND&-9--(;xbL~XD|I^G05Nssn z0QG)?#18%gRglqJL8E_3djb~Ky$3&*t_o#MXBu2`m^IQ_v7?bN14_Pe;@Lp+I-E;- z;~nMJIDSFn91WL4@-Gd6hAk}W2J&tZ>Qys-uN-U!%E8j&fN7>ynONqb>~4V4BdZ5* z%@5HDs*E~b(m0p zD#0A`ulh&`IY$E?eit<9_{-hKV-`gWEbs0@E33^#NTLugR9>mQxxFM_7^)J%$^R6o z?_M7A9D&i(c*+u-oH*as}OxEpu}Re90Jm~Ik4JF<*b`- zVlV*e;$-7?))>>%=0Q@5h7peKoa^z2rz!5h=D2K2X2%@*EypQByNl*b6o}4hFo9N9 z1(hR5dqsE^*oO<8Yt^iwucNLIVL=m_$Y>1{r-XM9lt%iE^hi4OTa(@`&8+BXnA|D~ zhB6J%@*=84I+t3&jh7o!|`Q&T0@`EfAdckB_L(B8u-yB}BsoHlL5GKDH z&It#hf9aAai%sp`w<#P zINaytsen+?N^`hHyw7d3giPZ#%%9<^_J{ho7PO zM?(FZ+_embuWRqUpcFzkYpf?CI2g~pmoWhBUNH)f8~+5&KUKM0t9fhh!ng{yRpnKS z)Nz)bH6VnJnaF&#BZ9@_8CK?dcgM~#54aTIV<%C!D7{}JbERouYhYR3iX-oj9j@Z%y+HBZ3$Y;*~Df0Yw8Aa6YQKkWmFgLv^1C|SD z9*CR^4RDxiL)u1&Q9p0kfgbzwJmZjbnRfzowtMOUzR6ry?KbJSYf2NbVL!GWtD5>x~R<VX`x9O(VS|DT;|;T-J-4VbSzW$d4%2+tblhJV>%q&@7ndFS%9kf7l^8L;Hxt3iiv}O^%^Mb}N8svo19=&%%hy*Scb+mZhrZNPRR|1Z!%=)a8TZo5M$l+$OIk>DNg5@T8(>jL-a& zRWsg<&V6B1arj+9$M|xX4Ac>ThMWVT>NAqjcs7QTBoP{5`A{TCEh2$+F4_?_@`NjxeEoWj36_{ z7)7U%pqrDd!)7cTTSbY9+z!WW=Lp-Gk3XnlIH6odYS0H5ynLZIlW*>DID?TkavR)x zfomB9Qk^my_G1bZ_eND*R1Jy}OOL-?m^1y&c1{bB%eE=9(>B1f6j~lrhTN119bAQc z*PS!l@AHTsM|;Gq^t9if5}2$cms|_KQCJNtMHHx=@smY0R$cs!rhT3bt8$b+Vz`4M zSmvX2cKl|j2a(@t{?+FHW?HU^OVO1H-Z$FM+ZX%>=XeX4h!t8@7czO&DQ$4sr`dy1bGh!c4Mh4?OcHbf?syRI4Ppw~&EH|{ z)L)gyiI{8OuGd0RRFBo{z7=w$9R;hjY)H;Mk^Y!!>Z=Ze{DZGNmy+_dLv4MUm5OTe z7)Md_54xnp?e%GEll{izT4EM#op(^O%njvp?=?M(Bi4sjpt&w3ZBxy=28GU!y;GKlUZIIwz zJ;6CSrhzKA2CfEd*Ft;jDM#%GIwgEoZXI=c*xo@^{^WtmKwg985;Bm7#kTw=ZG4r*?9S6n>^PHuU{?<1+pHq=jq#O&TcSVmdJ5vyG(7V5 zi$?tNiVn`M8lF2mn~pl+Elyl}>z=0fc7T|I@5{l64n_(W2B~~Irt%n`#F?|7{*y*+ z^Tgh8j-bcK4Z8@hcdnC?mF0r_w92T6KR zokNjEwz=)NVfqg%unEx(%Tc;Yl=Ofi*5QW9D9qU_6q_P^&Ilh06hhtLZKTKSYw@SP zu`K>&se;@?$nnG_z#HA8~>H(n`s47H;26MS^_Yw6@e!gt&VP!FJQe9K7gS zmKP6Z^(jpotq!kI;#wXHgpRdtVF< zaix0OMBhHsrg9cxwSy~KdAlSpJ^^~8>c`(X?cg;1L+;2Yk`aT07RnytdaOO(S7)mdxKAu(L9H_)Ma|#|5Rsf8mdt)z` z=txb^Oo{BPs-Vv+>MS1e$}%0M zoYF3N;~EWaak@txO$PqrnXD1frwP821m+Z*faKMqK>rI#^pd z=2RVDC(iVqPJq;(xF=jm!T@6T$(n&`yw@t zQwA-skbI56J;@Ec0wrle`ChI$e34)QcDPXW4tp#3eJ~uZ|JqkWK3{|Wxe*NRkIJ|i z-K!BceOoix%Hcn1kUTOL+v*c{INnNhkEg`XKJoCR&PWS?UeU2(pU-oq!6Fck+LN8)x;2} zK*g@NE1D)$SH^uj_}8%%@}{`FCIMmCA0h1%CF6e_??=UxhO+&pY6_0msRfF}QV(xA z)X2mzy!j^%h=+Gy8SrKJt&k9#GLhEYd$f)_p%3|RQ^83~*9!Jyo7?T+;*a4k;_^P9 z_rdQcu&M~2tD$uM>(P6EGlA zYQDF}xaw4@zdjXR6n~4>lGxXr=jgFm9q0jpsrGSlOK}p{G4q5QLm2JMnf0=K<>~tc zbTY_%<+HNA!_43b)aI^T^Fg9X1krde3Lf(oW#Kyq+v{$r%tZr;X>f}URnUE( zOm9G~9>KBkQG@JVV0fClr%wiBNX6-L2a#s1kh4mz(T^e%rOuXTi))yBHhFOPF~eb@ zs%kt}OTwxnQdHeTK75RrvC&mMU7>7d4!GZ)28ou(6)FbymfiSGEQoNO(Ff7qRPsAY z_v5b!UQDG$qLra!>+D=NMk@<+y=ceh+!VFMulvk04OY|RIl5`W`^Y0RgJ@VX0i>sRFR=pKe- zdg$v5PnXNux99@B34^w3V9Frhc%zv|2&6LksL*WeUN?Om2-G}St~9A4h%-$Ybr(On z6k3?jxF9W5JuOd;!dxArme&F&0kJJcLUR;jtVYhnl~Sm*9&J4Bpy<{C^d5!On^@BX zmLo7$#M$_3v!6phsm$`pe`1)J{=_0t`U3hF+9j@sHH|FD;YC-A83IarOh zPCz@FfjaP?&JdnfyX>%8o?;b4C7y-lE*u%!`y?4$Mg?nt7PRuy+9nRSs`pu=H6&FN z^^JT@J2ls$8*7k&td0oVtA-04v_PA*cRxL|uUVQ>A`5a+I2%j*d}5Za*+{OC9SPO`X_pJ>N8ZWct7vq}I>>CY`U|Uke2RcwkmhHUCQSsTdP# zvINmvtaxmP{8ONPiEkoDtvB`sQHY_HUNi_16)--TnKFG~t$|UABtM(0W4WRB69yv2 zrEg!zNfLG|tJH^S0A+|lg>UIG`=tKx`Hmg9X+y5d?(FbkC)=TUH z*si4x2w?f|1xzXqX^rg#hfu=%w37Nq@`wI?p~GxVYgk`}9JA6;TVFJSKPj2NANt>s zXQf4rSOqrdUsyq%U!R$CzQqN~`E<2Ruey-??(Dux1mw!a$^=dcSms7RFkr4~qK5q( zEELR+tUvbVxxL68=Q9h7yCCqYU63%UJJp8w8QBa0TM(vVkz{0SP0~45cY6uC8U|FU zm{(!!;8HT}6jd7d)JaQIjjD3L(0W!6hCT`G$3IO@^>-gC$nmh-WaPgxaSefP%v7(T zk(!L-YlONJ`R#7EwChKIWgQYJ+$wsqSWLU-%H5yViyGF;A zypPobv0+&($Wv=C;j$}2uQ`qK%a-EdsY7lWB3)FFo=_m~5>YYwxKh>!kTJH=6t<*y zQnlYTd7%*}>>WM3?LP>&x32pNteIP86QHv=2R>Ha^ZrdjgQa5{Jdqksgx+uez1bvCq~xV^#& zPnSuI`tfh4+kua!++u?5X-=mDUmL0 zY};2K$O&WeC5$G>A}D-QGv3f3oS++uXVlGGI9+Nu?d9eCXcfyy9BWytT*kdz3wfBIzEF>Ip4lho zlzjX?2)2zhephxrn82>esM-D25H)_h%%y(&W|YP~`>9S~gKt2$r<`$pgx)!`oUA~` zryMFD+Uu>ORffTW;Ah|#Db9}DZ>3t$JyKboSjUj}8~^2on!SEvj>rSIFd?$bt>zDP zeX1f%=HS9xvU%Tlu0<eVdz3{liS zn8le9xs!cRx|1EJX3bLGp}Y4?*!`9ErL= z#%D1|dtfuAx6E$nrvtM6)kIc#sXmnnN?Qd=1XX*r*aD#b2{04)4O$fmR4&3=$^k50 zS|_oK}~3Lhzb-^|_TG>;i3i zw#-w1Avf&Jd9GM1MtSy)`_!-aSGPE27hi@PX|_-(V`5L^`cglM{OsCGKTinEXRAv< z#ef98ReAd9RpwSUGpHXCdmz9a*rk?7$!GMCfK{esQ0^Dmd0*0YAhR+=EgsGT2`skT zbEeB6q>e=CFLK7WnhdDpIWhJq(tgDH{Nu!ZIQUa9~+8W1fNeWDl;pJEz zVRD3X(MUrp2^j6pfOss4@b&D&3IKAZCTB-XL z+n0N?ppOQ{uV+>n3am3;NA~B#RQkI&aMGT;s4b@+_-R@1F+(8iC(bl>LVY4+xho=u^AAxbxlUzNI za3dblAmnBdjh=`?)a4eHEM7YBK3tO41^6$mShn`UH(S#rj!>YyNl z4O&+Bgy~IBW`fbF4Py$|IfVxa}_kAvH#2kmk|ZBsI3Fn1LL|M zGr~9EA>eCJFq#3xtKV@#Dd%F-LDb)EzDrJOf>v2k<;DQxfZD8Xk;izi^91u5njzh! zM+C449$8v^eL-pDP+5Yau#fd>kD$na{WbC$b&Ksv`B0CA2qCS6wVCt3+}#@H_J7g_;X^8ggqQV?uwY z?!vx~v(DxE09vXAqOou_LuYf-cP6bH7-t1QUDJPrzii~jKJakfb|Iyj$T8k~!Mea^)G>Am*rK0$TH3`AZ4cY3`l*DP#^}0p&TG0FFj-QodOA^FRePlyHs#9 z6}jy8!~4eun16|-b7>(b1k);v=RU#o5_kUVn=u1S#F6Mr7jX*%tjmu7+*@gvbJYbgw+twD~?<@_Xu43rN0SH`dKZ7s&9$9GryQIK?REUdMD92B;h6JJl+Zv6Y`>iA?l6liH zn2Qj9ED0DfA+yO25FicFEu>c$An@LWCzLP2Gd;Bis`W;l$W``!_DQ>FVi=g`mK(($ zx@~ADf5hj6b!QcMf8}3mi9ac4MZ3;LlQfYd<~@M_Pt*Vw;oxJwXW62p%XTa)?)rFk zad77g5h|=nfWd$h9KBU?_>l%k%ebdKmJs3$?>LA>Mi8Z#{-kN*e4x^F{Kn2j3t$a< zevNkjt!}m;L#%BJsX8I+3y}nfLV`pxNRF-)h0lKs5GUvOA?lylO%V;$mb6 z1pdt-E#{j#RxLlmIG9Z#WiO^}^KkbLo3JB7(WQACux2y<(GP3JO0aaeK(7c0tk0Ey z!e;Gs^pt(Fgiiv~4euikh%K2K4vTdXKvAr#a!kLpcxVr8I^e*k>wg4wSFYEb5)!g|1QSt30y-}AFB+-AW12f@S0oU4Q=N>BI3Wp+REKWNxaWC#@|>5(OiRM$YJ z+5X+bE8cS@(24P*-U<_6T;?usBxZ;WrFkVk2 zUR^=W21!OszOd^GR51(nFL@9|vLJgJ-pk%|40Rn`H(LX7GSV|IQrqrN_xbAsg-@Zl z2+-tUiHCNG)w#*vtF#Qs?E)hxOi?xAovpCR|USuysIS1>igYxGG zQIz7u(Xt9y^0KhiiL6g1%#$BvuweNgKV?yS5{njxYYgfk57ZdEkLPFjJDL}T4EH+& za{Hl`+6P=F7ZFawI|spOZj9T=WD*_Md-9Q# z_BZ{1#aZ-R4qvwb)VXMPRT#1{!(C~HzgI+WiS)u|{kq40RB2UZ%ZnDQ4Kl<<0ks}o3>B1?pr=sju zg8~b8anYIol87Rh8G_V&zPHpM3|rhE zbevddhxmi{uF8IO`bflW)lMT!ZzvW@8-lAzh)bMU_w+JYEE6jUQH20znRs?2A;N?) zz~Y>9Q)_@6KtYT>GDdn2QfD`rA!VLKr463EXjB!D-}^b6y&t}8{!knko~Y7icCwt3 zSdsnk@v`56$D|eZzOx|5i6Uy89a2MSf4eJFC9wV#rGJkI2iG6Vub zRg)>$Gx)3#0iMSu`AaB|RP%E2+#o{oyU@R}EnjpVaNmEN$>c^3u4X>jGLk20m)WNa zoB(g;C2O3jlEy*vqU6>3GINj4&8xPIrt8V<$v=IVp0tv+?Q}-t{iF46>mD5EA6z8P8-$(Vf&DwWers=`4Ly<0xEDUnV?cD45E#4Yt*V5kpxL) zW+k|J!PZ99Ww;01(R;n{MqbiTpb-1a5d^DFo)lbqI?lEm-H#Mt?L|^sy<5RvUFnCn zI^9yU~`A z!C{&IYk@oj2Z?_b`yc_5a3kQT--(l-EH~sqNM9NiriyCIBPxn3$=MZIV!P6LBT)J7 zuE!c0VAb9_iquO-w!lwoW3e)kUg1IjIWeaLxm{pm!a&Qq!gDuKg}%VQS}oS&^s$_+ zWhJDx>PThuE$LyLx8mQ*{TsL1o4569O;+H15w9xdAhsOa6q{plu}MY4U#;+e%^ef9 za7NCH%G*h_1Jo^d$ri7tq%7#+ZnZEl0f2q3kPs}9e0u2=iT`Sq11++KDuh6`QtLav)MTv-s;ADAkIa;;Jv0MPJOy@CAjS z;j5-TMqbgaojyu4l!!r5nL_^aE3C?Ow2 zgF8s6zs$}bm(u?b!iuwj_#PHFuuDuU6fJbTRHZJ);)~ivr=Z==xax$cWr?MWjjMC2 z=p$D5BvJbg6|5xX`G$UsT5NQs1Z@Lhwuno_SMDZtAAX6; z462%$#v=)j*u~^Ne~*>CwwR~Sh?rt(HVk6z)BM?QKBSuP<%`oc3y{y(T&$eRB>`qW z7QFD>GTW7okA8D)Fw}uD*{IV=eWvCK1efE zlP5cFN7y$WGV$pj)lzI{a@V~ZT<`}Ni9KD?dF}SzB;*O=iJt+`D_vO{=w$aRHtGk$ zoeeYiEC}XMAV$8uh)EmlB)#V9RypW0uJdGEwlPLC3B9Xj0=$B)dM6l4ebmFD^X-lM zBkvA0!=kB{rLe2b3@!Lwy74Dn(?aip(i)?w0U~j9QSe2yg;{PT1{nkmv|BmWi%)U`QamteRv=9(IaNbei~uZ*R$MZ1B}r z^BGWkduxU}k(|7*#4^QT8Pn@;o{Av;=dwK5O_=g9#9My6z9UD41@*`X#l8ITw%Soe z$lZgSV9ZDFsZ}kSqaelMnI< z@F}HoP{69v(?(Yyc#hT(di154uTj#~k_)8vgN@pxR@2Qh77mylz4>vkvDdIHNbijc zgZxL~R=JTv2|lzdEWp@a53Ys^#c&bfb`}}02S$?ndv7q{>hZnYgaMS z$NxERzV^&-d*kMYH=vo=BqUeO9E{|JgR>1TteV9V#e>(WnCmf~Mz}Ff_^#N4dZn0l zkAoBul)*~nQAns7IinCyBaSkEV%RIeF(`MMe<>TcN_7%=!it|D;8IIy38_nH?#L;M ztG^w$9YqeP(;1Q&L$ucXg2$s|!I=@DhV}P9JxuBhpy2_Np`@2bD5GEX)VX%F%G=k&@V(#e0^FEtpd7gx3}6CQS%6^SSFeB}bK#&< zxhffwFQ9=}f2#6|sl|*LBv;>Ly{jMzZeeln@s5L>&s?o=@>|^zGL-NmxR#mDW^S>w z2@lx5$RZ9agL|9FoA0a$3!Fu&x!w+1SOC?=*pbFAhBppZsytTW#WPy6NJ|c6`bfcE zURH*>4>jvKNXl^x3^HDCoXySzAY*ucZ=+D<@vN`n)Y zA;6{4p?+=h05#Qq+RgzX)vH2ZZnFPV5!-=71{l4vlkr~_!a&FQu_KE(Y$?Z#jMw^9Yx}xoDoJ#IjtJt}6Kt$m2_t>9 zejNxZs2Q;dIrJ-y+NVrHkY+5PrN(Bnl!{mZ2DPsI)$_mpc(i%U`0GfB0iUaungn($ z0*Sly7hY`AwMN5W27}}&cRGjVdSp!7^^wl5auMIyDpr00^F8IVcCH(Q$Gb0rA$=(@ z|KXAXS8C!_;%*;Fq0J*2#hldLPyA&V0NRH}cH@O;>3(Bz@yJyp-?{X6m~^q$VYoH? zsuD+J`p(&PA{(+7Gk3bRvKp~UYh#$deJcL4Pt_=^NXE0j;1w~D5iG1tkISO*(s(0I zj|?zX1oOjNFp2oN@Vi#^6R#)s_s3Wx1$@eadQ&BI=4|Es25_~MNB~{!{<0|5|GYaV zDZ|NYlcj9xdfD`|L;<7c?CKYbNxbHB3!q`%)+q!*el&NeK#WEn(P0C;HXcTfEF}as zwhFBji7z4rgSfKPmf>INuf+whMu%o~W{DSejj36&2cuJ>-;n_wwtTG!=tu$$TiL;> zv^V-Bj~1;@t72AFj(eb;_CD-PvKmTN2rRD}G_W)A;TbK9v&U97=a8SGlz#%Ka1j5V z!y@dktdDSxxQW$%ld(A&fiPP`33gMXsovDZLBo=#aQrZqf_t@N)_GJ=Ys^Khh-K7R z&+luI=q58mn)j!w#Mq4$Fr9scxVT7yeRWn!AISNSAq~i z4g4T|oFK)Dv@?!nx1bcmUU<{#7>G?}bX0=ag*1|XyzmW$kC?W25c|V{>OtI~l+vVo zgRt>6t8$krCp_pXve_W4!aomrr{4b7svzfH5ec#>Vgu&RC`}GhaVdKbo|edVmTi}* zWBjdcw?nBE=4VvD)LPWYDRK+@O=~N0A$@1poib0-U#mQtnG6D>!YlD)CNS|Ar5<>S z8g7y)y(PR7cyM@rlYtp4R)Og-Kpt0qia1eR?(%v|cw}eP)b=GOn+c*G!kR8FZHZY~ zVF?!)PrybPU*4rWb^ahS)4;XJz2Hhf?sKc?`W?Z{DwN|_4-o;nfE_Vdz&zgj_CFVP zeI2~^kgioiws9!p$s!UGB*Jka0J_%jhte!q{Qx{wk`GB@-;(Kn`Js+~2#RI&#hBJ4 zX-Ex%y1Ghx?I!$sWtmu29zh2AL{tq$O;OpNQ8)aKgr-0`(jpvtx&tw*x*#F_wv9jQ z`Bz%D;A-c{IS??GaTR20j7J{VKXE!#0000}Y7lFp&~bbK0pfUos0aYD^^l{n#Ao{g K000001X)^a`4u++ From dbc0fe88592e01b61a5f31d75a48718e90d7524a Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 8 Jun 2021 08:47:15 +0200 Subject: [PATCH 133/139] zypper_repository: fix idempotency on adding repo with releasever and basearch variables (#2722) (#2753) * zypper_repository: Check idempotency on adding repo with releasever * Name required when adding non-repo files. * Initial try to fix releasever * Replace re.sub with .replace * name releaseverrepo releaseverrepo * Change to ansible_distribution_version for removing repo * improve asserts format * add changelog * Fix changelog formatting Co-authored-by: Felix Fontein * improve command used for retrieving releasever variable Co-authored-by: Felix Fontein * add basearch replace * Add basearch to changelog fragment * Check for releasever and basearch only when they are there Co-authored-by: Felix Fontein (cherry picked from commit 94a53adff1da71b253536e843bbe20b6d7a16c76) Co-authored-by: Amin Vakil --- ...potency_on_adding_repo_with_releasever.yml | 5 ++ .../modules/packaging/os/zypper_repository.py | 14 ++++- .../tasks/zypper_repository.yml | 58 +++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/2722-zypper_repository-fix_idempotency_on_adding_repo_with_releasever.yml diff --git a/changelogs/fragments/2722-zypper_repository-fix_idempotency_on_adding_repo_with_releasever.yml b/changelogs/fragments/2722-zypper_repository-fix_idempotency_on_adding_repo_with_releasever.yml new file mode 100644 index 0000000000..faada2e9bf --- /dev/null +++ b/changelogs/fragments/2722-zypper_repository-fix_idempotency_on_adding_repo_with_releasever.yml @@ -0,0 +1,5 @@ +--- +bugfixes: + - zypper_repository - fix idempotency on adding repository with + ``$releasever`` and ``$basearch`` variables + (https://github.com/ansible-collections/community.general/issues/1985). diff --git a/plugins/modules/packaging/os/zypper_repository.py b/plugins/modules/packaging/os/zypper_repository.py index f1d85376f5..608675528d 100644 --- a/plugins/modules/packaging/os/zypper_repository.py +++ b/plugins/modules/packaging/os/zypper_repository.py @@ -175,7 +175,7 @@ def _parse_repos(module): module.fail_json(msg='Failed to execute "%s"' % " ".join(cmd), rc=rc, stdout=stdout, stderr=stderr) -def _repo_changes(realrepo, repocmp): +def _repo_changes(module, realrepo, repocmp): "Check whether the 2 given repos have different settings." for k in repocmp: if repocmp[k] and k not in realrepo: @@ -186,6 +186,16 @@ def _repo_changes(realrepo, repocmp): valold = str(repocmp[k] or "") valnew = v or "" if k == "url": + if '$releasever' in valold or '$releasever' in valnew: + cmd = ['rpm', '-q', '--qf', '%{version}', '-f', '/etc/os-release'] + rc, stdout, stderr = module.run_command(cmd, check_rc=True) + valnew = valnew.replace('$releasever', stdout) + valold = valold.replace('$releasever', stdout) + if '$basearch' in valold or '$basearch' in valnew: + cmd = ['rpm', '-q', '--qf', '%{arch}', '-f', '/etc/os-release'] + rc, stdout, stderr = module.run_command(cmd, check_rc=True) + valnew = valnew.replace('$basearch', stdout) + valold = valold.replace('$basearch', stdout) valold, valnew = valold.rstrip("/"), valnew.rstrip("/") if valold != valnew: return True @@ -215,7 +225,7 @@ def repo_exists(module, repodata, overwrite_multiple): return (False, False, None) elif len(repos) == 1: # Found an existing repo, look for changes - has_changes = _repo_changes(repos[0], repodata) + has_changes = _repo_changes(module, repos[0], repodata) return (True, has_changes, repos) elif len(repos) >= 2: if overwrite_multiple: diff --git a/tests/integration/targets/zypper_repository/tasks/zypper_repository.yml b/tests/integration/targets/zypper_repository/tasks/zypper_repository.yml index 0290fa4da2..4490ddca7d 100644 --- a/tests/integration/targets/zypper_repository/tasks/zypper_repository.yml +++ b/tests/integration/targets/zypper_repository/tasks/zypper_repository.yml @@ -125,3 +125,61 @@ priority: 100 auto_import_keys: true state: "present" + +- name: add a repo by releasever + community.general.zypper_repository: + name: releaseverrepo + repo: http://download.opensuse.org/repositories/devel:/languages:/ruby/openSUSE_Leap_$releasever/ + state: present + register: add_repo + +- name: add a repo by releasever again + community.general.zypper_repository: + name: releaseverrepo + repo: http://download.opensuse.org/repositories/devel:/languages:/ruby/openSUSE_Leap_$releasever/ + state: present + register: add_repo_again + +- assert: + that: + - add_repo is changed + - add_repo_again is not changed + +- name: remove added repo + community.general.zypper_repository: + repo: http://download.opensuse.org/repositories/devel:/languages:/ruby/openSUSE_Leap_{{ ansible_distribution_version }}/ + state: absent + register: remove_repo + +- assert: + that: + - remove_repo is changed + +- name: add a repo by basearch + community.general.zypper_repository: + name: basearchrepo + repo: https://packagecloud.io/netdata/netdata/opensuse/13.2/$basearch + state: present + register: add_repo + +- name: add a repo by basearch again + community.general.zypper_repository: + name: basearchrepo + repo: https://packagecloud.io/netdata/netdata/opensuse/13.2/$basearch + state: present + register: add_repo_again + +- assert: + that: + - add_repo is changed + - add_repo_again is not changed + +- name: remove added repo + community.general.zypper_repository: + repo: https://packagecloud.io/netdata/netdata/opensuse/13.2/x86_64 + state: absent + register: remove_repo + +- assert: + that: + - remove_repo is changed From ac543f5ef0e5ab6ff2204924a95f4ea2ea3933a1 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 8 Jun 2021 09:14:10 +0200 Subject: [PATCH 134/139] flatpak: add tests in CI, add no_dependencies parameter (#2751) (#2754) * Similar version restrictions than flatpak_remote tests. * ... * Try to work around missing dependencies. * Revert "Try to work around missing dependencies." This reverts commit 66a4e385668d0212e1150dcfb743478cf5aa042e. * Add changelog. * App8 -> App2; make sure that there are two apps App1 and App2. * Fix forgotten variabe. * Remove test notices. * Seems like flatpak no longer supports file:// URLs. The tests would need to be rewritten to offer the URL via http:// instead. * Try local HTTP server for URL tests. * ... * Lint, add status check. * Add boilerplate. * Add 'ps aux'. * Surrender to -f. * Work around apparent flatpak bug. * Fix YAML. * Improve condition. * Make sure test reruns behave better. (cherry picked from commit bb37b67166a8c80efca92e608f397e4cd820eb5e) Co-authored-by: Felix Fontein --- .../2751-flatpak-no_dependencies.yml | 2 + plugins/modules/packaging/os/flatpak.py | 55 ++++++------- .../modules/packaging/os/flatpak_remote.py | 21 ----- tests/integration/targets/flatpak/aliases | 3 +- .../targets/flatpak/files/serve.py | 65 +++++++++++++++ .../integration/targets/flatpak/meta/main.yml | 1 + .../targets/flatpak/tasks/check_mode.yml | 39 +++++---- .../targets/flatpak/tasks/main.yml | 21 ++++- .../targets/flatpak/tasks/setup.yml | 44 +++++++--- .../targets/flatpak/tasks/test.yml | 76 ++++++++++++------ .../setup_flatpak_remote/create-repo.sh | 68 +++++++++------- .../setup_flatpak_remote/files/repo.tar.xz | Bin 5524 -> 6436 bytes 12 files changed, 255 insertions(+), 140 deletions(-) create mode 100644 changelogs/fragments/2751-flatpak-no_dependencies.yml create mode 100644 tests/integration/targets/flatpak/files/serve.py diff --git a/changelogs/fragments/2751-flatpak-no_dependencies.yml b/changelogs/fragments/2751-flatpak-no_dependencies.yml new file mode 100644 index 0000000000..a07ead96da --- /dev/null +++ b/changelogs/fragments/2751-flatpak-no_dependencies.yml @@ -0,0 +1,2 @@ +minor_changes: +- "flatpak - add ``no_dependencies`` parameter (https://github.com/ansible/ansible/pull/55452, https://github.com/ansible-collections/community.general/pull/2751)." diff --git a/plugins/modules/packaging/os/flatpak.py b/plugins/modules/packaging/os/flatpak.py index 1be1a72243..4a9e214fde 100644 --- a/plugins/modules/packaging/os/flatpak.py +++ b/plugins/modules/packaging/os/flatpak.py @@ -6,27 +6,6 @@ # Copyright: (c) 2017 Ansible Project # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# ATTENTION CONTRIBUTORS! -# -# TL;DR: Run this module's integration tests manually before opening a pull request -# -# Long explanation: -# The integration tests for this module are currently NOT run on the Ansible project's continuous -# delivery pipeline. So please: When you make changes to this module, make sure that you run the -# included integration tests manually for both Python 2 and Python 3: -# -# Python 2: -# ansible-test integration -v --docker fedora28 --docker-privileged --allow-unsupported --python 2.7 flatpak -# Python 3: -# ansible-test integration -v --docker fedora28 --docker-privileged --allow-unsupported --python 3.6 flatpak -# -# Because of external dependencies, the current integration tests are somewhat too slow and brittle -# to be included right now. I have plans to rewrite the integration tests based on a local flatpak -# repository so that they can be included into the normal CI pipeline. -# //oolongbrothers - - from __future__ import (absolute_import, division, print_function) __metaclass__ = type @@ -60,18 +39,28 @@ options: name: description: - The name of the flatpak to manage. - - When used with I(state=present), I(name) can be specified as an C(http(s)) URL to a + - When used with I(state=present), I(name) can be specified as a URL to a C(flatpakref) file or the unique reverse DNS name that identifies a flatpak. + - Both C(https://) and C(http://) URLs are supported. - When supplying a reverse DNS name, you can use the I(remote) option to specify on what remote to look for the flatpak. An example for a reverse DNS name is C(org.gnome.gedit). - When used with I(state=absent), it is recommended to specify the name in the reverse DNS format. - - When supplying an C(http(s)) URL with I(state=absent), the module will try to match the + - When supplying a URL with I(state=absent), the module will try to match the installed flatpak based on the name of the flatpakref to remove it. However, there is no guarantee that the names of the flatpakref file and the reverse DNS name of the installed flatpak do match. type: str required: true + no_dependencies: + description: + - If installing runtime dependencies should be omitted or not + - This parameter is primarily implemented for integration testing this module. + There might however be some use cases where you would want to have this, like when you are + packaging your own flatpaks. + type: bool + default: false + version_added: 3.2.0 remote: description: - The flatpak remote (repository) to install the flatpak from. @@ -94,10 +83,11 @@ EXAMPLES = r''' name: https://s3.amazonaws.com/alexlarsson/spotify-repo/spotify.flatpakref state: present -- name: Install the gedit flatpak package +- name: Install the gedit flatpak package without dependencies (not recommended) community.general.flatpak: name: https://git.gnome.org/browse/gnome-apps-nightly/plain/gedit.flatpakref state: present + no_dependencies: true - name: Install the gedit package from flathub for current user community.general.flatpak: @@ -153,18 +143,21 @@ from ansible.module_utils.basic import AnsibleModule OUTDATED_FLATPAK_VERSION_ERROR_MESSAGE = "Unknown option --columns=application" -def install_flat(module, binary, remote, name, method): +def install_flat(module, binary, remote, name, method, no_dependencies): """Add a new flatpak.""" global result flatpak_version = _flatpak_version(module, binary) + command = [binary, "install", "--{0}".format(method)] if StrictVersion(flatpak_version) < StrictVersion('1.1.3'): - noninteractive_arg = "-y" + command += ["-y"] else: - noninteractive_arg = "--noninteractive" + command += ["--noninteractive"] + if no_dependencies: + command += ["--no-deps"] if name.startswith('http://') or name.startswith('https://'): - command = [binary, "install", "--{0}".format(method), noninteractive_arg, name] + command += [name] else: - command = [binary, "install", "--{0}".format(method), noninteractive_arg, remote, name] + command += [remote, name] _flatpak_command(module, module.check_mode, command) result['changed'] = True @@ -279,6 +272,7 @@ def main(): choices=['user', 'system']), state=dict(type='str', default='present', choices=['absent', 'present']), + no_dependencies=dict(type='bool', default=False), executable=dict(type='path', default='flatpak') ), supports_check_mode=True, @@ -287,6 +281,7 @@ def main(): name = module.params['name'] state = module.params['state'] remote = module.params['remote'] + no_dependencies = module.params['no_dependencies'] method = module.params['method'] executable = module.params['executable'] binary = module.get_bin_path(executable, None) @@ -301,7 +296,7 @@ def main(): module.fail_json(msg="Executable '%s' was not found on the system." % executable, **result) if state == 'present' and not flatpak_exists(module, binary, name, method): - install_flat(module, binary, remote, name, method) + install_flat(module, binary, remote, name, method, no_dependencies) elif state == 'absent' and flatpak_exists(module, binary, name, method): uninstall_flat(module, binary, name, method) diff --git a/plugins/modules/packaging/os/flatpak_remote.py b/plugins/modules/packaging/os/flatpak_remote.py index dbb211c2fb..a7767621d7 100644 --- a/plugins/modules/packaging/os/flatpak_remote.py +++ b/plugins/modules/packaging/os/flatpak_remote.py @@ -6,27 +6,6 @@ # Copyright: (c) 2017 Ansible Project # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# ATTENTION CONTRIBUTORS! -# -# TL;DR: Run this module's integration tests manually before opening a pull request -# -# Long explanation: -# The integration tests for this module are currently NOT run on the Ansible project's continuous -# delivery pipeline. So please: When you make changes to this module, make sure that you run the -# included integration tests manually for both Python 2 and Python 3: -# -# Python 2: -# ansible-test integration -v --docker fedora28 --docker-privileged --allow-unsupported --python 2.7 flatpak_remote -# Python 3: -# ansible-test integration -v --docker fedora28 --docker-privileged --allow-unsupported --python 3.6 flatpak_remote -# -# Because of external dependencies, the current integration tests are somewhat too slow and brittle -# to be included right now. I have plans to rewrite the integration tests based on a local flatpak -# repository so that they can be included into the normal CI pipeline. -# //oolongbrothers - - from __future__ import (absolute_import, division, print_function) __metaclass__ = type diff --git a/tests/integration/targets/flatpak/aliases b/tests/integration/targets/flatpak/aliases index 59e306f8b4..39291d435b 100644 --- a/tests/integration/targets/flatpak/aliases +++ b/tests/integration/targets/flatpak/aliases @@ -1,4 +1,4 @@ -unsupported +shippable/posix/group3 destructive skip/aix skip/freebsd @@ -6,4 +6,3 @@ skip/osx skip/macos skip/rhel needs/root -needs/privileged diff --git a/tests/integration/targets/flatpak/files/serve.py b/tests/integration/targets/flatpak/files/serve.py new file mode 100644 index 0000000000..d9ca2d17a5 --- /dev/null +++ b/tests/integration/targets/flatpak/files/serve.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import posixpath +import sys + +try: + from http.server import SimpleHTTPRequestHandler, HTTPServer + from urllib.parse import unquote +except ImportError: + from SimpleHTTPServer import SimpleHTTPRequestHandler + from BaseHTTPServer import HTTPServer + from urllib import unquote + + +# Argument parsing +if len(sys.argv) != 4: + print('Syntax: {0} '.format(sys.argv[0])) + sys.exit(-1) + +HOST, PORT, PATH = sys.argv[1:4] +PORT = int(PORT) + + +# The HTTP request handler +class Handler(SimpleHTTPRequestHandler): + def translate_path(self, path): + # Modified from Python 3.6's version of SimpleHTTPRequestHandler + # to support using another base directory than CWD. + + # abandon query parameters + path = path.split('?', 1)[0] + path = path.split('#', 1)[0] + # Don't forget explicit trailing slash when normalizing. Issue17324 + trailing_slash = path.rstrip().endswith('/') + try: + path = unquote(path, errors='surrogatepass') + except (UnicodeDecodeError, TypeError) as exc: + path = unquote(path) + path = posixpath.normpath(path) + words = path.split('/') + words = filter(None, words) + path = PATH + for word in words: + if os.path.dirname(word) or word in (os.curdir, os.pardir): + # Ignore components that are not a simple file/directory name + continue + path = os.path.join(path, word) + if trailing_slash: + path += '/' + return path + + +# Run simple HTTP server +httpd = HTTPServer((HOST, PORT), Handler) + +try: + httpd.serve_forever() +except KeyboardInterrupt: + pass + +httpd.server_close() diff --git a/tests/integration/targets/flatpak/meta/main.yml b/tests/integration/targets/flatpak/meta/main.yml index 07faa21776..314f77eba9 100644 --- a/tests/integration/targets/flatpak/meta/main.yml +++ b/tests/integration/targets/flatpak/meta/main.yml @@ -1,2 +1,3 @@ dependencies: - prepare_tests + - setup_flatpak_remote diff --git a/tests/integration/targets/flatpak/tasks/check_mode.yml b/tests/integration/targets/flatpak/tasks/check_mode.yml index 3186fd2830..2270e0a9be 100644 --- a/tests/integration/targets/flatpak/tasks/check_mode.yml +++ b/tests/integration/targets/flatpak/tasks/check_mode.yml @@ -4,8 +4,8 @@ - name: Test addition of absent flatpak (check mode) flatpak: - name: org.gnome.Characters - remote: flathub + name: com.dummy.App1 + remote: dummy-remote state: present register: addition_result check_mode: true @@ -18,8 +18,8 @@ - name: Test non-existent idempotency of addition of absent flatpak (check mode) flatpak: - name: org.gnome.Characters - remote: flathub + name: com.dummy.App1 + remote: dummy-remote state: present register: double_addition_result check_mode: true @@ -36,7 +36,7 @@ - name: Test removal of absent flatpak check mode flatpak: - name: org.gnome.Characters + name: com.dummy.App1 state: absent register: removal_result check_mode: true @@ -51,8 +51,8 @@ - name: Test addition of absent flatpak with url (check mode) flatpak: - name: https://flathub.org/repo/appstream/org.gnome.Characters.flatpakref - remote: flathub + name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref + remote: dummy-remote state: present register: url_addition_result check_mode: true @@ -65,8 +65,8 @@ - name: Test non-existent idempotency of addition of absent flatpak with url (check mode) flatpak: - name: https://flathub.org/repo/appstream/org.gnome.Characters.flatpakref - remote: flathub + name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref + remote: dummy-remote state: present register: double_url_addition_result check_mode: true @@ -85,7 +85,7 @@ - name: Test removal of absent flatpak with url not doing anything (check mode) flatpak: - name: https://flathub.org/repo/appstream/org.gnome.Characters.flatpakref + name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref state: absent register: url_removal_result check_mode: true @@ -96,15 +96,14 @@ - url_removal_result is not changed msg: "Removing an absent flatpak shall mark module execution as not changed" - # - Tests with present flatpak ------------------------------------------------- # state=present on present flatpak - name: Test addition of present flatpak (check mode) flatpak: - name: org.gnome.Calculator - remote: flathub + name: com.dummy.App2 + remote: dummy-remote state: present register: addition_present_result check_mode: true @@ -119,7 +118,7 @@ - name: Test removal of present flatpak (check mode) flatpak: - name: org.gnome.Calculator + name: com.dummy.App2 state: absent register: removal_present_result check_mode: true @@ -132,7 +131,7 @@ - name: Test non-existent idempotency of removal (check mode) flatpak: - name: org.gnome.Calculator + name: com.dummy.App2 state: absent register: double_removal_present_result check_mode: true @@ -149,8 +148,8 @@ - name: Test addition with url of present flatpak (check mode) flatpak: - name: https://flathub.org/repo/appstream/org.gnome.Calculator.flatpakref - remote: flathub + name: http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref + remote: dummy-remote state: present register: url_addition_present_result check_mode: true @@ -165,7 +164,7 @@ - name: Test removal with url of present flatpak (check mode) flatpak: - name: https://flathub.org/repo/appstream/org.gnome.Calculator.flatpakref + name: http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref state: absent register: url_removal_present_result check_mode: true @@ -178,8 +177,8 @@ - name: Test non-existent idempotency of removal with url of present flatpak (check mode) flatpak: - name: https://flathub.org/repo/appstream/org.gnome.Calculator.flatpakref - remote: flathub + name: http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref + remote: dummy-remote state: absent register: double_url_removal_present_result check_mode: true diff --git a/tests/integration/targets/flatpak/tasks/main.yml b/tests/integration/targets/flatpak/tasks/main.yml index a1d1bda8a4..68d41d2efe 100644 --- a/tests/integration/targets/flatpak/tasks/main.yml +++ b/tests/integration/targets/flatpak/tasks/main.yml @@ -30,8 +30,8 @@ - name: Test executable override flatpak: - name: org.gnome.Characters - remote: flathub + name: com.dummy.App1 + remote: dummy-remote state: present executable: nothing-that-exists ignore_errors: true @@ -57,5 +57,20 @@ vars: method: system + always: + + - name: Check HTTP server status + async_status: + jid: "{{ webserver_status.ansible_job_id }}" + ignore_errors: true + + - name: List processes + command: ps aux + + - name: Stop HTTP server + command: >- + pkill -f -- '{{ remote_tmp_dir }}/serve.py' + when: | - ansible_distribution in ('Fedora', 'Ubuntu') + ansible_distribution == 'Fedora' or + ansible_distribution == 'Ubuntu' and not ansible_distribution_major_version | int < 16 diff --git a/tests/integration/targets/flatpak/tasks/setup.yml b/tests/integration/targets/flatpak/tasks/setup.yml index 2dfa33a0b1..98b07cd480 100644 --- a/tests/integration/targets/flatpak/tasks/setup.yml +++ b/tests/integration/targets/flatpak/tasks/setup.yml @@ -4,32 +4,58 @@ state: present become: true when: ansible_distribution == 'Fedora' + - block: - name: Activate flatpak ppa on Ubuntu apt_repository: repo: ppa:alexlarsson/flatpak state: present mode: '0644' + when: ansible_lsb.major_release | int < 18 + - name: Install flatpak package on Ubuntu apt: name: flatpak state: present - become: true + when: ansible_distribution == 'Ubuntu' -- name: Enable flathub for user + +- name: Install dummy remote for user flatpak_remote: - name: flathub + name: dummy-remote state: present - flatpakrepo_url: https://dl.flathub.org/repo/flathub.flatpakrepo + flatpakrepo_url: /tmp/flatpak/repo/dummy-repo.flatpakrepo method: user -- name: Enable flathub for system + +- name: Install dummy remote for system flatpak_remote: - name: flathub + name: dummy-remote state: present - flatpakrepo_url: https://dl.flathub.org/repo/flathub.flatpakrepo + flatpakrepo_url: /tmp/flatpak/repo/dummy-repo.flatpakrepo method: system + +- name: Remove (if necessary) flatpak for testing check mode on absent flatpak + flatpak: + name: com.dummy.App1 + remote: dummy-remote + state: absent + no_dependencies: true + - name: Add flatpak for testing check mode on present flatpak flatpak: - name: org.gnome.Calculator - remote: flathub + name: com.dummy.App2 + remote: dummy-remote state: present + no_dependencies: true + +- name: Copy HTTP server + copy: + src: serve.py + dest: '{{ remote_tmp_dir }}/serve.py' + mode: '0755' + +- name: Start HTTP server + command: '{{ remote_tmp_dir }}/serve.py 127.0.0.1 8000 /tmp/flatpak/' + async: 120 + poll: 0 + register: webserver_status diff --git a/tests/integration/targets/flatpak/tasks/test.yml b/tests/integration/targets/flatpak/tasks/test.yml index 1e7d888bb5..7442e4b468 100644 --- a/tests/integration/targets/flatpak/tasks/test.yml +++ b/tests/integration/targets/flatpak/tasks/test.yml @@ -2,10 +2,11 @@ - name: Test addition - {{ method }} flatpak: - name: org.gnome.Characters - remote: flathub + name: com.dummy.App1 + remote: dummy-remote state: present method: "{{ method }}" + no_dependencies: true register: addition_result - name: Verify addition test result - {{ method }} @@ -16,10 +17,11 @@ - name: Test idempotency of addition - {{ method }} flatpak: - name: org.gnome.Characters - remote: flathub + name: com.dummy.App1 + remote: dummy-remote state: present method: "{{ method }}" + no_dependencies: true register: double_addition_result - name: Verify idempotency of addition test result - {{ method }} @@ -32,9 +34,10 @@ - name: Test removal - {{ method }} flatpak: - name: org.gnome.Characters + name: com.dummy.App1 state: absent method: "{{ method }}" + no_dependencies: true register: removal_result - name: Verify removal test result - {{ method }} @@ -45,9 +48,10 @@ - name: Test idempotency of removal - {{ method }} flatpak: - name: org.gnome.Characters + name: com.dummy.App1 state: absent method: "{{ method }}" + no_dependencies: true register: double_removal_result - name: Verify idempotency of removal test result - {{ method }} @@ -60,10 +64,11 @@ - name: Test addition with url - {{ method }} flatpak: - name: https://flathub.org/repo/appstream/org.gnome.Characters.flatpakref - remote: flathub + name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref + remote: dummy-remote state: present method: "{{ method }}" + no_dependencies: true register: url_addition_result - name: Verify addition test result - {{ method }} @@ -74,10 +79,11 @@ - name: Test idempotency of addition with url - {{ method }} flatpak: - name: https://flathub.org/repo/appstream/org.gnome.Characters.flatpakref - remote: flathub + name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref + remote: dummy-remote state: present method: "{{ method }}" + no_dependencies: true register: double_url_addition_result - name: Verify idempotency of addition with url test result - {{ method }} @@ -90,26 +96,46 @@ - name: Test removal with url - {{ method }} flatpak: - name: https://flathub.org/repo/appstream/org.gnome.Characters.flatpakref + name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref state: absent method: "{{ method }}" + no_dependencies: true register: url_removal_result + ignore_errors: true -- name: Verify removal test result - {{ method }} +- name: Verify removal test result failed - {{ method }} + # It looks like flatpak has a bug when the hostname contains a port. If this is the case, it emits + # the following message, which we check for. If another error happens, we fail. + # Upstream issue: https://github.com/flatpak/flatpak/issues/4307 + # (The second message happens with Ubuntu 18.04.) assert: that: - - url_removal_result is changed - msg: "state=absent with url as name shall remove flatpak when present" + - >- + url_removal_result.msg in [ + "error: Invalid branch 127.0.0.1:8000: Branch can't contain :", + "error: Invalid id http:: Name can't contain :", + ] + when: url_removal_result is failed -- name: Test idempotency of removal with url - {{ method }} - flatpak: - name: https://flathub.org/repo/appstream/org.gnome.Characters.flatpakref - state: absent - method: "{{ method }}" - register: double_url_removal_result +- when: url_removal_result is not failed + block: -- name: Verify idempotency of removal with url test result - {{ method }} - assert: - that: - - double_url_removal_result is not changed - msg: "state=absent with url as name shall not do anything when flatpak is not present" + - name: Verify removal test result - {{ method }} + assert: + that: + - url_removal_result is changed + msg: "state=absent with url as name shall remove flatpak when present" + + - name: Test idempotency of removal with url - {{ method }} + flatpak: + name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref + state: absent + method: "{{ method }}" + no_dependencies: true + register: double_url_removal_result + + - name: Verify idempotency of removal with url test result - {{ method }} + assert: + that: + - double_url_removal_result is not changed + msg: "state=absent with url as name shall not do anything when flatpak is not present" diff --git a/tests/integration/targets/setup_flatpak_remote/create-repo.sh b/tests/integration/targets/setup_flatpak_remote/create-repo.sh index 1b09bb7956..4ece76ccfc 100755 --- a/tests/integration/targets/setup_flatpak_remote/create-repo.sh +++ b/tests/integration/targets/setup_flatpak_remote/create-repo.sh @@ -1,51 +1,59 @@ #!/usr/bin/env bash set -eux -flatpak install -y --system flathub org.freedesktop.Platform//1.6 org.freedesktop.Sdk//1.6 - -echo $'#!/bin/sh\necho hello world' > hello.sh - -export NUM=1 -flatpak build-init appdir$NUM com.dummy.App$NUM org.freedesktop.Sdk org.freedesktop.Platform 1.6; -flatpak build appdir$NUM mkdir /app/bin; -flatpak build appdir$NUM install --mode=750 hello.sh /app/bin; -flatpak build-finish --command=hello.sh appdir$NUM - -flatpak build-export repo appdir$NUM stable +# Delete traces from last run +rm -rf appdir* dummy-repo.gpg gpg hello.sh repo +# Create GPG key mkdir -p gpg chmod 0700 gpg gpg --homedir gpg --batch --passphrase '' --quick-gen-key test@dummy.com future-default default 10y - KEY_ID=$(gpg --homedir=gpg --list-keys --with-colons test@dummy.com | grep fpr: | head -1 | cut -d ':' -f 10) - gpg --homedir=gpg --export "${KEY_ID}" > dummy-repo.gpg - BASE64_PUBLIC_KEY=$(base64 dummy-repo.gpg | tr -d '\n') -cat > repo/com.dummy.App1.flatpakref < hello.sh + +for NUM in 1 2; do + flatpak build-init appdir${NUM} com.dummy.App${NUM} org.freedesktop.Sdk org.freedesktop.Platform 1.6; + flatpak build appdir${NUM} mkdir /app/bin; + flatpak build appdir${NUM} install --mode=750 hello.sh /app/bin; + flatpak build-finish --command=hello.sh appdir${NUM} + + flatpak build-export repo appdir${NUM} stable + + cat > repo/com.dummy.App${NUM}.flatpakref < repo/dummy-repo.flatpakrepo <v>5N@un}Hi1L#y~)Z- z{84!W3f)Esb7jq8xj(H~uV-ILw_hEK-tS2ml%=3W(9ZbK%*zGuyzw% zx|CRvE$)Z8hP(q}r5_|!pL6c&F%PC`(i85LvmX4tby$`<){6<0vLZ&gXzNHVZ&Xf~SL^u8sOHdo})6*qX{X~g@Rb%r$B zquEDB>&GQIE73m2JY`xc#+vdGzyT>afBQP{JpJd%k^#05fTyu|mQGF%YV6zMjsMHtkdFZgCC3Hu1hT#!3sP zlX%{M1-qoEJrl#7R+_{(He}QOx3|*uAuy=7BSbaUQ8?+uC3n_im4s73NG;MPAh=aV zsr!5fZ9@geCLM}Jn>G|r+q1urn&NgkY4kCkgSRk&Nj)-6mJ}r({(ADFv?Rj1Qi%V= z#?W3PY}yyhh)TAJTmea{WQz!$!kLBs#hrb!Oe&|_EO+32=p~I7Sqw@dyF6|0q@M8hmxVyd6gGOW|A*fgO zCjkQ-W<>L7srkC{ZDbazsy?xXWtl6Tn^-^s5r^=XB~c~PZoyai;ogn=Y?otN+g6?B zWT2F(AKl^h>@zuadxsdm1EXN(hxfSJYH8;e zz;C?|(!_t_gVJQO-YhxZ#DIbf^JItaMJEvG3=GNsV|Pda>WptsL5Ak0>x>89MY&QR zvxJw5)nrELLCY}g=4zkb23M+VcZJ$kRf>*B)7NH^5*~YC1&?h)!NDqJ#4h)y^7lSF zi0y|>Mb(4Bi+hVEtJNPzDGi5ePhs41$l@VJ6rX;uYD1>|^@C@*E|^CE22`*L6)9O( z?oddJ%D4`7)w*+JE5dme9)yRz6QUBv7seZjaaPl+=5^@LXrU2)SW!puqXN*k~< zxJ=^x0|xbva8VGz2sP|0OQ49+NDlq!uPRo^kf`w}9bO}}YYnnZfrnFS6OoqH0DR0Z z)13cHH?2TM5eIPv98c!~DoZUl=tf4~Ez+DZpFz9!hD8{t@ygq-u-`2F@8>dIx~3Pp z_~>w^QGN4mH_|yzkiIl29x4}JQ`?SIiDy8OIc$Rthg#B&sK;_kF(Hm(+xpjo$9{3} zf@XWNwLx*Vd_dj*OANsrRiQ-b!<{tKhioy&{7kMaBAL9ZYqlDm`$jG_&t~4py9Ya*Ge+y~Pv>HtJcFY8 zihplQ2s3yH>rf+Gfp*T`P}GI@BX&K=2Culc>vvXu$qsx^^i!;(p07mgthO5Vt3XwW z-S*i?CrwF}cE4bC?{sxVTM0iKA}878XK!_j}n zlK6Acn`k-ISyDh<>V?YujFd0=*QcORor3$IxiL^c^H>cZN#Ti~LF>Z*guR2b@FiEP zi%z<6o<4R@1mf4(89Y@fr2_iLU2H;6^ScvM6>{p5qy#U3#`+2b5+>I~Z1{Qcp68UB>zR!!-prXQw5y4( zgDKV1lMkGqQl!qMQYo**XhY34KJT4ex%fejcv zZtoQ=*~j`gYdvg;tQHVS^TBB^88ATLx!w{}b>CjXr6-Gk!0=mAp!C5o2jJHp%{A6Q z);jVS6UGe2k_eN$vMlN9BEzj$P+lss#h9gtB0|Slj-IbZAjy0vp+wvw`|l=$>$Db{ z-zX7JIZcLr+t_(b6|;jMi!T zolTrC91#&H^S!VZL5FS!4n!;Ov1TVn?=$9+44O#ga`2q`7k`0GT9BdFrCf(5QkIcBh1g_v`9#z=X}^u zEX3sA`gUnR{hP2ok2#U)b{&^yKRK|m35I1K2YzRc@F<7ISA)5&68BU@T`2SaIh0{Q zR+4P&P?>nXe-5Tu4ADqcQ8IXzze|bQdAZbeumC-v_asSQn; zcsa{!jf~)!@ApoXJ|eoTn#@sI%n_!eZYFJ?wwYK}&b4lJ3xGVH*ed!&CYPC&HO*{2 zx!&?sSwm+%<^c6=(?~CB>I7PY3&9n2}!JRmQS?&N4(`>5bCe#G>_!l-U zV=&BmtaM!@pCI6<7{y&03<(BUBPfg=}#=V1QjNh9r^D3ZQ~$ z-+d4(XSuVNC#N0n>`4rUY=>51W00YMceM5OJr_HgTTfSLEz{8iti&SNn>(EV$o9JW z!m(K@?NUx=&_SExn*qX~{m)clg3E3uI!yy-DPLdxN1DU*tpvKk!8glk*Hf;dQar=R z7on>L@+5L?e(v{&A8(jHcO7kAloZWS&3%0pW#C-Auw_GzDtBS?LYD*}^H6l(nT4DYJ9ve?9;u&7=<;D*FhwV`{oy33F!QH)y+h(Q_{^S__4O*`fbWV(A7 zWjUxL4a#hZr!puK*C~5l45>P9E67TlKz$7iUb0YsC|Yb zCnipl&)YZ90KN)Bxo#d<(iou(K{&J$GWS^<<=I+@__=Xt(A)>w+Yi}dKp8?N2KRwN z^gr}Vwq&VE4@VV%9@O>z>ERVLH36<>+mQ?%=aXkN*odx#Kq2}t^_A!}w#ln1zKPps zedEUYxuo@>=iu>96C9}yB zCbMidGlvUKENqLxrW2cg``-*3sZf3a$US)1zpgLentlC+dxuXcb#e0pH6eYbJF<(` z_(Kj?UXp$c-l`|EQjCV;n|z?PW2`l{DIOv3&U`!(tFpw!5fx^g(=@fBZq$tCk;a}L z?6uR0bKlS#MZXT{8{XUTd)j)acoP7%fg`4QNBm-F=w;VM(4%AF&^DR|Guo7@3417* z1~o&vueD=BWCKjHpR(`EZpGc4HGP_xU-J_pCsD>lqJCrA#QFIhAjjF}&De*Ukji|& zwq=!tF1#YjM2Dln$(9PGgQxvK<_3#XaRKjv3FymIvD{+O|B~>3*5T`aNVtD;A^}9v zPqTh15!MoN?6?KmUg5QY4u|}W6V^A$t!@H*8YtK*JFgf5r2_F4+dd-;oDv7lRl?)A zjlAgqldfV%)8HzC&Ph+uhd^-yLWe^l=?8a&12-Ume96LIJV&0ayQ zEn?2vlqGF3$U=z(-(fZ$tm|>X99kReTLQ8t)u5ltKiMhYq8cL7?Ik@{Sl;Br$a^m& zFD{ZgAv<5POi51>jj>s4sY#-jfDD-Va9FS>^It5_)V8d1)gZs&3zY4)KNF@3d2tn_ zbmXJ*`qQy!S2LEe(bB>G+Y1`&U>rh%dhH3#{MJds9$SwyNYE0n8;s&C=F3DAF85K` zyz~>{k4>dfFy$ks6~q}?sE$8PqQ%BnWg}@qS&AEVvnB5oYxlSxFU|)8D}Re8y3`ur zUlS`Jr|{LMxcP;BwzbI=?!2m`=czdR!Gm*bZEG<;C*@u4)R_SOdzt}!#;0QU?GrWx z(Lv@(8um}*&n6Nas;|`H<~RFk{-`kFbxRuUy$aZ&=aIgMt*6Kx-_=&v6KPfrN&YcP z(ONj_*Q`9$^OcNv!)XRPW5)@JGiz>U2@9tp%aOVi5tfG;a(IT#T5aPIfsmM*BGw{3 z&>-cf;$BH$4La$#zC^ue#8eHZR}=l#%%=4|27{Roc&molVxkR1#f3crno(y59e7uY z;wGqG6(iv~UZT5Ck`J5l8bJv_bG{!(#C5rQyMgXIyVxxf)|HK zoh#K!_$D}6sygpkNZEj5Yy29c$dn03ZPXxSymbD0d@bNhq$4rvQ7=E@=g*}lpY3Ta z6DUhSvmpHVX~4A(|18}-FcAbQq=Et>e7pA(_V9tnXWQ#I4j{VFdF+cVXmQ#RE2bhV z;BUI6f#|8(?6$dxAB!|kOk}CvDP9uw{7OPr79RE6sfkBIqxl$>HUYW|X%H*0n>Z+x z$JeHb2AYZcPy9l7m|1V1i+YKu=rfEwX#rzJfs6&|WJZ!{1m&it#Y%K{3HW3b^2BAu zDxJD3_N=RGd-#Bcw9<(A4TluQX}beZ&4r?ZQ&f~b&ajHscRaFabd#BM5-vR$G{Tnm zakJ|iprJoO7nSuf*Jz4G7Ajx?kstaIqc^RXq=3k!8`QM>WD~YZUs_(<4iGAK0Gcp1 z*FsNFE#=b)cy+7F1D$*S57pxj4-|)vDN*O@8{UaYm9oJZO+;)GzF-U_wmGNGM`)4x zVC{Cq2QVh6mp}>&c>KRZym}qc{$QmdbC7MmVj~b34u%DbOycuRMi~Sz{I$=rNQv$y zDo5s_sUl8K2jV6fnXewZ(7Yeui~8!5peW@sCh5WYXG(eA@g)mpJK1vin?qY($3{n& zdyv10S$%^5I7L8{v6v@p&bt7X@7D#zHePiI_Hp(dIRfD^cR}4cY~IRq>>^{lVl|E zUt+k`p7s9=R+ji-(kp16*(WHvE>e0Oi{E5VRphpC?mL3_t*M5M1eiCBJ%Nk%cvO@7 z-UgmF$$xoxz94TH_m)K- zW>Nq`uil4P5J{Ir2+cL1V}w&1@BzO7B4L<@9JnPDz|u@4bb1C`^-ydjrW>}Kc8trq-Suw90+K&UIaW>GLwj@XbzXWmCp zn;kGaR8DThc(5iNBB^tN$`mHytB#qUu)ktV(B}87t6C%zrvid%=;)B_+f#Bkhed0k zb@OPvh^2Yp!h@4+C9s2zGobnbcGKYp5?!OH805IoPKw>nwhg;x4NJJ0e~`qumk|irf*8I#Ao{g000001X)@i7;SF= literal 5524 zcmV;F6>IAKH+ooF000E$*0e?f03iVu0001VFXf})@BbB4T>v>5N@un}Hi1L#y~)Z- z{84!W3f)Esb7jq5>fDNTXAtbJtFLh#1{z_@XdBbYO#I_6ejX}{k|qPV5*F#tV*(KZ z&8y&v@-_@%O$~^*VQ2&(ntw~=X4{`14ln0V8gAs7B)fP}6FAt~Kb*`}cin_F`PjKM z=gDE4I1`vmQzegt`_V-)uy0DRn8>u3#F{_S@Q?#j3Pf@d^@SuYQthQu*4bx}Wxgr^ zpzQnk7-!^ooWgD}Y<{Z)25({OuU|9(2RU`Q#t(Nms*UWhQUf?8R&lYuSf-byBX0K8 z^I}P z;jsPqKwt(94>NX^omDYN6iLjF8^%Fq74AggLtsy+E4;4W#LVx|OUJ_~rkBr=I9G`S z-`lF>zkaJh8c8uPIv7!1R#=VKn4$v5FVtOAT~e-|DG}P7pu?u zg2?4<^6J^x4!h7r^PhZef;GY0o&cgx`7rh$+7fCPFWMF3s{tZp9=q<`0M;3wj#_1g zy)AF_+45$2ZeN7&sq;gF7CAoR3TC{{A3kUkG`e@pmB_i|#|gx}R%AMZmCD*tQpM$A zmFmu|SZA0^w?;w2^J#7(!b+rZ$z`H1_w}(oKbr6?5#;6I*|C;sURHR-b#HK0GgHwl zWlO4wdEbX1D|5Dcj7=Qurtcf#d@UCH2{rv6(9o2ArZcO^C#+^h0?!I+spQj?8~88n z&E4e>R8^&N7+DMiqM6PD31Wv0giL;`XN??_@^TLV4hsB_WSOq_+c>H2$Dzqflv>9< zh9V#;-2)ZRNP$CY1HLx8Cx$ODMd$i>V~Lai-_=C*H-nB$WV7w4_|_RdZxY=@`)PU9 zGU-R&Fm5PR*l=QSUedJi+q~F%qp&wRE~3tnSu#;tV>1kSB#HCAD|;^tLzOsOObfGC zxl)v7r8Kf`JlpPMyfI81Mv@JKh+8vmq_9c@{#q=-N;#Y-+4)mJ77tr#mrvm(XFmSP zG`G5J9L|fhqonikigA&LzgIIzkD0JRwG!tEUQDZ}LZ|#5Ual6Xaun6M+(HDC&+jiB zxRa*KG2+)q*k=l9wu2EZW|NN;6w^HoI>w-V*1+BB&9amec?NGnkvXq>&?V<0S79xs zE);IWKN6$<=AHej%3g*(e+_xcmwPhy$}qM#E#@F{P)$5H9+(}YyEW0ZG;nQX00+iN zlwO}I{>mXc^=^Y1-~obpGtoH%Sg8VHbMnK%bcKXdHdNlomWIl)pzNw;A8lK?zqCL$ zNtth-_+Epfbrx87EX;Qr527&3oF#4}aE}OWga@2=Ygo`4h3Y^~>!X^knst8lFS%W5 z22|-1!ABSJyfe!9gP2T9@aCFHh_E-a`8#UE-nKN8K4Lw8PgF5GHLGhpl%DwU3GWAP zb)mCUGrJ1spZEsCe>(_RS+yylRnFv0&(HZPqRJiW{T9=KHLS>_%NoQ>AjypKmy>(K zStvuAI*Zm{SABkrITglicDPv7B=GyQ>NkIV*#NS+VqdSyXmh*i{Giej9qux%*V4!v z04}f5;K6g%G(3;;FrbnT{Vlj~6@tey6YDC&(V_B1$QFNs87L<@XGuRxb z-rW@&t@xrgkZjqx%OVI!>_M>rt9_fwcs-qXQM@YqO~2H@>&AFrl^o0=9KMF&+7hz8 zm9Z0~y=WvtQFC@A4HYGmx0;`V`j zTBirBrULceJufTw9S0oQrlQkQqL4U~0>5<_BHQxuNcybgxl+KdM;RrG>B_c1s)bSoOGy?7`dzpWg+m83c_Bfe}_G zs~{p8wWo+@hwfLuI(xH@T?B%SsJ~n@;DL)@45ldz@biq=qp>{HHsq0s`InRO9bUdOPHf1S(2GBdtU}U`lXj+^OaaJ0#?cIX zz`a_1oZoGHeOnV%cz?|}Ux!?f|BWlg`mh%HY&oR|SzSM*%ToXmZz^C-H2~|!G3&`d zCzie=S>qD)_I?rZJ#|kd6V&+zn{H`5&L{S%Bod&aajrBb!)rj#Xs~5!G zp(wBu%!MMS?AkiP;grvxR|8?)kmt33Ks3^UqR*k(HGaA1apho-VQ-xRYL`*9PsVQ* zgU=Tzp-Ab0@PL%xh?tv)VOvoR%C=YDQrO`Fh~-V^Gg1Am90nf<$hXh$Mj&A`=pj>y zBXH6u+B1j{O~Vxn)sMPc8YQ5@K?48f!TheWcJnpl#Kdl+zNEIal0C0Xxx*ay&BGTt zvJv?!ox`mJ2UfORJJr84*kW2)s;aizuM35WS7&vHCw{<)N>KpncOw%vC$e2I!T>HE z;hHcWk1BUPTsSh_eym-mFuSvZaS;o`j@#x|qz6gkPwEso`$pi&OqTtHJNMOyPYOY38xFB-B}fwBm;0_?4Ml@bxI6QfTp>DJr-^F%|W_ z$-Wlx_;e(f1)dO8QR&45;N*QG-c)lB-2)7qR9vsd*c(}Yp@Jf2nV38Y3W=}J^`9Xj z4^|H>om2DJ(AfpN96L<`CEV)e(`iQ>DemWjW z?#hsDws>z8($(!8fOwYzV|Q^~@ixxn#8TOMTj;{`7Ldq?z2;shLNYtuY?zsJ`8tJ>aXJ5j0S z95)Rb9qy4F`v;^O_Y)*9M+qOq=lX`2v?C+SZkuxNydCv@w$`OWJH43g%4!lk& zNEo2_0s;9TWv_KVzRWhB2Ntq-Xo$j9DB{AwI_{ac@FK$0Qjp|iDZC6+DAFbO-q&!W z9JWT6;p*bW#@Cmiceiq%R)QY|FOBs#3++h4b*o)4u*L^zDzolJbHB(k0dE3?6_-O% z7-;9MqjJs?r_{nm`Ve6AxTvebCYENAxyCW){#(NeH}OZa`;g1*+bVLLFzAHB|D-Bn z!&(K|XeU~^-&Y{a#(j+58(5j~ zLjy#sI4fG4xQ^X_kbH@F#sn}1!;X)2ykHi9Jc;`A34k%vE14LeTJF{G!4Ji4?=wR- z)zjB5K8bajhY%D+T|1S3fN#zt-?FPFOh}pCVrr6 zLTI^gc?vM+d%#YhHQbeZxy-NXZF;C!_oRTgHKSK$Q_i#ex>VZ#>|sc?EPYD?LI#1E zcN(_#74PgUZ)dY`{>3M{@8q@Kp?k1FwB^2l;-~(+A!BfIC4r|?y~l9}juyA2H!gXc zTrJt&h767*t{P?16$BU?g@U+X4XU622arWnyi9bWh1h~F4bjM%yWc*SR0g^_L0|Cx zry_hh3|iWe>UOV_PGS-w!U{Qou~SgKg3phkt06Pe&Z(lGvJ0%rrEzd8*_N{U-7w?m zGE%LF={|x#?(XU5_u{|zRAPuBYDdOfd9~rXcTN2OtliPE$`jdGDLDNHbzXBzGh
  • hitUvXK$sVWTuHQ4`ZdY6WW&L~ zYrr|UGRP5;Nk&K=A2@&o4^{3P!YbP$DR$8*fgz^$Sh1*c?`S(CY4dUUb9om`0^=(hr*Ce&t{Yz$ihlP(i21%ghcqYblmS!V)?*#g4GUc%yqbWw{q1EfU96 zdoUIg(;!t*YXS&P+ETGQ7(}uXNHx5qNdp#Hx)B2o6bgEIb#`ISwH203$fl`Qb1*w8`e`gB{_gynce{ znS8HH0?~yJro9En)?SFWZJC*b%Fvhh%OB7QjMOL9w*(-bFv?tLYogb}Jp6=hzY5rX z?7M`G$X;7JH)FIV&1&Brw(oot0Q^U?K2zJyz&+smc9-F6oS63gQp=36sY*D2xWZ>F zg7$w^{|SQy1o?Y9o%?D!Zix2U>s==f$i}meb-24lJQC*VpKu^3`Q#_GFkN(MW!Ybh z;=JF10DQ1ofCk~}{axu`@Q7TW6SP*i3jw6T*A{*zTwokFZi`oMbVj<_)}Xk36vi|x zKnsnf&pCxuvj;dc=59GwcagEJ9;;#uXs%TpKp+N?lF=RGED=EWet5#4$fiA|z_#p* zDDs0^=ISWtn=}DH7UbDn&`)$%x{t08%}FrW$b4G@9?{mEu~b~p4^r>ZL4+O<^Q zmWlBiQw+J1h|j%WUg;L-5wgiJ=nm)iEM>W06V*1yVI7rY^~0x~&!d=3nUl{gI4{MV zz{aoZ3`dP7q7{j+#B8hwedfY5r-n7`N8l4_12d1GeXQ!~GIK_)wTC0@6?g-b`B|lq2bG-zEloEM#*Y&L z>iQ{;vHn+)Q5IkmswrfxFf>0Hcf5c;#lq`U5DK5@QZ$xL_P)KksR+k449)S}RcT`3 zJ55QKuecH|_`LmTb$1nrdBjsKYJ>X?1=~Ldqaj@_k1A{!`qcnM9DxOzRjRZ$Gue$^ zKz)<LSF(d)Q0N`7h)2otJhEf+5ejV9Whz*;U%qDS zt!lPdMwT3{&pgHhh*}cnO$VoLYDLG;dkBFazn;HN^G=pPX|&& z`V(cM@h`Phy4B$m(G{apx$P@({_U4>E8Y>2+M)c?uO87t{wifMT1UloIoWeD)hB^= zFO2o1-z8`^O=PW1lyG$kt+EBo`AjbCs_N9QhRkW7K73AO-T6XVHPpVHeb~JhW0qKr zRkaP0XpQac_8d48VgHO4$-X_c9oM4h=WMmwCp|UYRHi0LK4F8HR3BA*>6ZsKZEFaZ zI7@6sqGB1x`6Wk^m6RgWy?l5DIu#0YJL&LVd*Ek_H_O;4Duo=^hH*OpHLstavsX5} za)|yUF{mUbR2do&rEK2-YWR4}6Mrn_q{3&RJ6g4PG_!pp#H3S$7x^y%nWeZw;Mwxy z2>Wa#Q((X*uxZKtlj?bxGlD>XMSo{^(n(q=)p#hSiN?stSFuvg!%px*vF-_oWE7_& z=^fo<7l_9=OvK$LGdGZO=<4tiGJ}tGYA4JSz{JLVGcm%62fajWhb+`0Ezbw+2uDZ_ z=`6RLzWT#dX3gKoYE$EXm_JK_!mwVwBN=!?H?4++G9*&csKyne*_VwXSq9#E1~s~F zMIi85_ukPN(T+_}kR2-9k#W*;r8n|SyDzP+b{?0njVMSb!wV%(ZkHTv2`vC Date: Tue, 8 Jun 2021 09:27:27 +0200 Subject: [PATCH 135/139] Prepare 3.2.0 release. --- changelogs/fragments/3.2.0.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/fragments/3.2.0.yml diff --git a/changelogs/fragments/3.2.0.yml b/changelogs/fragments/3.2.0.yml new file mode 100644 index 0000000000..4b1469c9fe --- /dev/null +++ b/changelogs/fragments/3.2.0.yml @@ -0,0 +1 @@ +release_summary: Regular bugfix and feature release. From f0f0704d64c18a6c019133c42d0153b864026286 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 8 Jun 2021 10:58:36 +0200 Subject: [PATCH 136/139] Fixed sanity checks for cloud/scaleway/ modules (#2678) (#2756) * fixed validation-modules for plugins/modules/cloud/scaleway/scaleway_image_info.py * fixed validation-modules for plugins/modules/cloud/scaleway/scaleway_ip_info.py * fixed validation-modules for plugins/modules/cloud/scaleway/scaleway_security_group_info.py * fixed validation-modules for plugins/modules/cloud/scaleway/scaleway_server_info.py * fixed validation-modules for plugins/modules/cloud/scaleway/scaleway_snapshot_info.py * fixed validation-modules for plugins/modules/cloud/scaleway/scaleway_volume_info.py * sanity fix (cherry picked from commit 9f344d716590b585a9cbfbd072dfa23c3b20ae13) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- plugins/modules/cloud/scaleway/scaleway_image_info.py | 9 +++++---- plugins/modules/cloud/scaleway/scaleway_ip_info.py | 7 +++++-- .../cloud/scaleway/scaleway_security_group_info.py | 7 +++++-- plugins/modules/cloud/scaleway/scaleway_server_info.py | 7 +++++-- plugins/modules/cloud/scaleway/scaleway_snapshot_info.py | 7 +++++-- plugins/modules/cloud/scaleway/scaleway_volume_info.py | 7 +++++-- tests/sanity/ignore-2.10.txt | 6 ------ tests/sanity/ignore-2.11.txt | 6 ------ tests/sanity/ignore-2.12.txt | 6 ------ tests/sanity/ignore-2.9.txt | 6 ------ 10 files changed, 30 insertions(+), 38 deletions(-) diff --git a/plugins/modules/cloud/scaleway/scaleway_image_info.py b/plugins/modules/cloud/scaleway/scaleway_image_info.py index 3fad216ee5..609ba3d1e8 100644 --- a/plugins/modules/cloud/scaleway/scaleway_image_info.py +++ b/plugins/modules/cloud/scaleway/scaleway_image_info.py @@ -19,9 +19,7 @@ author: extends_documentation_fragment: - community.general.scaleway - options: - region: type: str description: @@ -51,9 +49,12 @@ EXAMPLES = r''' RETURN = r''' --- scaleway_image_info: - description: Response from Scaleway API + description: + - Response from Scaleway API. + - "For more details please refer to: U(https://developers.scaleway.com/en/products/instance/api/)." returned: success - type: complex + type: list + elements: dict sample: "scaleway_image_info": [ { diff --git a/plugins/modules/cloud/scaleway/scaleway_ip_info.py b/plugins/modules/cloud/scaleway/scaleway_ip_info.py index 145fb20338..e2e49557cc 100644 --- a/plugins/modules/cloud/scaleway/scaleway_ip_info.py +++ b/plugins/modules/cloud/scaleway/scaleway_ip_info.py @@ -49,9 +49,12 @@ EXAMPLES = r''' RETURN = r''' --- scaleway_ip_info: - description: Response from Scaleway API + description: + - Response from Scaleway API. + - "For more details please refer to: U(https://developers.scaleway.com/en/products/instance/api/)." returned: success - type: complex + type: list + elements: dict sample: "scaleway_ip_info": [ { diff --git a/plugins/modules/cloud/scaleway/scaleway_security_group_info.py b/plugins/modules/cloud/scaleway/scaleway_security_group_info.py index d3488f0c8b..1f5af7da53 100644 --- a/plugins/modules/cloud/scaleway/scaleway_security_group_info.py +++ b/plugins/modules/cloud/scaleway/scaleway_security_group_info.py @@ -49,9 +49,12 @@ EXAMPLES = r''' RETURN = r''' --- scaleway_security_group_info: - description: Response from Scaleway API + description: + - Response from Scaleway API. + - "For more details please refer to: U(https://developers.scaleway.com/en/products/instance/api/)." returned: success - type: complex + type: list + elements: dict sample: "scaleway_security_group_info": [ { diff --git a/plugins/modules/cloud/scaleway/scaleway_server_info.py b/plugins/modules/cloud/scaleway/scaleway_server_info.py index 43b0badc14..61bd9de41b 100644 --- a/plugins/modules/cloud/scaleway/scaleway_server_info.py +++ b/plugins/modules/cloud/scaleway/scaleway_server_info.py @@ -49,9 +49,12 @@ EXAMPLES = r''' RETURN = r''' --- scaleway_server_info: - description: Response from Scaleway API + description: + - Response from Scaleway API. + - "For more details please refer to: U(https://developers.scaleway.com/en/products/instance/api/)." returned: success - type: complex + type: list + elements: dict sample: "scaleway_server_info": [ { diff --git a/plugins/modules/cloud/scaleway/scaleway_snapshot_info.py b/plugins/modules/cloud/scaleway/scaleway_snapshot_info.py index f31b74b00e..95ec04d16f 100644 --- a/plugins/modules/cloud/scaleway/scaleway_snapshot_info.py +++ b/plugins/modules/cloud/scaleway/scaleway_snapshot_info.py @@ -49,9 +49,12 @@ EXAMPLES = r''' RETURN = r''' --- scaleway_snapshot_info: - description: Response from Scaleway API + description: + - Response from Scaleway API. + - "For more details please refer to: U(https://developers.scaleway.com/en/products/instance/api/)." returned: success - type: complex + type: list + elements: dict sample: "scaleway_snapshot_info": [ { diff --git a/plugins/modules/cloud/scaleway/scaleway_volume_info.py b/plugins/modules/cloud/scaleway/scaleway_volume_info.py index ff6093e830..0042146795 100644 --- a/plugins/modules/cloud/scaleway/scaleway_volume_info.py +++ b/plugins/modules/cloud/scaleway/scaleway_volume_info.py @@ -49,9 +49,12 @@ EXAMPLES = r''' RETURN = r''' --- scaleway_volume_info: - description: Response from Scaleway API + description: + - Response from Scaleway API. + - "For more details please refer to: U(https://developers.scaleway.com/en/products/instance/api/)." returned: success - type: complex + type: list + elements: dict sample: "scaleway_volume_info": [ { diff --git a/tests/sanity/ignore-2.10.txt b/tests/sanity/ignore-2.10.txt index d4ab945043..6a58e6b20a 100644 --- a/tests/sanity/ignore-2.10.txt +++ b/tests/sanity/ignore-2.10.txt @@ -11,13 +11,7 @@ plugins/modules/cloud/rackspace/rax_files.py validate-modules:parameter-state-in plugins/modules/cloud/rackspace/rax_files_objects.py use-argspec-type-path plugins/modules/cloud/rackspace/rax_mon_notification_plan.py validate-modules:parameter-list-no-elements plugins/modules/cloud/rackspace/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values -plugins/modules/cloud/scaleway/scaleway_image_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_ip_info.py validate-modules:return-syntax-error plugins/modules/cloud/scaleway/scaleway_organization_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_security_group_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_server_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_snapshot_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_volume_info.py validate-modules:return-syntax-error plugins/modules/cloud/smartos/vmadm.py validate-modules:parameter-type-not-in-doc plugins/modules/cloud/smartos/vmadm.py validate-modules:undocumented-parameter plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py validate-modules:parameter-list-no-elements diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 9795211211..69f021b9c6 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -10,13 +10,7 @@ plugins/modules/cloud/rackspace/rax_files.py validate-modules:parameter-state-in plugins/modules/cloud/rackspace/rax_files_objects.py use-argspec-type-path plugins/modules/cloud/rackspace/rax_mon_notification_plan.py validate-modules:parameter-list-no-elements plugins/modules/cloud/rackspace/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values -plugins/modules/cloud/scaleway/scaleway_image_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_ip_info.py validate-modules:return-syntax-error plugins/modules/cloud/scaleway/scaleway_organization_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_security_group_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_server_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_snapshot_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_volume_info.py validate-modules:return-syntax-error plugins/modules/cloud/smartos/vmadm.py validate-modules:parameter-type-not-in-doc plugins/modules/cloud/smartos/vmadm.py validate-modules:undocumented-parameter plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py validate-modules:parameter-list-no-elements diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index efa12cda04..2af0d25f6e 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -10,13 +10,7 @@ plugins/modules/cloud/rackspace/rax_files.py validate-modules:parameter-state-in plugins/modules/cloud/rackspace/rax_files_objects.py use-argspec-type-path plugins/modules/cloud/rackspace/rax_mon_notification_plan.py validate-modules:parameter-list-no-elements plugins/modules/cloud/rackspace/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values -plugins/modules/cloud/scaleway/scaleway_image_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_ip_info.py validate-modules:return-syntax-error plugins/modules/cloud/scaleway/scaleway_organization_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_security_group_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_server_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_snapshot_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_volume_info.py validate-modules:return-syntax-error plugins/modules/cloud/smartos/vmadm.py validate-modules:parameter-type-not-in-doc plugins/modules/cloud/smartos/vmadm.py validate-modules:undocumented-parameter plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py validate-modules:parameter-list-no-elements diff --git a/tests/sanity/ignore-2.9.txt b/tests/sanity/ignore-2.9.txt index e00cee8b52..06aff8d41c 100644 --- a/tests/sanity/ignore-2.9.txt +++ b/tests/sanity/ignore-2.9.txt @@ -8,13 +8,7 @@ plugins/modules/cloud/lxc/lxc_container.py validate-modules:use-run-command-not- plugins/modules/cloud/rackspace/rax.py use-argspec-type-path plugins/modules/cloud/rackspace/rax_files_objects.py use-argspec-type-path plugins/modules/cloud/rackspace/rax_scaling_group.py use-argspec-type-path # fix needed, expanduser() applied to dict values -plugins/modules/cloud/scaleway/scaleway_image_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_ip_info.py validate-modules:return-syntax-error plugins/modules/cloud/scaleway/scaleway_organization_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_security_group_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_server_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_snapshot_info.py validate-modules:return-syntax-error -plugins/modules/cloud/scaleway/scaleway_volume_info.py validate-modules:return-syntax-error plugins/modules/cloud/smartos/vmadm.py validate-modules:parameter-type-not-in-doc plugins/modules/cloud/smartos/vmadm.py validate-modules:undocumented-parameter plugins/modules/cloud/spotinst/spotinst_aws_elastigroup.py validate-modules:parameter-type-not-in-doc From 33f9f0b05ff47953fa96010994ef31f438d869eb Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 8 Jun 2021 10:59:02 +0200 Subject: [PATCH 137/139] with great powers come great responsibility (#2755) (#2759) (cherry picked from commit eef645c3f7c94d5086532feb29184f71e72ab994) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- .github/BOTMETA.yml | 2 -- commit-rights.md | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 6727373e85..d9f99c60dc 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -1,7 +1,5 @@ automerge: true files: - plugins/: - supershipit: russoz changelogs/fragments/: support: community $actions: diff --git a/commit-rights.md b/commit-rights.md index 7aae8617fb..9b39d47b2c 100644 --- a/commit-rights.md +++ b/commit-rights.md @@ -67,6 +67,7 @@ Individuals who have been asked to become a part of this group have generally be | Name | GitHub ID | IRC Nick | Other | | ------------------- | -------------------- | ------------------ | -------------------- | +| Alexei Znamensky | russoz | russoz | | | Amin Vakil | aminvakil | aminvakil | | | Andrew Klychkov | andersson007 | andersson007_ | | | Felix Fontein | felixfontein | felixfontein | | From a44356c966a083c57a94c684439e9b9dfce08de7 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 8 Jun 2021 12:09:49 +0200 Subject: [PATCH 138/139] Add domain option to onepassword lookup (#2735) (#2760) * Add domain to onepassword lookup * Add changelog * Add default to domain documentation * Improve format * Fix sanity issue * Add option type to documentation Co-authored-by: Felix Fontein * Add domain to init Co-authored-by: Felix Fontein (cherry picked from commit dab5d941e6ecc6401f97075eb9a5dabef984178e) Co-authored-by: Amin Vakil --- .../fragments/2735-onepassword-add_domain_option.yml | 3 +++ plugins/lookup/onepassword.py | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/2735-onepassword-add_domain_option.yml diff --git a/changelogs/fragments/2735-onepassword-add_domain_option.yml b/changelogs/fragments/2735-onepassword-add_domain_option.yml new file mode 100644 index 0000000000..eef74439ce --- /dev/null +++ b/changelogs/fragments/2735-onepassword-add_domain_option.yml @@ -0,0 +1,3 @@ +--- +minor_changes: + - onepassword lookup plugin - add ``domain`` option (https://github.com/ansible-collections/community.general/issues/2734). diff --git a/plugins/lookup/onepassword.py b/plugins/lookup/onepassword.py index a2346ed072..715c337ffd 100644 --- a/plugins/lookup/onepassword.py +++ b/plugins/lookup/onepassword.py @@ -30,6 +30,11 @@ DOCUMENTATION = ''' aliases: ['vault_password'] 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). + version_added: 3.2.0 + default: '1password.com' + type: str subdomain: description: The 1Password subdomain to authenticate against. username: @@ -109,6 +114,7 @@ class OnePass(object): self.logged_in = False self.token = None self.subdomain = None + self.domain = None self.username = None self.secret_key = None self.master_password = None @@ -168,7 +174,7 @@ class OnePass(object): args = [ 'signin', - '{0}.1password.com'.format(self.subdomain), + '{0}.{1}'.format(self.subdomain, self.domain), to_bytes(self.username), to_bytes(self.secret_key), '--output=raw', @@ -265,6 +271,7 @@ class LookupModule(LookupBase): section = kwargs.get('section') vault = kwargs.get('vault') op.subdomain = kwargs.get('subdomain') + op.domain = kwargs.get('domain', '1password.com') op.username = kwargs.get('username') op.secret_key = kwargs.get('secret_key') op.master_password = kwargs.get('master_password', kwargs.get('vault_password')) From f0c1b1065a2b19227fc6fd1bf22f6477a563153e Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 8 Jun 2021 14:47:09 +0200 Subject: [PATCH 139/139] Release 3.2.0. --- CHANGELOG.rst | 94 +++++++++++++ changelogs/changelog.yaml | 130 ++++++++++++++++++ .../fragments/2126-consul_kv-pass-token.yml | 4 - .../2461-ovirt4-fix-configparser.yml | 3 - .../2510-jenkins_plugin_use_post_method.yml | 2 - ...r-for-comment-operation-of-jira-module.yml | 2 - .../fragments/2557-cloud-misc-refactor.yml | 7 - .../2560-java_cert-pkcs12-alias-bugfix.yml | 2 - .../fragments/2564-mh-cmd-process-output.yml | 2 - ...reduce-stormssh-searches-based-on-host.yml | 2 - ...2571-rhsm_release-fix-release_matcher.yaml | 2 - .../2573-terraform-overwrite-init.yml | 2 - .../fragments/2578-ini-file-utf8-bom.yml | 2 - .../fragments/2579-redis-cache-ipv6.yml | 2 - ...0-netcup_dns-exception-no-message-attr.yml | 2 - ...b_user-fix-issue-introduced-in-PR#2499.yml | 2 - ...2616-archive-exclusion_patterns-option.yml | 2 - changelogs/fragments/2632-cleanup.yml | 2 - .../2634-terraform-switch-workspace.yml | 2 - .../2635-nmcli-add-ignore-auto-arguments.yml | 2 - ...2648-proxmox_kvm-fix-vmid-return-value.yml | 2 - .../2650-composer-add_composer_executable.yml | 3 - .../2661-maven_artifact-add-sha1-option.yml | 2 - ...ix-broken-query-of-async_status-result.yml | 6 - .../fragments/2681-stacki-host-bugfix.yml | 4 - ...ingle-target-multiple-portal-overrides.yml | 3 - ...-iptables_state-2700-async_status-call.yml | 4 - ...potency_on_adding_repo_with_releasever.yml | 5 - changelogs/fragments/2731-mh-cmd-locale.yml | 4 - .../2735-onepassword-add_domain_option.yml | 3 - .../2751-flatpak-no_dependencies.yml | 2 - changelogs/fragments/3.2.0.yml | 1 - .../fragments/json_query_more_types.yml | 3 - .../keycloak-realm-no-log-password-reset.yml | 2 - .../fragments/keycloak_realm_ssl_required.yml | 3 - changelogs/fragments/script-removal.yml | 2 - 36 files changed, 224 insertions(+), 93 deletions(-) delete mode 100644 changelogs/fragments/2126-consul_kv-pass-token.yml delete mode 100644 changelogs/fragments/2461-ovirt4-fix-configparser.yml delete mode 100644 changelogs/fragments/2510-jenkins_plugin_use_post_method.yml delete mode 100644 changelogs/fragments/2556-add-comment_visibility-parameter-for-comment-operation-of-jira-module.yml delete mode 100644 changelogs/fragments/2557-cloud-misc-refactor.yml delete mode 100644 changelogs/fragments/2560-java_cert-pkcs12-alias-bugfix.yml delete mode 100644 changelogs/fragments/2564-mh-cmd-process-output.yml delete mode 100644 changelogs/fragments/2568-ssh_config-reduce-stormssh-searches-based-on-host.yml delete mode 100644 changelogs/fragments/2571-rhsm_release-fix-release_matcher.yaml delete mode 100644 changelogs/fragments/2573-terraform-overwrite-init.yml delete mode 100644 changelogs/fragments/2578-ini-file-utf8-bom.yml delete mode 100644 changelogs/fragments/2579-redis-cache-ipv6.yml delete mode 100644 changelogs/fragments/2590-netcup_dns-exception-no-message-attr.yml delete mode 100644 changelogs/fragments/2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml delete mode 100644 changelogs/fragments/2616-archive-exclusion_patterns-option.yml delete mode 100644 changelogs/fragments/2632-cleanup.yml delete mode 100644 changelogs/fragments/2634-terraform-switch-workspace.yml delete mode 100644 changelogs/fragments/2635-nmcli-add-ignore-auto-arguments.yml delete mode 100644 changelogs/fragments/2648-proxmox_kvm-fix-vmid-return-value.yml delete mode 100644 changelogs/fragments/2650-composer-add_composer_executable.yml delete mode 100644 changelogs/fragments/2661-maven_artifact-add-sha1-option.yml delete mode 100644 changelogs/fragments/2671-fix-broken-query-of-async_status-result.yml delete mode 100644 changelogs/fragments/2681-stacki-host-bugfix.yml delete mode 100644 changelogs/fragments/2684-open_iscsi-single-target-multiple-portal-overrides.yml delete mode 100644 changelogs/fragments/2711-fix-iptables_state-2700-async_status-call.yml delete mode 100644 changelogs/fragments/2722-zypper_repository-fix_idempotency_on_adding_repo_with_releasever.yml delete mode 100644 changelogs/fragments/2731-mh-cmd-locale.yml delete mode 100644 changelogs/fragments/2735-onepassword-add_domain_option.yml delete mode 100644 changelogs/fragments/2751-flatpak-no_dependencies.yml delete mode 100644 changelogs/fragments/3.2.0.yml delete mode 100644 changelogs/fragments/json_query_more_types.yml delete mode 100644 changelogs/fragments/keycloak-realm-no-log-password-reset.yml delete mode 100644 changelogs/fragments/keycloak_realm_ssl_required.yml delete mode 100644 changelogs/fragments/script-removal.yml diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5ae15a68d4..bc968361bf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,100 @@ Community General Release Notes This changelog describes changes after version 2.0.0. +v3.2.0 +====== + +Release Summary +--------------- + +Regular bugfix and feature release. + +Minor Changes +------------- + +- Remove unnecessary ``__init__.py`` files from ``plugins/`` (https://github.com/ansible-collections/community.general/pull/2632). +- archive - added ``exclusion_patterns`` option to exclude files or subdirectories from archives (https://github.com/ansible-collections/community.general/pull/2616). +- cloud_init_data_facts - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). +- composer - add ``composer_executable`` option (https://github.com/ansible-collections/community.general/issues/2649). +- flatpak - add ``no_dependencies`` parameter (https://github.com/ansible/ansible/pull/55452, https://github.com/ansible-collections/community.general/pull/2751). +- ini_file - opening file with encoding ``utf-8-sig`` (https://github.com/ansible-collections/community.general/issues/2189). +- jira - add comment visibility parameter for comment operation (https://github.com/ansible-collections/community.general/pull/2556). +- maven_artifact - added ``checksum_alg`` option to support SHA1 checksums in order to support FIPS systems (https://github.com/ansible-collections/community.general/pull/2662). +- module_helper module utils - method ``CmdMixin.run_command()`` now accepts ``process_output`` specifying a function to process the outcome of the underlying ``module.run_command()`` (https://github.com/ansible-collections/community.general/pull/2564). +- nmcli - add new options to ignore automatic DNS servers and gateways (https://github.com/ansible-collections/community.general/issues/1087). +- onepassword lookup plugin - add ``domain`` option (https://github.com/ansible-collections/community.general/issues/2734). +- open_iscsi - add ``auto_portal_startup`` parameter to allow ``node.startup`` setting per portal (https://github.com/ansible-collections/community.general/issues/2685). +- open_iscsi - also consider ``portal`` and ``port`` to check if already logged in or not (https://github.com/ansible-collections/community.general/issues/2683). +- proxmox_group_info - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). +- proxmox_kvm - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). +- rhevm - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). +- serverless - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). +- stacki_host - minor refactoring (https://github.com/ansible-collections/community.general/pull/2681). +- terraform - add option ``overwrite_init`` to skip init if exists (https://github.com/ansible-collections/community.general/pull/2573). +- terraform - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). + +Deprecated Features +------------------- + +- All inventory and vault scripts will be removed from community.general in version 4.0.0. If you are referencing them, please update your references to the new `contrib-scripts GitHub repository `_ so your workflow will not break once community.general 4.0.0 is released (https://github.com/ansible-collections/community.general/pull/2697). + +Bugfixes +-------- + +- consul_kv lookup plugin - allow to set ``recurse``, ``index``, ``datacenter`` and ``token`` as keyword arguments (https://github.com/ansible-collections/community.general/issues/2124). +- cpanm - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/pull/2731). +- influxdb_user - fix bug which removed current privileges instead of appending them to existing ones (https://github.com/ansible-collections/community.general/issues/2609, https://github.com/ansible-collections/community.general/pull/2614). +- iptables_state - call ``async_status`` action plugin rather than its module (https://github.com/ansible-collections/community.general/issues/2700). +- iptables_state - fix a broken query of ``async_status`` result with current ansible-core development version (https://github.com/ansible-collections/community.general/issues/2627, https://github.com/ansible-collections/community.general/pull/2671). +- java_cert - fix issue with incorrect alias used on PKCS#12 certificate import (https://github.com/ansible-collections/community.general/pull/2560). +- jenkins_plugin - use POST method for sending request to jenkins API when ``state`` option is one of ``enabled``, ``disabled``, ``pinned``, ``unpinned``, or ``absent`` (https://github.com/ansible-collections/community.general/issues/2510). +- json_query filter plugin - avoid 'unknown type' errors for more Ansible internal types (https://github.com/ansible-collections/community.general/pull/2607). +- keycloak_realm - ``ssl_required`` changed from a boolean type to accept the strings ``none``, ``external`` or ``all``. This is not a breaking change since the module always failed when a boolean was supplied (https://github.com/ansible-collections/community.general/pull/2693). +- keycloak_realm - remove warning that ``reset_password_allowed`` needs to be marked as ``no_log`` (https://github.com/ansible-collections/community.general/pull/2694). +- module_helper module utils - ``CmdMixin`` must also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/pull/2731). +- netcup_dns - use ``str(ex)`` instead of unreliable ``ex.message`` in exception handling to fix ``AttributeError`` in error cases (https://github.com/ansible-collections/community.general/pull/2590). +- ovir4 inventory script - improve configparser creation to avoid crashes for options without values (https://github.com/ansible-collections/community.general/issues/674). +- proxmox_kvm - fixed ``vmid`` return value when VM with ``name`` already exists (https://github.com/ansible-collections/community.general/issues/2648). +- redis cache - improved connection string parsing (https://github.com/ansible-collections/community.general/issues/497). +- rhsm_release - fix the issue that module considers 8, 7Client and 7Workstation as invalid releases (https://github.com/ansible-collections/community.general/pull/2571). +- ssh_config - reduce stormssh searches based on host (https://github.com/ansible-collections/community.general/pull/2568/). +- stacki_host - when adding a new server, ``rack`` and ``rank`` must be passed, and network parameters are optional (https://github.com/ansible-collections/community.general/pull/2681). +- terraform - ensure the workspace is set back to its previous value when the apply fails (https://github.com/ansible-collections/community.general/pull/2634). +- xfconf - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/issues/2715). +- zypper_repository - fix idempotency on adding repository with ``$releasever`` and ``$basearch`` variables (https://github.com/ansible-collections/community.general/issues/1985). + +New Plugins +----------- + +Lookup +~~~~~~ + +- random_string - Generates random string + +New Modules +----------- + +Database +~~~~~~~~ + +saphana +^^^^^^^ + +- hana_query - Execute SQL on HANA + +Files +~~~~~ + +- sapcar_extract - Manages SAP SAPCAR archives + +Packaging +~~~~~~~~~ + +os +^^ + +- pacman_key - Manage pacman's list of trusted keys + v3.1.0 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index b51e963768..b4eb74fac4 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -1156,3 +1156,133 @@ releases: name: random_pet namespace: null release_date: '2021-05-18' + 3.2.0: + changes: + bugfixes: + - consul_kv lookup plugin - allow to set ``recurse``, ``index``, ``datacenter`` + and ``token`` as keyword arguments (https://github.com/ansible-collections/community.general/issues/2124). + - cpanm - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/pull/2731). + - influxdb_user - fix bug which removed current privileges instead of appending + them to existing ones (https://github.com/ansible-collections/community.general/issues/2609, + https://github.com/ansible-collections/community.general/pull/2614). + - iptables_state - call ``async_status`` action plugin rather than its module + (https://github.com/ansible-collections/community.general/issues/2700). + - iptables_state - fix a broken query of ``async_status`` result with current + ansible-core development version (https://github.com/ansible-collections/community.general/issues/2627, + https://github.com/ansible-collections/community.general/pull/2671). + - java_cert - fix issue with incorrect alias used on PKCS#12 certificate import + (https://github.com/ansible-collections/community.general/pull/2560). + - jenkins_plugin - use POST method for sending request to jenkins API when ``state`` + option is one of ``enabled``, ``disabled``, ``pinned``, ``unpinned``, or ``absent`` + (https://github.com/ansible-collections/community.general/issues/2510). + - json_query filter plugin - avoid 'unknown type' errors for more Ansible internal + types (https://github.com/ansible-collections/community.general/pull/2607). + - keycloak_realm - ``ssl_required`` changed from a boolean type to accept the + strings ``none``, ``external`` or ``all``. This is not a breaking change since + the module always failed when a boolean was supplied (https://github.com/ansible-collections/community.general/pull/2693). + - keycloak_realm - remove warning that ``reset_password_allowed`` needs to be + marked as ``no_log`` (https://github.com/ansible-collections/community.general/pull/2694). + - module_helper module utils - ``CmdMixin`` must also use ``LC_ALL`` to enforce + locale choice (https://github.com/ansible-collections/community.general/pull/2731). + - netcup_dns - use ``str(ex)`` instead of unreliable ``ex.message`` in exception + handling to fix ``AttributeError`` in error cases (https://github.com/ansible-collections/community.general/pull/2590). + - ovir4 inventory script - improve configparser creation to avoid crashes for + options without values (https://github.com/ansible-collections/community.general/issues/674). + - proxmox_kvm - fixed ``vmid`` return value when VM with ``name`` already exists + (https://github.com/ansible-collections/community.general/issues/2648). + - redis cache - improved connection string parsing (https://github.com/ansible-collections/community.general/issues/497). + - rhsm_release - fix the issue that module considers 8, 7Client and 7Workstation + as invalid releases (https://github.com/ansible-collections/community.general/pull/2571). + - ssh_config - reduce stormssh searches based on host (https://github.com/ansible-collections/community.general/pull/2568/). + - stacki_host - when adding a new server, ``rack`` and ``rank`` must be passed, + and network parameters are optional (https://github.com/ansible-collections/community.general/pull/2681). + - terraform - ensure the workspace is set back to its previous value when the + apply fails (https://github.com/ansible-collections/community.general/pull/2634). + - xfconf - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/issues/2715). + - zypper_repository - fix idempotency on adding repository with ``$releasever`` + and ``$basearch`` variables (https://github.com/ansible-collections/community.general/issues/1985). + deprecated_features: + - All inventory and vault scripts will be removed from community.general in + version 4.0.0. If you are referencing them, please update your references + to the new `contrib-scripts GitHub repository `_ + so your workflow will not break once community.general 4.0.0 is released (https://github.com/ansible-collections/community.general/pull/2697). + minor_changes: + - Remove unnecessary ``__init__.py`` files from ``plugins/`` (https://github.com/ansible-collections/community.general/pull/2632). + - archive - added ``exclusion_patterns`` option to exclude files or subdirectories + from archives (https://github.com/ansible-collections/community.general/pull/2616). + - cloud_init_data_facts - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). + - composer - add ``composer_executable`` option (https://github.com/ansible-collections/community.general/issues/2649). + - flatpak - add ``no_dependencies`` parameter (https://github.com/ansible/ansible/pull/55452, + https://github.com/ansible-collections/community.general/pull/2751). + - ini_file - opening file with encoding ``utf-8-sig`` (https://github.com/ansible-collections/community.general/issues/2189). + - jira - add comment visibility parameter for comment operation (https://github.com/ansible-collections/community.general/pull/2556). + - maven_artifact - added ``checksum_alg`` option to support SHA1 checksums in + order to support FIPS systems (https://github.com/ansible-collections/community.general/pull/2662). + - module_helper module utils - method ``CmdMixin.run_command()`` now accepts + ``process_output`` specifying a function to process the outcome of the underlying + ``module.run_command()`` (https://github.com/ansible-collections/community.general/pull/2564). + - nmcli - add new options to ignore automatic DNS servers and gateways (https://github.com/ansible-collections/community.general/issues/1087). + - onepassword lookup plugin - add ``domain`` option (https://github.com/ansible-collections/community.general/issues/2734). + - open_iscsi - add ``auto_portal_startup`` parameter to allow ``node.startup`` + setting per portal (https://github.com/ansible-collections/community.general/issues/2685). + - open_iscsi - also consider ``portal`` and ``port`` to check if already logged + in or not (https://github.com/ansible-collections/community.general/issues/2683). + - proxmox_group_info - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). + - proxmox_kvm - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). + - rhevm - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). + - serverless - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). + - stacki_host - minor refactoring (https://github.com/ansible-collections/community.general/pull/2681). + - terraform - add option ``overwrite_init`` to skip init if exists (https://github.com/ansible-collections/community.general/pull/2573). + - terraform - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). + release_summary: Regular bugfix and feature release. + fragments: + - 2126-consul_kv-pass-token.yml + - 2461-ovirt4-fix-configparser.yml + - 2510-jenkins_plugin_use_post_method.yml + - 2556-add-comment_visibility-parameter-for-comment-operation-of-jira-module.yml + - 2557-cloud-misc-refactor.yml + - 2560-java_cert-pkcs12-alias-bugfix.yml + - 2564-mh-cmd-process-output.yml + - 2568-ssh_config-reduce-stormssh-searches-based-on-host.yml + - 2571-rhsm_release-fix-release_matcher.yaml + - 2573-terraform-overwrite-init.yml + - 2578-ini-file-utf8-bom.yml + - 2579-redis-cache-ipv6.yml + - 2590-netcup_dns-exception-no-message-attr.yml + - 2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml + - 2616-archive-exclusion_patterns-option.yml + - 2632-cleanup.yml + - 2634-terraform-switch-workspace.yml + - 2635-nmcli-add-ignore-auto-arguments.yml + - 2648-proxmox_kvm-fix-vmid-return-value.yml + - 2650-composer-add_composer_executable.yml + - 2661-maven_artifact-add-sha1-option.yml + - 2671-fix-broken-query-of-async_status-result.yml + - 2681-stacki-host-bugfix.yml + - 2684-open_iscsi-single-target-multiple-portal-overrides.yml + - 2711-fix-iptables_state-2700-async_status-call.yml + - 2722-zypper_repository-fix_idempotency_on_adding_repo_with_releasever.yml + - 2731-mh-cmd-locale.yml + - 2735-onepassword-add_domain_option.yml + - 2751-flatpak-no_dependencies.yml + - 3.2.0.yml + - json_query_more_types.yml + - keycloak-realm-no-log-password-reset.yml + - keycloak_realm_ssl_required.yml + - script-removal.yml + modules: + - description: Execute SQL on HANA + name: hana_query + namespace: database.saphana + - description: Manage pacman's list of trusted keys + name: pacman_key + namespace: packaging.os + - description: Manages SAP SAPCAR archives + name: sapcar_extract + namespace: files + plugins: + lookup: + - description: Generates random string + name: random_string + namespace: null + release_date: '2021-06-08' diff --git a/changelogs/fragments/2126-consul_kv-pass-token.yml b/changelogs/fragments/2126-consul_kv-pass-token.yml deleted file mode 100644 index a60fd2efcd..0000000000 --- a/changelogs/fragments/2126-consul_kv-pass-token.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -bugfixes: - - consul_kv lookup plugin - allow to set ``recurse``, ``index``, ``datacenter`` and ``token`` as keyword arguments - (https://github.com/ansible-collections/community.general/issues/2124). diff --git a/changelogs/fragments/2461-ovirt4-fix-configparser.yml b/changelogs/fragments/2461-ovirt4-fix-configparser.yml deleted file mode 100644 index 6e3845b21a..0000000000 --- a/changelogs/fragments/2461-ovirt4-fix-configparser.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - ovir4 inventory script - improve configparser creation to avoid crashes for options without values (https://github.com/ansible-collections/community.general/issues/674). diff --git a/changelogs/fragments/2510-jenkins_plugin_use_post_method.yml b/changelogs/fragments/2510-jenkins_plugin_use_post_method.yml deleted file mode 100644 index b310e27061..0000000000 --- a/changelogs/fragments/2510-jenkins_plugin_use_post_method.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - jenkins_plugin - use POST method for sending request to jenkins API when ``state`` option is one of ``enabled``, ``disabled``, ``pinned``, ``unpinned``, or ``absent`` (https://github.com/ansible-collections/community.general/issues/2510). diff --git a/changelogs/fragments/2556-add-comment_visibility-parameter-for-comment-operation-of-jira-module.yml b/changelogs/fragments/2556-add-comment_visibility-parameter-for-comment-operation-of-jira-module.yml deleted file mode 100644 index e31fad744a..0000000000 --- a/changelogs/fragments/2556-add-comment_visibility-parameter-for-comment-operation-of-jira-module.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - jira - add comment visibility parameter for comment operation (https://github.com/ansible-collections/community.general/pull/2556). diff --git a/changelogs/fragments/2557-cloud-misc-refactor.yml b/changelogs/fragments/2557-cloud-misc-refactor.yml deleted file mode 100644 index 82e56dc942..0000000000 --- a/changelogs/fragments/2557-cloud-misc-refactor.yml +++ /dev/null @@ -1,7 +0,0 @@ -minor_changes: - - cloud_init_data_facts - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). - - proxmox_group_info - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). - - proxmox_kvm - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). - - rhevm - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). - - serverless - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). - - terraform - minor refactor (https://github.com/ansible-collections/community.general/pull/2557). diff --git a/changelogs/fragments/2560-java_cert-pkcs12-alias-bugfix.yml b/changelogs/fragments/2560-java_cert-pkcs12-alias-bugfix.yml deleted file mode 100644 index 471962d74f..0000000000 --- a/changelogs/fragments/2560-java_cert-pkcs12-alias-bugfix.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - "java_cert - fix issue with incorrect alias used on PKCS#12 certificate import (https://github.com/ansible-collections/community.general/pull/2560)." diff --git a/changelogs/fragments/2564-mh-cmd-process-output.yml b/changelogs/fragments/2564-mh-cmd-process-output.yml deleted file mode 100644 index 717c0d7fbb..0000000000 --- a/changelogs/fragments/2564-mh-cmd-process-output.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - module_helper module utils - method ``CmdMixin.run_command()`` now accepts ``process_output`` specifying a function to process the outcome of the underlying ``module.run_command()`` (https://github.com/ansible-collections/community.general/pull/2564). diff --git a/changelogs/fragments/2568-ssh_config-reduce-stormssh-searches-based-on-host.yml b/changelogs/fragments/2568-ssh_config-reduce-stormssh-searches-based-on-host.yml deleted file mode 100644 index 2f3e400e7e..0000000000 --- a/changelogs/fragments/2568-ssh_config-reduce-stormssh-searches-based-on-host.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - ssh_config - reduce stormssh searches based on host (https://github.com/ansible-collections/community.general/pull/2568/). diff --git a/changelogs/fragments/2571-rhsm_release-fix-release_matcher.yaml b/changelogs/fragments/2571-rhsm_release-fix-release_matcher.yaml deleted file mode 100644 index 764743303f..0000000000 --- a/changelogs/fragments/2571-rhsm_release-fix-release_matcher.yaml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - rhsm_release - fix the issue that module considers 8, 7Client and 7Workstation as invalid releases (https://github.com/ansible-collections/community.general/pull/2571). diff --git a/changelogs/fragments/2573-terraform-overwrite-init.yml b/changelogs/fragments/2573-terraform-overwrite-init.yml deleted file mode 100644 index f2dad6a7ee..0000000000 --- a/changelogs/fragments/2573-terraform-overwrite-init.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - terraform - add option ``overwrite_init`` to skip init if exists (https://github.com/ansible-collections/community.general/pull/2573). diff --git a/changelogs/fragments/2578-ini-file-utf8-bom.yml b/changelogs/fragments/2578-ini-file-utf8-bom.yml deleted file mode 100644 index 00640c0b23..0000000000 --- a/changelogs/fragments/2578-ini-file-utf8-bom.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - ini_file - opening file with encoding ``utf-8-sig`` (https://github.com/ansible-collections/community.general/issues/2189). diff --git a/changelogs/fragments/2579-redis-cache-ipv6.yml b/changelogs/fragments/2579-redis-cache-ipv6.yml deleted file mode 100644 index aaa5e78b34..0000000000 --- a/changelogs/fragments/2579-redis-cache-ipv6.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - redis cache - improved connection string parsing (https://github.com/ansible-collections/community.general/issues/497). diff --git a/changelogs/fragments/2590-netcup_dns-exception-no-message-attr.yml b/changelogs/fragments/2590-netcup_dns-exception-no-message-attr.yml deleted file mode 100644 index 06cac9ad1b..0000000000 --- a/changelogs/fragments/2590-netcup_dns-exception-no-message-attr.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - netcup_dns - use ``str(ex)`` instead of unreliable ``ex.message`` in exception handling to fix ``AttributeError`` in error cases (https://github.com/ansible-collections/community.general/pull/2590). diff --git a/changelogs/fragments/2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml b/changelogs/fragments/2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml deleted file mode 100644 index dfae3f2bdf..0000000000 --- a/changelogs/fragments/2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - influxdb_user - fix bug which removed current privileges instead of appending them to existing ones (https://github.com/ansible-collections/community.general/issues/2609, https://github.com/ansible-collections/community.general/pull/2614). diff --git a/changelogs/fragments/2616-archive-exclusion_patterns-option.yml b/changelogs/fragments/2616-archive-exclusion_patterns-option.yml deleted file mode 100644 index 86ef806b63..0000000000 --- a/changelogs/fragments/2616-archive-exclusion_patterns-option.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - archive - added ``exclusion_patterns`` option to exclude files or subdirectories from archives (https://github.com/ansible-collections/community.general/pull/2616). diff --git a/changelogs/fragments/2632-cleanup.yml b/changelogs/fragments/2632-cleanup.yml deleted file mode 100644 index def89de634..0000000000 --- a/changelogs/fragments/2632-cleanup.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: -- "Remove unnecessary ``__init__.py`` files from ``plugins/`` (https://github.com/ansible-collections/community.general/pull/2632)." diff --git a/changelogs/fragments/2634-terraform-switch-workspace.yml b/changelogs/fragments/2634-terraform-switch-workspace.yml deleted file mode 100644 index 247447b3a8..0000000000 --- a/changelogs/fragments/2634-terraform-switch-workspace.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - terraform - ensure the workspace is set back to its previous value when the apply fails (https://github.com/ansible-collections/community.general/pull/2634). diff --git a/changelogs/fragments/2635-nmcli-add-ignore-auto-arguments.yml b/changelogs/fragments/2635-nmcli-add-ignore-auto-arguments.yml deleted file mode 100644 index e75ceb6a1b..0000000000 --- a/changelogs/fragments/2635-nmcli-add-ignore-auto-arguments.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - nmcli - add new options to ignore automatic DNS servers and gateways (https://github.com/ansible-collections/community.general/issues/1087). diff --git a/changelogs/fragments/2648-proxmox_kvm-fix-vmid-return-value.yml b/changelogs/fragments/2648-proxmox_kvm-fix-vmid-return-value.yml deleted file mode 100644 index 7971fc24eb..0000000000 --- a/changelogs/fragments/2648-proxmox_kvm-fix-vmid-return-value.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - proxmox_kvm - fixed ``vmid`` return value when VM with ``name`` already exists (https://github.com/ansible-collections/community.general/issues/2648). diff --git a/changelogs/fragments/2650-composer-add_composer_executable.yml b/changelogs/fragments/2650-composer-add_composer_executable.yml deleted file mode 100644 index b1cccc689c..0000000000 --- a/changelogs/fragments/2650-composer-add_composer_executable.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: - - composer - add ``composer_executable`` option (https://github.com/ansible-collections/community.general/issues/2649). diff --git a/changelogs/fragments/2661-maven_artifact-add-sha1-option.yml b/changelogs/fragments/2661-maven_artifact-add-sha1-option.yml deleted file mode 100644 index 827942200b..0000000000 --- a/changelogs/fragments/2661-maven_artifact-add-sha1-option.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: - - maven_artifact - added ``checksum_alg`` option to support SHA1 checksums in order to support FIPS systems (https://github.com/ansible-collections/community.general/pull/2662). diff --git a/changelogs/fragments/2671-fix-broken-query-of-async_status-result.yml b/changelogs/fragments/2671-fix-broken-query-of-async_status-result.yml deleted file mode 100644 index 993caaa323..0000000000 --- a/changelogs/fragments/2671-fix-broken-query-of-async_status-result.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -bugfixes: - - "iptables_state - fix a broken query of ``async_status`` result - with current ansible-core development version - (https://github.com/ansible-collections/community.general/issues/2627, - https://github.com/ansible-collections/community.general/pull/2671)." diff --git a/changelogs/fragments/2681-stacki-host-bugfix.yml b/changelogs/fragments/2681-stacki-host-bugfix.yml deleted file mode 100644 index 3403bfbfbe..0000000000 --- a/changelogs/fragments/2681-stacki-host-bugfix.yml +++ /dev/null @@ -1,4 +0,0 @@ -bugfixes: - - stacki_host - when adding a new server, ``rack`` and ``rank`` must be passed, and network parameters are optional (https://github.com/ansible-collections/community.general/pull/2681). -minor_changes: - - stacki_host - minor refactoring (https://github.com/ansible-collections/community.general/pull/2681). diff --git a/changelogs/fragments/2684-open_iscsi-single-target-multiple-portal-overrides.yml b/changelogs/fragments/2684-open_iscsi-single-target-multiple-portal-overrides.yml deleted file mode 100644 index cb14a08ba0..0000000000 --- a/changelogs/fragments/2684-open_iscsi-single-target-multiple-portal-overrides.yml +++ /dev/null @@ -1,3 +0,0 @@ -minor_changes: - - open_iscsi - also consider ``portal`` and ``port`` to check if already logged in or not (https://github.com/ansible-collections/community.general/issues/2683). - - open_iscsi - add ``auto_portal_startup`` parameter to allow ``node.startup`` setting per portal (https://github.com/ansible-collections/community.general/issues/2685). diff --git a/changelogs/fragments/2711-fix-iptables_state-2700-async_status-call.yml b/changelogs/fragments/2711-fix-iptables_state-2700-async_status-call.yml deleted file mode 100644 index 8f94cf5178..0000000000 --- a/changelogs/fragments/2711-fix-iptables_state-2700-async_status-call.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -bugfixes: - - "iptables_state - call ``async_status`` action plugin rather than its module - (https://github.com/ansible-collections/community.general/issues/2700)." diff --git a/changelogs/fragments/2722-zypper_repository-fix_idempotency_on_adding_repo_with_releasever.yml b/changelogs/fragments/2722-zypper_repository-fix_idempotency_on_adding_repo_with_releasever.yml deleted file mode 100644 index faada2e9bf..0000000000 --- a/changelogs/fragments/2722-zypper_repository-fix_idempotency_on_adding_repo_with_releasever.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -bugfixes: - - zypper_repository - fix idempotency on adding repository with - ``$releasever`` and ``$basearch`` variables - (https://github.com/ansible-collections/community.general/issues/1985). diff --git a/changelogs/fragments/2731-mh-cmd-locale.yml b/changelogs/fragments/2731-mh-cmd-locale.yml deleted file mode 100644 index b917493f4c..0000000000 --- a/changelogs/fragments/2731-mh-cmd-locale.yml +++ /dev/null @@ -1,4 +0,0 @@ -bugfixes: - - module_helper module utils - ``CmdMixin`` must also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/pull/2731). - - xfconf - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/issues/2715). - - cpanm - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/pull/2731). diff --git a/changelogs/fragments/2735-onepassword-add_domain_option.yml b/changelogs/fragments/2735-onepassword-add_domain_option.yml deleted file mode 100644 index eef74439ce..0000000000 --- a/changelogs/fragments/2735-onepassword-add_domain_option.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -minor_changes: - - onepassword lookup plugin - add ``domain`` option (https://github.com/ansible-collections/community.general/issues/2734). diff --git a/changelogs/fragments/2751-flatpak-no_dependencies.yml b/changelogs/fragments/2751-flatpak-no_dependencies.yml deleted file mode 100644 index a07ead96da..0000000000 --- a/changelogs/fragments/2751-flatpak-no_dependencies.yml +++ /dev/null @@ -1,2 +0,0 @@ -minor_changes: -- "flatpak - add ``no_dependencies`` parameter (https://github.com/ansible/ansible/pull/55452, https://github.com/ansible-collections/community.general/pull/2751)." diff --git a/changelogs/fragments/3.2.0.yml b/changelogs/fragments/3.2.0.yml deleted file mode 100644 index 4b1469c9fe..0000000000 --- a/changelogs/fragments/3.2.0.yml +++ /dev/null @@ -1 +0,0 @@ -release_summary: Regular bugfix and feature release. diff --git a/changelogs/fragments/json_query_more_types.yml b/changelogs/fragments/json_query_more_types.yml deleted file mode 100644 index 4ac69b67c0..0000000000 --- a/changelogs/fragments/json_query_more_types.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - json_query filter plugin - avoid 'unknown type' errors for more Ansible internal types (https://github.com/ansible-collections/community.general/pull/2607). diff --git a/changelogs/fragments/keycloak-realm-no-log-password-reset.yml b/changelogs/fragments/keycloak-realm-no-log-password-reset.yml deleted file mode 100644 index 104bf4179b..0000000000 --- a/changelogs/fragments/keycloak-realm-no-log-password-reset.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - keycloak_realm - remove warning that ``reset_password_allowed`` needs to be marked as ``no_log`` (https://github.com/ansible-collections/community.general/pull/2694). diff --git a/changelogs/fragments/keycloak_realm_ssl_required.yml b/changelogs/fragments/keycloak_realm_ssl_required.yml deleted file mode 100644 index 7476612e2f..0000000000 --- a/changelogs/fragments/keycloak_realm_ssl_required.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -bugfixes: - - keycloak_realm - ``ssl_required`` changed from a boolean type to accept the strings ``none``, ``external`` or ``all``. This is not a breaking change since the module always failed when a boolean was supplied (https://github.com/ansible-collections/community.general/pull/2693). diff --git a/changelogs/fragments/script-removal.yml b/changelogs/fragments/script-removal.yml deleted file mode 100644 index be17f6ad65..0000000000 --- a/changelogs/fragments/script-removal.yml +++ /dev/null @@ -1,2 +0,0 @@ -deprecated_features: -- "All inventory and vault scripts will be removed from community.general in version 4.0.0. If you are referencing them, please update your references to the new `contrib-scripts GitHub repository `_ so your workflow will not break once community.general 4.0.0 is released (https://github.com/ansible-collections/community.general/pull/2697)."