mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-28 09:26:44 +00:00
Compare commits
161 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a71909770 | ||
|
|
9d0af30702 | ||
|
|
9dc21447cc | ||
|
|
940130c959 | ||
|
|
0b239199e7 | ||
|
|
f0d6fcb3fa | ||
|
|
e1aad0db30 | ||
|
|
7701ea0293 | ||
|
|
9afb84c8f3 | ||
|
|
1746d11749 | ||
|
|
ea3b8eeee7 | ||
|
|
8c9add3d15 | ||
|
|
9244d0ae47 | ||
|
|
22591fb6e1 | ||
|
|
166fa1a7fa | ||
|
|
9e541a6f11 | ||
|
|
dbb37194d4 | ||
|
|
3cd7b0ec25 | ||
|
|
1c84389f50 | ||
|
|
61de9ce51c | ||
|
|
7ccd5c9116 | ||
|
|
e3cea35f2c | ||
|
|
94f58d1920 | ||
|
|
0f884bbadc | ||
|
|
6ca3e78d11 | ||
|
|
a09d70daa0 | ||
|
|
c2a3cf35c7 | ||
|
|
ee5ff3b31b | ||
|
|
18b7333f93 | ||
|
|
3197ef2e38 | ||
|
|
5f971e677a | ||
|
|
1b5d91153b | ||
|
|
2ce9ea8c54 | ||
|
|
eec4861c36 | ||
|
|
82e7e931a8 | ||
|
|
4b59174063 | ||
|
|
58d8469759 | ||
|
|
6d5dbfd455 | ||
|
|
6357048068 | ||
|
|
a861149a0e | ||
|
|
9a9b0b04a5 | ||
|
|
0a4e9379e2 | ||
|
|
7d1abf5d6a | ||
|
|
7ef25be10c | ||
|
|
0d0194fdf8 | ||
|
|
36f64367cf | ||
|
|
d827601c95 | ||
|
|
2efd31bacf | ||
|
|
6eaf047739 | ||
|
|
80268b0828 | ||
|
|
1e848c56f2 | ||
|
|
f74756d7fc | ||
|
|
138b57230a | ||
|
|
d32193afef | ||
|
|
ef8aa73dab | ||
|
|
28007079a4 | ||
|
|
f0b7233e8d | ||
|
|
48cc39a2b1 | ||
|
|
c34dc24d3a | ||
|
|
0760f60ca5 | ||
|
|
48b1bc7d47 | ||
|
|
769233808d | ||
|
|
7361ca5430 | ||
|
|
2322937a4a | ||
|
|
82225e5850 | ||
|
|
2d237987ae | ||
|
|
dc14070e08 | ||
|
|
feb1c1081e | ||
|
|
20bda07aaf | ||
|
|
1f6aa62210 | ||
|
|
5308f61b78 | ||
|
|
29636c1cc8 | ||
|
|
830734d6cf | ||
|
|
0296c200c7 | ||
|
|
2b435a591d | ||
|
|
ec2c793b08 | ||
|
|
a6bffa274c | ||
|
|
b653a9a84a | ||
|
|
8c209bdedc | ||
|
|
d4b4370ec4 | ||
|
|
e34276fa92 | ||
|
|
59d7850900 | ||
|
|
151b482fe6 | ||
|
|
ea04bb97cb | ||
|
|
5dd64a45de | ||
|
|
4df33d26b1 | ||
|
|
766f2dfe46 | ||
|
|
8a7128997d | ||
|
|
b598ca28f9 | ||
|
|
c943f7aa56 | ||
|
|
9565be5e50 | ||
|
|
725e670b47 | ||
|
|
ffdef00a6a | ||
|
|
92ccc6f013 | ||
|
|
f0c1b1065a | ||
|
|
a44356c966 | ||
|
|
33f9f0b05f | ||
|
|
f0f0704d64 | ||
|
|
55fe140230 | ||
|
|
ac543f5ef0 | ||
|
|
dbc0fe8859 | ||
|
|
42a1318fe3 | ||
|
|
d25352dc06 | ||
|
|
55682c52df | ||
|
|
46781d9fd1 | ||
|
|
4545d1c91e | ||
|
|
6570dfeb7d | ||
|
|
94c368f7df | ||
|
|
4cba1e60d9 | ||
|
|
321fb6c974 | ||
|
|
eb4d7a4199 | ||
|
|
4b07d45b7e | ||
|
|
d4a33433b4 | ||
|
|
e30b91cb8d | ||
|
|
b2b65c431b | ||
|
|
9ade4f6dd6 | ||
|
|
635d4f2138 | ||
|
|
6549e41ab8 | ||
|
|
6faface39e | ||
|
|
3b893ec421 | ||
|
|
65805e2dd6 | ||
|
|
297b50fb96 | ||
|
|
2edadb42fb | ||
|
|
4e1bf2d4ba | ||
|
|
b1a4a0ff21 | ||
|
|
e74ea7c8b8 | ||
|
|
6590f5e082 | ||
|
|
7483f71d31 | ||
|
|
6b215e3a9c | ||
|
|
3723e458d3 | ||
|
|
0f8bb43723 | ||
|
|
f33530dd61 | ||
|
|
8f3043058e | ||
|
|
3987b8a291 | ||
|
|
f7403a0b34 | ||
|
|
0a676406b3 | ||
|
|
5a7d234d80 | ||
|
|
fb9730f75e | ||
|
|
928aeafe1d | ||
|
|
5b68665571 | ||
|
|
e6b84acd1e | ||
|
|
c242993291 | ||
|
|
4f3de5658e | ||
|
|
301fcc3b7e | ||
|
|
0f0e9b2dca | ||
|
|
ed0636dc27 | ||
|
|
057321c6c6 | ||
|
|
1a4814de53 | ||
|
|
89b67a014b | ||
|
|
57bfbdc407 | ||
|
|
e19dffbf29 | ||
|
|
113e7cdfa0 | ||
|
|
c12be67a69 | ||
|
|
3a076fd585 | ||
|
|
4ef05a6483 | ||
|
|
936dd28395 | ||
|
|
e3b47899c5 | ||
|
|
fd8193e0bd | ||
|
|
fa477ebb35 | ||
|
|
43e766dd44 | ||
|
|
b25e0f360c |
23
.github/BOTMETA.yml
vendored
23
.github/BOTMETA.yml
vendored
@@ -1,17 +1,14 @@
|
||||
automerge: true
|
||||
files:
|
||||
plugins/:
|
||||
supershipit: aminvakil russoz
|
||||
supershipit: quidame Ajpantuso
|
||||
changelogs/fragments/:
|
||||
support: community
|
||||
$actions:
|
||||
labels: action
|
||||
$actions/aireos.py:
|
||||
labels: aireos cisco networking
|
||||
$actions/ironware.py:
|
||||
maintainers: paulquack
|
||||
labels: ironware networking
|
||||
$actions/shutdown.py:
|
||||
$actions/system/iptables_state.py:
|
||||
maintainers: quidame
|
||||
$actions/system/shutdown.py:
|
||||
maintainers: nitzmahone samdoran aminvakil
|
||||
$becomes/:
|
||||
labels: become
|
||||
@@ -120,6 +117,8 @@ files:
|
||||
$lookups/nios:
|
||||
maintainers: $team_networking sganesh-infoblox
|
||||
labels: infoblox networking
|
||||
$lookups/random_string.py:
|
||||
maintainers: Akasurde
|
||||
$module_utils/:
|
||||
labels: module_utils
|
||||
$module_utils/gitlab.py:
|
||||
@@ -347,6 +346,8 @@ files:
|
||||
$modules/database/mssql/mssql_db.py:
|
||||
maintainers: vedit Jmainguy kenichi-ogawa-1988
|
||||
labels: mssql_db
|
||||
$modules/database/saphana/hana_query.py:
|
||||
maintainers: rainerleber
|
||||
$modules/database/vertica/:
|
||||
maintainers: dareko
|
||||
$modules/files/archive.py:
|
||||
@@ -650,6 +651,9 @@ files:
|
||||
maintainers: elasticdog indrajitr tchernomax
|
||||
labels: pacman
|
||||
ignore: elasticdog
|
||||
$modules/packaging/os/pacman_key.py:
|
||||
maintainers: grawlinson
|
||||
labels: pacman
|
||||
$modules/packaging/os/pkgin.py:
|
||||
maintainers: $team_solaris L2G jasperla szinck martinm82
|
||||
labels: pkgin solaris
|
||||
@@ -715,8 +719,9 @@ files:
|
||||
labels: zypper
|
||||
ignore: dirtyharrycallahan robinro
|
||||
$modules/packaging/os/zypper_repository.py:
|
||||
maintainers: $team_suse matze
|
||||
maintainers: $team_suse
|
||||
labels: zypper
|
||||
ignore: matze
|
||||
$modules/remote_management/cobbler/:
|
||||
maintainers: dagwieers
|
||||
$modules/remote_management/hpilo/:
|
||||
@@ -845,6 +850,8 @@ files:
|
||||
labels: interfaces_file
|
||||
$modules/system/iptables_state.py:
|
||||
maintainers: quidame
|
||||
$modules/system/shutdown.py:
|
||||
maintainers: nitzmahone samdoran aminvakil
|
||||
$modules/system/java_cert.py:
|
||||
maintainers: haad absynth76
|
||||
$modules/system/java_keystore.py:
|
||||
|
||||
247
CHANGELOG.rst
247
CHANGELOG.rst
@@ -6,6 +6,253 @@ Community General Release Notes
|
||||
|
||||
This changelog describes changes after version 2.0.0.
|
||||
|
||||
v3.4.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix and feature release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- archive - added ``dest_state`` return value to describe final state of ``dest`` after successful task execution (https://github.com/ansible-collections/community.general/pull/2913).
|
||||
- archive - refactoring prior to fix for idempotency checks. The fix will be a breaking change and only appear in community.general 4.0.0 (https://github.com/ansible-collections/community.general/pull/2987).
|
||||
- datadog_monitor - allow creation of composite datadog monitors (https://github.com/ansible-collections/community.general/issues/2956).
|
||||
- filesystem - extend support for FreeBSD. Avoid potential data loss by checking existence of a filesystem with ``fstyp`` (native command) if ``blkid`` (foreign command) doesn't find one. Add support for character devices and ``ufs`` filesystem type (https://github.com/ansible-collections/community.general/pull/2902).
|
||||
- gitlab_project - add new options ``allow_merge_on_skipped_pipeline``, ``only_allow_merge_if_all_discussions_are_resolved``, ``only_allow_merge_if_pipeline_succeeds``, ``packages_enabled``, ``remove_source_branch_after_merge``, ``squash_option`` (https://github.com/ansible-collections/community.general/pull/3002).
|
||||
- jenkins_job_info - the ``password`` and ``token`` parameters can also be omitted to retrieve only public information (https://github.com/ansible-collections/community.general/pull/2948).
|
||||
- keycloak_authentication - enhanced diff mode to also return before and after state when the authentication flow is updated (https://github.com/ansible-collections/community.general/pull/2963).
|
||||
- keycloak_client - add ``authentication_flow_binding_overrides`` option (https://github.com/ansible-collections/community.general/pull/2949).
|
||||
- module_helper module utils - added feature flag parameters to ``CmdMixin`` to control whether ``rc``, ``out`` and ``err`` are automatically added to the module output (https://github.com/ansible-collections/community.general/pull/2922).
|
||||
- nmcli - add ``runner`` and ``runner_hwaddr_policy`` options (https://github.com/ansible-collections/community.general/issues/2901).
|
||||
- rax_mon_notification_plan - fixed validation checks by specifying type ``str`` as the ``elements`` of parameters ``ok_state``, ``warning_state`` and ``critical_state`` (https://github.com/ansible-collections/community.general/pull/2955).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- launchd - fixed sanity check in the module's code (https://github.com/ansible-collections/community.general/pull/2960).
|
||||
- pamd - fixed problem with files containing only one or two lines (https://github.com/ansible-collections/community.general/issues/2925).
|
||||
- proxmox inventory plugin - fixed parsing failures when some cluster nodes are offline (https://github.com/ansible-collections/community.general/issues/2931).
|
||||
- redfish_command - fix extraneous error caused by missing ``bootdevice`` argument when using the ``DisableBootOverride`` sub-command (https://github.com/ansible-collections/community.general/issues/3005).
|
||||
- snap - fix formatting of ``--channel`` argument when the ``channel`` option is used (https://github.com/ansible-collections/community.general/pull/3028).
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
Identity
|
||||
~~~~~~~~
|
||||
|
||||
keycloak
|
||||
^^^^^^^^
|
||||
|
||||
- keycloak_clientscope - Allows administration of Keycloak client_scopes via Keycloak API
|
||||
- keycloak_role - Allows administration of Keycloak roles via Keycloak API
|
||||
|
||||
Source Control
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
gitlab
|
||||
^^^^^^
|
||||
|
||||
- gitlab_protected_branch - (un)Marking existing branches for protection
|
||||
|
||||
v3.3.2
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Extraordinary bugfix release to fix some annoying bugs.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- archive - fixed task failure when using the ``remove`` option with a ``path`` containing nested files for ``format``s other than ``zip`` (https://github.com/ansible-collections/community.general/issues/2919).
|
||||
- lvol - honor ``check_mode`` on thinpool (https://github.com/ansible-collections/community.general/issues/2934).
|
||||
- module_helper module utils - fixed change-tracking for dictionaries and lists (https://github.com/ansible-collections/community.general/pull/2951).
|
||||
- npm - correctly handle cases where a dependency does not have a ``version`` property because it is either missing or invalid (https://github.com/ansible-collections/community.general/issues/2917).
|
||||
- pacman - fix changed status when ignorepkg has been defined (https://github.com/ansible-collections/community.general/issues/1758).
|
||||
- snap - fixed the order of the ``--classic`` parameter in the command line invocation (https://github.com/ansible-collections/community.general/issues/2916).
|
||||
|
||||
v3.3.1
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Extraordinary bugfix release to fix a fatal bug in ``snap``.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- keycloak_authentication - fix bug when two identical executions are in the same authentication flow (https://github.com/ansible-collections/community.general/pull/2904).
|
||||
- module_helper module utils - avoid failing when non-zero ``rc`` is present on regular exit (https://github.com/ansible-collections/community.general/pull/2912).
|
||||
- snap - fix various bugs which prevented the module from working at all, and which resulted in ``state=absent`` fail on absent snaps (https://github.com/ansible-collections/community.general/issues/2835, https://github.com/ansible-collections/community.general/issues/2906, https://github.com/ansible-collections/community.general/pull/2912).
|
||||
|
||||
v3.3.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular feature and bugfix release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Avoid internal ansible-core module_utils in favor of equivalent public API available since at least Ansible 2.9 (https://github.com/ansible-collections/community.general/pull/2877).
|
||||
- datadog_event - adding parameter ``api_host`` to allow selecting a datadog API endpoint instead of using the default one (https://github.com/ansible-collections/community.general/issues/2774, https://github.com/ansible-collections/community.general/pull/2775).
|
||||
- flatpak - allows installing or uninstalling a list of packages (https://github.com/ansible-collections/community.general/pull/2521).
|
||||
- gem - add ``bindir`` option to specify an installation path for executables such as ``/home/user/bin`` or ``/home/user/.local/bin`` (https://github.com/ansible-collections/community.general/pull/2837).
|
||||
- gem - add ``norc`` option to avoid loading any ``.gemrc`` file (https://github.com/ansible-collections/community.general/pull/2837).
|
||||
- gitlab_project - projects can be created under other user's namespaces with the new ``username`` option (https://github.com/ansible-collections/community.general/pull/2824).
|
||||
- gitlab_user - add functionality for adding external identity providers to a GitLab user (https://github.com/ansible-collections/community.general/pull/2691).
|
||||
- gitlab_user - allow to reset an existing password with the new ``reset_password`` option (https://github.com/ansible-collections/community.general/pull/2691).
|
||||
- gitlab_user - specifying a password is no longer necessary (https://github.com/ansible-collections/community.general/pull/2691).
|
||||
- jenkins_build - support stopping a running jenkins build (https://github.com/ansible-collections/community.general/pull/2850).
|
||||
- jenkins_plugin - add fallback url(s) for failure of plugin installation/download (https://github.com/ansible-collections/community.general/pull/1334).
|
||||
- nmcli - add ``disabled`` value to ``method6`` option (https://github.com/ansible-collections/community.general/issues/2730).
|
||||
- nmcli - add ``routing_rules4`` and ``may_fail4`` options (https://github.com/ansible-collections/community.general/issues/2730).
|
||||
- nrdp callback plugin - parameters are now converted to strings, except ``validate_certs`` which is converted to boolean (https://github.com/ansible-collections/community.general/pull/2878).
|
||||
- redhat_subscription - add ``server_prefix`` and ``server_port`` parameters (https://github.com/ansible-collections/community.general/pull/2779).
|
||||
- redis - allow to use the term ``replica`` instead of ``slave``, which has been the official Redis terminology since 2018 (https://github.com/ansible-collections/community.general/pull/2867).
|
||||
- snap - added ``enabled`` and ``disabled`` states (https://github.com/ansible-collections/community.general/issues/1990).
|
||||
- splunk callback plugin - add ``batch`` option for user-configurable correlation ID's (https://github.com/ansible-collections/community.general/issues/2790).
|
||||
- terraform - add ``check_destroy`` optional parameter to check for deletion of resources before it is applied (https://github.com/ansible-collections/community.general/pull/2874).
|
||||
- timezone - print error message to debug instead of warning when timedatectl fails (https://github.com/ansible-collections/community.general/issues/1942).
|
||||
|
||||
Deprecated Features
|
||||
-------------------
|
||||
|
||||
- ali_instance_info - marked removal version of deprecated parameters ``availability_zone`` and ``instance_names`` (https://github.com/ansible-collections/community.general/issues/2429).
|
||||
- serverless - deprecating parameter ``functions`` because it was not used in the code (https://github.com/ansible-collections/community.general/pull/2845).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- _mount module utils - fixed the sanity checks (https://github.com/ansible-collections/community.general/pull/2883).
|
||||
- archive - fixed ``exclude_path`` values causing incorrect archive root (https://github.com/ansible-collections/community.general/pull/2816).
|
||||
- archive - fixed improper file names for single file zip archives (https://github.com/ansible-collections/community.general/issues/2818).
|
||||
- archive - fixed incorrect ``state`` result value documentation (https://github.com/ansible-collections/community.general/pull/2816).
|
||||
- gitlab_project - user projects are created using namespace ID now, instead of user ID (https://github.com/ansible-collections/community.general/pull/2881).
|
||||
- ini_file - fix Unicode processing for Python 2 (https://github.com/ansible-collections/community.general/pull/2875).
|
||||
- ipa_sudorule - call ``sudorule_add_allow_command`` method instead of ``sudorule_add_allow_command_group`` (https://github.com/ansible-collections/community.general/issues/2442).
|
||||
- java_keystore - add parameter ``keystore_type`` to control output file format and override ``keytool``'s default, which depends on Java version (https://github.com/ansible-collections/community.general/issues/2515).
|
||||
- jenkins_build - examine presence of ``build_number`` before deleting a jenkins build (https://github.com/ansible-collections/community.general/pull/2850).
|
||||
- modprobe - added additional checks to ensure module load/unload is effective (https://github.com/ansible-collections/community.general/issues/1608).
|
||||
- nmcli - fixes team-slave configuration by adding connection.slave-type (https://github.com/ansible-collections/community.general/issues/766).
|
||||
- npm - when the ``version`` option is used the comparison of installed vs missing will use name@version instead of just name, allowing version specific updates (https://github.com/ansible-collections/community.general/issues/2021).
|
||||
- proxmox_kvm - fix parsing of Proxmox VM information with device info not containing a comma, like disks backed by ZFS zvols (https://github.com/ansible-collections/community.general/issues/2840).
|
||||
- scaleway plugin inventory - fix ``JSON object must be str, not 'bytes'`` with Python 3.5 (https://github.com/ansible-collections/community.general/issues/2769).
|
||||
- yum_versionlock - fix idempotency when using wildcard (asterisk) in ``name`` option (https://github.com/ansible-collections/community.general/issues/2761).
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
Identity
|
||||
~~~~~~~~
|
||||
|
||||
keycloak
|
||||
^^^^^^^^
|
||||
|
||||
- keycloak_authentication - Configure authentication in Keycloak
|
||||
|
||||
v3.2.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix and feature release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Remove unnecessary ``__init__.py`` files from ``plugins/`` (https://github.com/ansible-collections/community.general/pull/2632).
|
||||
- archive - added ``exclusion_patterns`` option to exclude files or subdirectories from archives (https://github.com/ansible-collections/community.general/pull/2616).
|
||||
- cloud_init_data_facts - minor refactor (https://github.com/ansible-collections/community.general/pull/2557).
|
||||
- composer - add ``composer_executable`` option (https://github.com/ansible-collections/community.general/issues/2649).
|
||||
- flatpak - add ``no_dependencies`` parameter (https://github.com/ansible/ansible/pull/55452, https://github.com/ansible-collections/community.general/pull/2751).
|
||||
- ini_file - opening file with encoding ``utf-8-sig`` (https://github.com/ansible-collections/community.general/issues/2189).
|
||||
- jira - add comment visibility parameter for comment operation (https://github.com/ansible-collections/community.general/pull/2556).
|
||||
- maven_artifact - added ``checksum_alg`` option to support SHA1 checksums in order to support FIPS systems (https://github.com/ansible-collections/community.general/pull/2662).
|
||||
- module_helper module utils - method ``CmdMixin.run_command()`` now accepts ``process_output`` specifying a function to process the outcome of the underlying ``module.run_command()`` (https://github.com/ansible-collections/community.general/pull/2564).
|
||||
- nmcli - add new options to ignore automatic DNS servers and gateways (https://github.com/ansible-collections/community.general/issues/1087).
|
||||
- onepassword lookup plugin - add ``domain`` option (https://github.com/ansible-collections/community.general/issues/2734).
|
||||
- open_iscsi - add ``auto_portal_startup`` parameter to allow ``node.startup`` setting per portal (https://github.com/ansible-collections/community.general/issues/2685).
|
||||
- open_iscsi - also consider ``portal`` and ``port`` to check if already logged in or not (https://github.com/ansible-collections/community.general/issues/2683).
|
||||
- proxmox_group_info - minor refactor (https://github.com/ansible-collections/community.general/pull/2557).
|
||||
- proxmox_kvm - minor refactor (https://github.com/ansible-collections/community.general/pull/2557).
|
||||
- rhevm - minor refactor (https://github.com/ansible-collections/community.general/pull/2557).
|
||||
- serverless - minor refactor (https://github.com/ansible-collections/community.general/pull/2557).
|
||||
- stacki_host - minor refactoring (https://github.com/ansible-collections/community.general/pull/2681).
|
||||
- terraform - add option ``overwrite_init`` to skip init if exists (https://github.com/ansible-collections/community.general/pull/2573).
|
||||
- terraform - minor refactor (https://github.com/ansible-collections/community.general/pull/2557).
|
||||
|
||||
Deprecated Features
|
||||
-------------------
|
||||
|
||||
- All inventory and vault scripts will be removed from community.general in version 4.0.0. If you are referencing them, please update your references to the new `contrib-scripts GitHub repository <https://github.com/ansible-community/contrib-scripts>`_ so your workflow will not break once community.general 4.0.0 is released (https://github.com/ansible-collections/community.general/pull/2697).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- consul_kv lookup plugin - allow to set ``recurse``, ``index``, ``datacenter`` and ``token`` as keyword arguments (https://github.com/ansible-collections/community.general/issues/2124).
|
||||
- cpanm - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/pull/2731).
|
||||
- influxdb_user - fix bug which removed current privileges instead of appending them to existing ones (https://github.com/ansible-collections/community.general/issues/2609, https://github.com/ansible-collections/community.general/pull/2614).
|
||||
- iptables_state - call ``async_status`` action plugin rather than its module (https://github.com/ansible-collections/community.general/issues/2700).
|
||||
- iptables_state - fix a broken query of ``async_status`` result with current ansible-core development version (https://github.com/ansible-collections/community.general/issues/2627, https://github.com/ansible-collections/community.general/pull/2671).
|
||||
- java_cert - fix issue with incorrect alias used on PKCS#12 certificate import (https://github.com/ansible-collections/community.general/pull/2560).
|
||||
- jenkins_plugin - use POST method for sending request to jenkins API when ``state`` option is one of ``enabled``, ``disabled``, ``pinned``, ``unpinned``, or ``absent`` (https://github.com/ansible-collections/community.general/issues/2510).
|
||||
- json_query filter plugin - avoid 'unknown type' errors for more Ansible internal types (https://github.com/ansible-collections/community.general/pull/2607).
|
||||
- keycloak_realm - ``ssl_required`` changed from a boolean type to accept the strings ``none``, ``external`` or ``all``. This is not a breaking change since the module always failed when a boolean was supplied (https://github.com/ansible-collections/community.general/pull/2693).
|
||||
- keycloak_realm - remove warning that ``reset_password_allowed`` needs to be marked as ``no_log`` (https://github.com/ansible-collections/community.general/pull/2694).
|
||||
- module_helper module utils - ``CmdMixin`` must also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/pull/2731).
|
||||
- netcup_dns - use ``str(ex)`` instead of unreliable ``ex.message`` in exception handling to fix ``AttributeError`` in error cases (https://github.com/ansible-collections/community.general/pull/2590).
|
||||
- ovir4 inventory script - improve configparser creation to avoid crashes for options without values (https://github.com/ansible-collections/community.general/issues/674).
|
||||
- proxmox_kvm - fixed ``vmid`` return value when VM with ``name`` already exists (https://github.com/ansible-collections/community.general/issues/2648).
|
||||
- redis cache - improved connection string parsing (https://github.com/ansible-collections/community.general/issues/497).
|
||||
- rhsm_release - fix the issue that module considers 8, 7Client and 7Workstation as invalid releases (https://github.com/ansible-collections/community.general/pull/2571).
|
||||
- ssh_config - reduce stormssh searches based on host (https://github.com/ansible-collections/community.general/pull/2568/).
|
||||
- stacki_host - when adding a new server, ``rack`` and ``rank`` must be passed, and network parameters are optional (https://github.com/ansible-collections/community.general/pull/2681).
|
||||
- terraform - ensure the workspace is set back to its previous value when the apply fails (https://github.com/ansible-collections/community.general/pull/2634).
|
||||
- xfconf - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/issues/2715).
|
||||
- zypper_repository - fix idempotency on adding repository with ``$releasever`` and ``$basearch`` variables (https://github.com/ansible-collections/community.general/issues/1985).
|
||||
|
||||
New Plugins
|
||||
-----------
|
||||
|
||||
Lookup
|
||||
~~~~~~
|
||||
|
||||
- random_string - Generates random string
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
Database
|
||||
~~~~~~~~
|
||||
|
||||
saphana
|
||||
^^^^^^^
|
||||
|
||||
- hana_query - Execute SQL on HANA
|
||||
|
||||
Files
|
||||
~~~~~
|
||||
|
||||
- sapcar_extract - Manages SAP SAPCAR archives
|
||||
|
||||
Packaging
|
||||
~~~~~~~~~
|
||||
|
||||
os
|
||||
^^
|
||||
|
||||
- pacman_key - Manage pacman's list of trusted keys
|
||||
|
||||
v3.1.0
|
||||
======
|
||||
|
||||
|
||||
36
CONTRIBUTING.md
Normal file
36
CONTRIBUTING.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Contributing
|
||||
|
||||
We follow [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html) in all our contributions and interactions within this repository.
|
||||
|
||||
If you are a committer, also refer to the [collection's committer guidelines](https://github.com/ansible-collections/community.general/blob/main/commit-rights.md).
|
||||
|
||||
## Issue tracker
|
||||
|
||||
Whether you are looking for an opportunity to contribute or you found a bug and already know how to solve it, please go to the [issue tracker](https://github.com/ansible-collections/community.general/issues).
|
||||
There you can find feature ideas to implement, reports about bugs to solve, or submit an issue to discuss your idea before implementing it which can help choose a right direction at the beginning of your work and potentially save a lot of time and effort.
|
||||
Also somebody may already have started discussing or working on implementing the same or a similar idea,
|
||||
so you can cooperate to create a better solution together.
|
||||
|
||||
* If you are interested in starting with an easy issue, look for [issues with an `easyfix` label](https://github.com/ansible-collections/community.general/labels/easyfix).
|
||||
* Often issues that are waiting for contributors to pick up have [the `waiting_on_contributor` label](https://github.com/ansible-collections/community.general/labels/waiting_on_contributor).
|
||||
|
||||
## Open pull requests
|
||||
|
||||
Look through currently [open pull requests](https://github.com/ansible-collections/community.general/pulls).
|
||||
You can help by reviewing them. Reviews help move pull requests to merge state. Some good pull requests cannot be merged only due to a lack of reviews. And it is always worth saying that good reviews are often more valuable than pull requests themselves.
|
||||
Note that reviewing does not only mean code review, but also offering comments on new interfaces added to existing plugins/modules, interfaces of new plugins/modules, improving language (not everyone is a native english speaker), or testing bugfixes and new features!
|
||||
|
||||
Also, consider taking up a valuable, reviewed, but abandoned pull request which you could politely ask the original authors to complete yourself.
|
||||
|
||||
* Try committing your changes with an informative but short commit message.
|
||||
* All commits of a pull request branch will be squashed into one commit at last. That does not mean you must have only one commit on your pull request, though!
|
||||
* Please try not to force-push if it is not needed, so reviewers and other users looking at your pull request later can see the pull request commit history.
|
||||
* Do not add merge commits to your PR. The bot will complain and you will have to rebase ([instructions for rebasing](https://docs.ansible.com/ansible/latest/dev_guide/developing_rebasing.html)) to remove them before your PR can be merged. To avoid that git automatically does merges during pulls, you can configure it to do rebases instead by running `git config pull.rebase true` inside the respository checkout.
|
||||
|
||||
You can also read [our Quick-start development guide](https://github.com/ansible/community-docs/blob/main/create_pr_quick_start_guide.rst).
|
||||
|
||||
## 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.
|
||||
51
README.md
51
README.md
@@ -3,12 +3,18 @@
|
||||
[](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
|
||||
[](https://codecov.io/gh/ansible-collections/community.general)
|
||||
|
||||
This repo contains the `community.general` Ansible Collection. The collection includes many modules and plugins supported by Ansible community which are not part of more specialized community collections.
|
||||
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.
|
||||
|
||||
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 and ansible-core 2.11 releases and the current development version of ansible-core. Ansible versions before 2.9.10 are not supported.
|
||||
@@ -23,7 +29,9 @@ Please check the included content on the [Ansible Galaxy page for this collectio
|
||||
|
||||
## Using this collection
|
||||
|
||||
Before using the General community collection, you need to install the collection with the `ansible-galaxy` CLI:
|
||||
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:
|
||||
|
||||
ansible-galaxy collection install community.general
|
||||
|
||||
@@ -34,38 +42,51 @@ 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
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
For example, if you are working in the `~/dev` directory:
|
||||
We are actively accepting new contributors.
|
||||
|
||||
```
|
||||
cd ~/dev
|
||||
git clone git@github.com:ansible-collections/community.general.git collections/ansible_collections/community/general
|
||||
export COLLECTIONS_PATH=$(pwd)/collections:$COLLECTIONS_PATH
|
||||
```
|
||||
All types of contributions are very welcome.
|
||||
|
||||
You don't know how to start? Refer to our [contribution guide](https://github.com/ansible-collections/community.general/blob/main/CONTRIBUTING.md)!
|
||||
|
||||
The current maintainers are listed in the [commit-rights.md](https://github.com/ansible-collections/community.general/blob/main/commit-rights.md#people) file. If you have questions or need help, feel free to mention them in the proposals.
|
||||
|
||||
You can find more information in the [developer guide for collections](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections.html#contributing-to-collections), and in the [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html).
|
||||
|
||||
Also for some notes specific to this collection see [our CONTRIBUTING documentation](https://github.com/ansible-collections/community.general/blob/main/CONTRIBUTING.md).
|
||||
|
||||
### Running tests
|
||||
|
||||
See [here](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections.html#testing-collections).
|
||||
|
||||
### Communication
|
||||
|
||||
We have a dedicated Working Group for Ansible development.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
For more information about communities, meetings and agendas see [Community Wiki](https://github.com/ansible/community/wiki/Community).
|
||||
|
||||
For more information about [communication](https://docs.ansible.com/ansible/latest/community/communication.html)
|
||||
For more information about communication, refer to the [Ansible communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
|
||||
|
||||
### Publishing New Version
|
||||
|
||||
|
||||
@@ -1156,3 +1156,344 @@ releases:
|
||||
name: random_pet
|
||||
namespace: null
|
||||
release_date: '2021-05-18'
|
||||
3.2.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- consul_kv lookup plugin - allow to set ``recurse``, ``index``, ``datacenter``
|
||||
and ``token`` as keyword arguments (https://github.com/ansible-collections/community.general/issues/2124).
|
||||
- cpanm - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/pull/2731).
|
||||
- influxdb_user - fix bug which removed current privileges instead of appending
|
||||
them to existing ones (https://github.com/ansible-collections/community.general/issues/2609,
|
||||
https://github.com/ansible-collections/community.general/pull/2614).
|
||||
- iptables_state - call ``async_status`` action plugin rather than its module
|
||||
(https://github.com/ansible-collections/community.general/issues/2700).
|
||||
- iptables_state - fix a broken query of ``async_status`` result with current
|
||||
ansible-core development version (https://github.com/ansible-collections/community.general/issues/2627,
|
||||
https://github.com/ansible-collections/community.general/pull/2671).
|
||||
- java_cert - fix issue with incorrect alias used on PKCS#12 certificate import
|
||||
(https://github.com/ansible-collections/community.general/pull/2560).
|
||||
- jenkins_plugin - use POST method for sending request to jenkins API when ``state``
|
||||
option is one of ``enabled``, ``disabled``, ``pinned``, ``unpinned``, or ``absent``
|
||||
(https://github.com/ansible-collections/community.general/issues/2510).
|
||||
- json_query filter plugin - avoid 'unknown type' errors for more Ansible internal
|
||||
types (https://github.com/ansible-collections/community.general/pull/2607).
|
||||
- keycloak_realm - ``ssl_required`` changed from a boolean type to accept the
|
||||
strings ``none``, ``external`` or ``all``. This is not a breaking change since
|
||||
the module always failed when a boolean was supplied (https://github.com/ansible-collections/community.general/pull/2693).
|
||||
- keycloak_realm - remove warning that ``reset_password_allowed`` needs to be
|
||||
marked as ``no_log`` (https://github.com/ansible-collections/community.general/pull/2694).
|
||||
- module_helper module utils - ``CmdMixin`` must also use ``LC_ALL`` to enforce
|
||||
locale choice (https://github.com/ansible-collections/community.general/pull/2731).
|
||||
- netcup_dns - use ``str(ex)`` instead of unreliable ``ex.message`` in exception
|
||||
handling to fix ``AttributeError`` in error cases (https://github.com/ansible-collections/community.general/pull/2590).
|
||||
- ovir4 inventory script - improve configparser creation to avoid crashes for
|
||||
options without values (https://github.com/ansible-collections/community.general/issues/674).
|
||||
- proxmox_kvm - fixed ``vmid`` return value when VM with ``name`` already exists
|
||||
(https://github.com/ansible-collections/community.general/issues/2648).
|
||||
- redis cache - improved connection string parsing (https://github.com/ansible-collections/community.general/issues/497).
|
||||
- rhsm_release - fix the issue that module considers 8, 7Client and 7Workstation
|
||||
as invalid releases (https://github.com/ansible-collections/community.general/pull/2571).
|
||||
- ssh_config - reduce stormssh searches based on host (https://github.com/ansible-collections/community.general/pull/2568/).
|
||||
- stacki_host - when adding a new server, ``rack`` and ``rank`` must be passed,
|
||||
and network parameters are optional (https://github.com/ansible-collections/community.general/pull/2681).
|
||||
- terraform - ensure the workspace is set back to its previous value when the
|
||||
apply fails (https://github.com/ansible-collections/community.general/pull/2634).
|
||||
- xfconf - also use ``LC_ALL`` to enforce locale choice (https://github.com/ansible-collections/community.general/issues/2715).
|
||||
- zypper_repository - fix idempotency on adding repository with ``$releasever``
|
||||
and ``$basearch`` variables (https://github.com/ansible-collections/community.general/issues/1985).
|
||||
deprecated_features:
|
||||
- All inventory and vault scripts will be removed from community.general in
|
||||
version 4.0.0. If you are referencing them, please update your references
|
||||
to the new `contrib-scripts GitHub repository <https://github.com/ansible-community/contrib-scripts>`_
|
||||
so your workflow will not break once community.general 4.0.0 is released (https://github.com/ansible-collections/community.general/pull/2697).
|
||||
minor_changes:
|
||||
- Remove unnecessary ``__init__.py`` files from ``plugins/`` (https://github.com/ansible-collections/community.general/pull/2632).
|
||||
- archive - added ``exclusion_patterns`` option to exclude files or subdirectories
|
||||
from archives (https://github.com/ansible-collections/community.general/pull/2616).
|
||||
- cloud_init_data_facts - minor refactor (https://github.com/ansible-collections/community.general/pull/2557).
|
||||
- composer - add ``composer_executable`` option (https://github.com/ansible-collections/community.general/issues/2649).
|
||||
- flatpak - add ``no_dependencies`` parameter (https://github.com/ansible/ansible/pull/55452,
|
||||
https://github.com/ansible-collections/community.general/pull/2751).
|
||||
- ini_file - opening file with encoding ``utf-8-sig`` (https://github.com/ansible-collections/community.general/issues/2189).
|
||||
- jira - add comment visibility parameter for comment operation (https://github.com/ansible-collections/community.general/pull/2556).
|
||||
- maven_artifact - added ``checksum_alg`` option to support SHA1 checksums in
|
||||
order to support FIPS systems (https://github.com/ansible-collections/community.general/pull/2662).
|
||||
- module_helper module utils - method ``CmdMixin.run_command()`` now accepts
|
||||
``process_output`` specifying a function to process the outcome of the underlying
|
||||
``module.run_command()`` (https://github.com/ansible-collections/community.general/pull/2564).
|
||||
- nmcli - add new options to ignore automatic DNS servers and gateways (https://github.com/ansible-collections/community.general/issues/1087).
|
||||
- onepassword lookup plugin - add ``domain`` option (https://github.com/ansible-collections/community.general/issues/2734).
|
||||
- open_iscsi - add ``auto_portal_startup`` parameter to allow ``node.startup``
|
||||
setting per portal (https://github.com/ansible-collections/community.general/issues/2685).
|
||||
- open_iscsi - also consider ``portal`` and ``port`` to check if already logged
|
||||
in or not (https://github.com/ansible-collections/community.general/issues/2683).
|
||||
- proxmox_group_info - minor refactor (https://github.com/ansible-collections/community.general/pull/2557).
|
||||
- proxmox_kvm - minor refactor (https://github.com/ansible-collections/community.general/pull/2557).
|
||||
- rhevm - minor refactor (https://github.com/ansible-collections/community.general/pull/2557).
|
||||
- serverless - minor refactor (https://github.com/ansible-collections/community.general/pull/2557).
|
||||
- stacki_host - minor refactoring (https://github.com/ansible-collections/community.general/pull/2681).
|
||||
- terraform - add option ``overwrite_init`` to skip init if exists (https://github.com/ansible-collections/community.general/pull/2573).
|
||||
- terraform - minor refactor (https://github.com/ansible-collections/community.general/pull/2557).
|
||||
release_summary: Regular bugfix and feature release.
|
||||
fragments:
|
||||
- 2126-consul_kv-pass-token.yml
|
||||
- 2461-ovirt4-fix-configparser.yml
|
||||
- 2510-jenkins_plugin_use_post_method.yml
|
||||
- 2556-add-comment_visibility-parameter-for-comment-operation-of-jira-module.yml
|
||||
- 2557-cloud-misc-refactor.yml
|
||||
- 2560-java_cert-pkcs12-alias-bugfix.yml
|
||||
- 2564-mh-cmd-process-output.yml
|
||||
- 2568-ssh_config-reduce-stormssh-searches-based-on-host.yml
|
||||
- 2571-rhsm_release-fix-release_matcher.yaml
|
||||
- 2573-terraform-overwrite-init.yml
|
||||
- 2578-ini-file-utf8-bom.yml
|
||||
- 2579-redis-cache-ipv6.yml
|
||||
- 2590-netcup_dns-exception-no-message-attr.yml
|
||||
- 2614-influxdb_user-fix-issue-introduced-in-PR#2499.yml
|
||||
- 2616-archive-exclusion_patterns-option.yml
|
||||
- 2632-cleanup.yml
|
||||
- 2634-terraform-switch-workspace.yml
|
||||
- 2635-nmcli-add-ignore-auto-arguments.yml
|
||||
- 2648-proxmox_kvm-fix-vmid-return-value.yml
|
||||
- 2650-composer-add_composer_executable.yml
|
||||
- 2661-maven_artifact-add-sha1-option.yml
|
||||
- 2671-fix-broken-query-of-async_status-result.yml
|
||||
- 2681-stacki-host-bugfix.yml
|
||||
- 2684-open_iscsi-single-target-multiple-portal-overrides.yml
|
||||
- 2711-fix-iptables_state-2700-async_status-call.yml
|
||||
- 2722-zypper_repository-fix_idempotency_on_adding_repo_with_releasever.yml
|
||||
- 2731-mh-cmd-locale.yml
|
||||
- 2735-onepassword-add_domain_option.yml
|
||||
- 2751-flatpak-no_dependencies.yml
|
||||
- 3.2.0.yml
|
||||
- json_query_more_types.yml
|
||||
- keycloak-realm-no-log-password-reset.yml
|
||||
- keycloak_realm_ssl_required.yml
|
||||
- script-removal.yml
|
||||
modules:
|
||||
- description: Execute SQL on HANA
|
||||
name: hana_query
|
||||
namespace: database.saphana
|
||||
- description: Manage pacman's list of trusted keys
|
||||
name: pacman_key
|
||||
namespace: packaging.os
|
||||
- description: Manages SAP SAPCAR archives
|
||||
name: sapcar_extract
|
||||
namespace: files
|
||||
plugins:
|
||||
lookup:
|
||||
- description: Generates random string
|
||||
name: random_string
|
||||
namespace: null
|
||||
release_date: '2021-06-08'
|
||||
3.3.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- _mount module utils - fixed the sanity checks (https://github.com/ansible-collections/community.general/pull/2883).
|
||||
- archive - fixed ``exclude_path`` values causing incorrect archive root (https://github.com/ansible-collections/community.general/pull/2816).
|
||||
- archive - fixed improper file names for single file zip archives (https://github.com/ansible-collections/community.general/issues/2818).
|
||||
- archive - fixed incorrect ``state`` result value documentation (https://github.com/ansible-collections/community.general/pull/2816).
|
||||
- gitlab_project - user projects are created using namespace ID now, instead
|
||||
of user ID (https://github.com/ansible-collections/community.general/pull/2881).
|
||||
- ini_file - fix Unicode processing for Python 2 (https://github.com/ansible-collections/community.general/pull/2875).
|
||||
- ipa_sudorule - call ``sudorule_add_allow_command`` method instead of ``sudorule_add_allow_command_group``
|
||||
(https://github.com/ansible-collections/community.general/issues/2442).
|
||||
- java_keystore - add parameter ``keystore_type`` to control output file format
|
||||
and override ``keytool``'s default, which depends on Java version (https://github.com/ansible-collections/community.general/issues/2515).
|
||||
- jenkins_build - examine presence of ``build_number`` before deleting a jenkins
|
||||
build (https://github.com/ansible-collections/community.general/pull/2850).
|
||||
- modprobe - added additional checks to ensure module load/unload is effective
|
||||
(https://github.com/ansible-collections/community.general/issues/1608).
|
||||
- nmcli - fixes team-slave configuration by adding connection.slave-type (https://github.com/ansible-collections/community.general/issues/766).
|
||||
- npm - when the ``version`` option is used the comparison of installed vs missing
|
||||
will use name@version instead of just name, allowing version specific updates
|
||||
(https://github.com/ansible-collections/community.general/issues/2021).
|
||||
- proxmox_kvm - fix parsing of Proxmox VM information with device info not containing
|
||||
a comma, like disks backed by ZFS zvols (https://github.com/ansible-collections/community.general/issues/2840).
|
||||
- scaleway plugin inventory - fix ``JSON object must be str, not 'bytes'`` with
|
||||
Python 3.5 (https://github.com/ansible-collections/community.general/issues/2769).
|
||||
- yum_versionlock - fix idempotency when using wildcard (asterisk) in ``name``
|
||||
option (https://github.com/ansible-collections/community.general/issues/2761).
|
||||
deprecated_features:
|
||||
- ali_instance_info - marked removal version of deprecated parameters ``availability_zone``
|
||||
and ``instance_names`` (https://github.com/ansible-collections/community.general/issues/2429).
|
||||
- serverless - deprecating parameter ``functions`` because it was not used in
|
||||
the code (https://github.com/ansible-collections/community.general/pull/2845).
|
||||
minor_changes:
|
||||
- Avoid internal ansible-core module_utils in favor of equivalent public API
|
||||
available since at least Ansible 2.9 (https://github.com/ansible-collections/community.general/pull/2877).
|
||||
- datadog_event - adding parameter ``api_host`` to allow selecting a datadog
|
||||
API endpoint instead of using the default one (https://github.com/ansible-collections/community.general/issues/2774,
|
||||
https://github.com/ansible-collections/community.general/pull/2775).
|
||||
- flatpak - allows installing or uninstalling a list of packages (https://github.com/ansible-collections/community.general/pull/2521).
|
||||
- gem - add ``bindir`` option to specify an installation path for executables
|
||||
such as ``/home/user/bin`` or ``/home/user/.local/bin`` (https://github.com/ansible-collections/community.general/pull/2837).
|
||||
- gem - add ``norc`` option to avoid loading any ``.gemrc`` file (https://github.com/ansible-collections/community.general/pull/2837).
|
||||
- gitlab_project - projects can be created under other user's namespaces with
|
||||
the new ``username`` option (https://github.com/ansible-collections/community.general/pull/2824).
|
||||
- gitlab_user - add functionality for adding external identity providers to
|
||||
a GitLab user (https://github.com/ansible-collections/community.general/pull/2691).
|
||||
- gitlab_user - allow to reset an existing password with the new ``reset_password``
|
||||
option (https://github.com/ansible-collections/community.general/pull/2691).
|
||||
- gitlab_user - specifying a password is no longer necessary (https://github.com/ansible-collections/community.general/pull/2691).
|
||||
- jenkins_build - support stopping a running jenkins build (https://github.com/ansible-collections/community.general/pull/2850).
|
||||
- jenkins_plugin - add fallback url(s) for failure of plugin installation/download
|
||||
(https://github.com/ansible-collections/community.general/pull/1334).
|
||||
- nmcli - add ``disabled`` value to ``method6`` option (https://github.com/ansible-collections/community.general/issues/2730).
|
||||
- nmcli - add ``routing_rules4`` and ``may_fail4`` options (https://github.com/ansible-collections/community.general/issues/2730).
|
||||
- nrdp callback plugin - parameters are now converted to strings, except ``validate_certs``
|
||||
which is converted to boolean (https://github.com/ansible-collections/community.general/pull/2878).
|
||||
- redhat_subscription - add ``server_prefix`` and ``server_port`` parameters
|
||||
(https://github.com/ansible-collections/community.general/pull/2779).
|
||||
- redis - allow to use the term ``replica`` instead of ``slave``, which has
|
||||
been the official Redis terminology since 2018 (https://github.com/ansible-collections/community.general/pull/2867).
|
||||
- snap - added ``enabled`` and ``disabled`` states (https://github.com/ansible-collections/community.general/issues/1990).
|
||||
- splunk callback plugin - add ``batch`` option for user-configurable correlation
|
||||
ID's (https://github.com/ansible-collections/community.general/issues/2790).
|
||||
- terraform - add ``check_destroy`` optional parameter to check for deletion
|
||||
of resources before it is applied (https://github.com/ansible-collections/community.general/pull/2874).
|
||||
- timezone - print error message to debug instead of warning when timedatectl
|
||||
fails (https://github.com/ansible-collections/community.general/issues/1942).
|
||||
release_summary: Regular feature and bugfix release.
|
||||
fragments:
|
||||
- 1334-jenkins-plugin-fallback-urls.yaml
|
||||
- 1942_timezone.yml
|
||||
- 2411-snap-revamp-enabled-disabled-states.yml
|
||||
- 2516_fix_2515_keystore_type_jks.yml
|
||||
- 2521-flatpak-list.yml
|
||||
- 2691-gitlab_user-support-identity-provider.yml
|
||||
- 2732-nmcli_add_options.yml
|
||||
- 2771-scaleway_inventory_json_accept_byte_array.yml
|
||||
- 2774-datadog_event_api_parameter.yml
|
||||
- 2779_redhat_subscription-add_server_prefix_and_server_port.yml
|
||||
- 2787-yum_versionlock-fix_idempotency_when_using_wildcard.yml
|
||||
- 2790-callback_splunk-batch-option.yml
|
||||
- 2816-archive-refactor.yml
|
||||
- 2821-ipa_sudorule.yml
|
||||
- 2824-gitlab_project-project-under-user.yml
|
||||
- 2827-nmcli_fix_team_slave.yml
|
||||
- 2830-npm-version-update.yml
|
||||
- 2841-proxmox_kvm_zfs_devstr.yml
|
||||
- 2843-modprobe-failure-conditions.yml
|
||||
- 2844-ali_instance_info-deprecate-params.yml
|
||||
- 2845-serverless-deprecate-functions-param.yml
|
||||
- 2850-jenkins_build-support-stop-jenkins-build.yml
|
||||
- 2867-redis-terminology.yml
|
||||
- 2874-terraform-check-destroy.yml
|
||||
- 2875-ini_file-unicode.yml
|
||||
- 2878-validate-certs-bool.yml
|
||||
- 2881-gitlab_project-fix_workspace_user.yaml
|
||||
- 2883-_mount-fixed-sanity-checks.yml
|
||||
- 3.3.0.yml
|
||||
- ansible-core-_text.yml
|
||||
- gem_module_add_bindir_option.yml
|
||||
modules:
|
||||
- description: Configure authentication in Keycloak
|
||||
name: keycloak_authentication
|
||||
namespace: identity.keycloak
|
||||
release_date: '2021-06-29'
|
||||
3.3.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- keycloak_authentication - fix bug when two identical executions are in the
|
||||
same authentication flow (https://github.com/ansible-collections/community.general/pull/2904).
|
||||
- module_helper module utils - avoid failing when non-zero ``rc`` is present
|
||||
on regular exit (https://github.com/ansible-collections/community.general/pull/2912).
|
||||
- snap - fix various bugs which prevented the module from working at all, and
|
||||
which resulted in ``state=absent`` fail on absent snaps (https://github.com/ansible-collections/community.general/issues/2835,
|
||||
https://github.com/ansible-collections/community.general/issues/2906, https://github.com/ansible-collections/community.general/pull/2912).
|
||||
release_summary: Extraordinary bugfix release to fix a fatal bug in ``snap``.
|
||||
fragments:
|
||||
- 2904-fix-bug-when-2-identical-executions-in-same-auth-flow.yml
|
||||
- 2912-snap-module-helper.yml
|
||||
- 3.3.1.yml
|
||||
release_date: '2021-07-01'
|
||||
3.3.2:
|
||||
changes:
|
||||
bugfixes:
|
||||
- archive - fixed task failure when using the ``remove`` option with a ``path``
|
||||
containing nested files for ``format``s other than ``zip`` (https://github.com/ansible-collections/community.general/issues/2919).
|
||||
- lvol - honor ``check_mode`` on thinpool (https://github.com/ansible-collections/community.general/issues/2934).
|
||||
- module_helper module utils - fixed change-tracking for dictionaries and lists
|
||||
(https://github.com/ansible-collections/community.general/pull/2951).
|
||||
- npm - correctly handle cases where a dependency does not have a ``version``
|
||||
property because it is either missing or invalid (https://github.com/ansible-collections/community.general/issues/2917).
|
||||
- pacman - fix changed status when ignorepkg has been defined (https://github.com/ansible-collections/community.general/issues/1758).
|
||||
- snap - fixed the order of the ``--classic`` parameter in the command line
|
||||
invocation (https://github.com/ansible-collections/community.general/issues/2916).
|
||||
release_summary: Extraordinary bugfix release to fix some annoying bugs.
|
||||
fragments:
|
||||
- 2918-snap-param-order.yml
|
||||
- 2923-archive-remove-bugfix.yml
|
||||
- 2924-npm-fix-package-json.yml
|
||||
- 2935-lvol-support_check_mode_thinpool.yml
|
||||
- 2936-pacman-fix_changed_status_when_ignorepkg_has_been_defined.yml
|
||||
- 2951-mh-vars-deepcopy.yml
|
||||
- 3.3.2.yml
|
||||
release_date: '2021-07-08'
|
||||
3.4.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- launchd - fixed sanity check in the module's code (https://github.com/ansible-collections/community.general/pull/2960).
|
||||
- pamd - fixed problem with files containing only one or two lines (https://github.com/ansible-collections/community.general/issues/2925).
|
||||
- proxmox inventory plugin - fixed parsing failures when some cluster nodes
|
||||
are offline (https://github.com/ansible-collections/community.general/issues/2931).
|
||||
- redfish_command - fix extraneous error caused by missing ``bootdevice`` argument
|
||||
when using the ``DisableBootOverride`` sub-command (https://github.com/ansible-collections/community.general/issues/3005).
|
||||
- snap - fix formatting of ``--channel`` argument when the ``channel`` option
|
||||
is used (https://github.com/ansible-collections/community.general/pull/3028).
|
||||
minor_changes:
|
||||
- archive - added ``dest_state`` return value to describe final state of ``dest``
|
||||
after successful task execution (https://github.com/ansible-collections/community.general/pull/2913).
|
||||
- archive - refactoring prior to fix for idempotency checks. The fix will be
|
||||
a breaking change and only appear in community.general 4.0.0 (https://github.com/ansible-collections/community.general/pull/2987).
|
||||
- datadog_monitor - allow creation of composite datadog monitors (https://github.com/ansible-collections/community.general/issues/2956).
|
||||
- filesystem - extend support for FreeBSD. Avoid potential data loss by checking
|
||||
existence of a filesystem with ``fstyp`` (native command) if ``blkid`` (foreign
|
||||
command) doesn't find one. Add support for character devices and ``ufs`` filesystem
|
||||
type (https://github.com/ansible-collections/community.general/pull/2902).
|
||||
- gitlab_project - add new options ``allow_merge_on_skipped_pipeline``, ``only_allow_merge_if_all_discussions_are_resolved``,
|
||||
``only_allow_merge_if_pipeline_succeeds``, ``packages_enabled``, ``remove_source_branch_after_merge``,
|
||||
``squash_option`` (https://github.com/ansible-collections/community.general/pull/3002).
|
||||
- jenkins_job_info - the ``password`` and ``token`` parameters can also be omitted
|
||||
to retrieve only public information (https://github.com/ansible-collections/community.general/pull/2948).
|
||||
- keycloak_authentication - enhanced diff mode to also return before and after
|
||||
state when the authentication flow is updated (https://github.com/ansible-collections/community.general/pull/2963).
|
||||
- keycloak_client - add ``authentication_flow_binding_overrides`` option (https://github.com/ansible-collections/community.general/pull/2949).
|
||||
- module_helper module utils - added feature flag parameters to ``CmdMixin``
|
||||
to control whether ``rc``, ``out`` and ``err`` are automatically added to
|
||||
the module output (https://github.com/ansible-collections/community.general/pull/2922).
|
||||
- nmcli - add ``runner`` and ``runner_hwaddr_policy`` options (https://github.com/ansible-collections/community.general/issues/2901).
|
||||
- rax_mon_notification_plan - fixed validation checks by specifying type ``str``
|
||||
as the ``elements`` of parameters ``ok_state``, ``warning_state`` and ``critical_state``
|
||||
(https://github.com/ansible-collections/community.general/pull/2955).
|
||||
release_summary: Regular bugfix and feature release.
|
||||
fragments:
|
||||
- 2901-nmcli_teaming.yml
|
||||
- 2902-filesystem_extend_freebsd_support.yml
|
||||
- 2913-archive-dest_state.yml
|
||||
- 2922-mh-cmd-output-feature-flag.yml
|
||||
- 2948-jenkins_job_info-remove_necessities_on_password_or_token.yml
|
||||
- 2949-add_authentication-flow-binding_keycloak-client.yml
|
||||
- 2955-rax_mon_notification_plan-added-elements-to-list-params.yaml
|
||||
- 2958-datadog_monitor_support_composites.yml
|
||||
- 2960-launchd-validation-check.yaml
|
||||
- 2963-improve-diff-mode-on-keycloak_authentication.yml
|
||||
- 2967-proxmox_inventory-offline-node-fix.yml
|
||||
- 2987-archive-stage-idempotency-fix.yml
|
||||
- 2989-pamd-single-line.yaml
|
||||
- 3.4.0.yml
|
||||
- 3001-enhance_gitlab_module.yml
|
||||
- 3006-redfish_command-bootoverride-argument-check.yaml
|
||||
- 3028-snap-channel.yml
|
||||
modules:
|
||||
- description: (un)Marking existing branches for protection
|
||||
name: gitlab_protected_branch
|
||||
namespace: source_control.gitlab
|
||||
- description: Allows administration of Keycloak client_scopes via Keycloak API
|
||||
name: keycloak_clientscope
|
||||
namespace: identity.keycloak
|
||||
- description: Allows administration of Keycloak roles via Keycloak API
|
||||
name: keycloak_role
|
||||
namespace: identity.keycloak
|
||||
release_date: '2021-07-20'
|
||||
|
||||
@@ -67,6 +67,7 @@ Individuals who have been asked to become a part of this group have generally be
|
||||
|
||||
| Name | GitHub ID | IRC Nick | Other |
|
||||
| ------------------- | -------------------- | ------------------ | -------------------- |
|
||||
| Alexei Znamensky | russoz | russoz | |
|
||||
| Andrew Klychkov | andersson007 | andersson007_ | |
|
||||
| Felix Fontein | felixfontein | felixfontein | |
|
||||
| John R Barker | gundalow | gundalow | |
|
||||
|
||||
5
docs/docsite/extra-docs.yml
Normal file
5
docs/docsite/extra-docs.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
sections:
|
||||
- title: Guides
|
||||
toctree:
|
||||
- filter_guide
|
||||
753
docs/docsite/rst/filter_guide.rst
Normal file
753
docs/docsite/rst/filter_guide.rst
Normal file
@@ -0,0 +1,753 @@
|
||||
.. _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.
|
||||
|
||||
.. contents:: Topics
|
||||
|
||||
Paths
|
||||
-----
|
||||
|
||||
The ``path_join`` filter has been added in ansible-base 2.10. If you want to use this filter, but also need to support Ansible 2.9, you can use ``community.general``'s ``path_join`` shim, ``community.general.path_join``. This filter redirects to ``path_join`` for ansible-base 2.10 and ansible-core 2.11 or newer, and re-implements the filter for Ansible 2.9.
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
# ansible-base 2.10 or newer:
|
||||
path: {{ ('/etc', path, 'subdir', file) | path_join }}
|
||||
|
||||
# Also works with Ansible 2.9:
|
||||
path: {{ ('/etc', path, 'subdir', file) | community.general.path_join }}
|
||||
|
||||
.. versionadded:: 3.0.0
|
||||
|
||||
Abstract transformations
|
||||
------------------------
|
||||
|
||||
Dictionaries
|
||||
^^^^^^^^^^^^
|
||||
|
||||
You can use the ``dict_kv`` filter to create a single-entry dictionary with ``value | community.general.dict_kv(key)``:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
- name: Create a single-entry dictionary
|
||||
debug:
|
||||
msg: "{{ myvar | community.general.dict_kv('thatsmyvar') }}"
|
||||
vars:
|
||||
myvar: myvalue
|
||||
|
||||
- name: Create a list of dictionaries where the 'server' field is taken from a list
|
||||
debug:
|
||||
msg: >-
|
||||
{{ myservers | map('community.general.dict_kv', 'server')
|
||||
| map('combine', common_config) }}
|
||||
vars:
|
||||
common_config:
|
||||
type: host
|
||||
database: all
|
||||
myservers:
|
||||
- server1
|
||||
- server2
|
||||
|
||||
This produces:
|
||||
|
||||
.. code-block:: ansible-output
|
||||
|
||||
TASK [Create a single-entry dictionary] **************************************************
|
||||
ok: [localhost] => {
|
||||
"msg": {
|
||||
"thatsmyvar": "myvalue"
|
||||
}
|
||||
}
|
||||
|
||||
TASK [Create a list of dictionaries where the 'server' field is taken from a list] *******
|
||||
ok: [localhost] => {
|
||||
"msg": [
|
||||
{
|
||||
"database": "all",
|
||||
"server": "server1",
|
||||
"type": "host"
|
||||
},
|
||||
{
|
||||
"database": "all",
|
||||
"server": "server2",
|
||||
"type": "host"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
.. versionadded:: 2.0.0
|
||||
|
||||
If you need to convert a list of key-value pairs to a dictionary, you can use the ``dict`` function. Unfortunately, this function cannot be used with ``map``. For this, the ``community.general.dict`` filter can be used:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
- name: Create a dictionary with the dict function
|
||||
debug:
|
||||
msg: "{{ dict([[1, 2], ['a', 'b']]) }}"
|
||||
|
||||
- name: Create a dictionary with the community.general.dict filter
|
||||
debug:
|
||||
msg: "{{ [[1, 2], ['a', 'b']] | community.general.dict }}"
|
||||
|
||||
- name: Create a list of dictionaries with map and the community.general.dict filter
|
||||
debug:
|
||||
msg: >-
|
||||
{{ values | map('zip', ['k1', 'k2', 'k3'])
|
||||
| map('map', 'reverse')
|
||||
| map('community.general.dict') }}
|
||||
vars:
|
||||
values:
|
||||
- - foo
|
||||
- 23
|
||||
- a
|
||||
- - bar
|
||||
- 42
|
||||
- b
|
||||
|
||||
This produces:
|
||||
|
||||
.. code-block:: ansible-output
|
||||
|
||||
TASK [Create a dictionary with the dict function] ****************************************
|
||||
ok: [localhost] => {
|
||||
"msg": {
|
||||
"1": 2,
|
||||
"a": "b"
|
||||
}
|
||||
}
|
||||
|
||||
TASK [Create a dictionary with the community.general.dict filter] ************************
|
||||
ok: [localhost] => {
|
||||
"msg": {
|
||||
"1": 2,
|
||||
"a": "b"
|
||||
}
|
||||
}
|
||||
|
||||
TASK [Create a list of dictionaries with map and the community.general.dict filter] ******
|
||||
ok: [localhost] => {
|
||||
"msg": [
|
||||
{
|
||||
"k1": "foo",
|
||||
"k2": 23,
|
||||
"k3": "a"
|
||||
},
|
||||
{
|
||||
"k1": "bar",
|
||||
"k2": 42,
|
||||
"k3": "b"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
.. versionadded:: 3.0.0
|
||||
|
||||
Grouping
|
||||
^^^^^^^^
|
||||
|
||||
If you have a list of dictionaries, the Jinja2 ``groupby`` filter allows to group the list by an attribute. This results in a list of ``(grouper, list)`` namedtuples, where ``list`` contains all dictionaries where the selected attribute equals ``grouper``. If you know that for every ``grouper``, there will be a most one entry in that list, you can use the ``community.general.groupby_as_dict`` filter to convert the original list into a dictionary which maps ``grouper`` to the corresponding dictionary.
|
||||
|
||||
One example is ``ansible_facts.mounts``, which is a list of dictionaries where each has one ``device`` element to indicate the device which is mounted. Therefore, ``ansible_facts.mounts | community.general.groupby_as_dict('device')`` is a dictionary mapping a device to the mount information:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
- name: Output mount facts grouped by device name
|
||||
debug:
|
||||
var: ansible_facts.mounts | community.general.groupby_as_dict('device')
|
||||
|
||||
- name: Output mount facts grouped by mount point
|
||||
debug:
|
||||
var: ansible_facts.mounts | community.general.groupby_as_dict('mount')
|
||||
|
||||
This produces:
|
||||
|
||||
.. code-block:: ansible-output
|
||||
|
||||
TASK [Output mount facts grouped by device name] ******************************************
|
||||
ok: [localhost] => {
|
||||
"ansible_facts.mounts | community.general.groupby_as_dict('device')": {
|
||||
"/dev/sda1": {
|
||||
"block_available": 2000,
|
||||
"block_size": 4096,
|
||||
"block_total": 2345,
|
||||
"block_used": 345,
|
||||
"device": "/dev/sda1",
|
||||
"fstype": "ext4",
|
||||
"inode_available": 500,
|
||||
"inode_total": 512,
|
||||
"inode_used": 12,
|
||||
"mount": "/boot",
|
||||
"options": "rw,relatime,data=ordered",
|
||||
"size_available": 56821,
|
||||
"size_total": 543210,
|
||||
"uuid": "ab31cade-d9c1-484d-8482-8a4cbee5241a"
|
||||
},
|
||||
"/dev/sda2": {
|
||||
"block_available": 1234,
|
||||
"block_size": 4096,
|
||||
"block_total": 12345,
|
||||
"block_used": 11111,
|
||||
"device": "/dev/sda2",
|
||||
"fstype": "ext4",
|
||||
"inode_available": 1111,
|
||||
"inode_total": 1234,
|
||||
"inode_used": 123,
|
||||
"mount": "/",
|
||||
"options": "rw,relatime",
|
||||
"size_available": 42143,
|
||||
"size_total": 543210,
|
||||
"uuid": "abcdef01-2345-6789-0abc-def012345678"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TASK [Output mount facts grouped by mount point] ******************************************
|
||||
ok: [localhost] => {
|
||||
"ansible_facts.mounts | community.general.groupby_as_dict('mount')": {
|
||||
"/": {
|
||||
"block_available": 1234,
|
||||
"block_size": 4096,
|
||||
"block_total": 12345,
|
||||
"block_used": 11111,
|
||||
"device": "/dev/sda2",
|
||||
"fstype": "ext4",
|
||||
"inode_available": 1111,
|
||||
"inode_total": 1234,
|
||||
"inode_used": 123,
|
||||
"mount": "/",
|
||||
"options": "rw,relatime",
|
||||
"size_available": 42143,
|
||||
"size_total": 543210,
|
||||
"uuid": "bdf50b7d-4859-40af-8665-c637ee7a7808"
|
||||
},
|
||||
"/boot": {
|
||||
"block_available": 2000,
|
||||
"block_size": 4096,
|
||||
"block_total": 2345,
|
||||
"block_used": 345,
|
||||
"device": "/dev/sda1",
|
||||
"fstype": "ext4",
|
||||
"inode_available": 500,
|
||||
"inode_total": 512,
|
||||
"inode_used": 12,
|
||||
"mount": "/boot",
|
||||
"options": "rw,relatime,data=ordered",
|
||||
"size_available": 56821,
|
||||
"size_total": 543210,
|
||||
"uuid": "ab31cade-d9c1-484d-8482-8a4cbee5241a"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.. versionadded: 3.0.0
|
||||
|
||||
Merging lists of dictionaries
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you have two lists of dictionaries and want to combine them into a list of merged dictionaries, where two dictionaries are merged if they coincide in one attribute, you can use the ``lists_mergeby`` filter.
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
- name: Merge two lists by common attribute 'name'
|
||||
debug:
|
||||
var: list1 | community.general.lists_mergeby(list2, 'name')
|
||||
vars:
|
||||
list1:
|
||||
- name: foo
|
||||
extra: true
|
||||
- name: bar
|
||||
extra: false
|
||||
- name: meh
|
||||
extra: true
|
||||
list2:
|
||||
- name: foo
|
||||
path: /foo
|
||||
- name: baz
|
||||
path: /bazzz
|
||||
|
||||
This produces:
|
||||
|
||||
.. code-block:: ansible-output
|
||||
|
||||
TASK [Merge two lists by common attribute 'name'] ****************************************
|
||||
ok: [localhost] => {
|
||||
"list1 | community.general.lists_mergeby(list2, 'name')": [
|
||||
{
|
||||
"extra": false,
|
||||
"name": "bar"
|
||||
},
|
||||
{
|
||||
"name": "baz",
|
||||
"path": "/bazzz"
|
||||
},
|
||||
{
|
||||
"extra": true,
|
||||
"name": "foo",
|
||||
"path": "/foo"
|
||||
},
|
||||
{
|
||||
"extra": true,
|
||||
"name": "meh"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
.. versionadded: 2.0.0
|
||||
|
||||
Working with times
|
||||
------------------
|
||||
|
||||
The ``to_time_unit`` filter allows to convert times from a human-readable string to a unit. For example, ``'4h 30min 12second' | community.general.to_time_unit('hour')`` gives the number of hours that correspond to 4 hours, 30 minutes and 12 seconds.
|
||||
|
||||
There are shorthands to directly convert to various units, like ``to_hours``, ``to_minutes``, ``to_seconds``, and so on. The following table lists all units that can be used:
|
||||
|
||||
.. list-table:: Units
|
||||
:widths: 25 25 25 25
|
||||
:header-rows: 1
|
||||
|
||||
* - Unit name
|
||||
- Unit value in seconds
|
||||
- Unit strings for filter
|
||||
- Shorthand filter
|
||||
* - Millisecond
|
||||
- 1/1000 second
|
||||
- ``ms``, ``millisecond``, ``milliseconds``, ``msec``, ``msecs``, ``msecond``, ``mseconds``
|
||||
- ``to_milliseconds``
|
||||
* - Second
|
||||
- 1 second
|
||||
- ``s``, ``sec``, ``secs``, ``second``, ``seconds``
|
||||
- ``to_seconds``
|
||||
* - Minute
|
||||
- 60 seconds
|
||||
- ``m``, ``min``, ``mins``, ``minute``, ``minutes``
|
||||
- ``to_minutes``
|
||||
* - Hour
|
||||
- 60*60 seconds
|
||||
- ``h``, ``hour``, ``hours``
|
||||
- ``to_hours``
|
||||
* - Day
|
||||
- 24*60*60 seconds
|
||||
- ``d``, ``day``, ``days``
|
||||
- ``to_days``
|
||||
* - Week
|
||||
- 7*24*60*60 seconds
|
||||
- ``w``, ``week``, ``weeks``
|
||||
- ``to_weeks``
|
||||
* - Month
|
||||
- 30*24*60*60 seconds
|
||||
- ``mo``, ``month``, ``months``
|
||||
- ``to_months``
|
||||
* - Year
|
||||
- 365*24*60*60 seconds
|
||||
- ``y``, ``year``, ``years``
|
||||
- ``to_years``
|
||||
|
||||
Note that months and years are using a simplified representation: a month is 30 days, and a year is 365 days. If you need different definitions of months or years, you can pass them as keyword arguments. For example, if you want a year to be 365.25 days, and a month to be 30.5 days, you can write ``'11months 4' | community.general.to_years(year=365.25, month=30.5)``. These keyword arguments can be specified to ``to_time_unit`` and to all shorthand filters.
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
- name: Convert string to seconds
|
||||
debug:
|
||||
msg: "{{ '30h 20m 10s 123ms' | community.general.to_time_unit('seconds') }}"
|
||||
|
||||
- name: Convert string to hours
|
||||
debug:
|
||||
msg: "{{ '30h 20m 10s 123ms' | community.general.to_hours }}"
|
||||
|
||||
- name: Convert string to years (using 365.25 days == 1 year)
|
||||
debug:
|
||||
msg: "{{ '400d 15h' | community.general.to_years(year=365.25) }}"
|
||||
|
||||
This produces:
|
||||
|
||||
.. code-block:: ansible-output
|
||||
|
||||
TASK [Convert string to seconds] **********************************************************
|
||||
ok: [localhost] => {
|
||||
"msg": "109210.123"
|
||||
}
|
||||
|
||||
TASK [Convert string to hours] ************************************************************
|
||||
ok: [localhost] => {
|
||||
"msg": "30.336145277778"
|
||||
}
|
||||
|
||||
TASK [Convert string to years (using 365.25 days == 1 year)] ******************************
|
||||
ok: [localhost] => {
|
||||
"msg": "1.096851471595"
|
||||
}
|
||||
|
||||
.. versionadded: 0.2.0
|
||||
|
||||
Working with versions
|
||||
---------------------
|
||||
|
||||
If you need to sort a list of version numbers, the Jinja ``sort`` filter is problematic. Since it sorts lexicographically, ``2.10`` will come before ``2.9``. To treat version numbers correctly, you can use the ``version_sort`` filter:
|
||||
|
||||
.. code-block:: yaml+jinja
|
||||
|
||||
- name: Sort list by version number
|
||||
debug:
|
||||
var: ansible_versions | community.general.version_sort
|
||||
vars:
|
||||
ansible_versions:
|
||||
- '2.8.0'
|
||||
- '2.11.0'
|
||||
- '2.7.0'
|
||||
- '2.10.0'
|
||||
- '2.9.0'
|
||||
|
||||
This produces:
|
||||
|
||||
.. code-block:: ansible-output
|
||||
|
||||
TASK [Sort list by version number] ********************************************************
|
||||
ok: [localhost] => {
|
||||
"ansible_versions | community.general.version_sort": [
|
||||
"2.7.0",
|
||||
"2.8.0",
|
||||
"2.9.0",
|
||||
"2.10.0",
|
||||
"2.11.0"
|
||||
]
|
||||
}
|
||||
|
||||
.. versionadded: 2.2.0
|
||||
|
||||
Creating identifiers
|
||||
--------------------
|
||||
|
||||
The following filters allow to create identifiers.
|
||||
|
||||
Hashids
|
||||
^^^^^^^
|
||||
|
||||
`Hashids <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) }}"
|
||||
|
||||
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
|
||||
|
||||
.. _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.
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace: community
|
||||
name: general
|
||||
version: 3.1.0
|
||||
version: 3.4.0
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (https://github.com/ansible)
|
||||
|
||||
244
meta/runtime.yml
244
meta/runtime.yml
@@ -1,31 +1,5 @@
|
||||
---
|
||||
requires_ansible: '>=2.9.10'
|
||||
action_groups:
|
||||
ovirt:
|
||||
- ovirt_affinity_label_facts
|
||||
- ovirt_api_facts
|
||||
- ovirt_cluster_facts
|
||||
- ovirt_datacenter_facts
|
||||
- ovirt_disk_facts
|
||||
- ovirt_event_facts
|
||||
- ovirt_external_provider_facts
|
||||
- ovirt_group_facts
|
||||
- ovirt_host_facts
|
||||
- ovirt_host_storage_facts
|
||||
- ovirt_network_facts
|
||||
- ovirt_nic_facts
|
||||
- ovirt_permission_facts
|
||||
- ovirt_quota_facts
|
||||
- ovirt_scheduling_policy_facts
|
||||
- ovirt_snapshot_facts
|
||||
- ovirt_storage_domain_facts
|
||||
- ovirt_storage_template_facts
|
||||
- ovirt_storage_vm_facts
|
||||
- ovirt_tag_facts
|
||||
- ovirt_template_facts
|
||||
- ovirt_user_facts
|
||||
- ovirt_vm_facts
|
||||
- ovirt_vmpool_facts
|
||||
plugin_routing:
|
||||
connection:
|
||||
docker:
|
||||
@@ -40,15 +14,18 @@ plugin_routing:
|
||||
nios:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios lookup plugin has been deprecated. Please use infoblox.nios_modules.nios_lookup instead.
|
||||
warning_text: The community.general.nios lookup plugin has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_lookup instead.
|
||||
nios_next_ip:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_next_ip lookup plugin has been deprecated. Please use infoblox.nios_modules.nios_next_ip instead.
|
||||
warning_text: The community.general.nios_next_ip lookup plugin has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_next_ip instead.
|
||||
nios_next_network:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_next_network lookup plugin has been deprecated. Please use infoblox.nios_modules.nios_next_network instead.
|
||||
warning_text: The community.general.nios_next_network lookup plugin has been
|
||||
deprecated. Please use infoblox.nios_modules.nios_next_network instead.
|
||||
modules:
|
||||
ali_instance_facts:
|
||||
tombstone:
|
||||
@@ -153,11 +130,13 @@ plugin_routing:
|
||||
gcp_forwarding_rule:
|
||||
tombstone:
|
||||
removal_version: 2.0.0
|
||||
warning_text: Use google.cloud.gcp_compute_forwarding_rule or google.cloud.gcp_compute_global_forwarding_rule instead.
|
||||
warning_text: Use google.cloud.gcp_compute_forwarding_rule or google.cloud.gcp_compute_global_forwarding_rule
|
||||
instead.
|
||||
gcp_healthcheck:
|
||||
tombstone:
|
||||
removal_version: 2.0.0
|
||||
warning_text: Use google.cloud.gcp_compute_health_check, google.cloud.gcp_compute_http_health_check or google.cloud.gcp_compute_https_health_check instead.
|
||||
warning_text: Use google.cloud.gcp_compute_health_check, google.cloud.gcp_compute_http_health_check
|
||||
or google.cloud.gcp_compute_https_health_check instead.
|
||||
gcp_target_proxy:
|
||||
tombstone:
|
||||
removal_version: 2.0.0
|
||||
@@ -168,37 +147,22 @@ plugin_routing:
|
||||
warning_text: Use google.cloud.gcp_compute_url_map instead.
|
||||
gcpubsub:
|
||||
redirect: community.google.gcpubsub
|
||||
gcpubsub_info:
|
||||
redirect: community.google.gcpubsub_info
|
||||
gcpubsub_facts:
|
||||
tombstone:
|
||||
removal_version: 3.0.0
|
||||
warning_text: Use community.google.gcpubsub_info instead.
|
||||
gcpubsub_info:
|
||||
redirect: community.google.gcpubsub_info
|
||||
gcspanner:
|
||||
tombstone:
|
||||
removal_version: 2.0.0
|
||||
warning_text: Use google.cloud.gcp_spanner_database and/or google.cloud.gcp_spanner_instance instead.
|
||||
warning_text: Use google.cloud.gcp_spanner_database and/or google.cloud.gcp_spanner_instance
|
||||
instead.
|
||||
github_hooks:
|
||||
tombstone:
|
||||
removal_version: 2.0.0
|
||||
warning_text: Use community.general.github_webhook and community.general.github_webhook_info instead.
|
||||
# Adding tombstones burns the old name, so we simply remove the entries:
|
||||
# gluster_heal_info:
|
||||
# tombstone:
|
||||
# removal_version: 3.0.0
|
||||
# warning_text: The gluster modules have migrated to the gluster.gluster collection. Use gluster.gluster.gluster_heal_info instead.
|
||||
# gluster_peer:
|
||||
# tombstone:
|
||||
# removal_version: 3.0.0
|
||||
# warning_text: The gluster modules have migrated to the gluster.gluster collection. Use gluster.gluster.gluster_peer instead.
|
||||
# gluster_volume:
|
||||
# tombstone:
|
||||
# removal_version: 3.0.0
|
||||
# warning_text: The gluster modules have migrated to the gluster.gluster collection. Use gluster.gluster.gluster_volume instead.
|
||||
# helm:
|
||||
# tombstone:
|
||||
# removal_version: 3.0.0
|
||||
# warning_text: Use community.kubernetes.helm instead.
|
||||
warning_text: Use community.general.github_webhook and community.general.github_webhook_info
|
||||
instead.
|
||||
hetzner_failover_ip:
|
||||
redirect: community.hrobot.failover_ip
|
||||
hetzner_failover_ip_info:
|
||||
@@ -246,11 +210,13 @@ plugin_routing:
|
||||
logicmonitor:
|
||||
tombstone:
|
||||
removal_version: 1.0.0
|
||||
warning_text: The logicmonitor_facts module is no longer maintained and the API used has been disabled in 2017.
|
||||
warning_text: The logicmonitor_facts module is no longer maintained and the
|
||||
API used has been disabled in 2017.
|
||||
logicmonitor_facts:
|
||||
tombstone:
|
||||
removal_version: 1.0.0
|
||||
warning_text: The logicmonitor_facts module is no longer maintained and the API used has been disabled in 2017.
|
||||
warning_text: The logicmonitor_facts module is no longer maintained and the
|
||||
API used has been disabled in 2017.
|
||||
memset_memstore_facts:
|
||||
tombstone:
|
||||
removal_version: 3.0.0
|
||||
@@ -295,74 +261,90 @@ plugin_routing:
|
||||
tombstone:
|
||||
removal_version: 3.0.0
|
||||
warning_text: Use netapp.ontap.na_ontap_info instead.
|
||||
nios_a_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_a_record module has been deprecated. Please use infoblox.nios_modules.nios_a_record instead.
|
||||
nios_aaaa_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_aaaa_record module has been deprecated. Please use infoblox.nios_modules.nios_aaaa_record instead.
|
||||
nios_cname_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_cname_record module has been deprecated. Please use infoblox.nios_modules.nios_cname_record instead.
|
||||
nios_dns_view:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_dns_view module has been deprecated. Please use infoblox.nios_modules.nios_dns_view instead.
|
||||
nios_fixed_address:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_fixed_address module has been deprecated. Please use infoblox.nios_modules.nios_fixed_address instead.
|
||||
nios_host_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_host_record module has been deprecated. Please use infoblox.nios_modules.nios_host_record instead.
|
||||
nios_member:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_member module has been deprecated. Please use infoblox.nios_modules.nios_member instead.
|
||||
nios_mx_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_mx_record module has been deprecated. Please use infoblox.nios_modules.nios_mx_record instead.
|
||||
nios_naptr_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_naptr_record module has been deprecated. Please use infoblox.nios_modules.nios_naptr_record instead.
|
||||
nios_network:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_network module has been deprecated. Please use infoblox.nios_modules.nios_network instead.
|
||||
nios_network_view:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_network_view module has been deprecated. Please use infoblox.nios_modules.nios_network_view instead.
|
||||
nios_nsgroup:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_nsgroup module has been deprecated. Please use infoblox.nios_modules.nios_nsgroup instead.
|
||||
nios_ptr_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_ptr_record module has been deprecated. Please use infoblox.nios_modules.nios_ptr_record instead.
|
||||
nios_srv_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_srv_record module has been deprecated. Please use infoblox.nios_modules.nios_srv_record instead.
|
||||
nios_txt_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_txt_record module has been deprecated. Please use infoblox.nios_modules.nios_txt_record instead.
|
||||
nios_zone:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_zone module has been deprecated. Please use infoblox.nios_modules.nios_zone instead.
|
||||
nginx_status_facts:
|
||||
tombstone:
|
||||
removal_version: 3.0.0
|
||||
warning_text: Use community.general.nginx_status_info instead.
|
||||
nios_a_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_a_record module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_a_record instead.
|
||||
nios_aaaa_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_aaaa_record module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_aaaa_record instead.
|
||||
nios_cname_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_cname_record module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_cname_record instead.
|
||||
nios_dns_view:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_dns_view module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_dns_view instead.
|
||||
nios_fixed_address:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_fixed_address module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_fixed_address instead.
|
||||
nios_host_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_host_record module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_host_record instead.
|
||||
nios_member:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_member module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_member instead.
|
||||
nios_mx_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_mx_record module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_mx_record instead.
|
||||
nios_naptr_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_naptr_record module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_naptr_record instead.
|
||||
nios_network:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_network module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_network instead.
|
||||
nios_network_view:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_network_view module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_network_view instead.
|
||||
nios_nsgroup:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_nsgroup module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_nsgroup instead.
|
||||
nios_ptr_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_ptr_record module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_ptr_record instead.
|
||||
nios_srv_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_srv_record module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_srv_record instead.
|
||||
nios_txt_record:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_txt_record module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_txt_record instead.
|
||||
nios_zone:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios_zone module has been deprecated.
|
||||
Please use infoblox.nios_modules.nios_zone instead.
|
||||
ome_device_info:
|
||||
redirect: dellemc.openmanage.ome_device_info
|
||||
one_image_facts:
|
||||
@@ -396,7 +378,8 @@ plugin_routing:
|
||||
oneview_logical_interconnect_group_facts:
|
||||
tombstone:
|
||||
removal_version: 3.0.0
|
||||
warning_text: Use community.general.oneview_logical_interconnect_group_info instead.
|
||||
warning_text: Use community.general.oneview_logical_interconnect_group_info
|
||||
instead.
|
||||
oneview_network_set_facts:
|
||||
tombstone:
|
||||
removal_version: 3.0.0
|
||||
@@ -553,10 +536,10 @@ plugin_routing:
|
||||
redirect: community.postgresql.postgresql_table
|
||||
postgresql_tablespace:
|
||||
redirect: community.postgresql.postgresql_tablespace
|
||||
postgresql_user_obj_stat_info:
|
||||
redirect: community.postgresql.postgresql_user_obj_stat_info
|
||||
postgresql_user:
|
||||
redirect: community.postgresql.postgresql_user
|
||||
postgresql_user_obj_stat_info:
|
||||
redirect: community.postgresql.postgresql_user_obj_stat_info
|
||||
purefa_facts:
|
||||
tombstone:
|
||||
removal_version: 3.0.0
|
||||
@@ -647,7 +630,8 @@ plugin_routing:
|
||||
nios:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.nios document fragment has been deprecated. Please use infoblox.nios_modules.nios instead.
|
||||
warning_text: The community.general.nios document fragment has been deprecated.
|
||||
Please use infoblox.nios_modules.nios instead.
|
||||
postgresql:
|
||||
redirect: community.postgresql.postgresql
|
||||
module_utils:
|
||||
@@ -668,26 +652,30 @@ plugin_routing:
|
||||
net_tools.nios.api:
|
||||
deprecation:
|
||||
removal_version: 5.0.0
|
||||
warning_text: The community.general.net_tools.nios.api module_utils has been deprecated. Please use infoblox.nios_modules.api instead.
|
||||
warning_text: The community.general.net_tools.nios.api module_utils has been
|
||||
deprecated. Please use infoblox.nios_modules.api instead.
|
||||
postgresql:
|
||||
redirect: community.postgresql.postgresql
|
||||
remote_management.dellemc.dellemc_idrac:
|
||||
redirect: dellemc.openmanage.dellemc_idrac
|
||||
remote_management.dellemc.ome:
|
||||
redirect: dellemc.openmanage.ome
|
||||
postgresql:
|
||||
redirect: community.postgresql.postgresql
|
||||
callback:
|
||||
actionable:
|
||||
tombstone:
|
||||
removal_version: 2.0.0
|
||||
warning_text: Use the 'default' callback plugin with 'display_skipped_hosts = no' and 'display_ok_hosts = no' options.
|
||||
warning_text: Use the 'default' callback plugin with 'display_skipped_hosts
|
||||
= no' and 'display_ok_hosts = no' options.
|
||||
full_skip:
|
||||
tombstone:
|
||||
removal_version: 2.0.0
|
||||
warning_text: Use the 'default' callback plugin with 'display_skipped_hosts = no' option.
|
||||
warning_text: Use the 'default' callback plugin with 'display_skipped_hosts
|
||||
= no' option.
|
||||
stderr:
|
||||
tombstone:
|
||||
removal_version: 2.0.0
|
||||
warning_text: Use the 'default' callback plugin with 'display_failed_stderr = yes' option.
|
||||
warning_text: Use the 'default' callback plugin with 'display_failed_stderr
|
||||
= yes' option.
|
||||
inventory:
|
||||
docker_machine:
|
||||
redirect: community.docker.docker_machine
|
||||
|
||||
@@ -40,19 +40,27 @@ class ActionModule(ActionBase):
|
||||
"(=%s) to 0, and 'async' (=%s) to a value >2 and not greater than "
|
||||
"'ansible_timeout' (=%s) (recommended).")
|
||||
|
||||
def _async_result(self, module_args, task_vars, timeout):
|
||||
def _async_result(self, async_status_args, task_vars, timeout):
|
||||
'''
|
||||
Retrieve results of the asynchonous task, and display them in place of
|
||||
the async wrapper results (those with the ansible_job_id key).
|
||||
'''
|
||||
async_status = self._task.copy()
|
||||
async_status.args = async_status_args
|
||||
async_status.action = 'ansible.builtin.async_status'
|
||||
async_status.async_val = 0
|
||||
async_action = self._shared_loader_obj.action_loader.get(
|
||||
async_status.action, task=async_status, connection=self._connection,
|
||||
play_context=self._play_context, loader=self._loader, templar=self._templar,
|
||||
shared_loader_obj=self._shared_loader_obj)
|
||||
|
||||
if async_status.args['mode'] == 'cleanup':
|
||||
return async_action.run(task_vars=task_vars)
|
||||
|
||||
# At least one iteration is required, even if timeout is 0.
|
||||
for dummy in range(max(1, timeout)):
|
||||
async_result = self._execute_module(
|
||||
module_name='ansible.builtin.async_status',
|
||||
module_args=module_args,
|
||||
task_vars=task_vars,
|
||||
wrap_async=False)
|
||||
if async_result['finished'] == 1:
|
||||
async_result = async_action.run(task_vars=task_vars)
|
||||
if async_result.get('finished', 0) == 1:
|
||||
break
|
||||
time.sleep(min(1, timeout))
|
||||
|
||||
@@ -106,7 +114,7 @@ class ActionModule(ActionBase):
|
||||
# longer on the controller); and set a backup file path.
|
||||
module_args['_timeout'] = task_async
|
||||
module_args['_back'] = '%s/iptables.state' % async_dir
|
||||
async_status_args = dict(_async_dir=async_dir)
|
||||
async_status_args = dict(mode='status')
|
||||
confirm_cmd = 'rm -f %s' % module_args['_back']
|
||||
starter_cmd = 'touch %s.starter' % module_args['_back']
|
||||
remaining_time = max(task_async, max_timeout)
|
||||
@@ -168,11 +176,7 @@ class ActionModule(ActionBase):
|
||||
del result['invocation']['module_args'][key]
|
||||
|
||||
async_status_args['mode'] = 'cleanup'
|
||||
dummy = self._execute_module(
|
||||
module_name='ansible.builtin.async_status',
|
||||
module_args=async_status_args,
|
||||
task_vars=task_vars,
|
||||
wrap_async=False)
|
||||
dummy = self._async_result(async_status_args, task_vars, 0)
|
||||
|
||||
if not wrap_async:
|
||||
# remove a temporary path we created
|
||||
|
||||
@@ -7,7 +7,7 @@ from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleConnectionFailure
|
||||
from ansible.module_utils._text import to_native, to_text
|
||||
from ansible.module_utils.common.text.converters 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
|
||||
|
||||
@@ -81,7 +81,7 @@ DOCUMENTATION = '''
|
||||
|
||||
import re
|
||||
|
||||
from ansible.module_utils._text import to_bytes
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.plugins.become import BecomeBase
|
||||
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ DOCUMENTATION = '''
|
||||
|
||||
import re
|
||||
|
||||
from ansible.module_utils._text import to_bytes
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.plugins.become import BecomeBase
|
||||
|
||||
|
||||
|
||||
16
plugins/cache/redis.py
vendored
16
plugins/cache/redis.py
vendored
@@ -61,12 +61,13 @@ DOCUMENTATION = '''
|
||||
type: integer
|
||||
'''
|
||||
|
||||
import re
|
||||
import time
|
||||
import json
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters 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
|
||||
@@ -91,6 +92,8 @@ class CacheModule(BaseCacheModule):
|
||||
performance.
|
||||
"""
|
||||
_sentinel_service_name = None
|
||||
re_url_conn = re.compile(r'^([^:]+|\[[^]]+\]):(\d+):(\d+)(?::(.*))?$')
|
||||
re_sent_conn = re.compile(r'^(.*):(\d+)$')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
uri = ''
|
||||
@@ -130,11 +133,18 @@ class CacheModule(BaseCacheModule):
|
||||
self._db = self._get_sentinel_connection(uri, kw)
|
||||
# normal connection
|
||||
else:
|
||||
connection = uri.split(':')
|
||||
connection = self._parse_connection(self.re_url_conn, uri)
|
||||
self._db = StrictRedis(*connection, **kw)
|
||||
|
||||
display.vv('Redis connection: %s' % self._db)
|
||||
|
||||
@staticmethod
|
||||
def _parse_connection(re_patt, uri):
|
||||
match = re_patt.match(uri)
|
||||
if not match:
|
||||
raise AnsibleError("Unable to parse connection string")
|
||||
return match.groups()
|
||||
|
||||
def _get_sentinel_connection(self, uri, kw):
|
||||
"""
|
||||
get sentinel connection details from _uri
|
||||
@@ -158,7 +168,7 @@ class CacheModule(BaseCacheModule):
|
||||
except IndexError:
|
||||
pass # password is optional
|
||||
|
||||
sentinels = [tuple(shost.split(':')) for shost in connections]
|
||||
sentinels = [self._parse_connection(self.re_sent_conn, shost) for shost in connections]
|
||||
display.vv('\nUsing redis sentinels: %s' % sentinels)
|
||||
scon = Sentinel(sentinels, **kw)
|
||||
try:
|
||||
|
||||
@@ -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._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
|
||||
class DummyStdout(object):
|
||||
|
||||
@@ -31,7 +31,7 @@ import time
|
||||
import json
|
||||
|
||||
from ansible.utils.path import makedirs_safe
|
||||
from ansible.module_utils._text import to_bytes
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.module_utils.common._collections_compat import MutableMapping
|
||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
@@ -111,7 +111,7 @@ try:
|
||||
except ImportError:
|
||||
HAS_FLATDICT = False
|
||||
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
# Todo:
|
||||
|
||||
@@ -62,7 +62,7 @@ import re
|
||||
import smtplib
|
||||
|
||||
from ansible.module_utils.six import string_types
|
||||
from ansible.module_utils._text import to_bytes
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
|
||||
@@ -10,22 +10,23 @@ DOCUMENTATION = '''
|
||||
name: nrdp
|
||||
type: notification
|
||||
author: "Remi VERCHERE (@rverchere)"
|
||||
short_description: post task result to a nagios server through nrdp
|
||||
short_description: Post task results to a Nagios server through nrdp
|
||||
description:
|
||||
- this callback send playbook result to nagios
|
||||
- nagios shall use NRDP to recive passive events
|
||||
- the passive check is sent to a dedicated host/service for ansible
|
||||
- This callback send playbook result to Nagios.
|
||||
- Nagios shall use NRDP to recive passive events.
|
||||
- The passive check is sent to a dedicated host/service for Ansible.
|
||||
options:
|
||||
url:
|
||||
description: url of the nrdp server
|
||||
required: True
|
||||
description: URL of the nrdp server.
|
||||
required: true
|
||||
env:
|
||||
- name : NRDP_URL
|
||||
ini:
|
||||
- section: callback_nrdp
|
||||
key: url
|
||||
type: string
|
||||
validate_certs:
|
||||
description: (bool) validate the SSL certificate of the nrdp server. (For HTTPS url)
|
||||
description: Validate the SSL certificate of the nrdp server. (Used for HTTPS URLs.)
|
||||
env:
|
||||
- name: NRDP_VALIDATE_CERTS
|
||||
ini:
|
||||
@@ -33,32 +34,36 @@ DOCUMENTATION = '''
|
||||
key: validate_nrdp_certs
|
||||
- section: callback_nrdp
|
||||
key: validate_certs
|
||||
default: False
|
||||
type: boolean
|
||||
default: false
|
||||
aliases: [ validate_nrdp_certs ]
|
||||
token:
|
||||
description: token to be allowed to push nrdp events
|
||||
required: True
|
||||
description: Token to be allowed to push nrdp events.
|
||||
required: true
|
||||
env:
|
||||
- name: NRDP_TOKEN
|
||||
ini:
|
||||
- section: callback_nrdp
|
||||
key: token
|
||||
type: string
|
||||
hostname:
|
||||
description: hostname where the passive check is linked to
|
||||
required: True
|
||||
description: Hostname where the passive check is linked to.
|
||||
required: true
|
||||
env:
|
||||
- name : NRDP_HOSTNAME
|
||||
ini:
|
||||
- section: callback_nrdp
|
||||
key: hostname
|
||||
type: string
|
||||
servicename:
|
||||
description: service where the passive check is linked to
|
||||
required: True
|
||||
description: Service where the passive check is linked to.
|
||||
required: true
|
||||
env:
|
||||
- name : NRDP_SERVICENAME
|
||||
ini:
|
||||
- section: callback_nrdp
|
||||
key: servicename
|
||||
type: string
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
@@ -40,7 +40,7 @@ import difflib
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
try:
|
||||
codeCodes = C.COLOR_CODES
|
||||
|
||||
@@ -58,7 +58,7 @@ import os
|
||||
import uuid
|
||||
|
||||
from ansible import context
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
|
||||
@@ -68,6 +68,16 @@ DOCUMENTATION = '''
|
||||
type: bool
|
||||
default: false
|
||||
version_added: 2.0.0
|
||||
batch:
|
||||
description:
|
||||
- Correlation ID which can be set across multiple playbook executions.
|
||||
env:
|
||||
- name: SPLUNK_BATCH
|
||||
ini:
|
||||
- section: callback_splunk
|
||||
key: batch
|
||||
type: str
|
||||
version_added: 3.3.0
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -107,7 +117,7 @@ class SplunkHTTPCollectorSource(object):
|
||||
self.ip_address = socket.gethostbyname(socket.gethostname())
|
||||
self.user = getpass.getuser()
|
||||
|
||||
def send_event(self, url, authtoken, validate_certs, include_milliseconds, state, result, runtime):
|
||||
def send_event(self, url, authtoken, validate_certs, include_milliseconds, batch, state, result, runtime):
|
||||
if result._task_fields['args'].get('_ansible_check_mode') is True:
|
||||
self.ansible_check_mode = True
|
||||
|
||||
@@ -126,6 +136,8 @@ class SplunkHTTPCollectorSource(object):
|
||||
data = {}
|
||||
data['uuid'] = result._task._uuid
|
||||
data['session'] = self.session
|
||||
if batch is not None:
|
||||
data['batch'] = batch
|
||||
data['status'] = state
|
||||
|
||||
if include_milliseconds:
|
||||
@@ -175,6 +187,7 @@ class CallbackModule(CallbackBase):
|
||||
self.authtoken = None
|
||||
self.validate_certs = None
|
||||
self.include_milliseconds = None
|
||||
self.batch = None
|
||||
self.splunk = SplunkHTTPCollectorSource()
|
||||
|
||||
def _runtime(self, result):
|
||||
@@ -212,6 +225,8 @@ class CallbackModule(CallbackBase):
|
||||
|
||||
self.include_milliseconds = self.get_option('include_milliseconds')
|
||||
|
||||
self.batch = self.get_option('batch')
|
||||
|
||||
def v2_playbook_on_start(self, playbook):
|
||||
self.splunk.ansible_playbook = basename(playbook._file_name)
|
||||
|
||||
@@ -227,6 +242,7 @@ class CallbackModule(CallbackBase):
|
||||
self.authtoken,
|
||||
self.validate_certs,
|
||||
self.include_milliseconds,
|
||||
self.batch,
|
||||
'OK',
|
||||
result,
|
||||
self._runtime(result)
|
||||
@@ -238,6 +254,7 @@ class CallbackModule(CallbackBase):
|
||||
self.authtoken,
|
||||
self.validate_certs,
|
||||
self.include_milliseconds,
|
||||
self.batch,
|
||||
'SKIPPED',
|
||||
result,
|
||||
self._runtime(result)
|
||||
@@ -249,6 +266,7 @@ class CallbackModule(CallbackBase):
|
||||
self.authtoken,
|
||||
self.validate_certs,
|
||||
self.include_milliseconds,
|
||||
self.batch,
|
||||
'FAILED',
|
||||
result,
|
||||
self._runtime(result)
|
||||
@@ -260,6 +278,7 @@ class CallbackModule(CallbackBase):
|
||||
self.authtoken,
|
||||
self.validate_certs,
|
||||
self.include_milliseconds,
|
||||
self.batch,
|
||||
'FAILED',
|
||||
result,
|
||||
self._runtime(result)
|
||||
@@ -271,6 +290,7 @@ class CallbackModule(CallbackBase):
|
||||
self.authtoken,
|
||||
self.validate_certs,
|
||||
self.include_milliseconds,
|
||||
self.batch,
|
||||
'UNREACHABLE',
|
||||
result,
|
||||
self._runtime(result)
|
||||
|
||||
@@ -22,7 +22,7 @@ DOCUMENTATION = '''
|
||||
from os.path import basename
|
||||
from ansible import constants as C
|
||||
from ansible import context
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.utils.color import colorize, hostcolor
|
||||
from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import re
|
||||
import string
|
||||
import sys
|
||||
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
from ansible.module_utils.six import string_types
|
||||
from ansible.parsing.yaml.dumper import AnsibleDumper
|
||||
from ansible.plugins.callback import CallbackBase, strip_internal_keys, module_response_deepcopy
|
||||
|
||||
@@ -54,7 +54,7 @@ from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.basic import is_executable
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.six.moves import shlex_quote
|
||||
from ansible.module_utils._text import to_bytes, to_native
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native
|
||||
from ansible.plugins.connection import ConnectionBase, BUFSIZE
|
||||
from ansible.utils.display import Display
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ DOCUMENTATION = '''
|
||||
import subprocess
|
||||
|
||||
from ansible_collections.community.general.plugins.connection.jail import Connection as Jail
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.utils.display import Display
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ import traceback
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.six.moves import shlex_quote
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||
from ansible.plugins.connection import ConnectionBase, BUFSIZE
|
||||
from ansible.utils.display import Display
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ except ImportError:
|
||||
pass
|
||||
|
||||
from ansible import errors
|
||||
from ansible.module_utils._text import to_bytes, to_native
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native
|
||||
from ansible.plugins.connection import ConnectionBase
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ from distutils.spawn import find_executable
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
from ansible.plugins.connection import ConnectionBase
|
||||
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ DOCUMENTATION = '''
|
||||
|
||||
import subprocess
|
||||
|
||||
from ansible.module_utils._text import to_bytes
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.plugins.connection import ConnectionBase, ensure_connect
|
||||
from ansible.errors import AnsibleConnectionFailure
|
||||
from ansible.utils.display import Display
|
||||
|
||||
@@ -33,7 +33,7 @@ import traceback
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.six.moves import shlex_quote
|
||||
from ansible.module_utils._text import to_bytes
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.plugins.connection import ConnectionBase, BUFSIZE
|
||||
from ansible.utils.display import Display
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.csv import (initialize_dialect, read_csv, CSVError,
|
||||
DialectNotAvailableError,
|
||||
|
||||
@@ -35,9 +35,11 @@ def json_query(data, expr):
|
||||
raise AnsibleError('You need to install "jmespath" prior to running '
|
||||
'json_query filter')
|
||||
|
||||
# Hack to handle Ansible String Types
|
||||
# Hack to handle Ansible Unsafe text, AnsibleMapping and AnsibleSequence
|
||||
# See issue: https://github.com/ansible-collections/community.general/issues/320
|
||||
jmespath.functions.REVERSE_TYPES_MAP['string'] = jmespath.functions.REVERSE_TYPES_MAP['string'] + ('AnsibleUnicode', 'AnsibleUnsafeText', )
|
||||
jmespath.functions.REVERSE_TYPES_MAP['array'] = jmespath.functions.REVERSE_TYPES_MAP['array'] + ('AnsibleSequence', )
|
||||
jmespath.functions.REVERSE_TYPES_MAP['object'] = jmespath.functions.REVERSE_TYPES_MAP['object'] + ('AnsibleMapping', )
|
||||
try:
|
||||
return jmespath.search(expr, data)
|
||||
except jmespath.exceptions.JMESPathError as e:
|
||||
|
||||
@@ -72,7 +72,7 @@ from distutils.version import LooseVersion
|
||||
import socket
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.common._collections_compat import MutableMapping
|
||||
from ansible.module_utils.six import iteritems
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, to_safe_group_name
|
||||
|
||||
@@ -82,7 +82,7 @@ keyed_groups:
|
||||
'''
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleParserError
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||
|
||||
try:
|
||||
|
||||
@@ -122,7 +122,7 @@ import time
|
||||
import os
|
||||
import socket
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin
|
||||
from ansible.module_utils._text import to_native, to_text
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.module_utils.common.dict_transformations import dict_merge
|
||||
from ansible.errors import AnsibleError, AnsibleParserError
|
||||
from ansible_collections.community.general.plugins.module_utils.compat import ipaddress
|
||||
|
||||
@@ -56,7 +56,7 @@ from subprocess import Popen, PIPE
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.errors import AnsibleParserError
|
||||
from ansible.module_utils._text import to_native, to_text
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ from sys import version as python_version
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin
|
||||
from ansible.module_utils._text import to_native, to_text
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.module_utils.ansible_release import __version__ as ansible_version
|
||||
from ansible.module_utils.six.moves.urllib.parse import urljoin
|
||||
|
||||
|
||||
@@ -369,6 +369,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
if node['type'] == 'node':
|
||||
self.inventory.add_child(nodes_group, node['node'])
|
||||
|
||||
if node['status'] == 'offline':
|
||||
continue
|
||||
|
||||
# get node IP address
|
||||
if self.get_option("want_proxmox_nodes_ansible_host"):
|
||||
ip = self._get_node_ip(node['node'])
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
# Copyright (c) 2017 Ansible Project
|
||||
# Copyright: (c) 2017 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 = '''
|
||||
DOCUMENTATION = r'''
|
||||
name: scaleway
|
||||
author:
|
||||
- Remy Leone (@sieben)
|
||||
short_description: Scaleway inventory source
|
||||
description:
|
||||
- Get inventory hosts from Scaleway
|
||||
- Get inventory hosts from Scaleway.
|
||||
options:
|
||||
plugin:
|
||||
description: token that ensures this is a source file for the 'scaleway' plugin.
|
||||
description: Token that ensures this is a source file for the 'scaleway' plugin.
|
||||
required: True
|
||||
choices: ['scaleway', 'community.general.scaleway']
|
||||
regions:
|
||||
description: Filter results on a specific Scaleway region
|
||||
description: Filter results on a specific Scaleway region.
|
||||
type: list
|
||||
default:
|
||||
- ams1
|
||||
@@ -26,11 +26,13 @@ DOCUMENTATION = '''
|
||||
- par2
|
||||
- waw1
|
||||
tags:
|
||||
description: Filter results on a specific tag
|
||||
description: Filter results on a specific tag.
|
||||
type: list
|
||||
oauth_token:
|
||||
required: True
|
||||
description: Scaleway OAuth token.
|
||||
description:
|
||||
- Scaleway OAuth token.
|
||||
- More details on L(how to generate token, https://www.scaleway.com/en/docs/generate-api-keys/).
|
||||
env:
|
||||
# in order of precedence
|
||||
- name: SCW_TOKEN
|
||||
@@ -48,14 +50,14 @@ DOCUMENTATION = '''
|
||||
- hostname
|
||||
- id
|
||||
variables:
|
||||
description: 'set individual variables: keys are variable names and
|
||||
description: 'Set individual variables: keys are variable names and
|
||||
values are templates. Any value returned by the
|
||||
L(Scaleway API, https://developer.scaleway.com/#servers-server-get)
|
||||
can be used.'
|
||||
type: dict
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
EXAMPLES = r'''
|
||||
# scaleway_inventory.yml file in YAML format
|
||||
# Example command line: ansible-inventory --list -i scaleway_inventory.yml
|
||||
|
||||
@@ -81,6 +83,15 @@ regions:
|
||||
- par1
|
||||
variables:
|
||||
ansible_host: public_ip.address
|
||||
|
||||
# Using static strings as variables
|
||||
plugin: community.general.scaleway
|
||||
hostnames:
|
||||
- hostname
|
||||
variables:
|
||||
ansible_host: public_ip.address
|
||||
ansible_connection: "'ssh'"
|
||||
ansible_user: "'admin'"
|
||||
'''
|
||||
|
||||
import json
|
||||
@@ -89,7 +100,7 @@ from ansible.errors import AnsibleError
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||
from ansible_collections.community.general.plugins.module_utils.scaleway import SCALEWAY_LOCATION, parse_pagination_link
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
|
||||
import ansible.module_utils.six.moves.urllib.parse as urllib_parse
|
||||
|
||||
@@ -105,7 +116,7 @@ def _fetch_information(token, url):
|
||||
except Exception as e:
|
||||
raise AnsibleError("Error while fetching %s: %s" % (url, to_native(e)))
|
||||
try:
|
||||
raw_json = json.loads(response.read())
|
||||
raw_json = json.loads(to_text(response.read()))
|
||||
except ValueError:
|
||||
raise AnsibleError("Incorrect JSON payload")
|
||||
|
||||
@@ -230,8 +241,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
|
||||
if not matching_tags:
|
||||
return set()
|
||||
else:
|
||||
return matching_tags.union((server_zone,))
|
||||
return matching_tags.union((server_zone,))
|
||||
|
||||
def _filter_host(self, host_infos, hostname_preferences):
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ DOCUMENTATION = '''
|
||||
name: stackpath_compute
|
||||
short_description: StackPath Edge Computing inventory source
|
||||
version_added: 1.2.0
|
||||
author:
|
||||
- UNKNOWN (@shayrybak)
|
||||
extends_documentation_fragment:
|
||||
- inventory_cache
|
||||
- constructed
|
||||
|
||||
@@ -56,7 +56,7 @@ import os
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from ansible.errors import AnsibleParserError
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.common._collections_compat import MutableMapping
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
|
||||
@@ -106,7 +106,7 @@ import os
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlparse
|
||||
from ansible.errors import AnsibleError, AnsibleAssertionError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
try:
|
||||
import consul
|
||||
@@ -171,10 +171,10 @@ class LookupModule(LookupBase):
|
||||
|
||||
paramvals = {
|
||||
'key': params[0],
|
||||
'token': None,
|
||||
'recurse': False,
|
||||
'index': None,
|
||||
'datacenter': None
|
||||
'token': self.get_option('token'),
|
||||
'recurse': self.get_option('recurse'),
|
||||
'index': self.get_option('index'),
|
||||
'datacenter': self.get_option('datacenter')
|
||||
}
|
||||
|
||||
# parameters specified?
|
||||
|
||||
@@ -74,7 +74,7 @@ from subprocess import Popen
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.parsing.splitter import parse_kv
|
||||
from ansible.module_utils._text import to_bytes, to_text, to_native
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text, to_native
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
|
||||
@@ -152,7 +152,7 @@ RETURN = """
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
import socket
|
||||
|
||||
try:
|
||||
|
||||
@@ -54,7 +54,7 @@ except ImportError:
|
||||
pass
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
# ==============================================================
|
||||
|
||||
@@ -138,7 +138,7 @@ import re
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.utils.display import Display
|
||||
from ansible.module_utils.basic import missing_required_lib
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.errors import AnsibleError, AnsibleLookupError
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ except ImportError:
|
||||
pass
|
||||
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils._text import to_native, to_text
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
|
||||
@@ -63,7 +63,7 @@ import os
|
||||
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.utils.cmd_functions import run_cmd
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
ANSIBLE_HIERA_CFG = os.getenv('ANSIBLE_HIERA_CFG', '/etc/hiera.yaml')
|
||||
ANSIBLE_HIERA_BIN = os.getenv('ANSIBLE_HIERA_BIN', '/usr/bin/hiera')
|
||||
|
||||
@@ -39,7 +39,7 @@ RETURN = """
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ _raw:
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils._text import to_native, to_text
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
HAVE_LMDB = True
|
||||
try:
|
||||
import lmdb
|
||||
|
||||
@@ -74,7 +74,7 @@ _list:
|
||||
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiLookup
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.errors import AnsibleError
|
||||
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ _list:
|
||||
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible_collections.community.general.plugins.module_utils.net_tools.nios.api import WapiLookup
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.errors import AnsibleError
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,11 @@ DOCUMENTATION = '''
|
||||
aliases: ['vault_password']
|
||||
section:
|
||||
description: Item section containing the field to retrieve (case-insensitive). If absent will return first match from any section.
|
||||
domain:
|
||||
description: Domain of 1Password. Default is U(1password.com).
|
||||
version_added: 3.2.0
|
||||
default: '1password.com'
|
||||
type: str
|
||||
subdomain:
|
||||
description: The 1Password subdomain to authenticate against.
|
||||
username:
|
||||
@@ -98,7 +103,7 @@ from subprocess import Popen, PIPE
|
||||
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.errors import AnsibleLookupError
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
|
||||
|
||||
class OnePass(object):
|
||||
@@ -109,6 +114,7 @@ class OnePass(object):
|
||||
self.logged_in = False
|
||||
self.token = None
|
||||
self.subdomain = None
|
||||
self.domain = None
|
||||
self.username = None
|
||||
self.secret_key = None
|
||||
self.master_password = None
|
||||
@@ -168,7 +174,7 @@ class OnePass(object):
|
||||
|
||||
args = [
|
||||
'signin',
|
||||
'{0}.1password.com'.format(self.subdomain),
|
||||
'{0}.{1}'.format(self.subdomain, self.domain),
|
||||
to_bytes(self.username),
|
||||
to_bytes(self.secret_key),
|
||||
'--output=raw',
|
||||
@@ -265,6 +271,7 @@ class LookupModule(LookupBase):
|
||||
section = kwargs.get('section')
|
||||
vault = kwargs.get('vault')
|
||||
op.subdomain = kwargs.get('subdomain')
|
||||
op.domain = kwargs.get('domain', '1password.com')
|
||||
op.username = kwargs.get('username')
|
||||
op.secret_key = kwargs.get('secret_key')
|
||||
op.master_password = kwargs.get('master_password', kwargs.get('vault_password'))
|
||||
|
||||
@@ -142,7 +142,7 @@ import yaml
|
||||
|
||||
from distutils import util
|
||||
from ansible.errors import AnsibleError, AnsibleAssertionError
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||
from ansible.utils.display import Display
|
||||
from ansible.utils.encrypt import random_password
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
220
plugins/lookup/random_string.py
Normal file
220
plugins/lookup/random_string.py
Normal file
@@ -0,0 +1,220 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright: (c) 2021, Abhijeet Kasurde <akasurde@redhat.com>
|
||||
# Copyright: (c) 2018, Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
name: random_string
|
||||
author:
|
||||
- Abhijeet Kasurde (@Akasurde)
|
||||
short_description: Generates random string
|
||||
version_added: '3.2.0'
|
||||
description:
|
||||
- Generates random string based upon the given constraints.
|
||||
options:
|
||||
length:
|
||||
description: The length of the string.
|
||||
default: 8
|
||||
type: int
|
||||
upper:
|
||||
description:
|
||||
- Include uppercase letters in the string.
|
||||
default: true
|
||||
type: bool
|
||||
lower:
|
||||
description:
|
||||
- Include lowercase letters in the string.
|
||||
default: true
|
||||
type: bool
|
||||
numbers:
|
||||
description:
|
||||
- Include numbers in the string.
|
||||
default: true
|
||||
type: bool
|
||||
special:
|
||||
description:
|
||||
- Include special characters in the string.
|
||||
- Special characters are taken from Python standard library C(string).
|
||||
See L(the documentation of string.punctuation,https://docs.python.org/3/library/string.html#string.punctuation)
|
||||
for which characters will be used.
|
||||
- The choice of special characters can be changed to setting I(override_special).
|
||||
default: true
|
||||
type: bool
|
||||
min_numeric:
|
||||
description:
|
||||
- Minimum number of numeric characters in the string.
|
||||
- If set, overrides I(numbers=false).
|
||||
default: 0
|
||||
type: int
|
||||
min_upper:
|
||||
description:
|
||||
- Minimum number of uppercase alphabets in the string.
|
||||
- If set, overrides I(upper=false).
|
||||
default: 0
|
||||
type: int
|
||||
min_lower:
|
||||
description:
|
||||
- Minimum number of lowercase alphabets in the string.
|
||||
- If set, overrides I(lower=false).
|
||||
default: 0
|
||||
type: int
|
||||
min_special:
|
||||
description:
|
||||
- Minimum number of special character in the string.
|
||||
default: 0
|
||||
type: int
|
||||
override_special:
|
||||
description:
|
||||
- Overide a list of special characters to use in the string.
|
||||
- If set I(min_special) should be set to a non-default value.
|
||||
type: str
|
||||
override_all:
|
||||
description:
|
||||
- Override all values of I(numbers), I(upper), I(lower), and I(special) with
|
||||
the given list of characters.
|
||||
type: str
|
||||
base64:
|
||||
description:
|
||||
- Returns base64 encoded string.
|
||||
type: bool
|
||||
default: false
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
- name: Generate random string
|
||||
ansible.builtin.debug:
|
||||
var: lookup('community.general.random_string')
|
||||
# Example result: ['DeadBeeF']
|
||||
|
||||
- name: Generate random string with length 12
|
||||
ansible.builtin.debug:
|
||||
var: lookup('community.general.random_string', length=12)
|
||||
# Example result: ['Uan0hUiX5kVG']
|
||||
|
||||
- name: Generate base64 encoded random string
|
||||
ansible.builtin.debug:
|
||||
var: lookup('community.general.random_string', base64=True)
|
||||
# Example result: ['NHZ6eWN5Qk0=']
|
||||
|
||||
- name: Generate a random string with 1 lower, 1 upper, 1 number and 1 special char (atleast)
|
||||
ansible.builtin.debug:
|
||||
var: lookup('community.general.random_string', min_lower=1, min_upper=1, min_special=1, min_numeric=1)
|
||||
# Example result: ['&Qw2|E[-']
|
||||
|
||||
- name: Generate a random string with all lower case characters
|
||||
debug:
|
||||
var: query('community.general.random_string', upper=false, numbers=false, special=false)
|
||||
# Example result: ['exolxzyz']
|
||||
|
||||
- name: Generate random hexadecimal string
|
||||
debug:
|
||||
var: query('community.general.random_string', upper=false, lower=false, override_special=hex_chars, numbers=false)
|
||||
vars:
|
||||
hex_chars: '0123456789ABCDEF'
|
||||
# Example result: ['D2A40737']
|
||||
|
||||
- name: Generate random hexadecimal string with override_all
|
||||
debug:
|
||||
var: query('community.general.random_string', override_all=hex_chars)
|
||||
vars:
|
||||
hex_chars: '0123456789ABCDEF'
|
||||
# Example result: ['D2A40737']
|
||||
"""
|
||||
|
||||
RETURN = r"""
|
||||
_raw:
|
||||
description: A one-element list containing a random string
|
||||
type: list
|
||||
elements: str
|
||||
"""
|
||||
|
||||
import base64
|
||||
import random
|
||||
import string
|
||||
|
||||
from ansible.errors import AnsibleLookupError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
@staticmethod
|
||||
def get_random(random_generator, chars, length):
|
||||
if not chars:
|
||||
raise AnsibleLookupError(
|
||||
"Available characters cannot be None, please change constraints"
|
||||
)
|
||||
return "".join(random_generator.choice(chars) for dummy in range(length))
|
||||
|
||||
@staticmethod
|
||||
def b64encode(string_value, encoding="utf-8"):
|
||||
return to_text(
|
||||
base64.b64encode(
|
||||
to_bytes(string_value, encoding=encoding, errors="surrogate_or_strict")
|
||||
)
|
||||
)
|
||||
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
number_chars = string.digits
|
||||
lower_chars = string.ascii_lowercase
|
||||
upper_chars = string.ascii_uppercase
|
||||
special_chars = string.punctuation
|
||||
random_generator = random.SystemRandom()
|
||||
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
length = self.get_option("length")
|
||||
base64_flag = self.get_option("base64")
|
||||
override_all = self.get_option("override_all")
|
||||
values = ""
|
||||
available_chars_set = ""
|
||||
|
||||
if override_all:
|
||||
# Override all the values
|
||||
available_chars_set = override_all
|
||||
else:
|
||||
upper = self.get_option("upper")
|
||||
lower = self.get_option("lower")
|
||||
numbers = self.get_option("numbers")
|
||||
special = self.get_option("special")
|
||||
override_special = self.get_option("override_special")
|
||||
|
||||
if override_special:
|
||||
special_chars = override_special
|
||||
|
||||
if upper:
|
||||
available_chars_set += upper_chars
|
||||
if lower:
|
||||
available_chars_set += lower_chars
|
||||
if numbers:
|
||||
available_chars_set += number_chars
|
||||
if special:
|
||||
available_chars_set += special_chars
|
||||
|
||||
mapping = {
|
||||
"min_numeric": number_chars,
|
||||
"min_lower": lower_chars,
|
||||
"min_upper": upper_chars,
|
||||
"min_special": special_chars,
|
||||
}
|
||||
|
||||
for m in mapping:
|
||||
if self.get_option(m):
|
||||
values += self.get_random(random_generator, mapping[m], self.get_option(m))
|
||||
|
||||
remaining_pass_len = length - len(values)
|
||||
values += self.get_random(random_generator, available_chars_set, remaining_pass_len)
|
||||
|
||||
# Get pseudo randomization
|
||||
shuffled_values = list(values)
|
||||
# Randomize the order
|
||||
random.shuffle(shuffled_values)
|
||||
|
||||
if base64_flag:
|
||||
return [self.b64encode("".join(shuffled_values))]
|
||||
|
||||
return ["".join(shuffled_values)]
|
||||
@@ -80,7 +80,7 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ import shelve
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleAssertionError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils._text import to_bytes, to_text
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
|
||||
@@ -103,6 +103,14 @@ EXAMPLES = r"""
|
||||
| items2dict(key_name='slug',
|
||||
value_name='itemValue'))['password']
|
||||
}}
|
||||
|
||||
- hosts: localhost
|
||||
vars:
|
||||
secret_password: >-
|
||||
{{ ((lookup('community.general.tss', 1) | from_json).get('items') | items2dict(key_name='slug', value_name='itemValue'))['password'] }}"
|
||||
tasks:
|
||||
- ansible.builtin.debug:
|
||||
msg: the password is {{ secret_password }}
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleOptionsError
|
||||
|
||||
@@ -48,6 +48,10 @@
|
||||
# agrees to be bound by the terms and conditions of this License
|
||||
# Agreement.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
import os
|
||||
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
try:
|
||||
from ansible.module_utils.ansible_release import __version__ as ansible_version
|
||||
|
||||
@@ -10,7 +10,7 @@ __metaclass__ = type
|
||||
import csv
|
||||
from io import BytesIO, StringIO
|
||||
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.module_utils.six import PY3
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ __metaclass__ = type
|
||||
|
||||
import json
|
||||
|
||||
from ansible.module_utils._text import to_native, to_text
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.module_utils.urls import fetch_url
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ from distutils.version import StrictVersion
|
||||
|
||||
from ansible.module_utils.basic import missing_required_lib
|
||||
from ansible.module_utils.urls import fetch_url
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
try:
|
||||
from urllib import quote_plus # Python 2.X
|
||||
|
||||
@@ -21,7 +21,7 @@ except ImportError:
|
||||
|
||||
from ansible.module_utils.basic import (AnsibleModule, env_fallback,
|
||||
missing_required_lib)
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
|
||||
class HwcModuleException(Exception):
|
||||
|
||||
@@ -9,7 +9,7 @@ __metaclass__ = type
|
||||
import traceback
|
||||
|
||||
from functools import wraps
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.module_utils.basic import missing_required_lib
|
||||
|
||||
PYXCLI_INSTALLED = True
|
||||
|
||||
@@ -33,9 +33,9 @@ import json
|
||||
import traceback
|
||||
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlencode
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlencode, quote
|
||||
from ansible.module_utils.six.moves.urllib.error import HTTPError
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
|
||||
URL_REALMS = "{url}/admin/realms"
|
||||
URL_REALM = "{url}/admin/realms/{realm}"
|
||||
@@ -43,14 +43,36 @@ URL_REALM = "{url}/admin/realms/{realm}"
|
||||
URL_TOKEN = "{url}/realms/{realm}/protocol/openid-connect/token"
|
||||
URL_CLIENT = "{url}/admin/realms/{realm}/clients/{id}"
|
||||
URL_CLIENTS = "{url}/admin/realms/{realm}/clients"
|
||||
|
||||
URL_CLIENT_ROLES = "{url}/admin/realms/{realm}/clients/{id}/roles"
|
||||
URL_CLIENT_ROLE = "{url}/admin/realms/{realm}/clients/{id}/roles/{name}"
|
||||
URL_CLIENT_ROLE_COMPOSITES = "{url}/admin/realms/{realm}/clients/{id}/roles/{name}/composites"
|
||||
|
||||
URL_REALM_ROLES = "{url}/admin/realms/{realm}/roles"
|
||||
URL_REALM_ROLE = "{url}/admin/realms/{realm}/roles/{name}"
|
||||
URL_REALM_ROLE_COMPOSITES = "{url}/admin/realms/{realm}/roles/{name}/composites"
|
||||
|
||||
URL_CLIENTTEMPLATE = "{url}/admin/realms/{realm}/client-templates/{id}"
|
||||
URL_CLIENTTEMPLATES = "{url}/admin/realms/{realm}/client-templates"
|
||||
URL_GROUPS = "{url}/admin/realms/{realm}/groups"
|
||||
URL_GROUP = "{url}/admin/realms/{realm}/groups/{groupid}"
|
||||
|
||||
URL_CLIENTSCOPES = "{url}/admin/realms/{realm}/client-scopes"
|
||||
URL_CLIENTSCOPE = "{url}/admin/realms/{realm}/client-scopes/{id}"
|
||||
URL_CLIENTSCOPE_PROTOCOLMAPPERS = "{url}/admin/realms/{realm}/client-scopes/{id}/protocol-mappers/models"
|
||||
URL_CLIENTSCOPE_PROTOCOLMAPPER = "{url}/admin/realms/{realm}/client-scopes/{id}/protocol-mappers/models/{mapper_id}"
|
||||
|
||||
URL_AUTHENTICATION_FLOWS = "{url}/admin/realms/{realm}/authentication/flows"
|
||||
URL_AUTHENTICATION_FLOW = "{url}/admin/realms/{realm}/authentication/flows/{id}"
|
||||
URL_AUTHENTICATION_FLOW_COPY = "{url}/admin/realms/{realm}/authentication/flows/{copyfrom}/copy"
|
||||
URL_AUTHENTICATION_FLOW_EXECUTIONS = "{url}/admin/realms/{realm}/authentication/flows/{flowalias}/executions"
|
||||
URL_AUTHENTICATION_FLOW_EXECUTIONS_EXECUTION = "{url}/admin/realms/{realm}/authentication/flows/{flowalias}/executions/execution"
|
||||
URL_AUTHENTICATION_FLOW_EXECUTIONS_FLOW = "{url}/admin/realms/{realm}/authentication/flows/{flowalias}/executions/flow"
|
||||
URL_AUTHENTICATION_EXECUTION_CONFIG = "{url}/admin/realms/{realm}/authentication/executions/{id}/config"
|
||||
URL_AUTHENTICATION_EXECUTION_RAISE_PRIORITY = "{url}/admin/realms/{realm}/authentication/executions/{id}/raise-priority"
|
||||
URL_AUTHENTICATION_EXECUTION_LOWER_PRIORITY = "{url}/admin/realms/{realm}/authentication/executions/{id}/lower-priority"
|
||||
URL_AUTHENTICATION_CONFIG = "{url}/admin/realms/{realm}/authentication/config/{id}"
|
||||
|
||||
|
||||
def keycloak_argument_spec():
|
||||
"""
|
||||
@@ -132,6 +154,59 @@ def get_token(module_params):
|
||||
}
|
||||
|
||||
|
||||
def is_struct_included(struct1, struct2, exclude=None):
|
||||
"""
|
||||
This function compare if the first parameter structure is included in the second.
|
||||
The function use every elements of struct1 and validates they are present in the struct2 structure.
|
||||
The two structure does not need to be equals for that function to return true.
|
||||
Each elements are compared recursively.
|
||||
:param struct1:
|
||||
type:
|
||||
dict for the initial call, can be dict, list, bool, int or str for recursive calls
|
||||
description:
|
||||
reference structure
|
||||
:param struct2:
|
||||
type:
|
||||
dict for the initial call, can be dict, list, bool, int or str for recursive calls
|
||||
description:
|
||||
structure to compare with first parameter.
|
||||
:param exclude:
|
||||
type:
|
||||
list
|
||||
description:
|
||||
Key to exclude from the comparison.
|
||||
default: None
|
||||
:return:
|
||||
type:
|
||||
bool
|
||||
description:
|
||||
Return True if all element of dict 1 are present in dict 2, return false otherwise.
|
||||
"""
|
||||
if isinstance(struct1, list) and isinstance(struct2, list):
|
||||
for item1 in struct1:
|
||||
if isinstance(item1, (list, dict)):
|
||||
for item2 in struct2:
|
||||
if not is_struct_included(item1, item2, exclude):
|
||||
return False
|
||||
else:
|
||||
if item1 not in struct2:
|
||||
return False
|
||||
return True
|
||||
elif isinstance(struct1, dict) and isinstance(struct2, dict):
|
||||
try:
|
||||
for key in struct1:
|
||||
if not (exclude and key in exclude):
|
||||
if not is_struct_included(struct1[key], struct2[key], exclude):
|
||||
return False
|
||||
return True
|
||||
except KeyError:
|
||||
return False
|
||||
elif isinstance(struct1, bool) and isinstance(struct2, bool):
|
||||
return struct1 == struct2
|
||||
else:
|
||||
return to_text(struct1, 'utf-8') == to_text(struct2, 'utf-8')
|
||||
|
||||
|
||||
class KeycloakAPI(object):
|
||||
""" Keycloak API access; Keycloak uses OAuth 2.0 to protect its API, an access token for which
|
||||
is obtained through OpenID connect
|
||||
@@ -441,6 +516,239 @@ class KeycloakAPI(object):
|
||||
self.module.fail_json(msg='Could not delete client template %s in realm %s: %s'
|
||||
% (id, realm, str(e)))
|
||||
|
||||
def get_clientscopes(self, realm="master"):
|
||||
""" Fetch the name and ID of all clientscopes on the Keycloak server.
|
||||
|
||||
To fetch the full data of the group, make a subsequent call to
|
||||
get_clientscope_by_clientscopeid, passing in the ID of the group you wish to return.
|
||||
|
||||
:param realm: Realm in which the clientscope resides; default 'master'.
|
||||
:return The clientscopes of this realm (default "master")
|
||||
"""
|
||||
clientscopes_url = URL_CLIENTSCOPES.format(url=self.baseurl, realm=realm)
|
||||
try:
|
||||
return json.loads(to_native(open_url(clientscopes_url, method="GET", headers=self.restheaders,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Could not fetch list of clientscopes in realm %s: %s"
|
||||
% (realm, str(e)))
|
||||
|
||||
def get_clientscope_by_clientscopeid(self, cid, realm="master"):
|
||||
""" Fetch a keycloak clientscope from the provided realm using the clientscope's unique ID.
|
||||
|
||||
If the clientscope does not exist, None is returned.
|
||||
|
||||
gid is a UUID provided by the Keycloak API
|
||||
:param cid: UUID of the clientscope to be returned
|
||||
:param realm: Realm in which the clientscope resides; default 'master'.
|
||||
"""
|
||||
clientscope_url = URL_CLIENTSCOPE.format(url=self.baseurl, realm=realm, id=cid)
|
||||
try:
|
||||
return json.loads(to_native(open_url(clientscope_url, method="GET", headers=self.restheaders,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
|
||||
except HTTPError as e:
|
||||
if e.code == 404:
|
||||
return None
|
||||
else:
|
||||
self.module.fail_json(msg="Could not fetch clientscope %s in realm %s: %s"
|
||||
% (cid, realm, str(e)))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Could not clientscope group %s in realm %s: %s"
|
||||
% (cid, realm, str(e)))
|
||||
|
||||
def get_clientscope_by_name(self, name, realm="master"):
|
||||
""" Fetch a keycloak clientscope within a realm based on its name.
|
||||
|
||||
The Keycloak API does not allow filtering of the clientscopes resource by name.
|
||||
As a result, this method first retrieves the entire list of clientscopes - name and ID -
|
||||
then performs a second query to fetch the group.
|
||||
|
||||
If the clientscope does not exist, None is returned.
|
||||
:param name: Name of the clientscope to fetch.
|
||||
:param realm: Realm in which the clientscope resides; default 'master'
|
||||
"""
|
||||
try:
|
||||
all_clientscopes = self.get_clientscopes(realm=realm)
|
||||
|
||||
for clientscope in all_clientscopes:
|
||||
if clientscope['name'] == name:
|
||||
return self.get_clientscope_by_clientscopeid(clientscope['id'], realm=realm)
|
||||
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Could not fetch clientscope %s in realm %s: %s"
|
||||
% (name, realm, str(e)))
|
||||
|
||||
def create_clientscope(self, clientscoperep, realm="master"):
|
||||
""" Create a Keycloak clientscope.
|
||||
|
||||
:param clientscoperep: a ClientScopeRepresentation of the clientscope to be created. Must contain at minimum the field name.
|
||||
:return: HTTPResponse object on success
|
||||
"""
|
||||
clientscopes_url = URL_CLIENTSCOPES.format(url=self.baseurl, realm=realm)
|
||||
try:
|
||||
return open_url(clientscopes_url, method='POST', headers=self.restheaders,
|
||||
data=json.dumps(clientscoperep), validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Could not create clientscope %s in realm %s: %s"
|
||||
% (clientscoperep['name'], realm, str(e)))
|
||||
|
||||
def update_clientscope(self, clientscoperep, realm="master"):
|
||||
""" Update an existing clientscope.
|
||||
|
||||
:param grouprep: A GroupRepresentation of the updated group.
|
||||
:return HTTPResponse object on success
|
||||
"""
|
||||
clientscope_url = URL_CLIENTSCOPE.format(url=self.baseurl, realm=realm, id=clientscoperep['id'])
|
||||
|
||||
try:
|
||||
return open_url(clientscope_url, method='PUT', headers=self.restheaders,
|
||||
data=json.dumps(clientscoperep), validate_certs=self.validate_certs)
|
||||
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not update clientscope %s in realm %s: %s'
|
||||
% (clientscoperep['name'], realm, str(e)))
|
||||
|
||||
def delete_clientscope(self, name=None, cid=None, realm="master"):
|
||||
""" Delete a clientscope. One of name or cid must be provided.
|
||||
|
||||
Providing the clientscope ID is preferred as it avoids a second lookup to
|
||||
convert a clientscope name to an ID.
|
||||
|
||||
:param name: The name of the clientscope. A lookup will be performed to retrieve the clientscope ID.
|
||||
:param cid: The ID of the clientscope (preferred to name).
|
||||
:param realm: The realm in which this group resides, default "master".
|
||||
"""
|
||||
|
||||
if cid is None and name is None:
|
||||
# prefer an exception since this is almost certainly a programming error in the module itself.
|
||||
raise Exception("Unable to delete group - one of group ID or name must be provided.")
|
||||
|
||||
# only lookup the name if cid isn't provided.
|
||||
# in the case that both are provided, prefer the ID, since it's one
|
||||
# less lookup.
|
||||
if cid is None and name is not None:
|
||||
for clientscope in self.get_clientscopes(realm=realm):
|
||||
if clientscope['name'] == name:
|
||||
cid = clientscope['id']
|
||||
break
|
||||
|
||||
# if the group doesn't exist - no problem, nothing to delete.
|
||||
if cid is None:
|
||||
return None
|
||||
|
||||
# should have a good cid by here.
|
||||
clientscope_url = URL_CLIENTSCOPE.format(realm=realm, id=cid, url=self.baseurl)
|
||||
try:
|
||||
return open_url(clientscope_url, method='DELETE', headers=self.restheaders,
|
||||
validate_certs=self.validate_certs)
|
||||
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Unable to delete clientscope %s: %s" % (cid, str(e)))
|
||||
|
||||
def get_clientscope_protocolmappers(self, cid, realm="master"):
|
||||
""" Fetch the name and ID of all clientscopes on the Keycloak server.
|
||||
|
||||
To fetch the full data of the group, make a subsequent call to
|
||||
get_clientscope_by_clientscopeid, passing in the ID of the group you wish to return.
|
||||
|
||||
:param cid: id of clientscope (not name).
|
||||
:param realm: Realm in which the clientscope resides; default 'master'.
|
||||
:return The protocolmappers of this realm (default "master")
|
||||
"""
|
||||
protocolmappers_url = URL_CLIENTSCOPE_PROTOCOLMAPPERS.format(id=cid, url=self.baseurl, realm=realm)
|
||||
try:
|
||||
return json.loads(to_native(open_url(protocolmappers_url, method="GET", headers=self.restheaders,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Could not fetch list of protocolmappers in realm %s: %s"
|
||||
% (realm, str(e)))
|
||||
|
||||
def get_clientscope_protocolmapper_by_protocolmapperid(self, pid, cid, realm="master"):
|
||||
""" Fetch a keycloak clientscope from the provided realm using the clientscope's unique ID.
|
||||
|
||||
If the clientscope does not exist, None is returned.
|
||||
|
||||
gid is a UUID provided by the Keycloak API
|
||||
|
||||
:param cid: UUID of the protocolmapper to be returned
|
||||
:param cid: UUID of the clientscope to be returned
|
||||
:param realm: Realm in which the clientscope resides; default 'master'.
|
||||
"""
|
||||
protocolmapper_url = URL_CLIENTSCOPE_PROTOCOLMAPPER.format(url=self.baseurl, realm=realm, id=cid, mapper_id=pid)
|
||||
try:
|
||||
return json.loads(to_native(open_url(protocolmapper_url, method="GET", headers=self.restheaders,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
|
||||
except HTTPError as e:
|
||||
if e.code == 404:
|
||||
return None
|
||||
else:
|
||||
self.module.fail_json(msg="Could not fetch protocolmapper %s in realm %s: %s"
|
||||
% (pid, realm, str(e)))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Could not fetch protocolmapper %s in realm %s: %s"
|
||||
% (cid, realm, str(e)))
|
||||
|
||||
def get_clientscope_protocolmapper_by_name(self, cid, name, realm="master"):
|
||||
""" Fetch a keycloak clientscope within a realm based on its name.
|
||||
|
||||
The Keycloak API does not allow filtering of the clientscopes resource by name.
|
||||
As a result, this method first retrieves the entire list of clientscopes - name and ID -
|
||||
then performs a second query to fetch the group.
|
||||
|
||||
If the clientscope does not exist, None is returned.
|
||||
:param cid: Id of the clientscope (not name).
|
||||
:param name: Name of the protocolmapper to fetch.
|
||||
:param realm: Realm in which the clientscope resides; default 'master'
|
||||
"""
|
||||
try:
|
||||
all_protocolmappers = self.get_clientscope_protocolmappers(cid, realm=realm)
|
||||
|
||||
for protocolmapper in all_protocolmappers:
|
||||
if protocolmapper['name'] == name:
|
||||
return self.get_clientscope_protocolmapper_by_protocolmapperid(protocolmapper['id'], cid, realm=realm)
|
||||
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Could not fetch protocolmapper %s in realm %s: %s"
|
||||
% (name, realm, str(e)))
|
||||
|
||||
def create_clientscope_protocolmapper(self, cid, mapper_rep, realm="master"):
|
||||
""" Create a Keycloak clientscope protocolmapper.
|
||||
|
||||
:param cid: Id of the clientscope.
|
||||
:param mapper_rep: a ProtocolMapperRepresentation of the protocolmapper to be created. Must contain at minimum the field name.
|
||||
:return: HTTPResponse object on success
|
||||
"""
|
||||
protocolmappers_url = URL_CLIENTSCOPE_PROTOCOLMAPPERS.format(url=self.baseurl, id=cid, realm=realm)
|
||||
try:
|
||||
return open_url(protocolmappers_url, method='POST', headers=self.restheaders,
|
||||
data=json.dumps(mapper_rep), validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Could not create protocolmapper %s in realm %s: %s"
|
||||
% (mapper_rep['name'], realm, str(e)))
|
||||
|
||||
def update_clientscope_protocolmappers(self, cid, mapper_rep, realm="master"):
|
||||
""" Update an existing clientscope.
|
||||
|
||||
:param cid: Id of the clientscope.
|
||||
:param mapper_rep: A ProtocolMapperRepresentation of the updated protocolmapper.
|
||||
:return HTTPResponse object on success
|
||||
"""
|
||||
protocolmapper_url = URL_CLIENTSCOPE_PROTOCOLMAPPER.format(url=self.baseurl, realm=realm, id=cid, mapper_id=mapper_rep['id'])
|
||||
|
||||
try:
|
||||
return open_url(protocolmapper_url, method='PUT', headers=self.restheaders,
|
||||
data=json.dumps(mapper_rep), validate_certs=self.validate_certs)
|
||||
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not update protocolmappers for clientscope %s in realm %s: %s'
|
||||
% (mapper_rep, realm, str(e)))
|
||||
|
||||
def get_groups(self, realm="master"):
|
||||
""" Fetch the name and ID of all groups on the Keycloak server.
|
||||
|
||||
@@ -568,6 +876,444 @@ class KeycloakAPI(object):
|
||||
try:
|
||||
return open_url(group_url, method='DELETE', headers=self.restheaders,
|
||||
validate_certs=self.validate_certs)
|
||||
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Unable to delete group %s: %s" % (groupid, str(e)))
|
||||
|
||||
def get_realm_roles(self, realm='master'):
|
||||
""" Obtains role representations for roles in a realm
|
||||
|
||||
:param realm: realm to be queried
|
||||
:return: list of dicts of role representations
|
||||
"""
|
||||
rolelist_url = URL_REALM_ROLES.format(url=self.baseurl, realm=realm)
|
||||
try:
|
||||
return json.loads(to_native(open_url(rolelist_url, method='GET', headers=self.restheaders,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
except ValueError as e:
|
||||
self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of roles for realm %s: %s'
|
||||
% (realm, str(e)))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not obtain list of roles for realm %s: %s'
|
||||
% (realm, str(e)))
|
||||
|
||||
def get_realm_role(self, name, realm='master'):
|
||||
""" Fetch a keycloak role from the provided realm using the role's name.
|
||||
|
||||
If the role does not exist, None is returned.
|
||||
:param name: Name of the role to fetch.
|
||||
:param realm: Realm in which the role resides; default 'master'.
|
||||
"""
|
||||
role_url = URL_REALM_ROLE.format(url=self.baseurl, realm=realm, name=name)
|
||||
try:
|
||||
return json.loads(to_native(open_url(role_url, method="GET", headers=self.restheaders,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
except HTTPError as e:
|
||||
if e.code == 404:
|
||||
return None
|
||||
else:
|
||||
self.module.fail_json(msg='Could not fetch role %s in realm %s: %s'
|
||||
% (name, realm, str(e)))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not fetch role %s in realm %s: %s'
|
||||
% (name, realm, str(e)))
|
||||
|
||||
def create_realm_role(self, rolerep, realm='master'):
|
||||
""" Create a Keycloak realm role.
|
||||
|
||||
:param rolerep: a RoleRepresentation of the role to be created. Must contain at minimum the field name.
|
||||
:return: HTTPResponse object on success
|
||||
"""
|
||||
roles_url = URL_REALM_ROLES.format(url=self.baseurl, realm=realm)
|
||||
try:
|
||||
return open_url(roles_url, method='POST', headers=self.restheaders,
|
||||
data=json.dumps(rolerep), validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not create role %s in realm %s: %s'
|
||||
% (rolerep['name'], realm, str(e)))
|
||||
|
||||
def update_realm_role(self, rolerep, realm='master'):
|
||||
""" Update an existing realm role.
|
||||
|
||||
:param rolerep: A RoleRepresentation of the updated role.
|
||||
:return HTTPResponse object on success
|
||||
"""
|
||||
role_url = URL_REALM_ROLE.format(url=self.baseurl, realm=realm, name=rolerep['name'])
|
||||
try:
|
||||
return open_url(role_url, method='PUT', headers=self.restheaders,
|
||||
data=json.dumps(rolerep), validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not update role %s in realm %s: %s'
|
||||
% (rolerep['name'], realm, str(e)))
|
||||
|
||||
def delete_realm_role(self, name, realm='master'):
|
||||
""" Delete a realm role.
|
||||
|
||||
:param name: The name of the role.
|
||||
:param realm: The realm in which this role resides, default "master".
|
||||
"""
|
||||
role_url = URL_REALM_ROLE.format(url=self.baseurl, realm=realm, name=name)
|
||||
try:
|
||||
return open_url(role_url, method='DELETE', headers=self.restheaders,
|
||||
validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Unable to delete role %s in realm %s: %s'
|
||||
% (name, realm, str(e)))
|
||||
|
||||
def get_client_roles(self, clientid, realm='master'):
|
||||
""" Obtains role representations for client roles in a specific client
|
||||
|
||||
:param clientid: Client id to be queried
|
||||
:param realm: Realm to be queried
|
||||
:return: List of dicts of role representations
|
||||
"""
|
||||
cid = self.get_client_id(clientid, realm=realm)
|
||||
if cid is None:
|
||||
self.module.fail_json(msg='Could not find client %s in realm %s'
|
||||
% (clientid, realm))
|
||||
rolelist_url = URL_CLIENT_ROLES.format(url=self.baseurl, realm=realm, id=cid)
|
||||
try:
|
||||
return json.loads(to_native(open_url(rolelist_url, method='GET', headers=self.restheaders,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
except ValueError as e:
|
||||
self.module.fail_json(msg='API returned incorrect JSON when trying to obtain list of roles for client %s in realm %s: %s'
|
||||
% (clientid, realm, str(e)))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not obtain list of roles for client %s in realm %s: %s'
|
||||
% (clientid, realm, str(e)))
|
||||
|
||||
def get_client_role(self, name, clientid, realm='master'):
|
||||
""" Fetch a keycloak client role from the provided realm using the role's name.
|
||||
|
||||
:param name: Name of the role to fetch.
|
||||
:param clientid: Client id for the client role
|
||||
:param realm: Realm in which the role resides
|
||||
:return: Dict of role representation
|
||||
If the role does not exist, None is returned.
|
||||
"""
|
||||
cid = self.get_client_id(clientid, realm=realm)
|
||||
if cid is None:
|
||||
self.module.fail_json(msg='Could not find client %s in realm %s'
|
||||
% (clientid, realm))
|
||||
role_url = URL_CLIENT_ROLE.format(url=self.baseurl, realm=realm, id=cid, name=name)
|
||||
try:
|
||||
return json.loads(to_native(open_url(role_url, method="GET", headers=self.restheaders,
|
||||
validate_certs=self.validate_certs).read()))
|
||||
except HTTPError as e:
|
||||
if e.code == 404:
|
||||
return None
|
||||
else:
|
||||
self.module.fail_json(msg='Could not fetch role %s in client %s of realm %s: %s'
|
||||
% (name, clientid, realm, str(e)))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not fetch role %s for client %s in realm %s: %s'
|
||||
% (name, clientid, realm, str(e)))
|
||||
|
||||
def create_client_role(self, rolerep, clientid, realm='master'):
|
||||
""" Create a Keycloak client role.
|
||||
|
||||
:param rolerep: a RoleRepresentation of the role to be created. Must contain at minimum the field name.
|
||||
:param clientid: Client id for the client role
|
||||
:param realm: Realm in which the role resides
|
||||
:return: HTTPResponse object on success
|
||||
"""
|
||||
cid = self.get_client_id(clientid, realm=realm)
|
||||
if cid is None:
|
||||
self.module.fail_json(msg='Could not find client %s in realm %s'
|
||||
% (clientid, realm))
|
||||
roles_url = URL_CLIENT_ROLES.format(url=self.baseurl, realm=realm, id=cid)
|
||||
try:
|
||||
return open_url(roles_url, method='POST', headers=self.restheaders,
|
||||
data=json.dumps(rolerep), validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not create role %s for client %s in realm %s: %s'
|
||||
% (rolerep['name'], clientid, realm, str(e)))
|
||||
|
||||
def update_client_role(self, rolerep, clientid, realm="master"):
|
||||
""" Update an existing client role.
|
||||
|
||||
:param rolerep: A RoleRepresentation of the updated role.
|
||||
:param clientid: Client id for the client role
|
||||
:param realm: Realm in which the role resides
|
||||
:return HTTPResponse object on success
|
||||
"""
|
||||
cid = self.get_client_id(clientid, realm=realm)
|
||||
if cid is None:
|
||||
self.module.fail_json(msg='Could not find client %s in realm %s'
|
||||
% (clientid, realm))
|
||||
role_url = URL_CLIENT_ROLE.format(url=self.baseurl, realm=realm, id=cid, name=rolerep['name'])
|
||||
try:
|
||||
return open_url(role_url, method='PUT', headers=self.restheaders,
|
||||
data=json.dumps(rolerep), validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not update role %s for client %s in realm %s: %s'
|
||||
% (rolerep['name'], clientid, realm, str(e)))
|
||||
|
||||
def delete_client_role(self, name, clientid, realm="master"):
|
||||
""" Delete a role. One of name or roleid must be provided.
|
||||
|
||||
:param name: The name of the role.
|
||||
:param clientid: Client id for the client role
|
||||
:param realm: Realm in which the role resides
|
||||
"""
|
||||
cid = self.get_client_id(clientid, realm=realm)
|
||||
if cid is None:
|
||||
self.module.fail_json(msg='Could not find client %s in realm %s'
|
||||
% (clientid, realm))
|
||||
role_url = URL_CLIENT_ROLE.format(url=self.baseurl, realm=realm, id=cid, name=name)
|
||||
try:
|
||||
return open_url(role_url, method='DELETE', headers=self.restheaders,
|
||||
validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Unable to delete role %s for client %s in realm %s: %s'
|
||||
% (name, clientid, realm, str(e)))
|
||||
|
||||
def get_authentication_flow_by_alias(self, alias, realm='master'):
|
||||
"""
|
||||
Get an authentication flow by it's alias
|
||||
:param alias: Alias of the authentication flow to get.
|
||||
:param realm: Realm.
|
||||
:return: Authentication flow representation.
|
||||
"""
|
||||
try:
|
||||
authentication_flow = {}
|
||||
# Check if the authentication flow exists on the Keycloak serveraders
|
||||
authentications = json.load(open_url(URL_AUTHENTICATION_FLOWS.format(url=self.baseurl, realm=realm), method='GET', headers=self.restheaders))
|
||||
for authentication in authentications:
|
||||
if authentication["alias"] == alias:
|
||||
authentication_flow = authentication
|
||||
break
|
||||
return authentication_flow
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Unable get authentication flow %s: %s" % (alias, str(e)))
|
||||
|
||||
def delete_authentication_flow_by_id(self, id, realm='master'):
|
||||
"""
|
||||
Delete an authentication flow from Keycloak
|
||||
:param id: id of authentication flow to be deleted
|
||||
:param realm: realm of client to be deleted
|
||||
:return: HTTPResponse object on success
|
||||
"""
|
||||
flow_url = URL_AUTHENTICATION_FLOW.format(url=self.baseurl, realm=realm, id=id)
|
||||
|
||||
try:
|
||||
return open_url(flow_url, method='DELETE', headers=self.restheaders,
|
||||
validate_certs=self.validate_certs)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not delete authentication flow %s in realm %s: %s'
|
||||
% (id, realm, str(e)))
|
||||
|
||||
def copy_auth_flow(self, config, realm='master'):
|
||||
"""
|
||||
Create a new authentication flow from a copy of another.
|
||||
:param config: Representation of the authentication flow to create.
|
||||
:param realm: Realm.
|
||||
:return: Representation of the new authentication flow.
|
||||
"""
|
||||
try:
|
||||
new_name = dict(
|
||||
newName=config["alias"]
|
||||
)
|
||||
open_url(
|
||||
URL_AUTHENTICATION_FLOW_COPY.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
copyfrom=quote(config["copyFrom"])),
|
||||
method='POST',
|
||||
headers=self.restheaders,
|
||||
data=json.dumps(new_name))
|
||||
flow_list = json.load(
|
||||
open_url(
|
||||
URL_AUTHENTICATION_FLOWS.format(url=self.baseurl,
|
||||
realm=realm),
|
||||
method='GET',
|
||||
headers=self.restheaders))
|
||||
for flow in flow_list:
|
||||
if flow["alias"] == config["alias"]:
|
||||
return flow
|
||||
return None
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not copy authentication flow %s in realm %s: %s'
|
||||
% (config["alias"], realm, str(e)))
|
||||
|
||||
def create_empty_auth_flow(self, config, realm='master'):
|
||||
"""
|
||||
Create a new empty authentication flow.
|
||||
:param config: Representation of the authentication flow to create.
|
||||
:param realm: Realm.
|
||||
:return: Representation of the new authentication flow.
|
||||
"""
|
||||
try:
|
||||
new_flow = dict(
|
||||
alias=config["alias"],
|
||||
providerId=config["providerId"],
|
||||
description=config["description"],
|
||||
topLevel=True
|
||||
)
|
||||
open_url(
|
||||
URL_AUTHENTICATION_FLOWS.format(
|
||||
url=self.baseurl,
|
||||
realm=realm),
|
||||
method='POST',
|
||||
headers=self.restheaders,
|
||||
data=json.dumps(new_flow))
|
||||
flow_list = json.load(
|
||||
open_url(
|
||||
URL_AUTHENTICATION_FLOWS.format(
|
||||
url=self.baseurl,
|
||||
realm=realm),
|
||||
method='GET',
|
||||
headers=self.restheaders))
|
||||
for flow in flow_list:
|
||||
if flow["alias"] == config["alias"]:
|
||||
return flow
|
||||
return None
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not create empty authentication flow %s in realm %s: %s'
|
||||
% (config["alias"], realm, str(e)))
|
||||
|
||||
def update_authentication_executions(self, flowAlias, updatedExec, realm='master'):
|
||||
""" Update authentication executions
|
||||
|
||||
:param flowAlias: name of the parent flow
|
||||
:param updatedExec: JSON containing updated execution
|
||||
:return: HTTPResponse object on success
|
||||
"""
|
||||
try:
|
||||
open_url(
|
||||
URL_AUTHENTICATION_FLOW_EXECUTIONS.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
flowalias=quote(flowAlias)),
|
||||
method='PUT',
|
||||
headers=self.restheaders,
|
||||
data=json.dumps(updatedExec))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Unable to update executions %s: %s" % (updatedExec, str(e)))
|
||||
|
||||
def add_authenticationConfig_to_execution(self, executionId, authenticationConfig, realm='master'):
|
||||
""" Add autenticatorConfig to the execution
|
||||
|
||||
:param executionId: id of execution
|
||||
:param authenticationConfig: config to add to the execution
|
||||
:return: HTTPResponse object on success
|
||||
"""
|
||||
try:
|
||||
open_url(
|
||||
URL_AUTHENTICATION_EXECUTION_CONFIG.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
id=executionId),
|
||||
method='POST',
|
||||
headers=self.restheaders,
|
||||
data=json.dumps(authenticationConfig))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Unable to add authenticationConfig %s: %s" % (executionId, str(e)))
|
||||
|
||||
def create_subflow(self, subflowName, flowAlias, realm='master'):
|
||||
""" Create new sublow on the flow
|
||||
|
||||
:param subflowName: name of the subflow to create
|
||||
:param flowAlias: name of the parent flow
|
||||
:return: HTTPResponse object on success
|
||||
"""
|
||||
try:
|
||||
newSubFlow = {}
|
||||
newSubFlow["alias"] = subflowName
|
||||
newSubFlow["provider"] = "registration-page-form"
|
||||
newSubFlow["type"] = "basic-flow"
|
||||
open_url(
|
||||
URL_AUTHENTICATION_FLOW_EXECUTIONS_FLOW.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
flowalias=quote(flowAlias)),
|
||||
method='POST',
|
||||
headers=self.restheaders,
|
||||
data=json.dumps(newSubFlow))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Unable to create new subflow %s: %s" % (subflowName, str(e)))
|
||||
|
||||
def create_execution(self, execution, flowAlias, realm='master'):
|
||||
""" Create new execution on the flow
|
||||
|
||||
:param execution: name of execution to create
|
||||
:param flowAlias: name of the parent flow
|
||||
:return: HTTPResponse object on success
|
||||
"""
|
||||
try:
|
||||
newExec = {}
|
||||
newExec["provider"] = execution["providerId"]
|
||||
newExec["requirement"] = execution["requirement"]
|
||||
open_url(
|
||||
URL_AUTHENTICATION_FLOW_EXECUTIONS_EXECUTION.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
flowalias=quote(flowAlias)),
|
||||
method='POST',
|
||||
headers=self.restheaders,
|
||||
data=json.dumps(newExec))
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Unable to create new execution %s: %s" % (execution["provider"], str(e)))
|
||||
|
||||
def change_execution_priority(self, executionId, diff, realm='master'):
|
||||
""" Raise or lower execution priority of diff time
|
||||
|
||||
:param executionId: id of execution to lower priority
|
||||
:param realm: realm the client is in
|
||||
:param diff: Integer number, raise of diff time if positive lower of diff time if negative
|
||||
:return: HTTPResponse object on success
|
||||
"""
|
||||
try:
|
||||
if diff > 0:
|
||||
for i in range(diff):
|
||||
open_url(
|
||||
URL_AUTHENTICATION_EXECUTION_RAISE_PRIORITY.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
id=executionId),
|
||||
method='POST',
|
||||
headers=self.restheaders)
|
||||
elif diff < 0:
|
||||
for i in range(-diff):
|
||||
open_url(
|
||||
URL_AUTHENTICATION_EXECUTION_LOWER_PRIORITY.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
id=executionId),
|
||||
method='POST',
|
||||
headers=self.restheaders)
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg="Unable to change execution priority %s: %s" % (executionId, str(e)))
|
||||
|
||||
def get_executions_representation(self, config, realm='master'):
|
||||
"""
|
||||
Get a representation of the executions for an authentication flow.
|
||||
:param config: Representation of the authentication flow
|
||||
:param realm: Realm
|
||||
:return: Representation of the executions
|
||||
"""
|
||||
try:
|
||||
# Get executions created
|
||||
executions = json.load(
|
||||
open_url(
|
||||
URL_AUTHENTICATION_FLOW_EXECUTIONS.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
flowalias=quote(config["alias"])),
|
||||
method='GET',
|
||||
headers=self.restheaders))
|
||||
for execution in executions:
|
||||
if "authenticationConfig" in execution:
|
||||
execConfigId = execution["authenticationConfig"]
|
||||
execConfig = json.load(
|
||||
open_url(
|
||||
URL_AUTHENTICATION_CONFIG.format(
|
||||
url=self.baseurl,
|
||||
realm=realm,
|
||||
id=execConfigId),
|
||||
method='GET',
|
||||
headers=self.restheaders))
|
||||
execution["authenticationConfig"] = execConfig
|
||||
return executions
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Could not get executions for authentication flow %s in realm %s: %s'
|
||||
% (config["alias"], realm, str(e)))
|
||||
|
||||
@@ -18,7 +18,7 @@ import socket
|
||||
import uuid
|
||||
|
||||
import re
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.six import PY3
|
||||
from ansible.module_utils.six.moves.urllib.parse import quote
|
||||
from ansible.module_utils.urls import fetch_url, HAS_GSSAPI
|
||||
|
||||
@@ -10,7 +10,7 @@ from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
import traceback
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
try:
|
||||
import ldap
|
||||
|
||||
@@ -20,7 +20,7 @@ import ssl
|
||||
from ansible.module_utils.urls import generic_urlparse
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlparse
|
||||
from ansible.module_utils.six.moves import http_client
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
# httplib/http.client connection using unix domain socket
|
||||
HTTPConnection = http_client.HTTPConnection
|
||||
|
||||
@@ -59,4 +59,7 @@ class ModuleHelperBase(object):
|
||||
self.__init_module__()
|
||||
self.__run__()
|
||||
self.__quit_module__()
|
||||
self.module.exit_json(changed=self.has_changed(), **self.output)
|
||||
output = self.output
|
||||
if 'failed' not in output:
|
||||
output['failed'] = False
|
||||
self.module.exit_json(changed=self.has_changed(), **output)
|
||||
|
||||
@@ -152,16 +152,36 @@ class CmdMixin(object):
|
||||
def process_command_output(self, rc, out, err):
|
||||
return rc, out, err
|
||||
|
||||
def run_command(self, extra_params=None, params=None, *args, **kwargs):
|
||||
def run_command(self,
|
||||
extra_params=None,
|
||||
params=None,
|
||||
process_output=None,
|
||||
publish_rc=True,
|
||||
publish_out=True,
|
||||
publish_err=True,
|
||||
*args, **kwargs):
|
||||
self.vars.cmd_args = self._calculate_args(extra_params, params)
|
||||
options = dict(self.run_command_fixed_options)
|
||||
env_update = dict(options.get('environ_update', {}))
|
||||
options['check_rc'] = options.get('check_rc', self.check_rc)
|
||||
options.update(kwargs)
|
||||
env_update = dict(options.get('environ_update', {}))
|
||||
if self.force_lang:
|
||||
env_update.update({'LANGUAGE': self.force_lang})
|
||||
env_update.update({
|
||||
'LANGUAGE': self.force_lang,
|
||||
'LC_ALL': self.force_lang,
|
||||
})
|
||||
self.update_output(force_lang=self.force_lang)
|
||||
options['environ_update'] = env_update
|
||||
options.update(kwargs)
|
||||
rc, out, err = self.module.run_command(self.vars.cmd_args, *args, **options)
|
||||
self.update_output(rc=rc, stdout=out, stderr=err)
|
||||
return self.process_command_output(rc, out, err)
|
||||
if publish_rc:
|
||||
self.update_output(rc=rc)
|
||||
if publish_out:
|
||||
self.update_output(stdout=out)
|
||||
if publish_err:
|
||||
self.update_output(stderr=err)
|
||||
if process_output is None:
|
||||
_process = self.process_command_output
|
||||
else:
|
||||
_process = process_output
|
||||
|
||||
return _process(rc, out, err)
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
import copy
|
||||
|
||||
|
||||
class VarMeta(object):
|
||||
NOTHING = object()
|
||||
@@ -30,11 +32,11 @@ class VarMeta(object):
|
||||
if fact is not None:
|
||||
self.fact = fact
|
||||
if initial_value is not self.NOTHING:
|
||||
self.initial_value = initial_value
|
||||
self.initial_value = copy.deepcopy(initial_value)
|
||||
|
||||
def set_value(self, value):
|
||||
if not self.init:
|
||||
self.initial_value = value
|
||||
self.initial_value = copy.deepcopy(value)
|
||||
self.init = True
|
||||
self.value = value
|
||||
return self
|
||||
|
||||
@@ -14,9 +14,9 @@ __metaclass__ = type
|
||||
|
||||
import os
|
||||
from functools import partial
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.module_utils.six import iteritems
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils.basic import env_fallback
|
||||
from ansible.module_utils.common.validation import check_type_dict
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ except ImportError:
|
||||
|
||||
from ansible.module_utils import six
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.module_utils.common._collections_compat import Mapping
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ except ImportError:
|
||||
HAS_OCI_PY_SDK = False
|
||||
|
||||
|
||||
from ansible.module_utils._text import to_bytes
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.module_utils.six import iteritems
|
||||
|
||||
__version__ = "1.6.0-dev"
|
||||
|
||||
@@ -6,8 +6,8 @@ __metaclass__ = type
|
||||
|
||||
import json
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils.six.moves import http_client
|
||||
from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
|
||||
from ansible.module_utils.six.moves.urllib.parse import urlparse
|
||||
@@ -1582,13 +1582,14 @@ class RedfishUtils(object):
|
||||
|
||||
boot = data[key]
|
||||
|
||||
annotation = 'BootSourceOverrideTarget@Redfish.AllowableValues'
|
||||
if annotation in boot:
|
||||
allowable_values = boot[annotation]
|
||||
if isinstance(allowable_values, list) and bootdevice not in allowable_values:
|
||||
return {'ret': False,
|
||||
'msg': "Boot device %s not in list of allowable values (%s)" %
|
||||
(bootdevice, allowable_values)}
|
||||
if override_enabled != 'Disabled':
|
||||
annotation = 'BootSourceOverrideTarget@Redfish.AllowableValues'
|
||||
if annotation in boot:
|
||||
allowable_values = boot[annotation]
|
||||
if isinstance(allowable_values, list) and bootdevice not in allowable_values:
|
||||
return {'ret': False,
|
||||
'msg': "Boot device %s not in list of allowable values (%s)" %
|
||||
(bootdevice, allowable_values)}
|
||||
|
||||
# read existing values
|
||||
cur_enabled = boot.get('BootSourceOverrideEnabled')
|
||||
|
||||
@@ -7,7 +7,7 @@ __metaclass__ = type
|
||||
|
||||
import json
|
||||
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils.basic import env_fallback
|
||||
from ansible.module_utils.urls import fetch_url, basic_auth_header
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user