Compare commits

..

60 Commits

Author SHA1 Message Date
Felix Fontein
3f46cdc588 Release 2.1.1. 2021-02-17 21:49:42 +01:00
Felix Fontein
ea530784b8 Adjust version. 2021-02-17 21:46:40 +01:00
patchback[bot]
dc2fa05b1f proxmox_kvm: fix undefined local variable status (#1847) (#1851)
* proxmox_kvm: undefined local variable status

* proxmox_kvm: Add a changelog fragment

* Update changelogs/fragments/1847-proxmox-kvm-fix-status.yml

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

* proxmox_kvm: fix the RETURN document

* proxmox_kvm: fix name variable when state=current

The variable name is not always defined as the module can be called with
just a vmid.

Before:

> "msg": "VM None with vmid = 118 is stopped"

After:

> "msg": "VM test-instance with vmid = 118 is stopped"

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

Co-authored-by: Tristan Le Guern <tristan.leguern-presta@deveryware.com>
2021-02-17 21:44:02 +01:00
Felix Fontein
b2e51272ad Prepare 2.1.0 release. 2021-02-17 21:33:57 +01:00
Felix Fontein
afba9a11af Revert new feature so that we can make a bugfix release. Will re-revert this afterwards.
Revert "runit - deprecate param dist (#1838) (#1845)"

This reverts commit c3ac479ae2.
2021-02-17 21:32:16 +01:00
patchback[bot]
c3ac479ae2 runit - deprecate param dist (#1838) (#1845)
* Deprecate param dist

* added changelog fragment

* added changelog fragment

* Removed ignore lines for runit

(cherry picked from commit e0dd4b240f)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-02-17 08:01:13 +01:00
Felix Fontein
7e367244f7 Next expected release is 2.2.0. 2021-02-16 13:36:12 +01:00
Felix Fontein
331d2c7651 Release 2.1.0. 2021-02-16 12:13:27 +01:00
patchback[bot]
b35a262378 StatsD Module (#1793) (#1842)
* Pushing my WIP

* Update DOCUMENTATION

* Update EXAMPLES

* More friendly name

* Finish up the counter and gauge logic

* Cleanup DOCUMENTATION and add metric_type

* Apply autopep8

* Fixup the exits

* Stubbing out unit tests

* Whitespace

* Whitespace

* Removing unused modules

* Remove unused modules

* Might have have a prefix

* Rearrange imported modules

* Cleanup the if/elif blob

* Require python >= 2.7

* Update DOCUMENTATION

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

* Update DOCUMENTATION

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

* Add import guarding on statsd

* Add missing future import

* Include missing_required_lib

* Fixing sanity tests

* Fixing delta default and choices

* Formatting

* Close tcp connection

* Refactoring and unit tests

* Fix pep8 sanity tests

* Putting requirements.txt back to main

* Apply suggestions from code review

Co-authored-by: Mark Mercado <mmercado@digitalocean.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 6165438689)

Co-authored-by: Mark Mercado <mamercad@gmail.com>
2021-02-16 12:09:58 +01:00
patchback[bot]
7d400663b6 Previously LXD profiles were overwritten, now these are merged. (#1813) (#1836)
* added ``merge_profile`` parameter to merge configurations from the play to an existing profile

* add fragment

* cosmetic changes

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

Co-authored-by: Frank Dornheim <524257+conloos@users.noreply.github.com>
2021-02-16 10:58:34 +01:00
patchback[bot]
0d0884b069 Tidy up validations + bug fixes + deprecations (#1830) (#1841)
* fixed validation-modules for plugins/modules/database/misc/elasticsearch_plugin.py

* fixed validation-modules for plugins/modules/database/misc/kibana_plugin.py

* fixed validation-modules for plugins/modules/database/misc/riak.py

* fixed validation-modules for plugins/modules/database/vertica/vertica_info.py

* fixed validation-modules for plugins/modules/database/vertica/vertica_role.py

* fixed validation-modules for plugins/modules/database/vertica/vertica_schema.py

* fixed validation-modules for plugins/modules/database/vertica/vertica_user.py

* fixed validation-modules for plugins/modules/storage/ibm/ibm_sa_domain.py

* fixed validation-modules for plugins/modules/storage/ibm/ibm_sa_host_ports.py

* fixed validation-modules for plugins/modules/storage/ibm/ibm_sa_host.py

* fixed validation-modules for plugins/modules/storage/ibm/ibm_sa_pool.py

* fixed validation-modules for plugins/modules/storage/ibm/ibm_sa_vol.py

* fixed validation-modules for plugins/modules/storage/ibm/ibm_sa_vol_map.py

* fixed validation-modules for plugins/modules/storage/ibm/ibm_sa_host_ports.py

* fixed validation-modules for plugins/modules/system/runit.py

* fixed validation-modules for plugins/modules/source_control/bzr.py

* fixed validation-modules for plugins/modules/source_control/hg.py

* fixed validation-modules for plugins/modules/storage/emc/emc_vnx_sg_member.py

* fixed validation-modules for plugins/modules/identity/opendj/opendj_backendprop.py

* fixed validation-modules for plugins/modules/files/iso_extract.py

* fixed validation-modules for plugins/modules/monitoring/logstash_plugin.py

* fixed validation-modules for plugins/modules/database/aerospike/aerospike_migrations.py

* Tidy up a number of sanity checks for some modules

* added changelog fragment

* Some parameters in vertica_* had their aliases documented as the name, and sometimes vice-versa as well

* Adjustments per PR

* Rolled back sanity ignores for runit

* Update changelogs/fragments/1830-valmod_docmissingtype_batch1.yml

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-02-16 09:10:13 +00:00
patchback[bot]
dd400e8c21 Tidy up all pylint:blacklisted-name ignore lines (#1819) (#1839)
* fixed validation-modules for plugins/callback/hipchat.py

* fixed validation-modules for plugins/connection/lxc.py

* fixed validation-modules for plugins/modules/cloud/lxc/lxc_container.py

* fixed validation-modules for plugins/modules/monitoring/statusio_maintenance.py

* fixed validation-modules for plugins/modules/system/alternatives.py

* fixed validation-modules for plugins/modules/system/beadm.py

* fixed validation-modules for plugins/modules/system/cronvar.py

* fixed validation-modules for plugins/modules/system/dconf.py

* fixed validation-modules for plugins/modules/system/interfaces_file.py

* fixed validation-modules for plugins/modules/system/java_cert.py

* fixed validation-modules for plugins/modules/system/lvg.py

* fixed validation-modules for plugins/modules/system/lvol.py

* fixed validation-modules for plugins/modules/system/parted.py

* fixed validation-modules for plugins/modules/system/timezone.py

* fixed validation-modules for plugins/modules/web_infrastructure/rundeck_acl_policy.py

* Tidy up all pylint:blacklisted-name sanity checks ignore lines

* Missed one in statusio_maintenace.py

* fixed validation-modules for plugins/modules/system/filesystem.py

* Missed one in gconftool2.py

* Missed one in alternatives.py

* Using dummies now

* fixed indentation

* Made all the changes about replacing _ with dummy

* Rollback bug fixed

* Rollback bug fixed, part II

* added changelog fragment

* Improved changelog frag message per PR

(cherry picked from commit 03b7b39424)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-02-16 08:46:20 +01:00
patchback[bot]
a60f9bc78b dnsimple: Add support for CAA records (#1814) (#1835)
(cherry picked from commit 03fd6bd008)

Co-authored-by: Craig Roberts <github@craig.craig0990.co.uk>
2021-02-16 07:55:35 +01:00
Felix Fontein
47714ecf79 Add release summary for 1.2.0. 2021-02-16 07:48:13 +01:00
patchback[bot]
d15ed4135b Tidy up validate-modules:parameter-list-no-elements (batch 1) (#1795) (#1834)
* fixed validation-modules for plugins/modules/storage/netapp/na_ontap_gather_facts.py

* fixed validation-modules for plugins/modules/source_control/gitlab/gitlab_runner.py

* fixed validation-modules for plugins/modules/packaging/os/redhat_subscription.py

* fixed validation-modules for plugins/modules/notification/twilio.py

* fixed validation-modules for plugins/modules/notification/slack.py

* fixed validation-modules for plugins/modules/notification/sendgrid.py

* fixed validation-modules for plugins/modules/notification/rocketchat.py

* fixed validation-modules for plugins/modules/notification/office_365_connector_card.py

* fixed validation-modules for plugins/modules/notification/nexmo.py

* fixed validation-modules for plugins/modules/notification/mail.py

* fixed validation-modules for plugins/modules/net_tools/omapi_host.py

* fixed validation-modules for plugins/modules/net_tools/nsupdate.py

* fixed validation-modules for plugins/modules/net_tools/dnsimple.py

* fixed validation-modules for plugins/modules/monitoring/pagerduty.py

* fixed validation-modules for plugins/modules/monitoring/librato_annotation.py

* fixed validation-modules for plugins/modules/identity/onepassword_info.py

* fixed validation-modules for plugins/modules/identity/keycloak/keycloak_client.py

* fixed validation-modules for plugins/modules/files/xml.py

* fixed validation-modules for plugins/modules/cloud/softlayer/sl_vm.py

* fixed validation-modules for plugins/modules/cloud/smartos/vmadm.py

* fixed validation-modules for plugins/modules/cloud/pubnub/pubnub_blocks.py

* fixed validation-modules for plugins/modules/cloud/packet/packet_device.py

* fixed validation-modules for plugins/modules/cloud/lxd/lxd_container.py

* fixed validation-modules for plugins/module_utils/oracle/oci_utils.py

* fixed validation-modules for plugins/doc_fragments/oracle_creatable_resource.py

* Tidy up validate-modules:parameter-list-no-elements for some modules

* fixed validation-modules for plugins/modules/monitoring/statusio_maintenance.py

* Fixed pending issues from CI validation

* Fixed xml module elements for add_children & set_children

* added changelog fragment

* typo

* fix wording in changelog frag

(cherry picked from commit f33323ca89)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-02-16 07:38:50 +01:00
patchback[bot]
bd61228e40 proxmox_kvm: 500 error args parameter (#1783) (#1832)
* don't add args if set to 'no_defaults'

* never add force even if false, will require archive parameter other which is not implemented

* remove trailing whitespace

* add changelog fragment

* Update changelogs/fragments/1783-proxmox-kvm-fix-args-500-error.yaml

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

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

Co-authored-by: almdudler777 <43605831+almdudler777@users.noreply.github.com>
2021-02-16 07:10:40 +01:00
patchback[bot]
26d7c28b33 ease limitation for nios_host_record DNS Bypass (#1788) (#1826)
* ease limitation for nios_host_record DNS Bypass, the bypass should be allowed when configure_dns is disabled and view is set other than default

* add changelog fragment

Co-authored-by: Nils <ext-nils.haglund@elisa.fi>
(cherry picked from commit 8fae693d9c)

Co-authored-by: shieni <shieni@users.noreply.github.com>
2021-02-15 09:10:18 +01:00
patchback[bot]
2e533daffa Fix undeclared result for nomad_job_info module (#1721) (#1823)
* Fix unassigned variable

* Create 1721-fix-nomad_job_info-no-jobs-failure.yml

* refactor usage of variables in nomad_job_info

* Update changelogs/fragments/1721-fix-nomad_job_info-no-jobs-failure.yml

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

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

Co-authored-by: Víctor Suárez Fernández <15276132+vicsufer@users.noreply.github.com>
2021-02-15 09:04:44 +01:00
patchback[bot]
6c50119eab Added VMID to all returns (#1715) (#1824)
* Added VMID to all returns

Also added in the docs promised return of MAC and devices when state ==
current.

Fixes: #1641

* Revert devices and mac as get_vminfo works differently then I expected

* Added status output to a few more calls

* Update RETURNS docs

* Remove vmid where it is not available

* Added changelog fragment

* Update changelogs/fragments/1715-proxmox_kvm-add-vmid-to-returns.yml

You're right, this message is way better then mine.. :-)

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

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

Co-authored-by: Jeffrey van Pelt <jeff@vanpelt.one>
2021-02-15 08:57:38 +01:00
patchback[bot]
bc3435b993 Tidy up validation for storage/zfs modules (#1766) (#1821)
* fixed validation-modules for plugins/modules/storage/zfs/zfs.py

* fixed validation-modules for plugins/modules/storage/zfs/zfs_delegate_admin.py

* fixed validation-modules for plugins/modules/storage/zfs/zfs_facts.py

* fixed validation-modules for plugins/modules/storage/zfs/zpool_facts.py

* Tidy up validate-modules ignores for storage/zfs modules

* removed ignore lines in 2.11 files as well

* added changelog fragment per PR

* Update changelogs/fragments/1766-zfs-fixed-sanity.yml

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-02-15 07:27:23 +00:00
patchback[bot]
370f5d8082 Implemented fix pointed in issue (#1760) (#1818)
(cherry picked from commit 41bc7816f3)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-02-14 16:05:59 +01:00
patchback[bot]
e77c5413c9 Adjusted django_manage integration test files to reduce ignore lines in sanity tests (#1805) (#1810)
(cherry picked from commit e247300523)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-02-13 12:49:36 +01:00
patchback[bot]
800ee1bae0 Tidy up validate-modules ignores for cloud/centurylink modules (#1771) (#1811)
* fixed validation-modules for plugins/modules/cloud/centurylink/clc_alert_policy.py

* fixed validation-modules for plugins/modules/cloud/centurylink/clc_blueprint_package.py

* fixed validation-modules for plugins/modules/cloud/centurylink/clc_firewall_policy.py

* fixed validation-modules for plugins/modules/cloud/centurylink/clc_loadbalancer.py

* fixed validation-modules for plugins/modules/cloud/centurylink/clc_modify_server.py

* fixed validation-modules for plugins/modules/cloud/centurylink/clc_publicip.py

* fixed validation-modules for plugins/modules/cloud/centurylink/clc_server_snapshot.py

* fixed validation-modules for plugins/modules/cloud/centurylink/clc_server.py

* Tidy up validate-modules ignores for cloud/centurylink modules

* added changelog fragment per PR

(cherry picked from commit 865acdd4cf)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-02-13 12:35:18 +01:00
patchback[bot]
8de8d21062 Make selective callback work with ansible-core 2.11. (#1807) (#1809)
(cherry picked from commit 367c3c43ff)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-02-13 12:24:10 +01:00
patchback[bot]
81e71b5034 Improved parameter handling on proxmox modules (#1765) (#1801)
* Improved parameter handling on proxmox modules

* removed unused imports

* rollback change in plugins/modules/cloud/misc/proxmox_user_info.py

* added changelog fragment

* Update changelogs/fragments/1765-proxmox-params.yml

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-02-12 17:08:14 +01:00
patchback[bot]
44ce63ed85 Change type str -> path in argspec. (#1741) (#1800)
(cherry picked from commit f12df1d21b)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-02-12 08:23:40 +01:00
patchback[bot]
a3c9c688b9 Removed parameter-list-no-elements validation errors from redfish modules (#1761) (#1799)
* Removed parameter-list-no-elements validation errors from redfish modules

* added changelog fragment per PR

* Update changelogs/fragments/1761-redfish-tidy-up-validation.yml

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-02-12 07:14:07 +01:00
patchback[bot]
a332ed4429 Prevented the expansion of parameters in run_command() (#1794) (#1796)
(cherry picked from commit 436bbb0077)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-02-12 06:38:37 +01:00
patchback[bot]
91571f8bff Update CI (#1782) (#1787)
* Update targets for CI for devel branch; move some targets to stable-2.10.

* Skipping test on RHEL 8.3 (it is already skipped on RHEL 8.2).

* Linting.

* Shut 2.9/2.10 pylint complaints up.

(cherry picked from commit e9551df5ed)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-02-11 11:10:42 +01:00
patchback[bot]
43856eaa6f Fix typo in aerospike_migration module. (#1740) (#1785)
(cherry picked from commit 9a6031ab4e)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-02-11 07:31:05 +01:00
patchback[bot]
ae87b5479a only set param features when variable is not empty (#1763) (#1781)
* only set param features when variable is not empty

* Apply suggestions from code review

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

Co-authored-by: Topper Harly <topperharly@gmx.net>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 562ff7efb7)

Co-authored-by: topperharly <topperharly@users.noreply.github.com>
2021-02-10 22:32:01 +01:00
patchback[bot]
42cd462780 redfish module_utils: case insesitive search for situations where the hostname/FQDN on iLO is in caps (#1744) (#1780)
* case insesitive search for situations where the hostname/FQDN on iLO is in caps

* handle explicit and implicit nic_addr variable, added changelog fragment

* changelog linter fix

* changelog typo fix

Co-authored-by: Łukasz Kurdziel <Lukasz.Kurdziel@GAINCapital.com>
(cherry picked from commit 93e0aa7557)

Co-authored-by: lukurde <47138492+lukurde@users.noreply.github.com>
2021-02-10 20:37:49 +01:00
patchback[bot]
d871378574 xfconf: feature flag to disable facts and deprecation warning (#1747) (#1778)
* Added feature flag to disable facts and its associated deprecatoin warning

* added changelog fragment

* Update plugins/modules/system/xfconf.py

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

* Update plugins/modules/system/xfconf.py

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

* Update plugins/modules/system/xfconf.py

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

* Fixed deprecation message

* Fixed changelog frag

* Update changelogs/fragments/1475-xfconf-facts.yml

* Update plugins/modules/system/xfconf.py

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

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

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-02-10 20:37:31 +01:00
patchback[bot]
983b292399 timezone: add gentoo and alpine linux support (#1722) (#1779)
* add alpine linux as NosystemdTimezone

* syntax error fix and more self variables, so it works now...

* use timezone name instead of timezone path for setup-timezone command

* alpine linux zoneinfo links to /etc/zoneinfo instead of /usr/share/zoneinfo, so correct re.search() pattern

* add changelog fragment

* add gentoo linux support

* Update 1722_timezone.yml

* refactor code

(cherry picked from commit 9aef0ed17e)

Co-authored-by: Anatoly Pugachev <matorola@gmail.com>
2021-02-10 20:37:15 +01:00
patchback[bot]
6831aa5501 document what filesystem types are supported by 'resizefs' option (#1753) (#1775)
* document what filesystem types are supported by 'resizefs' option

* add changelog fragment

* remove info about lvol documentation changes in changelog fragment

(cherry picked from commit d1e54d2fd1)

Co-authored-by: quidame <quidame@poivron.org>
2021-02-10 13:09:33 +01:00
patchback[bot]
2d8a94a459 azure-pipelines: update container version (#1770) (#1773)
(cherry picked from commit e898e52d1b)

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>
2021-02-10 10:12:56 +01:00
patchback[bot]
f721e76fdc Tidy up validate-modules ignores for remote_management/ipmi modules (#1767) (#1769)
* fixed validation-modules for plugins/modules/remote_management/ipmi/ipmi_boot.py

* fixed validation-modules for plugins/modules/remote_management/ipmi/ipmi_power.py

* Tidy up validate-modules ignores for remote_management/ipmi modules

(cherry picked from commit 89ffb04dff)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
2021-02-10 08:24:33 +01:00
Felix Fontein
3eadb9d637 Revert "Revert new features since the 2.0.0 release so we can release 2.0.1 from this branch."
This reverts commit 1d90e91528.
2021-02-09 15:42:39 +01:00
Felix Fontein
033582b696 Next expected release is 2.1.0. 2021-02-09 15:42:39 +01:00
Felix Fontein
974997594f Release 2.0.1. 2021-02-09 13:34:53 +01:00
Felix Fontein
fa8ce6dea8 Add 2.0.1 relesae summary. 2021-02-09 13:32:06 +01:00
Felix Fontein
1d90e91528 Revert new features since the 2.0.0 release so we can release 2.0.1 from this branch.
Revert "datadog_monitor: Add missing monitor types query alert, trace-analytics alert, rum alert (#1723) (#1733)"
Revert "homebrew_tap: Add support for brew search path (#1708) (#1709)"

This reverts commits f613983cb4 and 646ca74810.
2021-02-09 13:30:39 +01:00
patchback[bot]
a90e2c8002 Various fixes for updating existing gitlab users (#1724) (#1757)
* fixes various issues related to updating an ...

... existing gitlab user, in detail:

  - fixes updating admin status not working
  - fixes user passwords not updated
  - fixes confirmation skipping param ignored for user updates
  - added tests for code changes

* fixing sanity issues

* fixing sanity issues 02

* fixing sanity issues 03

* fixing sanity issues 04

* fixing unit test failures

* fixing unit test failures 02

* add changelog fragment

* fixing unit test failures 03

* forgot to add changelog fragment

* fix changelog sanity issues

* fix changelog sanity issues 02

* incorporate review suggestions

Co-authored-by: Mirko Wilhelmi <Mirko.Wilhelmi@sma.de>
(cherry picked from commit c03ae754d2)

Co-authored-by: morco <thegreatwiper@web.de>
2021-02-09 12:02:03 +01:00
patchback[bot]
c506375f2a Fix CI (#1752) (#1754)
* Limit cryptography to < 3.4 for Python < 3.6.

* Work around old pip versions.

* Use constraints file when installing stormssh.

* Work around old pip in RHEL8.2, CentOS 8, Ubuntu 18.04, and OpenSuSE 15

(cherry picked from commit 909ac92fe2)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-02-09 10:28:39 +01:00
patchback[bot]
4def9439bd Fix a bunch of potential security issues (secret leaking) (#1736) (#1751)
* Fix a bunch of potential security issues (secret leaking).

* oneandone_server was already ok.

* Add more parameters for pagerduty_alert.

* Add more no_log=True.

(cherry picked from commit 29bd5a9486)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-02-08 17:04:38 +01:00
patchback[bot]
023654473b Make sure mercurial is also installed on OpenSuSE. (#1734) (#1738)
(cherry picked from commit 701a89eb1c)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-02-05 08:29:28 +01:00
patchback[bot]
a216f15dd9 parted: fix regex for version match and partition size output (#1695) (#1732)
* Fix 2 regex in parted related to parted version string and to parsing partition size output.

* Added changelog fragment.

* Updated changelog as per recommendation.

* Fix the regex matching the parted version. The space character at the end of the string may or may not be always present

* provided sample version output and corrected regex to match

* add/correct changelog fragment

* split parted_version function to allow creating a test unit

* test unit for parted version info

* ansible-test sanity fixes

* review fix

* Update changelogs/fragments/1695-parted-updatedregex.yaml

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

* comment fixes

* better function name

* Update plugins/modules/system/parted.py

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

* comment fixes

Co-authored-by: Claude Robitaille <claude@cbcr.me>
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 43da5b88db)

Co-authored-by: Anatoly Pugachev <matorola@gmail.com>
2021-02-05 07:51:43 +01:00
patchback[bot]
f613983cb4 datadog_monitor: Add missing monitor types query alert, trace-analytics alert, rum alert (#1723) (#1733)
* Add missing Datadog monitor types
This commit adds the following monitor types: query alert, trace-analytics alert, rum alert

* changelog PR1723 datadog_monitor types

* datadog_monitor 1723 Apply suggestions from code review

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

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

Co-authored-by: Rick Sherman <rick@shermdog.com>
2021-02-05 06:51:27 +00:00
patchback[bot]
c22199794d Add no_log to some module arguments (#1725) (#1730)
* Add no_log to some module arguments

This will prevent potentially sensitive information from being printed to
the console.

See: CVE-2021-20191

* Update changelogs/fragments/CVE-2021-20191_no_log.yml

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

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

Co-authored-by: David Moreau Simard <dmsimard@redhat.com>
2021-02-04 21:54:11 +01:00
patchback[bot]
24b1d92e84 module filesystem: partially fix idempotency issue #1457 (resizefs) (#1478) (#1720)
* Use 'xfs_info' to query fs size, that doesn't always require the device be
  mounted. Although still query mountpoint first for backward compatibility.
* Do not fail whith fstype=xfs and resizefs=yes if filesystem already fills
  its underlying device.
* Include xfs in the tasks that test idempotency of resizefs option
* Add changelogs/fragments/1478-filesystem-fix-1457-resizefs-idempotency.yml

(cherry picked from commit aa95d8a5b7)

Co-authored-by: quidame <quidame@poivron.org>
2021-02-03 10:42:29 +01:00
patchback[bot]
4bc44e4062 sensu-silence: fix json parsing of sensu API response (#1703) (#1718)
* sensu-silence: fix json parsing of sensu API response

* use ansible helper function to decode bytestream

* add changelog fragment

* Update changelogs, link to PR

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

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

Co-authored-by: Stefan Walluhn <stefan.walluhn@aboutsource.net>
2021-02-03 07:52:59 +01:00
patchback[bot]
06fd6d8742 Fedora 30 and 31 are EOL and will eventually be removed from devel. (#1705) (#1711)
(cherry picked from commit 6af3c96d8e)

Co-authored-by: Felix Fontein <felix@fontein.de>
2021-02-01 18:30:45 +01:00
Felix Fontein
dd0ae4a003 Announce DellEMC migration. (#1706) 2021-02-01 18:29:56 +01:00
patchback[bot]
646ca74810 homebrew_tap: Add support for brew search path (#1708) (#1709)
* homebrew_tap: Add support for brew search path

User can specify search path for brew executable.

Fixes: #1702

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>

* Change version

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

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

Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
2021-02-01 11:32:50 +01:00
patchback[bot]
d60c107818 BOTMETA.yml: add logstash plugin maintainer (#1700) (#1701)
Co-authored-by: Andrew Klychkov <andrew.klychkov@gmail.com>
(cherry picked from commit 9c648c8e3a)

Co-authored-by: Andrew Klychkov <aaklychkov@mail.ru>
2021-01-29 11:01:21 +01:00
patchback[bot]
ef2d14f24e Add Name and/or Id properties to resource inventory output (#1691) (#1698)
* add Name and/or Id properties to resource inventory output

* add changelog fragment

(cherry picked from commit 00f5f7dfe7)

Co-authored-by: Bill Dodd <billdodd@gmail.com>
2021-01-29 07:40:22 +01:00
Felix Fontein
b3cde9b8a4 Next expected release is 2.1.0. 2021-01-28 15:01:39 +01:00
Felix Fontein
dc4222df0d Fix links. 2021-01-28 13:52:13 +01:00
Felix Fontein
b9a89d6d0f Release 2.0.0. 2021-01-28 13:43:42 +01:00
Felix Fontein
f48913d91b Add release summary. 2021-01-28 13:42:22 +01:00
1867 changed files with 52476 additions and 86375 deletions

View File

@@ -0,0 +1,3 @@
## Azure Pipelines Configuration
Please see the [Documentation](https://github.com/ansible/community/wiki/Testing:-Azure-Pipelines) for more information.

View File

@@ -0,0 +1,315 @@
trigger:
batch: true
branches:
include:
- main
- stable-*
pr:
autoCancel: true
branches:
include:
- main
- stable-*
schedules:
- cron: 0 9 * * *
displayName: Nightly
always: true
branches:
include:
- main
- stable-*
variables:
- name: checkoutPath
value: ansible_collections/community/general
- name: coverageBranches
value: main
- name: pipelinesCoverage
value: coverage
- name: entryPoint
value: tests/utils/shippable/shippable.sh
- name: fetchDepth
value: 0
resources:
containers:
- container: default
image: quay.io/ansible/azure-pipelines-test-container:1.8.0
pool: Standard
stages:
### Sanity
- stage: Sanity_devel
displayName: Sanity devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: devel/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
- test: extra
- stage: Sanity_2_10
displayName: Sanity 2.10
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: 2.10/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
- stage: Sanity_2_9
displayName: Sanity 2.9
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: 2.9/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
### Units
- stage: Units_devel
displayName: Units devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: devel/units/{0}/1
targets:
- test: 2.6
- test: 2.7
- test: 3.5
- test: 3.6
- test: 3.7
- test: 3.8
- test: 3.9
- stage: Units_2_10
displayName: Units 2.10
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.10/units/{0}/1
targets:
- test: 2.6
- test: 2.7
- test: 3.5
- test: 3.6
- test: 3.7
- test: 3.8
- test: 3.9
- stage: Units_2_9
displayName: Units 2.9
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.9/units/{0}/1
targets:
- test: 2.6
- test: 2.7
- test: 3.5
- test: 3.6
- test: 3.7
- test: 3.8
## Remote
- stage: Remote_devel
displayName: Remote devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/{0}
targets:
- name: macOS 11.1
test: macos/11.1
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 8.3
test: rhel/8.3
- name: FreeBSD 11.4
test: freebsd/11.4
- name: FreeBSD 12.2
test: freebsd/12.2
groups:
- 1
- 2
- 3
- stage: Remote_2_10
displayName: Remote 2.10
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.10/{0}
targets:
- name: OS X 10.11
test: osx/10.11
- name: macOS 10.15
test: macos/10.15
- name: macOS 11.1
test: macos/11.1
- name: RHEL 7.8
test: rhel/7.8
- name: RHEL 8.2
test: rhel/8.2
- name: FreeBSD 12.1
test: freebsd/12.1
groups:
- 1
- 2
- stage: Remote_2_9
displayName: Remote 2.9
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.9/{0}
targets:
- name: RHEL 8.2
test: rhel/8.2
- name: FreeBSD 12.0
test: freebsd/12.0
groups:
- 1
- 2
### Docker
- stage: Docker_devel
displayName: Docker devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux/{0}
targets:
- name: CentOS 6
test: centos6
- name: CentOS 7
test: centos7
- name: CentOS 8
test: centos8
- name: Fedora 32
test: fedora32
- name: Fedora 33
test: fedora33
- name: openSUSE 15 py2
test: opensuse15py2
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 18.04
test: ubuntu1804
- name: Ubuntu 20.04
test: ubuntu2004
groups:
- 1
- 2
- 3
- stage: Docker_2_10
displayName: Docker 2.10
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.10/linux/{0}
targets:
- name: CentOS 8
test: centos8
- name: Fedora 32
test: fedora32
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 16.04
test: ubuntu1604
groups:
- 2
- 3
- stage: Docker_2_9
displayName: Docker 2.9
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.9/linux/{0}
targets:
- name: CentOS 8
test: centos8
- name: Fedora 31
test: fedora31
- name: openSUSE 15 py3
test: opensuse15
groups:
- 2
- 3
### Cloud
- stage: Cloud_devel
displayName: Cloud devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: devel/cloud/{0}/1
targets:
- test: 2.7
- test: 3.6
- stage: Cloud_2_10
displayName: Cloud 2.10
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.10/cloud/{0}/1
targets:
- test: 3.6
- stage: Cloud_2_9
displayName: Cloud 2.9
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.9/cloud/{0}/1
targets:
- test: 3.6
- stage: Summary
condition: succeededOrFailed()
dependsOn:
- Sanity_devel
- Sanity_2_9
- Sanity_2_10
- Units_devel
- Units_2_9
- Units_2_10
- Remote_devel
- Remote_2_9
- Remote_2_10
- Docker_devel
- Docker_2_9
- Docker_2_10
- Cloud_devel
- Cloud_2_9
- Cloud_2_10
jobs:
- template: templates/coverage.yml

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Aggregate code coverage results for later processing.
set -o pipefail -eu
agent_temp_directory="$1"
PATH="${PWD}/bin:${PATH}"
mkdir "${agent_temp_directory}/coverage/"
options=(--venv --venv-system-site-packages --color -v)
ansible-test coverage combine --export "${agent_temp_directory}/coverage/" "${options[@]}"
if ansible-test coverage analyze targets generate --help >/dev/null 2>&1; then
# Only analyze coverage if the installed version of ansible-test supports it.
# Doing so allows this script to work unmodified for multiple Ansible versions.
ansible-test coverage analyze targets generate "${agent_temp_directory}/coverage/coverage-analyze-targets.json" "${options[@]}"
fi

View File

@@ -0,0 +1,60 @@
#!/usr/bin/env python
"""
Combine coverage data from multiple jobs, keeping the data only from the most recent attempt from each job.
Coverage artifacts must be named using the format: "Coverage $(System.JobAttempt) {StableUniqueNameForEachJob}"
The recommended coverage artifact name format is: Coverage $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)
Keep in mind that Azure Pipelines does not enforce unique job display names (only names).
It is up to pipeline authors to avoid name collisions when deviating from the recommended format.
"""
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import re
import shutil
import sys
def main():
"""Main program entry point."""
source_directory = sys.argv[1]
if '/ansible_collections/' in os.getcwd():
output_path = "tests/output"
else:
output_path = "test/results"
destination_directory = os.path.join(output_path, 'coverage')
if not os.path.exists(destination_directory):
os.makedirs(destination_directory)
jobs = {}
count = 0
for name in os.listdir(source_directory):
match = re.search('^Coverage (?P<attempt>[0-9]+) (?P<label>.+)$', name)
label = match.group('label')
attempt = int(match.group('attempt'))
jobs[label] = max(attempt, jobs.get(label, 0))
for label, attempt in jobs.items():
name = 'Coverage {attempt} {label}'.format(label=label, attempt=attempt)
source = os.path.join(source_directory, name)
source_files = os.listdir(source)
for source_file in source_files:
source_path = os.path.join(source, source_file)
destination_path = os.path.join(destination_directory, source_file + '.' + label)
print('"%s" -> "%s"' % (source_path, destination_path))
shutil.copyfile(source_path, destination_path)
count += 1
print('Coverage file count: %d' % count)
print('##vso[task.setVariable variable=coverageFileCount]%d' % count)
print('##vso[task.setVariable variable=outputPath]%s' % output_path)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
# Check the test results and set variables for use in later steps.
set -o pipefail -eu
if [[ "$PWD" =~ /ansible_collections/ ]]; then
output_path="tests/output"
else
output_path="test/results"
fi
echo "##vso[task.setVariable variable=outputPath]${output_path}"
if compgen -G "${output_path}"'/junit/*.xml' > /dev/null; then
echo "##vso[task.setVariable variable=haveTestResults]true"
fi
if compgen -G "${output_path}"'/bot/ansible-test-*' > /dev/null; then
echo "##vso[task.setVariable variable=haveBotResults]true"
fi
if compgen -G "${output_path}"'/coverage/*' > /dev/null; then
echo "##vso[task.setVariable variable=haveCoverageData]true"
fi

View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
# Upload code coverage reports to codecov.io.
# Multiple coverage files from multiple languages are accepted and aggregated after upload.
# Python coverage, as well as PowerShell and Python stubs can all be uploaded.
set -o pipefail -eu
output_path="$1"
curl --silent --show-error https://codecov.io/bash > codecov.sh
for file in "${output_path}"/reports/coverage*.xml; do
name="${file}"
name="${name##*/}" # remove path
name="${name##coverage=}" # remove 'coverage=' prefix if present
name="${name%.xml}" # remove '.xml' suffix
bash codecov.sh \
-f "${file}" \
-n "${name}" \
-X coveragepy \
-X gcov \
-X fix \
-X search \
-X xcode \
|| echo "Failed to upload code coverage report to codecov.io: ${file}"
done

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
# Generate code coverage reports for uploading to Azure Pipelines and codecov.io.
set -o pipefail -eu
PATH="${PWD}/bin:${PATH}"
if ! ansible-test --help >/dev/null 2>&1; then
# Install the devel version of ansible-test for generating code coverage reports.
# This is only used by Ansible Collections, which are typically tested against multiple Ansible versions (in separate jobs).
# Since a version of ansible-test is required that can work the output from multiple older releases, the devel version is used.
pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
fi
ansible-test coverage xml --stub --venv --venv-system-site-packages --color -v

View File

@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Configure the test environment and run the tests.
set -o pipefail -eu
entry_point="$1"
test="$2"
read -r -a coverage_branches <<< "$3" # space separated list of branches to run code coverage on for scheduled builds
export COMMIT_MESSAGE
export COMPLETE
export COVERAGE
export IS_PULL_REQUEST
if [ "${SYSTEM_PULLREQUEST_TARGETBRANCH:-}" ]; then
IS_PULL_REQUEST=true
COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD^2)
else
IS_PULL_REQUEST=
COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD)
fi
COMPLETE=
COVERAGE=
if [ "${BUILD_REASON}" = "Schedule" ]; then
COMPLETE=yes
if printf '%s\n' "${coverage_branches[@]}" | grep -q "^${BUILD_SOURCEBRANCHNAME}$"; then
COVERAGE=yes
fi
fi
"${entry_point}" "${test}" 2>&1 | "$(dirname "$0")/time-command.py"

View File

@@ -0,0 +1,25 @@
#!/usr/bin/env python
"""Prepends a relative timestamp to each input line from stdin and writes it to stdout."""
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import sys
import time
def main():
"""Main program entry point."""
start = time.time()
sys.stdin.reconfigure(errors='surrogateescape')
sys.stdout.reconfigure(errors='surrogateescape')
for line in sys.stdin:
seconds = time.time() - start
sys.stdout.write('%02d:%02d %s' % (seconds // 60, seconds % 60, line))
sys.stdout.flush()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,39 @@
# This template adds a job for processing code coverage data.
# It will upload results to Azure Pipelines and codecov.io.
# Use it from a job stage that completes after all other jobs have completed.
# This can be done by placing it in a separate summary stage that runs after the test stage(s) have completed.
jobs:
- job: Coverage
displayName: Code Coverage
container: default
workspace:
clean: all
steps:
- checkout: self
fetchDepth: $(fetchDepth)
path: $(checkoutPath)
- task: DownloadPipelineArtifact@2
displayName: Download Coverage Data
inputs:
path: coverage/
patterns: "Coverage */*=coverage.combined"
- bash: .azure-pipelines/scripts/combine-coverage.py coverage/
displayName: Combine Coverage Data
- bash: .azure-pipelines/scripts/report-coverage.sh
displayName: Generate Coverage Report
condition: gt(variables.coverageFileCount, 0)
- task: PublishCodeCoverageResults@1
inputs:
codeCoverageTool: Cobertura
# Azure Pipelines only accepts a single coverage data file.
# That means only Python or PowerShell coverage can be uploaded, but not both.
# Set the "pipelinesCoverage" variable to determine which type is uploaded.
# Use "coverage" for Python and "coverage-powershell" for PowerShell.
summaryFileLocation: "$(outputPath)/reports/$(pipelinesCoverage).xml"
displayName: Publish to Azure Pipelines
condition: gt(variables.coverageFileCount, 0)
- bash: .azure-pipelines/scripts/publish-codecov.sh "$(outputPath)"
displayName: Publish to codecov.io
condition: gt(variables.coverageFileCount, 0)
continueOnError: true

View File

@@ -0,0 +1,55 @@
# This template uses the provided targets and optional groups to generate a matrix which is then passed to the test template.
# If this matrix template does not provide the required functionality, consider using the test template directly instead.
parameters:
# A required list of dictionaries, one per test target.
# Each item in the list must contain a "test" or "name" key.
# Both may be provided. If one is omitted, the other will be used.
- name: targets
type: object
# An optional list of values which will be used to multiply the targets list into a matrix.
# Values can be strings or numbers.
- name: groups
type: object
default: []
# An optional format string used to generate the job name.
# - {0} is the name of an item in the targets list.
- name: nameFormat
type: string
default: "{0}"
# An optional format string used to generate the test name.
# - {0} is the name of an item in the targets list.
- name: testFormat
type: string
default: "{0}"
# An optional format string used to add the group to the job name.
# {0} is the formatted name of an item in the targets list.
# {{1}} is the group -- be sure to include the double "{{" and "}}".
- name: nameGroupFormat
type: string
default: "{0} - {{1}}"
# An optional format string used to add the group to the test name.
# {0} is the formatted test of an item in the targets list.
# {{1}} is the group -- be sure to include the double "{{" and "}}".
- name: testGroupFormat
type: string
default: "{0}/{{1}}"
jobs:
- template: test.yml
parameters:
jobs:
- ${{ if eq(length(parameters.groups), 0) }}:
- ${{ each target in parameters.targets }}:
- name: ${{ format(parameters.nameFormat, coalesce(target.name, target.test)) }}
test: ${{ format(parameters.testFormat, coalesce(target.test, target.name)) }}
- ${{ if not(eq(length(parameters.groups), 0)) }}:
- ${{ each group in parameters.groups }}:
- ${{ each target in parameters.targets }}:
- name: ${{ format(format(parameters.nameGroupFormat, parameters.nameFormat), coalesce(target.name, target.test), group) }}
test: ${{ format(format(parameters.testGroupFormat, parameters.testFormat), coalesce(target.test, target.name), group) }}

View File

@@ -0,0 +1,45 @@
# This template uses the provided list of jobs to create test one or more test jobs.
# It can be used directly if needed, or through the matrix template.
parameters:
# A required list of dictionaries, one per test job.
# Each item in the list must contain a "job" and "name" key.
- name: jobs
type: object
jobs:
- ${{ each job in parameters.jobs }}:
- job: test_${{ replace(replace(replace(job.test, '/', '_'), '.', '_'), '-', '_') }}
displayName: ${{ job.name }}
container: default
workspace:
clean: all
steps:
- checkout: self
fetchDepth: $(fetchDepth)
path: $(checkoutPath)
- bash: .azure-pipelines/scripts/run-tests.sh "$(entryPoint)" "${{ job.test }}" "$(coverageBranches)"
displayName: Run Tests
- bash: .azure-pipelines/scripts/process-results.sh
condition: succeededOrFailed()
displayName: Process Results
- bash: .azure-pipelines/scripts/aggregate-coverage.sh "$(Agent.TempDirectory)"
condition: eq(variables.haveCoverageData, 'true')
displayName: Aggregate Coverage Data
- task: PublishTestResults@2
condition: eq(variables.haveTestResults, 'true')
inputs:
testResultsFiles: "$(outputPath)/junit/*.xml"
displayName: Publish Test Results
- task: PublishPipelineArtifact@1
condition: eq(variables.haveBotResults, 'true')
displayName: Publish Bot Results
inputs:
targetPath: "$(outputPath)/bot/"
artifactName: "Bot $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)"
- task: PublishPipelineArtifact@1
condition: eq(variables.haveCoverageData, 'true')
displayName: Publish Coverage Data
inputs:
targetPath: "$(Agent.TempDirectory)/coverage/"
artifactName: "Coverage $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)"

566
.github/BOTMETA.yml vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,149 +0,0 @@
---
name: Bug report
description: Create a report to help us improve
body:
- type: markdown
attributes:
value: |
Verify first that your issue is not [already reported on GitHub][issue search].
Also test if the latest release and devel branch are affected too.
*Complete **all** sections as described, this form is processed automatically.*
[issue search]: https://github.com/ansible-collections/community.general/search?q=is%3Aissue&type=issues
- type: textarea
attributes:
label: Summary
description: Explain the problem briefly below.
placeholder: >-
When I try to do X with the collection from the main branch on GitHub, Y
breaks in a way Z under the env E. Here are all the details I know
about this problem...
validations:
required: true
- type: dropdown
attributes:
label: Issue Type
# FIXME: Once GitHub allows defining the default choice, update this
options:
- Bug Report
validations:
required: true
- type: textarea
attributes:
# For smaller collections we could use a multi-select and hardcode the list
# May generate this list via GitHub action and walking files under https://github.com/ansible-collections/community.general/tree/main/plugins
# Select from list, filter as you type (`mysql` would only show the 3 mysql components)
# OR freeform - doesn't seem to be supported in adaptivecards
label: Component Name
description: >-
Write the short name of the module, plugin, task or feature below,
*use your best guess if unsure*.
placeholder: dnf, apt, yum, pip, user etc.
validations:
required: true
- type: textarea
attributes:
label: Ansible Version
description: >-
Paste verbatim output from `ansible --version` between
tripple backticks.
value: |
```console (paste below)
$ ansible --version
```
validations:
required: true
- type: textarea
attributes:
label: Community.general Version
description: >-
Paste verbatim output from "ansible-galaxy collection list community.general"
between tripple backticks.
value: |
```console (paste below)
$ ansible-galaxy collection list community.general
```
validations:
required: true
- type: textarea
attributes:
label: Configuration
description: >-
If this issue has an example piece of YAML that can help to reproduce this problem, please provide it.
This can be a piece of YAML from, e.g., an automation, script, scene or configuration.
Paste verbatim output from `ansible-config dump --only-changed` between quotes
value: |
```console (paste below)
$ ansible-config dump --only-changed
```
- type: textarea
attributes:
label: OS / Environment
description: >-
Provide all relevant information below, e.g. target OS versions,
network device firmware, etc.
placeholder: RHEL 8, CentOS Stream etc.
validations:
required: false
- type: textarea
attributes:
label: Steps to Reproduce
description: |
Describe exactly how to reproduce the problem, using a minimal test-case. It would *really* help us understand your problem if you could also pased any playbooks, configs and commands you used.
**HINT:** You can paste https://gist.github.com links for larger files.
value: |
<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
```
validations:
required: true
- type: textarea
attributes:
label: Expected Results
description: >-
Describe what you expected to happen when running the steps above.
placeholder: >-
I expected X to happen because I assumed Y.
that it did not.
validations:
required: true
- type: textarea
attributes:
label: Actual Results
description: |
Describe what actually happened. If possible run with extra verbosity (`-vvvv`).
Paste verbatim command output between quotes.
value: |
```console (paste below)
```
- type: checkboxes
attributes:
label: Code of Conduct
description: |
Read the [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_form--ansible-collections) first.
options:
- label: I agree to follow the Ansible Code of Conduct
required: true
...

View File

@@ -1,27 +0,0 @@
---
# Ref: https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository#configuring-the-template-chooser
blank_issues_enabled: false # default: true
contact_links:
- name: Security bug report
url: https://docs.ansible.com/ansible-core/devel/community/reporting_bugs_and_features.html?utm_medium=github&utm_source=issue_template_chooser_ansible_collections
about: |
Please learn how to report security vulnerabilities here.
For all security related bugs, email security@ansible.com
instead of using this issue tracker and you will receive
a prompt response.
For more information, see
https://docs.ansible.com/ansible/latest/community/reporting_bugs_and_features.html
- name: Ansible Code of Conduct
url: https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_template_chooser_ansible_collections
about: Be nice to other members of the community.
- name: Talks to the community
url: https://docs.ansible.com/ansible/latest/community/communication.html?utm_medium=github&utm_source=issue_template_chooser#mailing-list-information
about: Please ask and answer usage questions here
- name: Working groups
url: https://github.com/ansible/community/wiki
about: Interested in improving a specific area? Become a part of a working group!
- name: For Enterprise
url: https://www.ansible.com/products/engine?utm_medium=github&utm_source=issue_template_chooser_ansible_collections
about: Red Hat offers support for the Ansible Automation Platform

View File

@@ -1,125 +0,0 @@
---
name: Documentation Report
description: Ask us about docs
# NOTE: issue body is enabled to allow screenshots
body:
- type: markdown
attributes:
value: |
Verify first that your issue is not [already reported on GitHub][issue search].
Also test if the latest release and devel branch are affected too.
*Complete **all** sections as described, this form is processed automatically.*
[issue search]: https://github.com/ansible-collections/community.general/search?q=is%3Aissue&type=issues
- type: textarea
attributes:
label: Summary
description: |
Explain the problem briefly below, add suggestions to wording or structure.
**HINT:** Did you know the documentation has an `Edit on GitHub` link on every page?
placeholder: >-
I was reading the Collection documentation of version X and I'm having
problems understanding Y. It would be very helpful if that got
rephrased as Z.
validations:
required: true
- type: dropdown
attributes:
label: Issue Type
# FIXME: Once GitHub allows defining the default choice, update this
options:
- Documentation Report
validations:
required: true
- type: input
attributes:
label: Component Name
description: >-
Write the short name of the rst file, module, plugin, task or
feature below, *use your best guess if unsure*.
placeholder: mysql_user
validations:
required: true
- type: textarea
attributes:
label: Ansible Version
description: >-
Paste verbatim output from `ansible --version` between
tripple backticks.
value: |
```console (paste below)
$ ansible --version
```
validations:
required: false
- type: textarea
attributes:
label: Community.general Version
description: >-
Paste verbatim output from "ansible-galaxy collection list community.general"
between tripple backticks.
value: |
```console (paste below)
$ ansible-galaxy collection list community.general
```
validations:
required: true
- type: textarea
attributes:
label: Configuration
description: >-
Paste verbatim output from `ansible-config dump --only-changed` between quotes.
value: |
```console (paste below)
$ ansible-config dump --only-changed
```
validations:
required: false
- type: textarea
attributes:
label: OS / Environment
description: >-
Provide all relevant information below, e.g. OS version,
browser, etc.
placeholder: Fedora 33, Firefox etc.
validations:
required: false
- type: textarea
attributes:
label: Additional Information
description: |
Describe how this improves the documentation, e.g. before/after situation or screenshots.
**Tip:** It's not possible to upload the screenshot via this field directly but you can use the last textarea in this form to attach them.
**HINT:** You can paste https://gist.github.com links for larger files.
placeholder: >-
When the improvement is applied, it makes it more straightforward
to understand X.
validations:
required: false
- type: checkboxes
attributes:
label: Code of Conduct
description: |
Read the [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_form--ansible-collections) first.
options:
- label: I agree to follow the Ansible Code of Conduct
required: true
...

View File

@@ -1,69 +0,0 @@
---
name: Feature request
description: Suggest an idea for this project
body:
- type: markdown
attributes:
value: |
Verify first that your issue is not [already reported on GitHub][issue search].
Also test if the latest release and devel branch are affected too.
*Complete **all** sections as described, this form is processed automatically.*
[issue search]: https://github.com/ansible-collections/community.general/search?q=is%3Aissue&type=issues
- type: textarea
attributes:
label: Summary
description: Describe the new feature/improvement briefly below.
placeholder: >-
I am trying to do X with the collection from the main branch on GitHub and
I think that implementing a feature Y would be very helpful for me and
every other user of community.general because of Z.
validations:
required: true
- type: dropdown
attributes:
label: Issue Type
# FIXME: Once GitHub allows defining the default choice, update this
options:
- Feature Idea
validations:
required: true
- type: input
attributes:
label: Component Name
description: >-
Write the short name of the module, plugin, task or feature below,
*use your best guess if unsure*.
placeholder: dnf, apt, yum, pip, user etc.
validations:
required: true
- type: textarea
attributes:
label: Additional Information
description: |
Describe how the feature would be used, why it is needed and what it would solve.
**HINT:** You can paste https://gist.github.com links for larger files.
value: |
<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
```
validations:
required: false
- type: checkboxes
attributes:
label: Code of Conduct
description: |
Read the [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html?utm_medium=github&utm_source=issue_form--ansible-collections) first.
options:
- label: I agree to follow the Ansible Code of Conduct
required: true
...

View File

@@ -1,6 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
interval:
schedule: "weekly"

49
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: "Code scanning - action"
on:
schedule:
- cron: '26 19 * * 1'
jobs:
CodeQL-Build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

171
.gitignore vendored
View File

@@ -1,6 +1,6 @@
# Created by https://www.toptal.com/developers/gitignore/api/vim,git,macos,linux,pydev,emacs,dotenv,python,windows,webstorm,pycharm+all,jupyternotebooks
# Edit at https://www.toptal.com/developers/gitignore?templates=vim,git,macos,linux,pydev,emacs,dotenv,python,windows,webstorm,pycharm+all,jupyternotebooks
# Created by https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
# Edit at https://www.gitignore.io/?templates=git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
### dotenv ###
.env
@@ -71,19 +71,7 @@ flycheck_*.el
*_LOCAL_*.txt
*_REMOTE_*.txt
### JupyterNotebooks ###
# gitignore template for Jupyter Notebooks
# website: http://jupyter.org/
.ipynb_checkpoints
*/.ipynb_checkpoints/*
# IPython
profile_default/
ipython_config.py
# Remove previous ipynb_checkpoints
# git rm -r .ipynb_checkpoints/
#!! ERROR: jupyternotebook is undefined. Use list command to see defined gitignore types !!#
### Linux ###
@@ -99,41 +87,8 @@ ipython_config.py
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
### PyCharm+all ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
@@ -143,9 +98,6 @@ Temporary Items
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
@@ -166,9 +118,6 @@ Temporary Items
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
@@ -196,9 +145,6 @@ atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
@@ -212,13 +158,20 @@ fabric.properties
.idea/caches/build_file_checksums.ser
### PyCharm+all Patch ###
# Ignore everything but code style settings and run configurations
# that are supposed to be shared within teams.
# Ignores the whole .idea folder and all .iml files
# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
.idea/*
.idea/
!.idea/codeStyles
!.idea/runConfigurations
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
*.iml
modules.xml
.idea/misc.xml
*.ipr
# Sonarlint plugin
.idea/sonarlint
### pydev ###
.pydevproject
@@ -245,6 +198,7 @@ parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
@@ -271,25 +225,13 @@ htmlcov/
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
@@ -297,17 +239,10 @@ instance/
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
# IPython
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
@@ -316,39 +251,12 @@ target/
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
# celery beat schedule file
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
@@ -356,6 +264,10 @@ venv.bak/
# Rope project settings
.ropeproject
# Mr Developer
.mr.developer.cfg
.project
# mkdocs documentation
/site
@@ -367,23 +279,9 @@ dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
### Vim ###
# Swap
[._]*.s[a-v][a-z]
!*.svg # comment out if you don't need vector files
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
@@ -401,13 +299,11 @@ tags
[._]*.un~
### WebStorm ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
# AWS User-specific
# Generated files
# Sensitive or high-churn files
@@ -418,9 +314,6 @@ tags
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
@@ -441,8 +334,6 @@ tags
# Cursive Clojure plugin
# SonarLint plugin
# Crashlytics plugin (for Android Studio and IntelliJ)
# Editor-based Rest Client
@@ -458,27 +349,15 @@ tags
# *.ipr
# Sonarlint plugin
# https://plugins.jetbrains.com/plugin/7973-sonarlint
.idea/**/sonarlint/
# SonarQube Plugin
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator/
# Cache file creation bug
# See https://youtrack.jetbrains.com/issue/JBR-2257
.idea/$CACHE_FILE$
# CodeStream plugin
# https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml
### Windows ###
# Windows thumbnail cache files
Thumbs.db
@@ -505,4 +384,4 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/vim,git,macos,linux,pydev,emacs,dotenv,python,windows,webstorm,pycharm+all,jupyternotebooks
# End of https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv

File diff suppressed because it is too large Load Diff

View File

@@ -1,121 +0,0 @@
# 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.
* Do not squash your commits and force-push to your branch if not needed. Reviews of your pull request are much easier with individual commits to comprehend the pull request history. All commits of your pull request branch will be squashed into one commit by GitHub upon merge.
* Do not add merge commits to your PR. The bot will complain and you will have to rebase ([instructions for rebasing](https://docs.ansible.com/ansible/latest/dev_guide/developing_rebasing.html)) to remove them before your PR can be merged. To avoid that git automatically does merges during pulls, you can configure it to do rebases instead by running `git config pull.rebase true` inside the repository checkout.
* Make sure your PR includes a [changelog fragment](https://docs.ansible.com/ansible/devel/community/development_process.html#changelogs-how-to). (You must not include a fragment for new modules or new plugins, except for test and filter plugins. Also you shouldn't include one for docs-only changes. If you're not sure, simply don't include one, we'll tell you whether one is needed or not :) )
* Avoid reformatting unrelated parts of the codebase in your PR. These types of changes will likely be requested for reversion, create additional work for reviewers, and may cause approval to be delayed.
You can also read [our Quick-start development guide](https://github.com/ansible/community-docs/blob/main/create_pr_quick_start_guide.rst).
## Test pull requests
If you want to test a PR locally, refer to [our testing guide](https://github.com/ansible/community-docs/blob/main/test_pr_locally_guide.rst) for instructions on how do it quickly.
If you find any inconsistencies or places in this document which can be improved, feel free to raise an issue or pull request to fix it.
## Run sanity, unit or integration tests locally
You have to check out the repository into a specific path structure to be able to run `ansible-test`. The path to the git checkout must end with `.../ansible_collections/community/general`. Please see [our testing guide](https://github.com/ansible/community-docs/blob/main/test_pr_locally_guide.rst) for instructions on how to check out the repository into a correct path structure. The short version of these instructions is:
```.bash
mkdir -p ~/dev/ansible_collections/community
git clone https://github.com/ansible-collections/community.general.git ~/dev/ansible_collections/community/general
cd ~/dev/ansible_collections/community/general
```
Then you can run `ansible-test` (which is a part of [ansible-core](https://pypi.org/project/ansible-core/)) inside the checkout. The following example commands expect that you have installed Docker or Podman. Note that Podman has only been supported by more recent ansible-core releases. If you are using Docker, the following will work with Ansible 2.9+.
The following commands show how to run sanity tests:
```.bash
# Run sanity tests for all files in the collection:
ansible-test sanity --docker -v
# Run sanity tests for the given files and directories:
ansible-test sanity --docker -v plugins/modules/system/pids.py tests/integration/targets/pids/
```
The following commands show how to run unit tests:
```.bash
# Run all unit tests:
ansible-test units --docker -v
# Run all unit tests for one Python version (a lot faster):
ansible-test units --docker -v --python 3.8
# Run a specific unit test (for the nmcli module) for one Python version:
ansible-test units --docker -v --python 3.8 tests/unit/plugins/modules/net_tools/test_nmcli.py
```
The following commands show how to run integration tests:
```.bash
# Run integration tests for the interfaces_files module in a Docker container using the
# fedora35 operating system image (the supported images depend on your ansible-core version):
ansible-test integration --docker fedora35 -v interfaces_file
# Run integration tests for the flattened lookup **without any isolation**:
ansible-test integration -v lookup_flattened
```
If you are unsure about the integration test target name for a module or plugin, you can take a look in `tests/integration/targets/`. Tests for plugins have the plugin type prepended.
## Creating new modules or plugins
Creating new modules and plugins requires a bit more work than other Pull Requests.
1. Please make sure that your new module or plugin is of interest to a larger audience. Very specialized modules or plugins that
can only be used by very few people should better be added to more specialized collections.
2. Please do not add more than one plugin/module in one PR, especially if it is the first plugin/module you are contributing.
That makes it easier for reviewers, and increases the chance that your PR will get merged. If you plan to contribute a group
of plugins/modules (say, more than a module and a corresponding ``_info`` module), please mention that in the first PR. In
such cases, you also have to think whether it is better to publish the group of plugins/modules in a new collection.
3. When creating a new module or plugin, please make sure that you follow various guidelines:
- Follow [development conventions](https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_best_practices.html);
- Follow [documentation standards](https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_documenting.html) and
the [Ansible style guide](https://docs.ansible.com/ansible/devel/dev_guide/style_guide/index.html#style-guide);
- Make sure your modules and plugins are [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0-standalone.html) licensed
(new module_utils can also be [BSD-2-clause](https://opensource.org/licenses/BSD-2-Clause) licensed);
- Make sure that new plugins and modules have tests (unit tests, integration tests, or both); it is preferable to have some tests
which run in CI.
4. For modules and action plugins, make sure to create your module/plugin in the correct subdirectory, and create a symbolic link
from `plugins/modules/` respectively `plugins/action/` to the actual module/plugin code. (Other plugin types should not use
subdirectories.)
- Action plugins need to be accompanied by a module, even if the module file only contains documentation
(`DOCUMENTATION`, `EXAMPLES` and `RETURN`). The module must have the same name and directory path in `plugins/modules/`
than the action plugin has in `plugins/action/`.
5. Make sure to add a BOTMETA entry for your new module/plugin in `.github/BOTMETA.yml`. Search for other plugins/modules in the
same directory to see how entries could look. You should list all authors either as `maintainers` or under `ignore`. People
listed as `maintainers` will be pinged for new issues and PRs that modify the module/plugin or its tests.
When you add a new plugin/module, we expect that you perform maintainer duty for at least some time after contributing it.

View File

@@ -1,9 +0,0 @@
MIT License
Copyright (c) <year> <copyright holders>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,48 +0,0 @@
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
--------------------------------------------
1. This LICENSE AGREEMENT is between the Python Software Foundation
("PSF"), and the Individual or Organization ("Licensee") accessing and
otherwise using this software ("Python") in source or binary form and
its associated documentation.
2. Subject to the terms and conditions of this License Agreement, PSF hereby
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
analyze, test, perform and/or display publicly, prepare derivative works,
distribute, and otherwise use Python alone or in any derivative version,
provided, however, that PSF's License Agreement and PSF's notice of copyright,
i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Python Software Foundation;
All Rights Reserved" are retained in Python alone or in any derivative version
prepared by Licensee.
3. In the event Licensee prepares a derivative work that is based on
or incorporates Python or any part thereof, and wants to make
the derivative work available to others as provided herein, then
Licensee hereby agrees to include in any such work a brief summary of
the changes made to Python.
4. PSF is making Python available to Licensee on an "AS IS"
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
INFRINGE ANY THIRD PARTY RIGHTS.
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material
breach of its terms and conditions.
7. Nothing in this License Agreement shall be deemed to create any
relationship of agency, partnership, or joint venture between PSF and
Licensee. This License Agreement does not grant permission to use PSF
trademarks or trade name in a trademark sense to endorse or promote
products or services of Licensee, or any third party.
8. By copying, installing or otherwise using Python, Licensee
agrees to be bound by the terms and conditions of this License
Agreement.

View File

@@ -1,24 +1,15 @@
# Community General Collection
[![Build Status](https://dev.azure.com/ansible/community.general/_apis/build/status/CI?branchName=stable-4)](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
[![EOL CI](https://github.com/ansible-collections/community.general/workflows/EOL%20CI/badge.svg?event=push)](https://github.com/ansible-collections/community.general/actions)
[![Build Status](https://dev.azure.com/ansible/community.general/_apis/build/status/CI?branchName=stable-2)](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
[![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.general)](https://codecov.io/gh/ansible-collections/community.general)
This repository contains the `community.general` Ansible Collection. The collection is a part of the Ansible package and includes many modules and plugins supported by Ansible community which are not part of more specialized community collections.
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.
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.
## Code of Conduct
We follow [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html) in all our interactions within this project.
If you encounter abusive behavior violating the [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html), please refer to the [policy violations](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html#policy-violations) section of the Code of Conduct for information on how to raise a complaint.
## Tested with Ansible
Tested with the current Ansible 2.9, ansible-base 2.10, ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, and ansible-core 2.14 releases of ansible-core. Ansible versions before 2.9.10 are not supported.
Tested with the current Ansible 2.9 and 2.10 releases and the current development version of Ansible. Ansible versions before 2.9.10 are not supported.
## External requirements
@@ -30,9 +21,7 @@ Please check the included content on the [Ansible Galaxy page for this collectio
## Using this collection
This collection is shipped with the Ansible package. So if you have it installed, no more action is required.
If you have a minimal installation (only Ansible Core installed) or you want to use the latest version of the collection along with the whole Ansible package, you need to install the collection from [Ansible Galaxy](https://galaxy.ansible.com/community/general) manually with the `ansible-galaxy` command-line tool:
Before using the General community collection, you need to install the collection with the `ansible-galaxy` CLI:
ansible-galaxy collection install community.general
@@ -43,79 +32,57 @@ collections:
- name: community.general
```
Note that if you install the collection manually, it will not be upgraded automatically when you upgrade the Ansible package. To upgrade the collection to the latest available version, run the following command:
```bash
ansible-galaxy collection install community.general --upgrade
```
You can also install a specific version of the collection, for example, if you need to downgrade when something is broken in the latest version (please report an issue in this repository). Use the following syntax where `X.Y.Z` can be any [available version](https://galaxy.ansible.com/community/general):
```bash
ansible-galaxy collection install community.general:==X.Y.Z
```
See [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details.
## Contributing to this collection
The content of this collection is made by good people just like you, a community of individuals collaborating on making the world better through developing automation software.
If you want to develop new content for this collection or improve what is already here, the easiest way to work on the collection is to clone it into one of the configured [`COLLECTIONS_PATH`](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#collections-paths), and work on it there.
We are actively accepting new contributors.
For example, if you are working in the `~/dev` directory:
All types of contributions are very welcome.
You don't know how to start? Refer to our [contribution guide](https://github.com/ansible-collections/community.general/blob/stable-4/CONTRIBUTING.md)!
The current maintainers are listed in the [commit-rights.md](https://github.com/ansible-collections/community.general/blob/stable-4/commit-rights.md#people) file. If you have questions or need help, feel free to mention them in the proposals.
```
cd ~/dev
git clone git@github.com:ansible-collections/community.general.git collections/ansible_collections/community/general
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/stable-4/CONTRIBUTING.md).
### Running tests
See [here](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections.html#testing-collections).
## Collection maintenance
### Communication
To learn how to maintain / become a maintainer of this collection, refer to:
We have a dedicated Working Group for Ansible development.
* [Committer guidelines](https://github.com/ansible-collections/community.general/blob/stable-4/commit-rights.md).
* [Maintainer guidelines](https://github.com/ansible/community-docs/blob/main/maintaining.rst).
It is necessary for maintainers of this collection to be subscribed to:
* The collection itself (the `Watch` button → `All Activity` in the upper right corner of the repository's homepage).
* The "Changes Impacting Collection Contributors and Maintainers" [issue](https://github.com/ansible-collections/overview/issues/45).
They also should be subscribed to Ansible's [The Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn).
## Communication
We announce important development changes and releases through Ansible's [The Bullhorn newsletter](https://eepurl.com/gZmiEP). If you are a collection developer, be sure you are subscribed.
Join us in the `#ansible` (general use questions and support), `#ansible-community` (community and collection development questions), and other [IRC channels](https://docs.ansible.com/ansible/devel/community/communication.html#irc-channels) on [Libera.chat](https://libera.chat).
We take part in the global quarterly [Ansible Contributor Summit](https://github.com/ansible/community/wiki/Contributor-Summit) virtually or in-person. Track [The Bullhorn newsletter](https://eepurl.com/gZmiEP) and join us.
You can find other people interested on the following Freenode 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.
For more information about communities, meetings and agendas see [Community Wiki](https://github.com/ansible/community/wiki/Community).
For more information about communication, refer to Ansible's the [Communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
For more information about [communication](https://docs.ansible.com/ansible/latest/community/communication.html)
## Publishing New Version
### Publishing New Version
See the [Releasing guidelines](https://github.com/ansible/community-docs/blob/main/releasing_collections.rst) to learn how to release this collection.
Basic instructions without release branches:
1. Create `changelogs/fragments/<version>.yml` with `release_summary:` section (which must be a string, not a list).
2. Run `antsibull-changelog release --collection-flatmap yes`
3. Make sure `CHANGELOG.rst` and `changelogs/changelog.yaml` are added to git, and the deleted fragments have been removed.
4. Tag the commit with `<version>`. Push changes and tag to the main repository.
## Release notes
See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-4/CHANGELOG.rst).
See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-2/CHANGELOG.rst).
## Roadmap
In general, we plan to release a major version every six months, and minor versions every two months. Major versions can contain breaking changes, while minor versions only contain new features and bugfixes.
See [this issue](https://github.com/ansible-collections/community.general/issues/582) for information on releasing, versioning and deprecation.
See [this issue](https://github.com/ansible-collections/community.general/issues/582) for information on releasing, versioning, and deprecation.
In general, we plan to release a major version every six months, and minor versions every two months. Major versions can contain breaking changes, while minor versions only contain new features and bugfixes.
## More information

File diff suppressed because it is too large Load Diff

View File

@@ -1,74 +0,0 @@
Committers Guidelines for community.general
===========================================
This document is based on the [Ansible committer guidelines](https://github.com/ansible/ansible/blob/b57444af14062ec96e0af75fdfc2098c74fe2d9a/docs/docsite/rst/community/committer_guidelines.rst) ([latest version](https://docs.ansible.com/ansible/devel/community/committer_guidelines.html)).
These are the guidelines for people with commit privileges on the Ansible Community General Collection GitHub repository. Please read the guidelines before you commit.
These guidelines apply to everyone. At the same time, this is NOT a process document. So just use good judgment. You have been given commit access because we trust your judgment.
That said, use the trust wisely.
If you abuse the trust and break components and builds, and so on, the trust level falls and you may be asked not to commit or you may lose your commit privileges.
Our workflow on GitHub
----------------------
As a committer, you may already know this, but our workflow forms a lot of our team policies. Please ensure you are aware of the following workflow steps:
* Fork the repository upon which you want to do some work to your own personal repository
* Work on the specific branch upon which you need to commit
* Create a Pull Request back to the collection repository and await reviews
* Adjust code as necessary based on the Comments provided
* Ask someone from the other committers to do a final review and merge
Sometimes, committers merge their own pull requests. This section is a set of guidelines. If you are changing a comma in a doc or making a very minor change, you can use your best judgement. This is another trust thing. The process is critical for any major change, but for little things or getting something done quickly, use your best judgement and make sure people on the team are aware of your work.
Roles
-----
* Release managers: Merge pull requests to `stable-X` branches, create tags to do releases.
* Committers: Fine to do PRs for most things, but we should have a timebox. Hanging PRs may merge on the judgement of these devs.
* Module maintainers: Module maintainers own specific modules and have indirect commit access through the current module PR mechanisms. This is primary [ansibullbot](https://github.com/ansibullbot)'s `shipit` mechanism.
General rules
-------------
Individuals with direct commit access to this collection repository are entrusted with powers that allow them to do a broad variety of things--probably more than we can write down. Rather than rules, treat these as general *guidelines*, individuals with this power are expected to use their best judgement.
* Do NOTs:
- Do not commit directly.
- Do not merge your own PRs. Someone else should have a chance to review and approve the PR merge. You have a small amount of leeway here for very minor changes.
- Do not forget about non-standard / alternate environments. Consider the alternatives. Yes, people have bad/unusual/strange environments (like binaries from multiple init systems installed), but they are the ones who need us the most.
- Do not drag your community team members down. Discuss the technical merits of any pull requests you review. Avoid negativity and personal comments. For more guidance on being a good community member, read the [Ansible Community Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html).
- Do not forget about the maintenance burden. High-maintenance features may not be worth adding.
- Do not break playbooks. Always keep backwards compatibility in mind.
- Do not forget to keep it simple. Complexity breeds all kinds of problems.
- Do not merge to branches other than `main`, especially not to `stable-X`, if you do not have explicit permission to do so.
- Do not create tags. Tags are used in the release process, and should only be created by the people responsible for managing the stable branches.
* Do:
- Squash, avoid merges whenever possible, use GitHub's squash commits or cherry pick if needed (bisect thanks you).
- Be active. Committers who have no activity on the project (through merges, triage, commits, and so on) will have their permissions suspended.
- Consider backwards compatibility (goes back to "do not break existing playbooks").
- Write tests. PRs with tests are looked at with more priority than PRs without tests that should have them included. While not all changes require tests, be sure to add them for bug fixes or functionality changes.
- Discuss with other committers, specially when you are unsure of something.
- Document! If your PR is a new feature or a change to behavior, make sure you've updated all associated documentation or have notified the right people to do so.
- Consider scope, sometimes a fix can be generalized.
- Keep it simple, then things are maintainable, debuggable and intelligible.
Committers are expected to continue to follow the same community and contribution guidelines followed by the rest of the Ansible community.
People
------
Individuals who have been asked to become a part of this group have generally been contributing in significant ways to the community.general collection for some time. Should they agree, they are requested to add their names and GitHub IDs to this file, in the section below, through a pull request. Doing so indicates that these individuals agree to act in the ways that their fellow committers trust that they will act.
| Name | GitHub ID | IRC Nick | Other |
| ------------------- | -------------------- | ------------------ | -------------------- |
| Alexei Znamensky | russoz | russoz | |
| Andrew Klychkov | andersson007 | andersson007_ | |
| Andrew Pantuso | Ajpantuso | ajpantuso | |
| Felix Fontein | felixfontein | felixfontein | |
| John R Barker | gundalow | gundalow | |

View File

@@ -1,6 +0,0 @@
---
sections:
- title: Guides
toctree:
- filter_guide
- test_guide

View File

@@ -1,13 +0,0 @@
list1:
- name: foo
extra: true
- name: bar
extra: false
- name: meh
extra: true
list2:
- name: foo
path: /foo
- name: baz
path: /baz

View File

@@ -1,19 +0,0 @@
list1:
- name: myname01
param01:
x: default_value
y: default_value
list:
- default_value
- name: myname02
param01: [1, 1, 2, 3]
list2:
- name: myname01
param01:
y: patch_value
z: patch_value
list:
- patch_value
- name: myname02
param01: [3, 4, 4, {key: value}]

View File

@@ -1,10 +0,0 @@
---
- name: 1. Merge two lists by common attribute 'name'
include_vars:
dir: example-001_vars
- debug:
var: list3
when: debug|d(false)|bool
- template:
src: list3.out.j2
dest: example-001.out

View File

@@ -1 +0,0 @@
../default-common.yml

View File

@@ -1,2 +0,0 @@
list3: "{{ list1|
community.general.lists_mergeby(list2, 'name') }}"

View File

@@ -1,10 +0,0 @@
---
- name: 2. Merge two lists by common attribute 'name'
include_vars:
dir: example-002_vars
- debug:
var: list3
when: debug|d(false)|bool
- template:
src: list3.out.j2
dest: example-002.out

View File

@@ -1 +0,0 @@
../default-common.yml

View File

@@ -1,2 +0,0 @@
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name') }}"

View File

@@ -1,10 +0,0 @@
---
- name: 3. Merge recursive by 'name', replace lists (default)
include_vars:
dir: example-003_vars
- debug:
var: list3
when: debug|d(false)|bool
- template:
src: list3.out.j2
dest: example-003.out

View File

@@ -1 +0,0 @@
../default-recursive-true.yml

View File

@@ -1,3 +0,0 @@
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true) }}"

View File

@@ -1,10 +0,0 @@
---
- name: 4. Merge recursive by 'name', keep lists
include_vars:
dir: example-004_vars
- debug:
var: list3
when: debug|d(false)|bool
- template:
src: list3.out.j2
dest: example-004.out

View File

@@ -1 +0,0 @@
../default-recursive-true.yml

View File

@@ -1,4 +0,0 @@
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='keep') }}"

View File

@@ -1,10 +0,0 @@
---
- name: 5. Merge recursive by 'name', append lists
include_vars:
dir: example-005_vars
- debug:
var: list3
when: debug|d(false)|bool
- template:
src: list3.out.j2
dest: example-005.out

View File

@@ -1 +0,0 @@
../default-recursive-true.yml

View File

@@ -1,4 +0,0 @@
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='append') }}"

View File

@@ -1,10 +0,0 @@
---
- name: 6. Merge recursive by 'name', prepend lists
include_vars:
dir: example-006_vars
- debug:
var: list3
when: debug|d(false)|bool
- template:
src: list3.out.j2
dest: example-006.out

View File

@@ -1 +0,0 @@
../default-recursive-true.yml

View File

@@ -1,4 +0,0 @@
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='prepend') }}"

View File

@@ -1,10 +0,0 @@
---
- name: 7. Merge recursive by 'name', append lists 'remove present'
include_vars:
dir: example-007_vars
- debug:
var: list3
when: debug|d(false)|bool
- template:
src: list3.out.j2
dest: example-007.out

View File

@@ -1 +0,0 @@
../default-recursive-true.yml

View File

@@ -1,4 +0,0 @@
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='append_rp') }}"

View File

@@ -1,10 +0,0 @@
---
- name: 8. Merge recursive by 'name', prepend lists 'remove present'
include_vars:
dir: example-008_vars
- debug:
var: list3
when: debug|d(false)|bool
- template:
src: list3.out.j2
dest: example-008.out

View File

@@ -1 +0,0 @@
../default-recursive-true.yml

View File

@@ -1,4 +0,0 @@
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='prepend_rp') }}"

View File

@@ -1,50 +0,0 @@
---
examples:
- label: 'In the example below the lists are merged by the attribute ``name``:'
file: example-001_vars/list3.yml
lang: 'yaml+jinja'
- label: 'This produces:'
file: example-001.out
lang: 'yaml'
- label: 'It is possible to use a list of lists as an input of the filter:'
file: example-002_vars/list3.yml
lang: 'yaml+jinja'
- label: 'This produces the same result as in the previous example:'
file: example-002.out
lang: 'yaml'
- label: 'Example ``list_merge=replace`` (default):'
file: example-003_vars/list3.yml
lang: 'yaml+jinja'
- label: 'This produces:'
file: example-003.out
lang: 'yaml'
- label: 'Example ``list_merge=keep``:'
file: example-004_vars/list3.yml
lang: 'yaml+jinja'
- label: 'This produces:'
file: example-004.out
lang: 'yaml'
- label: 'Example ``list_merge=append``:'
file: example-005_vars/list3.yml
lang: 'yaml+jinja'
- label: 'This produces:'
file: example-005.out
lang: 'yaml'
- label: 'Example ``list_merge=prepend``:'
file: example-006_vars/list3.yml
lang: 'yaml+jinja'
- label: 'This produces:'
file: example-006.out
lang: 'yaml'
- label: 'Example ``list_merge=append_rp``:'
file: example-007_vars/list3.yml
lang: 'yaml+jinja'
- label: 'This produces:'
file: example-007.out
lang: 'yaml'
- label: 'Example ``list_merge=prepend_rp``:'
file: example-008_vars/list3.yml
lang: 'yaml+jinja'
- label: 'This produces:'
file: example-008.out
lang: 'yaml'

View File

@@ -1,8 +0,0 @@
{% for i in examples %}
{{ i.label }}
.. code-block:: {{ i.lang }}
{{ lookup('file', i.file)|indent(2) }}
{% endfor %}

View File

@@ -1,57 +0,0 @@
Merging lists of dictionaries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you have two or more lists of dictionaries and want to combine them into a list of merged dictionaries, where the dictionaries are merged by an attribute, you can use the ``lists_mergeby`` filter.
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See :ref:`the documentation for the community.general.yaml callback plugin <ansible_collections.community.general.yaml_callback>`.
Let us use the lists below in the following examples:
.. code-block:: yaml
{{ lookup('file', 'default-common.yml')|indent(2) }}
{% for i in examples[0:2] %}
{{ i.label }}
.. code-block:: {{ i.lang }}
{{ lookup('file', i.file)|indent(2) }}
{% endfor %}
.. versionadded:: 2.0.0
{% for i in examples[2:4] %}
{{ i.label }}
.. code-block:: {{ i.lang }}
{{ lookup('file', i.file)|indent(2) }}
{% endfor %}
The filter also accepts two optional parameters: ``recursive`` and ``list_merge``. These parameters are only supported when used with ansible-base 2.10 or ansible-core, but not with Ansible 2.9. This is available since community.general 4.4.0.
**recursive**
Is a boolean, default to ``False``. Should the ``community.general.lists_mergeby`` recursively merge nested hashes. Note: It does not depend on the value of the ``hash_behaviour`` setting in ``ansible.cfg``.
**list_merge**
Is a string, its possible values are ``replace`` (default), ``keep``, ``append``, ``prepend``, ``append_rp`` or ``prepend_rp``. It modifies the behaviour of ``community.general.lists_mergeby`` when the hashes to merge contain arrays/lists.
The examples below set ``recursive=true`` and display the differences among all six options of ``list_merge``. Functionality of the parameters is exactly the same as in the filter ``combine``. See :ref:`Combining hashes/dictionaries <combine_filter>` to learn details about these options.
Let us use the lists below in the following examples
.. code-block:: yaml
{{ lookup('file', 'default-recursive-true.yml')|indent(2) }}
{% for i in examples[4:16] %}
{{ i.label }}
.. code-block:: {{ i.lang }}
{{ lookup('file', i.file)|indent(2) }}
{% endfor %}

View File

@@ -1,2 +0,0 @@
list3:
{{ list3|to_nice_yaml(indent=0) }}

View File

@@ -1,59 +0,0 @@
---
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# 1) Run all examples and create example-XXX.out
# shell> ansible-playbook playbook.yml -e examples=true
#
# 2) Optionally, for testing, create examples_all.rst
# shell> ansible-playbook playbook.yml -e examples_all=true
#
# 3) Create docs REST files
# shell> ansible-playbook playbook.yml -e merging_lists_of_dictionaries=true
#
# Notes:
# * Use YAML callback, e.g. set ANSIBLE_STDOUT_CALLBACK=community.general.yaml
# * Use sphinx-view to render and review the REST files
# shell> sphinx-view <path_to_helper>/examples_all.rst
# * Proofread and copy completed docs *.rst files into the directory rst.
# * Then delete the *.rst and *.out files from this directory. Do not
# add *.rst and *.out in this directory to the version control.
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# community.general/docs/docsite/helper/lists_mergeby/playbook.yml
- hosts: localhost
gather_facts: false
tasks:
- block:
- import_tasks: example-001.yml
tags: t001
- import_tasks: example-002.yml
tags: t002
- import_tasks: example-003.yml
tags: t003
- import_tasks: example-004.yml
tags: t004
- import_tasks: example-005.yml
tags: t005
- import_tasks: example-006.yml
tags: t006
- import_tasks: example-007.yml
tags: t007
- import_tasks: example-008.yml
tags: t008
when: examples|d(false)|bool
- block:
- include_vars: examples.yml
- template:
src: examples_all.rst.j2
dest: examples_all.rst
when: examples_all|d(false)|bool
- block:
- include_vars: examples.yml
- template:
src: filter_guide_abstract_informations_merging_lists_of_dictionaries.rst.j2
dest: filter_guide_abstract_informations_merging_lists_of_dictionaries.rst
when: merging_lists_of_dictionaries|d(false)|bool

View File

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

View File

@@ -1,19 +0,0 @@
.. _ansible_collections.community.general.docsite.filter_guide:
community.general Filter Guide
==============================
The :ref:`community.general collection <plugins_in_community.general>` offers several useful filter plugins.
.. toctree::
:maxdepth: 2
filter_guide_paths
filter_guide_abstract_informations
filter_guide_working_with_times
filter_guide_working_with_versions
filter_guide_creating_identifiers
filter_guide_conversions
filter_guide_selecting_json_data
filter_guide_working_with_unicode

View File

@@ -1,10 +0,0 @@
Abstract transformations
------------------------
.. toctree::
:maxdepth: 1
filter_guide_abstract_informations_dictionaries
filter_guide_abstract_informations_grouping
filter_guide_abstract_informations_merging_lists_of_dictionaries
filter_guide_abstract_informations_counting_elements_in_sequence

View File

@@ -1,77 +0,0 @@
Counting elements in a sequence
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``community.general.counter`` filter plugin allows you to count (hashable) elements in a sequence. Elements are returned as dictionary keys and their counts are stored as dictionary values.
.. code-block:: yaml+jinja
- name: Count character occurrences in a string
debug:
msg: "{{ 'abccbaabca' | community.general.counter }}"
- name: Count items in a list
debug:
msg: "{{ ['car', 'car', 'bike', 'plane', 'bike'] | community.general.counter }}"
This produces:
.. code-block:: ansible-output
TASK [Count character occurrences in a string] ********************************************
ok: [localhost] => {
"msg": {
"a": 4,
"b": 3,
"c": 3
}
}
TASK [Count items in a list] **************************************************************
ok: [localhost] => {
"msg": {
"bike": 2,
"car": 2,
"plane": 1
}
}
This plugin is useful for selecting resources based on current allocation:
.. code-block:: yaml+jinja
- name: Get ID of SCSI controller(s) with less than 4 disks attached and choose the one with the least disks
debug:
msg: >-
{{
( disks | dict2items | map(attribute='value.adapter') | list
| community.general.counter | dict2items
| rejectattr('value', '>=', 4) | sort(attribute='value') | first
).key
}}
vars:
disks:
sda:
adapter: scsi_1
sdb:
adapter: scsi_1
sdc:
adapter: scsi_1
sdd:
adapter: scsi_1
sde:
adapter: scsi_2
sdf:
adapter: scsi_3
sdg:
adapter: scsi_3
This produces:
.. code-block:: ansible-output
TASK [Get ID of SCSI controller(s) with less than 4 disks attached and choose the one with the least disks]
ok: [localhost] => {
"msg": "scsi_2"
}
.. versionadded:: 4.3.0

View File

@@ -1,119 +0,0 @@
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

View File

@@ -1,98 +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

View File

@@ -1,292 +0,0 @@
Merging lists of dictionaries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you have two or more lists of dictionaries and want to combine them into a list of merged dictionaries, where the dictionaries are merged by an attribute, you can use the ``lists_mergeby`` filter.
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See :ref:`the documentation for the community.general.yaml callback plugin <ansible_collections.community.general.yaml_callback>`.
Let us use the lists below in the following examples:
.. code-block:: yaml
list1:
- name: foo
extra: true
- name: bar
extra: false
- name: meh
extra: true
list2:
- name: foo
path: /foo
- name: baz
path: /baz
In the example below the lists are merged by the attribute ``name``:
.. code-block:: yaml+jinja
list3: "{{ list1|
community.general.lists_mergeby(list2, 'name') }}"
This produces:
.. code-block:: yaml
list3:
- extra: false
name: bar
- name: baz
path: /baz
- extra: true
name: foo
path: /foo
- extra: true
name: meh
.. versionadded:: 2.0.0
It is possible to use a list of lists as an input of the filter:
.. code-block:: yaml+jinja
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name') }}"
This produces the same result as in the previous example:
.. code-block:: yaml
list3:
- extra: false
name: bar
- name: baz
path: /baz
- extra: true
name: foo
path: /foo
- extra: true
name: meh
The filter also accepts two optional parameters: ``recursive`` and ``list_merge``. These parameters are only supported when used with ansible-base 2.10 or ansible-core, but not with Ansible 2.9. This is available since community.general 4.4.0.
**recursive**
Is a boolean, default to ``False``. Should the ``community.general.lists_mergeby`` recursively merge nested hashes. Note: It does not depend on the value of the ``hash_behaviour`` setting in ``ansible.cfg``.
**list_merge**
Is a string, its possible values are ``replace`` (default), ``keep``, ``append``, ``prepend``, ``append_rp`` or ``prepend_rp``. It modifies the behaviour of ``community.general.lists_mergeby`` when the hashes to merge contain arrays/lists.
The examples below set ``recursive=true`` and display the differences among all six options of ``list_merge``. Functionality of the parameters is exactly the same as in the filter ``combine``. See :ref:`Combining hashes/dictionaries <combine_filter>` to learn details about these options.
Let us use the lists below in the following examples
.. code-block:: yaml
list1:
- name: myname01
param01:
x: default_value
y: default_value
list:
- default_value
- name: myname02
param01: [1, 1, 2, 3]
list2:
- name: myname01
param01:
y: patch_value
z: patch_value
list:
- patch_value
- name: myname02
param01: [3, 4, 4, {key: value}]
Example ``list_merge=replace`` (default):
.. code-block:: yaml+jinja
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true) }}"
This produces:
.. code-block:: yaml
list3:
- name: myname01
param01:
list:
- patch_value
x: default_value
y: patch_value
z: patch_value
- name: myname02
param01:
- 3
- 4
- 4
- key: value
Example ``list_merge=keep``:
.. code-block:: yaml+jinja
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='keep') }}"
This produces:
.. code-block:: yaml
list3:
- name: myname01
param01:
list:
- default_value
x: default_value
y: patch_value
z: patch_value
- name: myname02
param01:
- 1
- 1
- 2
- 3
Example ``list_merge=append``:
.. code-block:: yaml+jinja
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='append') }}"
This produces:
.. code-block:: yaml
list3:
- name: myname01
param01:
list:
- default_value
- patch_value
x: default_value
y: patch_value
z: patch_value
- name: myname02
param01:
- 1
- 1
- 2
- 3
- 3
- 4
- 4
- key: value
Example ``list_merge=prepend``:
.. code-block:: yaml+jinja
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='prepend') }}"
This produces:
.. code-block:: yaml
list3:
- name: myname01
param01:
list:
- patch_value
- default_value
x: default_value
y: patch_value
z: patch_value
- name: myname02
param01:
- 3
- 4
- 4
- key: value
- 1
- 1
- 2
- 3
Example ``list_merge=append_rp``:
.. code-block:: yaml+jinja
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='append_rp') }}"
This produces:
.. code-block:: yaml
list3:
- name: myname01
param01:
list:
- default_value
- patch_value
x: default_value
y: patch_value
z: patch_value
- name: myname02
param01:
- 1
- 1
- 2
- 3
- 4
- 4
- key: value
Example ``list_merge=prepend_rp``:
.. code-block:: yaml+jinja
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='prepend_rp') }}"
This produces:
.. code-block:: yaml
list3:
- name: myname01
param01:
list:
- patch_value
- default_value
x: default_value
y: patch_value
z: patch_value
- name: myname02
param01:
- 3
- 4
- 4
- key: value
- 1
- 1
- 2

View File

@@ -1,108 +0,0 @@
Conversions
-----------
Parsing CSV files
^^^^^^^^^^^^^^^^^
Ansible offers the :ref:`community.general.read_csv module <ansible_collections.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 <https://pypi.org/project/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 <https://pypi.org/project/jc/>`_ 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

View File

@@ -1,80 +0,0 @@
Creating identifiers
--------------------
The following filters allow to create identifiers.
Hashids
^^^^^^^
`Hashids <https://hashids.org/>`_ allow to convert sequences of integers to short unique string identifiers. This filter needs the `hashids Python library <https://pypi.org/project/hashids/>`_ 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 <https://en.wikipedia.org/wiki/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) }}"

View File

@@ -1,14 +0,0 @@
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

View File

@@ -1,144 +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 <http://jmespath.org/examples.html>`_.
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 <https://yaml.org/spec/current.html#id2534365>`_:
.. 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.

View File

@@ -1,84 +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

View File

@@ -1,30 +0,0 @@
Working with Unicode
---------------------
`Unicode <https://unicode.org/main.html>`_ makes it possible to produce two strings which may be visually equivalent, but are comprised of distinctly different characters/character sequences. To address this ``Unicode`` defines `normalization forms <https://unicode.org/reports/tr15/>`_ which avoid these distinctions by choosing a unique character sequence for a given visual representation.
You can use the ``community.general.unicode_normalize`` filter to normalize ``Unicode`` strings within your playbooks.
.. code-block:: yaml+jinja
- name: Compare Unicode representations
debug:
msg: "{{ with_combining_character | community.general.unicode_normalize == without_combining_character }}"
vars:
with_combining_character: "{{ 'Mayagu\u0308ez' }}"
without_combining_character: Mayagüez
This produces:
.. code-block:: ansible-output
TASK [Compare Unicode representations] ********************************************************
ok: [localhost] => {
"msg": true
}
The ``community.general.unicode_normalize`` filter accepts a keyword argument to select the ``Unicode`` form used to normalize the input string.
:form: One of ``'NFC'`` (default), ``'NFD'``, ``'NFKC'``, or ``'NFKD'``. See the `Unicode reference <https://unicode.org/reports/tr15/>`_ for more information.
.. versionadded:: 3.7.0

View File

@@ -1,34 +0,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

View File

@@ -1,28 +0,0 @@
.. _ansible_collections.community.general.docsite.test_guide:
community.general Test (Plugin) Guide
=====================================
The :ref:`community.general collection <plugins_in_community.general>` offers currently one test plugin.
.. contents:: Topics
Feature Tests
-------------
The ``a_module`` test allows to check whether a given string refers to an existing module or action plugin. This can be useful in roles, which can use this to ensure that required modules are present ahead of time.
.. code-block:: yaml+jinja
- name: Make sure that community.aws.route53 is available
assert:
that:
- >
'community.aws.route53' is community.general.a_module
- name: Make sure that community.general.does_not_exist is not a module or action plugin
assert:
that:
- "'community.general.does_not_exist' is not community.general.a_module"
.. versionadded:: 4.0.0

View File

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

View File

@@ -1,5 +1,31 @@
---
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:
@@ -11,17 +37,11 @@ plugin_routing:
redirect: community.google.gcp_storage_file
hashi_vault:
redirect: community.hashi_vault.hashi_vault
nios:
redirect: infoblox.nios_modules.nios_lookup
nios_next_ip:
redirect: infoblox.nios_modules.nios_next_ip
nios_next_network:
redirect: infoblox.nios_modules.nios_next_network
modules:
ali_instance_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.ali_instance_info instead.
warning_text: see plugin documentation for details
docker_compose:
redirect: community.docker.docker_compose
docker_config:
@@ -121,13 +141,11 @@ 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
@@ -138,22 +156,37 @@ plugin_routing:
warning_text: Use google.cloud.gcp_compute_url_map instead.
gcpubsub:
redirect: community.google.gcpubsub
gcpubsub_facts:
tombstone:
removal_version: 3.0.0
warning_text: Use community.google.gcpubsub_info instead.
gcpubsub_info:
redirect: community.google.gcpubsub_info
gcpubsub_facts:
redirect: community.google.gcpubsub_info
deprecation:
removal_version: 3.0.0
warning_text: Use community.google.gcpubsub_info instead.
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.
warning_text: Use community.general.github_webhook and community.general.github_webhook_info instead.
gluster_heal_info:
deprecation:
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:
deprecation:
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:
deprecation:
removal_version: 3.0.0
warning_text: The gluster modules have migrated to the gluster.gluster collection. Use gluster.gluster.gluster_volume instead.
helm:
deprecation:
removal_version: 3.0.0
warning_text: The helm module in community.general has been deprecated. Use community.kubernetes.helm instead.
hetzner_failover_ip:
redirect: community.hrobot.failover_ip
hetzner_failover_ip_info:
@@ -163,21 +196,17 @@ plugin_routing:
hetzner_firewall_info:
redirect: community.hrobot.firewall_info
hpilo_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.hpilo_info instead.
idrac_firmware:
redirect: dellemc.openmanage.idrac_firmware
warning_text: see plugin documentation for details
idrac_redfish_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.idrac_redfish_info instead.
idrac_server_config_profile:
redirect: dellemc.openmanage.idrac_server_config_profile
warning_text: see plugin documentation for details
jenkins_job_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.jenkins_job_info instead.
warning_text: see plugin documentation for details
katello:
tombstone:
removal_version: 2.0.0
@@ -195,27 +224,25 @@ plugin_routing:
kubevirt_vm:
redirect: community.kubevirt.kubevirt_vm
ldap_attr:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.ldap_attrs instead.
warning_text: see plugin documentation for details
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:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.memset_memstore_info instead.
warning_text: see plugin documentation for details
memset_server_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.memset_server_info instead.
warning_text: see plugin documentation for details
na_cdot_aggregate:
tombstone:
removal_version: 2.0.0
@@ -249,196 +276,161 @@ plugin_routing:
removal_version: 2.0.0
warning_text: Use netapp.ontap.na_ontap_volume instead.
na_ontap_gather_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use netapp.ontap.na_ontap_info instead.
warning_text: see plugin documentation for details
nginx_status_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.nginx_status_info instead.
nios_a_record:
redirect: infoblox.nios_modules.nios_a_record
nios_aaaa_record:
redirect: infoblox.nios_modules.nios_aaaa_record
nios_cname_record:
redirect: infoblox.nios_modules.nios_cname_record
nios_dns_view:
redirect: infoblox.nios_modules.nios_dns_view
nios_fixed_address:
redirect: infoblox.nios_modules.nios_fixed_address
nios_host_record:
redirect: infoblox.nios_modules.nios_host_record
nios_member:
redirect: infoblox.nios_modules.nios_member
nios_mx_record:
redirect: infoblox.nios_modules.nios_mx_record
nios_naptr_record:
redirect: infoblox.nios_modules.nios_naptr_record
nios_network:
redirect: infoblox.nios_modules.nios_network
nios_network_view:
redirect: infoblox.nios_modules.nios_network_view
nios_nsgroup:
redirect: infoblox.nios_modules.nios_nsgroup
nios_ptr_record:
redirect: infoblox.nios_modules.nios_ptr_record
nios_srv_record:
redirect: infoblox.nios_modules.nios_srv_record
nios_txt_record:
redirect: infoblox.nios_modules.nios_txt_record
nios_zone:
redirect: infoblox.nios_modules.nios_zone
ome_device_info:
redirect: dellemc.openmanage.ome_device_info
warning_text: see plugin documentation for details
one_image_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.one_image_info instead.
warning_text: see plugin documentation for details
onepassword_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.onepassword_info instead.
warning_text: see plugin documentation for details
oneview_datacenter_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.oneview_datacenter_info instead.
warning_text: see plugin documentation for details
oneview_enclosure_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.oneview_enclosure_info instead.
warning_text: see plugin documentation for details
oneview_ethernet_network_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.oneview_ethernet_network_info instead.
warning_text: see plugin documentation for details
oneview_fc_network_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.oneview_fc_network_info instead.
warning_text: see plugin documentation for details
oneview_fcoe_network_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.oneview_fcoe_network_info instead.
warning_text: see plugin documentation for details
oneview_logical_interconnect_group_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.oneview_logical_interconnect_group_info
instead.
warning_text: see plugin documentation for details
oneview_network_set_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.oneview_network_set_info instead.
warning_text: see plugin documentation for details
oneview_san_manager_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.oneview_san_manager_info instead.
warning_text: see plugin documentation for details
online_server_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.online_server_info instead.
warning_text: see plugin documentation for details
online_user_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.online_user_info instead.
warning_text: see plugin documentation for details
ovirt:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_vm instead.
warning_text: see plugin documentation for details
ovirt_affinity_label_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_affinity_label_info instead.
warning_text: see plugin documentation for details
ovirt_api_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_api_info instead.
warning_text: see plugin documentation for details
ovirt_cluster_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_cluster_info instead.
warning_text: see plugin documentation for details
ovirt_datacenter_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_datacenter_info instead.
warning_text: see plugin documentation for details
ovirt_disk_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_disk_info instead.
warning_text: see plugin documentation for details
ovirt_event_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_event_info instead.
warning_text: see plugin documentation for details
ovirt_external_provider_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_external_provider_info instead.
warning_text: see plugin documentation for details
ovirt_group_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_group_info instead.
warning_text: see plugin documentation for details
ovirt_host_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_host_info instead.
warning_text: see plugin documentation for details
ovirt_host_storage_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_host_storage_info instead.
warning_text: see plugin documentation for details
ovirt_network_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_network_info instead.
warning_text: see plugin documentation for details
ovirt_nic_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_nic_info instead.
warning_text: see plugin documentation for details
ovirt_permission_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_permission_info instead.
warning_text: see plugin documentation for details
ovirt_quota_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_quota_info instead.
warning_text: see plugin documentation for details
ovirt_scheduling_policy_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_scheduling_policy_info instead.
warning_text: see plugin documentation for details
ovirt_snapshot_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_snapshot_info instead.
warning_text: see plugin documentation for details
ovirt_storage_domain_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_storage_domain_info instead.
warning_text: see plugin documentation for details
ovirt_storage_template_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_storage_template_info instead.
warning_text: see plugin documentation for details
ovirt_storage_vm_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_storage_vm_info instead.
warning_text: see plugin documentation for details
ovirt_tag_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_tag_info instead.
warning_text: see plugin documentation for details
ovirt_template_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_template_info instead.
warning_text: see plugin documentation for details
ovirt_user_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_user_info instead.
warning_text: see plugin documentation for details
ovirt_vm_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_vm_info instead.
warning_text: see plugin documentation for details
ovirt_vmpool_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use ovirt.ovirt.ovirt_vmpool_info instead.
warning_text: see plugin documentation for details
postgresql_copy:
redirect: community.postgresql.postgresql_copy
postgresql_db:
@@ -479,54 +471,54 @@ plugin_routing:
redirect: community.postgresql.postgresql_table
postgresql_tablespace:
redirect: community.postgresql.postgresql_tablespace
postgresql_user:
redirect: community.postgresql.postgresql_user
postgresql_user_obj_stat_info:
redirect: community.postgresql.postgresql_user_obj_stat_info
postgresql_user:
redirect: community.postgresql.postgresql_user
purefa_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use purestorage.flasharray.purefa_info instead.
warning_text: see plugin documentation for details
purefb_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use purestorage.flashblade.purefb_info instead.
warning_text: see plugin documentation for details
python_requirements_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.python_requirements_info instead.
warning_text: see plugin documentation for details
redfish_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.redfish_info instead.
warning_text: see plugin documentation for details
scaleway_image_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_image_info instead.
warning_text: see plugin documentation for details
scaleway_ip_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_ip_info instead.
warning_text: see plugin documentation for details
scaleway_organization_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_organization_info instead.
warning_text: see plugin documentation for details
scaleway_security_group_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_security_group_info instead.
warning_text: see plugin documentation for details
scaleway_server_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_server_info instead.
warning_text: see plugin documentation for details
scaleway_snapshot_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_snapshot_info instead.
warning_text: see plugin documentation for details
scaleway_volume_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.scaleway_volume_info instead.
warning_text: see plugin documentation for details
sf_account_manager:
tombstone:
removal_version: 2.0.0
@@ -548,17 +540,17 @@ plugin_routing:
removal_version: 2.0.0
warning_text: Use netapp.elementsw.na_elementsw_volume instead.
smartos_image_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.smartos_image_info instead.
warning_text: see plugin documentation for details
vertica_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.vertica_info instead.
warning_text: see plugin documentation for details
xenserver_guest_facts:
tombstone:
deprecation:
removal_version: 3.0.0
warning_text: Use community.general.xenserver_guest_info instead.
warning_text: see plugin documentation for details
doc_fragments:
_gcp:
redirect: community.google._gcp
@@ -570,8 +562,6 @@ plugin_routing:
redirect: community.kubevirt.kubevirt_common_options
kubevirt_vm_options:
redirect: community.kubevirt.kubevirt_vm_options
nios:
redirect: infoblox.nios_modules.nios
postgresql:
redirect: community.postgresql.postgresql
module_utils:
@@ -589,30 +579,21 @@ plugin_routing:
redirect: community.hrobot.robot
kubevirt:
redirect: community.kubevirt.kubevirt
net_tools.nios.api:
redirect: infoblox.nios_modules.api
postgresql:
redirect: community.postgresql.postgresql
remote_management.dellemc.dellemc_idrac:
redirect: dellemc.openmanage.dellemc_idrac
remote_management.dellemc.ome:
redirect: dellemc.openmanage.ome
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
@@ -620,10 +601,3 @@ plugin_routing:
redirect: community.docker.docker_swarm
kubevirt:
redirect: community.kubevirt.kubevirt
filter:
path_join:
# The ansible.builtin.path_join filter has been added in ansible-base 2.10.
# Since plugin routing is only available since ansible-base 2.10, this
# redirect will be used for ansible-base 2.10 or later, and the included
# path_join filter will be used for Ansible 2.9 or earlier.
redirect: ansible.builtin.path_join

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2020, quidame <quidame@poivron.org>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
@@ -8,7 +7,7 @@ __metaclass__ = type
import time
from ansible.plugins.action import ActionBase
from ansible.errors import AnsibleActionFail, AnsibleConnectionFailure
from ansible.errors import AnsibleError, AnsibleActionFail, AnsibleConnectionFailure
from ansible.utils.vars import merge_hash
from ansible.utils.display import Display
@@ -41,27 +40,19 @@ 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, async_status_args, task_vars, timeout):
def _async_result(self, module_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 = async_action.run(task_vars=task_vars)
if async_result.get('finished', 0) == 1:
for i 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)
if async_result['finished'] == 1:
break
time.sleep(min(1, timeout))
@@ -85,6 +76,7 @@ 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':
@@ -115,7 +107,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(mode='status')
async_status_args = dict(_async_dir=async_dir)
confirm_cmd = 'rm -f %s' % module_args['_back']
starter_cmd = 'touch %s.starter' % module_args['_back']
remaining_time = max(task_async, max_timeout)
@@ -141,7 +133,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.
dummy = self._low_level_execute_command(starter_cmd, sudoable=self.DEFAULT_SUDOABLE)
garbage = 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'.
@@ -151,7 +143,7 @@ class ActionModule(ActionBase):
except AttributeError:
pass
for dummy in range(max_timeout):
for x in range(max_timeout):
time.sleep(1)
remaining_time -= 1
# - AnsibleConnectionFailure covers rejected requests (i.e.
@@ -159,7 +151,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:
dummy = self._low_level_execute_command(confirm_cmd, sudoable=self.DEFAULT_SUDOABLE)
garbage = self._low_level_execute_command(confirm_cmd, sudoable=self.DEFAULT_SUDOABLE)
break
except AnsibleConnectionFailure:
continue
@@ -172,12 +164,16 @@ class ActionModule(ActionBase):
del result[key]
if result.get('invocation', {}).get('module_args'):
for key in ('_back', '_timeout', '_async_dir', 'jid'):
if result['invocation']['module_args'].get(key):
del result['invocation']['module_args'][key]
if '_timeout' in result['invocation']['module_args']:
del result['invocation']['module_args']['_back']
del result['invocation']['module_args']['_timeout']
async_status_args['mode'] = 'cleanup'
dummy = self._async_result(async_status_args, task_vars, 0)
garbage = self._execute_module(
module_name='ansible.builtin.async_status',
module_args=async_status_args,
task_vars=task_vars,
wrap_async=False)
if not wrap_async:
# remove a temporary path we created

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2020, Amin Vakil <info@aminvakil.com>
# Copyright: (c) 2016-2018, Matt Davis <mdavis@ansible.com>
# Copyright: (c) 2018, Sam Doran <sdoran@redhat.com>
@@ -8,7 +7,7 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.errors import AnsibleError, AnsibleConnectionFailure
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.module_utils._text import to_native, to_text
from ansible.module_utils.common.collections import is_string
from ansible.plugins.action import ActionBase
from ansible.utils.display import Display

View File

@@ -9,7 +9,7 @@ DOCUMENTATION = '''
short_description: Do As user
description:
- This become plugins allows your remote/login user to execute commands as another user via the doas utility.
author: Ansible Core Team
author: ansible (@core)
options:
become_user:
description: User you 'become' to execute the task
@@ -81,7 +81,7 @@ DOCUMENTATION = '''
import re
from ansible.module_utils.common.text.converters import to_bytes
from ansible.module_utils._text import to_bytes
from ansible.plugins.become import BecomeBase

View File

@@ -8,7 +8,7 @@ DOCUMENTATION = '''
short_description: Centrify's Direct Authorize
description:
- This become plugins allows your remote/login user to execute commands as another user via the dzdo utility.
author: Ansible Core Team
author: ansible (@core)
options:
become_user:
description: User you 'become' to execute the task

View File

@@ -9,7 +9,7 @@ DOCUMENTATION = '''
short_description: Kerberos substitute user
description:
- This become plugins allows your remote/login user to execute commands as another user via the ksu utility.
author: Ansible Core Team
author: ansible (@core)
options:
become_user:
description: User you 'become' to execute the task
@@ -82,7 +82,7 @@ DOCUMENTATION = '''
import re
from ansible.module_utils.common.text.converters import to_bytes
from ansible.module_utils._text import to_bytes
from ansible.plugins.become import BecomeBase

View File

@@ -9,7 +9,7 @@ DOCUMENTATION = '''
short_description: Systemd's machinectl privilege escalation
description:
- This become plugins allows your remote/login user to execute commands as another user via the machinectl utility.
author: Ansible Core Team
author: ansible (@core)
options:
become_user:
description: User you 'become' to execute the task

View File

@@ -9,7 +9,7 @@ DOCUMENTATION = '''
short_description: PowerBroker run
description:
- This become plugins allows your remote/login user to execute commands as another user via the pbrun utility.
author: Ansible Core Team
author: ansible (@core)
options:
become_user:
description: User you 'become' to execute the task

View File

@@ -9,7 +9,7 @@ DOCUMENTATION = '''
short_description: profile based execution
description:
- This become plugins allows your remote/login user to execute commands as another user via the pfexec utility.
author: Ansible Core Team
author: ansible (@core)
options:
become_user:
description:
@@ -101,4 +101,4 @@ class BecomeModule(BecomeBase):
flags = self.get_option('become_flags')
noexe = not self.get_option('wrap_exe')
return '%s %s %s' % (exe, flags, self._build_success_command(cmd, shell, noexe=noexe))
return '%s %s "%s"' % (exe, flags, self._build_success_command(cmd, shell, noexe=noexe))

View File

@@ -9,7 +9,7 @@ DOCUMENTATION = '''
short_description: Privilege Manager run
description:
- This become plugins allows your remote/login user to execute commands as another user via the pmrun utility.
author: Ansible Core Team
author: ansible (@core)
options:
become_exe:
description: Sudo executable

View File

@@ -1,91 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2021, 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: sudosu
short_description: Run tasks using sudo su -
description:
- This become plugin allows your remote/login user to execute commands as another user via the C(sudo) and C(su) utilities combined.
author:
- Dag Wieers (@dagwieers)
version_added: 2.4.0
options:
become_user:
description: User you 'become' to execute the task.
default: root
ini:
- section: privilege_escalation
key: become_user
- section: sudo_become_plugin
key: user
vars:
- name: ansible_become_user
- name: ansible_sudo_user
env:
- name: ANSIBLE_BECOME_USER
- name: ANSIBLE_SUDO_USER
become_flags:
description: Options to pass to C(sudo).
default: -H -S -n
ini:
- section: privilege_escalation
key: become_flags
- section: sudo_become_plugin
key: flags
vars:
- name: ansible_become_flags
- name: ansible_sudo_flags
env:
- name: ANSIBLE_BECOME_FLAGS
- name: ANSIBLE_SUDO_FLAGS
become_pass:
description: Password to pass to C(sudo).
required: false
vars:
- name: ansible_become_password
- name: ansible_become_pass
- name: ansible_sudo_pass
env:
- name: ANSIBLE_BECOME_PASS
- name: ANSIBLE_SUDO_PASS
ini:
- section: sudo_become_plugin
key: password
"""
from ansible.plugins.become import BecomeBase
class BecomeModule(BecomeBase):
name = 'community.general.sudosu'
# messages for detecting prompted password issues
fail = ('Sorry, try again.',)
missing = ('Sorry, a password is required to run sudo', 'sudo: a password is required')
def build_become_command(self, cmd, shell):
super(BecomeModule, self).build_become_command(cmd, shell)
if not cmd:
return cmd
becomecmd = 'sudo'
flags = self.get_option('become_flags') or ''
prompt = ''
if self.get_option('become_pass'):
self.prompt = '[sudo via ansible, key=%s] password:' % self._id
if flags: # this could be simplified, but kept as is for now for backwards string matching
flags = flags.replace('-n', '')
prompt = '-p "%s"' % (self.prompt)
user = self.get_option('become_user') or ''
if user:
user = '%s' % (user)
return ' '.join([becomecmd, flags, prompt, 'su -l', user, self._build_success_command(cmd, shell)])

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# (c) 2014, Brian Coca, Josh Drake, et al
# (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
@@ -20,7 +19,6 @@ DOCUMENTATION = '''
- List of connection information for the memcached DBs
default: ['127.0.0.1:11211']
type: list
elements: string
env:
- name: ANSIBLE_CACHE_PLUGIN_CONNECTION
ini:
@@ -155,16 +153,16 @@ class CacheModuleKeys(MutableSet):
def __len__(self):
return len(self._keyset)
def add(self, value):
self._keyset[value] = time.time()
def add(self, key):
self._keyset[key] = time.time()
self._cache.set(self.PREFIX, self._keyset)
def discard(self, value):
del self._keyset[value]
def discard(self, key):
del self._keyset[key]
self._cache.set(self.PREFIX, self._keyset)
def remove_by_timerange(self, s_min, s_max):
for k in list(self._keyset.keys()):
for k in self._keyset.keys():
t = self._keyset[k]
if s_min < t < s_max:
del self._keyset[k]

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# (c) 2017, Brian Coca
# (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# (c) 2014, Brian Coca, Josh Drake, et al
# (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
@@ -62,13 +61,12 @@ DOCUMENTATION = '''
type: integer
'''
import re
import time
import json
from ansible import constants as C
from ansible.errors import AnsibleError
from ansible.module_utils.common.text.converters import to_native
from ansible.module_utils._text import to_native
from ansible.parsing.ajson import AnsibleJSONEncoder, AnsibleJSONDecoder
from ansible.plugins.cache import BaseCacheModule
from ansible.release import __version__ as ansible_base_version
@@ -93,8 +91,6 @@ 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 = ''
@@ -134,18 +130,11 @@ class CacheModule(BaseCacheModule):
self._db = self._get_sentinel_connection(uri, kw)
# normal connection
else:
connection = self._parse_connection(self.re_url_conn, uri)
connection = uri.split(':')
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
@@ -169,7 +158,7 @@ class CacheModule(BaseCacheModule):
except IndexError:
pass # password is optional
sentinels = [self._parse_connection(self.re_sent_conn, shost) for shost in connections]
sentinels = [tuple(shost.split(':')) for shost in connections]
display.vv('\nUsing redis sentinels: %s' % sentinels)
scon = Sentinel(sentinels, **kw)
try:
@@ -228,12 +217,14 @@ class CacheModule(BaseCacheModule):
self._db.zrem(self._keys_set, key)
def flush(self):
for key in list(self.keys()):
for key in self.keys():
self.delete(key)
def copy(self):
# TODO: there is probably a better way to do this in redis
ret = dict([(k, self.get(k)) for k in self.keys()])
ret = dict()
for key in self.keys():
ret[key] = self.get(key)
return ret
def __getstate__(self):

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# (c) 2017, Brian Coca
# (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# (C) 2012, Michael DeHaan, <michael.dehaan@gmail.com>
# (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# (c) 2018, Ivan Aragones Muniesa <ivan.aragones.muniesa@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
'''
@@ -45,8 +44,6 @@ class CallbackModule(CallbackBase):
_task_total = 0
_host_counter = 1
_host_total = 0
_current_batch_total = 0
_previous_batch_total = 0
def __init__(self):
super(CallbackModule, self).__init__()
@@ -78,11 +75,8 @@ class CallbackModule(CallbackBase):
self._display.banner(msg)
self._play = play
self._previous_batch_total = self._current_batch_total
self._current_batch_total = self._previous_batch_total + len(self._all_vars()['vars']['ansible_play_batch'])
self._host_total = len(self._all_vars()['vars']['ansible_play_hosts_all'])
self._task_total = len(self._play.get_tasks()[0])
self._task_counter = 1
def v2_playbook_on_stats(self, stats):
self._display.banner("PLAY RECAP")
@@ -150,7 +144,7 @@ class CallbackModule(CallbackBase):
path = task.get_path()
if path:
self._display.display("task path: %s" % path, color=C.COLOR_DEBUG)
self._host_counter = self._previous_batch_total
self._host_counter = 0
self._task_counter += 1
def v2_runner_on_ok(self, result):

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# (c) 2016, Dag Wieers <dag@wieers.com>
# (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
@@ -232,13 +231,13 @@ class CallbackModule(CallbackModule_default):
# Remove non-essential attributes
for attr in self.removed_attributes:
if attr in result:
del result[attr]
del(result[attr])
# Remove empty attributes (list, dict, str)
for attr in result.copy():
if isinstance(result[attr], (MutableSequence, MutableMapping, binary_type, text_type)):
if not result[attr]:
del result[attr]
del(result[attr])
def _handle_exceptions(self, result):
if 'exception' in result:

View File

@@ -792,7 +792,7 @@ from ansible.utils.color import colorize, hostcolor
from ansible.template import Templar
from ansible.vars.manager import VariableManager
from ansible.plugins.callback.default import CallbackModule as Default
from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils._text import to_text
class DummyStdout(object):
@@ -1013,7 +1013,7 @@ class CallbackModule(Default):
for attr in _stats_attributes:
_ret[self.DIY_NS]['stats'].update({attr: _get_value(obj=stats, attr=attr)})
_ret[self.DIY_NS].update({'top_level_var_names': list(_ret.keys())})
_ret[self.DIY_NS].update({'top_level_var_names': _ret.keys()})
return _ret

View File

@@ -1,423 +0,0 @@
# (C) 2021, Victor Martinez <VictorMartinezRubio@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = '''
author: Victor Martinez (@v1v) <VictorMartinezRubio@gmail.com>
name: elastic
type: notification
short_description: Create distributed traces for each Ansible task in Elastic APM
version_added: 3.8.0
description:
- This callback creates distributed traces for each Ansible task in Elastic APM.
- You can configure the plugin with environment variables.
- See U(https://www.elastic.co/guide/en/apm/agent/python/current/configuration.html).
options:
hide_task_arguments:
default: false
type: bool
description:
- Hide the arguments for a task.
env:
- name: ANSIBLE_OPENTELEMETRY_HIDE_TASK_ARGUMENTS
apm_service_name:
default: ansible
type: str
description:
- The service name resource attribute.
env:
- name: ELASTIC_APM_SERVICE_NAME
apm_server_url:
type: str
description:
- Use the APM server and its environment variables.
env:
- name: ELASTIC_APM_SERVER_URL
apm_secret_token:
type: str
description:
- Use the APM server token
env:
- name: ELASTIC_APM_SECRET_TOKEN
apm_api_key:
type: str
description:
- Use the APM API key
env:
- name: ELASTIC_APM_API_KEY
apm_verify_server_cert:
default: true
type: bool
description:
- Verifies the SSL certificate if an HTTPS connection.
env:
- name: ELASTIC_APM_VERIFY_SERVER_CERT
traceparent:
type: str
description:
- The L(W3C Trace Context header traceparent,https://www.w3.org/TR/trace-context-1/#traceparent-header).
env:
- name: TRACEPARENT
requirements:
- elastic-apm (Python library)
'''
EXAMPLES = '''
examples: |
Enable the plugin in ansible.cfg:
[defaults]
callbacks_enabled = community.general.elastic
Set the environment variable:
export ELASTIC_APM_SERVER_URL=<your APM server URL)>
export ELASTIC_APM_SERVICE_NAME=your_service_name
export ELASTIC_APM_API_KEY=your_APM_API_KEY
'''
import getpass
import socket
import time
import uuid
from collections import OrderedDict
from os.path import basename
from ansible.errors import AnsibleError, AnsibleRuntimeError
from ansible.module_utils.six import raise_from
from ansible.plugins.callback import CallbackBase
try:
from elasticapm import Client, capture_span, trace_parent_from_string, instrument, label
except ImportError as imp_exc:
ELASTIC_LIBRARY_IMPORT_ERROR = imp_exc
else:
ELASTIC_LIBRARY_IMPORT_ERROR = None
class TaskData:
"""
Data about an individual task.
"""
def __init__(self, uuid, name, path, play, action, args):
self.uuid = uuid
self.name = name
self.path = path
self.play = play
self.host_data = OrderedDict()
self.start = time.time()
self.action = action
self.args = args
def add_host(self, host):
if host.uuid in self.host_data:
if host.status == 'included':
# concatenate task include output from multiple items
host.result = '%s\n%s' % (self.host_data[host.uuid].result, host.result)
else:
return
self.host_data[host.uuid] = host
class HostData:
"""
Data about an individual host.
"""
def __init__(self, uuid, name, status, result):
self.uuid = uuid
self.name = name
self.status = status
self.result = result
self.finish = time.time()
class ElasticSource(object):
def __init__(self, display):
self.ansible_playbook = ""
self.ansible_version = None
self.session = str(uuid.uuid4())
self.host = socket.gethostname()
try:
self.ip_address = socket.gethostbyname(socket.gethostname())
except Exception as e:
self.ip_address = None
self.user = getpass.getuser()
self._display = display
def start_task(self, tasks_data, hide_task_arguments, play_name, task):
""" record the start of a task for one or more hosts """
uuid = task._uuid
if uuid in tasks_data:
return
name = task.get_name().strip()
path = task.get_path()
action = task.action
args = None
if not task.no_log and not hide_task_arguments:
args = ', '.join(('%s=%s' % a for a in task.args.items()))
tasks_data[uuid] = TaskData(uuid, name, path, play_name, action, args)
def finish_task(self, tasks_data, status, result):
""" record the results of a task for a single host """
task_uuid = result._task._uuid
if hasattr(result, '_host') and result._host is not None:
host_uuid = result._host._uuid
host_name = result._host.name
else:
host_uuid = 'include'
host_name = 'include'
task = tasks_data[task_uuid]
if self.ansible_version is None and result._task_fields['args'].get('_ansible_version'):
self.ansible_version = result._task_fields['args'].get('_ansible_version')
task.add_host(HostData(host_uuid, host_name, status, result))
def generate_distributed_traces(self, tasks_data, status, end_time, traceparent, apm_service_name,
apm_server_url, apm_verify_server_cert, apm_secret_token, apm_api_key):
""" generate distributed traces from the collected TaskData and HostData """
tasks = []
parent_start_time = None
for task_uuid, task in tasks_data.items():
if parent_start_time is None:
parent_start_time = task.start
tasks.append(task)
apm_cli = self.init_apm_client(apm_server_url, apm_service_name, apm_verify_server_cert, apm_secret_token, apm_api_key)
if apm_cli:
instrument() # Only call this once, as early as possible.
if traceparent:
parent = trace_parent_from_string(traceparent)
apm_cli.begin_transaction("Session", trace_parent=parent, start=parent_start_time)
else:
apm_cli.begin_transaction("Session", start=parent_start_time)
# Populate trace metadata attributes
if self.ansible_version is not None:
label(ansible_version=self.ansible_version)
label(ansible_session=self.session, ansible_host_name=self.host, ansible_host_user=self.user)
if self.ip_address is not None:
label(ansible_host_ip=self.ip_address)
for task_data in tasks:
for host_uuid, host_data in task_data.host_data.items():
self.create_span_data(apm_cli, task_data, host_data)
apm_cli.end_transaction(name=__name__, result=status, duration=end_time - parent_start_time)
def create_span_data(self, apm_cli, task_data, host_data):
""" create the span with the given TaskData and HostData """
name = '[%s] %s: %s' % (host_data.name, task_data.play, task_data.name)
message = "success"
status = "success"
enriched_error_message = None
if host_data.status == 'included':
rc = 0
else:
res = host_data.result._result
rc = res.get('rc', 0)
if host_data.status == 'failed':
message = self.get_error_message(res)
enriched_error_message = self.enrich_error_message(res)
status = "failure"
elif host_data.status == 'skipped':
if 'skip_reason' in res:
message = res['skip_reason']
else:
message = 'skipped'
status = "unknown"
with capture_span(task_data.name,
start=task_data.start,
span_type="ansible.task.run",
duration=host_data.finish - task_data.start,
labels={"ansible.task.args": task_data.args,
"ansible.task.message": message,
"ansible.task.module": task_data.action,
"ansible.task.name": name,
"ansible.task.result": rc,
"ansible.task.host.name": host_data.name,
"ansible.task.host.status": host_data.status}) as span:
span.outcome = status
if 'failure' in status:
exception = AnsibleRuntimeError(message="{0}: {1} failed with error message {2}".format(task_data.action, name, enriched_error_message))
apm_cli.capture_exception(exc_info=(type(exception), exception, exception.__traceback__), handled=True)
def init_apm_client(self, apm_server_url, apm_service_name, apm_verify_server_cert, apm_secret_token, apm_api_key):
if apm_server_url:
return Client(service_name=apm_service_name,
server_url=apm_server_url,
verify_server_cert=False,
secret_token=apm_secret_token,
api_key=apm_api_key,
use_elastic_traceparent_header=True,
debug=True)
@staticmethod
def get_error_message(result):
if result.get('exception') is not None:
return ElasticSource._last_line(result['exception'])
return result.get('msg', 'failed')
@staticmethod
def _last_line(text):
lines = text.strip().split('\n')
return lines[-1]
@staticmethod
def enrich_error_message(result):
message = result.get('msg', 'failed')
exception = result.get('exception')
stderr = result.get('stderr')
return ('message: "{0}"\nexception: "{1}"\nstderr: "{2}"').format(message, exception, stderr)
class CallbackModule(CallbackBase):
"""
This callback creates distributed traces with Elastic APM.
"""
CALLBACK_VERSION = 2.0
CALLBACK_TYPE = 'notification'
CALLBACK_NAME = 'community.general.elastic'
CALLBACK_NEEDS_ENABLED = True
def __init__(self, display=None):
super(CallbackModule, self).__init__(display=display)
self.hide_task_arguments = None
self.apm_service_name = None
self.ansible_playbook = None
self.traceparent = False
self.play_name = None
self.tasks_data = None
self.errors = 0
self.disabled = False
if ELASTIC_LIBRARY_IMPORT_ERROR:
raise_from(
AnsibleError('The `elastic-apm` must be installed to use this plugin'),
ELASTIC_LIBRARY_IMPORT_ERROR)
self.tasks_data = OrderedDict()
self.elastic = ElasticSource(display=self._display)
def set_options(self, task_keys=None, var_options=None, direct=None):
super(CallbackModule, self).set_options(task_keys=task_keys,
var_options=var_options,
direct=direct)
self.hide_task_arguments = self.get_option('hide_task_arguments')
self.apm_service_name = self.get_option('apm_service_name')
if not self.apm_service_name:
self.apm_service_name = 'ansible'
self.apm_server_url = self.get_option('apm_server_url')
self.apm_secret_token = self.get_option('apm_secret_token')
self.apm_api_key = self.get_option('apm_api_key')
self.apm_verify_server_cert = self.get_option('apm_verify_server_cert')
self.traceparent = self.get_option('traceparent')
def v2_playbook_on_start(self, playbook):
self.ansible_playbook = basename(playbook._file_name)
def v2_playbook_on_play_start(self, play):
self.play_name = play.get_name()
def v2_runner_on_no_hosts(self, task):
self.elastic.start_task(
self.tasks_data,
self.hide_task_arguments,
self.play_name,
task
)
def v2_playbook_on_task_start(self, task, is_conditional):
self.elastic.start_task(
self.tasks_data,
self.hide_task_arguments,
self.play_name,
task
)
def v2_playbook_on_cleanup_task_start(self, task):
self.elastic.start_task(
self.tasks_data,
self.hide_task_arguments,
self.play_name,
task
)
def v2_playbook_on_handler_task_start(self, task):
self.elastic.start_task(
self.tasks_data,
self.hide_task_arguments,
self.play_name,
task
)
def v2_runner_on_failed(self, result, ignore_errors=False):
self.errors += 1
self.elastic.finish_task(
self.tasks_data,
'failed',
result
)
def v2_runner_on_ok(self, result):
self.elastic.finish_task(
self.tasks_data,
'ok',
result
)
def v2_runner_on_skipped(self, result):
self.elastic.finish_task(
self.tasks_data,
'skipped',
result
)
def v2_playbook_on_include(self, included_file):
self.elastic.finish_task(
self.tasks_data,
'included',
included_file
)
def v2_playbook_on_stats(self, stats):
if self.errors == 0:
status = "success"
else:
status = "failure"
self.elastic.generate_distributed_traces(
self.tasks_data,
status,
time.time(),
self.traceparent,
self.apm_service_name,
self.apm_server_url,
self.apm_verify_server_cert,
self.apm_secret_token,
self.apm_api_key
)
def v2_runner_on_async_failed(self, result, **kwargs):
self.errors += 1

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# (C) 2014, Matt Martz <matt@sivel.net>
# (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

Some files were not shown because too many files have changed in this diff Show More