mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-29 09:56:53 +00:00
Compare commits
67 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
908a9836c0 | ||
|
|
adea41d773 | ||
|
|
2dd964cab3 | ||
|
|
410101a116 | ||
|
|
ec5dd70f8b | ||
|
|
3473cb504e | ||
|
|
c329192e82 | ||
|
|
7fe5e5f02c | ||
|
|
4482b04463 | ||
|
|
05608ea658 | ||
|
|
a43132ba93 | ||
|
|
33c5e17762 | ||
|
|
42efe21600 | ||
|
|
fc02a7c74e | ||
|
|
ef16e7ea4e | ||
|
|
dce0a65ffe | ||
|
|
ab2c0992e4 | ||
|
|
2c6b2e344b | ||
|
|
d87b91e279 | ||
|
|
505cde7e6b | ||
|
|
0fcf81dd18 | ||
|
|
e62a256724 | ||
|
|
ee7ba1a691 | ||
|
|
ee428ccd64 | ||
|
|
580f8b30a8 | ||
|
|
7204798479 | ||
|
|
59b1329337 | ||
|
|
e3eaeda81a | ||
|
|
b7e68f5b2d | ||
|
|
dcb38bece0 | ||
|
|
c82c375aef | ||
|
|
d5f6889f51 | ||
|
|
ff8e67840f | ||
|
|
c1d142f543 | ||
|
|
cb9be1349a | ||
|
|
59086813c1 | ||
|
|
12319f4a82 | ||
|
|
04b29342d2 | ||
|
|
0d23fa7a49 | ||
|
|
dbec1ebf7a | ||
|
|
feefec42df | ||
|
|
a60cba237f | ||
|
|
76d011ed4b | ||
|
|
3ba00d5a07 | ||
|
|
8eb3003894 | ||
|
|
89158ce325 | ||
|
|
7f8d77b9f3 | ||
|
|
3cf90b3e36 | ||
|
|
189b737c50 | ||
|
|
c4bd7c2b7b | ||
|
|
ea427d3c82 | ||
|
|
bc011c60e6 | ||
|
|
a76537b24f | ||
|
|
327777a1da | ||
|
|
d8ee97c7e9 | ||
|
|
52ffc4eb7c | ||
|
|
be8c05bf65 | ||
|
|
bf284a01cb | ||
|
|
c1f9aeaac8 | ||
|
|
1a5ad80589 | ||
|
|
f2e2157bcc | ||
|
|
20d2488f0f | ||
|
|
7d75bb3d7e | ||
|
|
c5f8719fe9 | ||
|
|
79cfc48dd5 | ||
|
|
e0489d738a | ||
|
|
3e1cbbb617 |
@@ -173,8 +173,8 @@ stages:
|
||||
targets:
|
||||
- name: Alpine 3.18
|
||||
test: alpine/3.18
|
||||
# - name: Fedora 38
|
||||
# test: fedora/38
|
||||
# - name: Fedora 39
|
||||
# test: fedora/39
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu/22.04
|
||||
groups:
|
||||
@@ -189,8 +189,8 @@ stages:
|
||||
targets:
|
||||
- name: macOS 13.2
|
||||
test: macos/13.2
|
||||
- name: RHEL 9.2
|
||||
test: rhel/9.2
|
||||
- name: RHEL 9.3
|
||||
test: rhel/9.3
|
||||
- name: FreeBSD 13.2
|
||||
test: freebsd/13.2
|
||||
groups:
|
||||
@@ -207,6 +207,8 @@ stages:
|
||||
targets:
|
||||
#- name: macOS 13.2
|
||||
# test: macos/13.2
|
||||
- name: RHEL 9.2
|
||||
test: rhel/9.2
|
||||
- name: RHEL 8.8
|
||||
test: rhel/8.8
|
||||
#- name: FreeBSD 13.2
|
||||
@@ -265,8 +267,8 @@ stages:
|
||||
parameters:
|
||||
testFormat: devel/linux/{0}
|
||||
targets:
|
||||
- name: Fedora 38
|
||||
test: fedora38
|
||||
- name: Fedora 39
|
||||
test: fedora39
|
||||
- name: Ubuntu 20.04
|
||||
test: ubuntu2004
|
||||
- name: Ubuntu 22.04
|
||||
@@ -285,6 +287,8 @@ stages:
|
||||
parameters:
|
||||
testFormat: 2.16/linux/{0}
|
||||
targets:
|
||||
- name: Fedora 38
|
||||
test: fedora38
|
||||
- name: openSUSE 15
|
||||
test: opensuse15
|
||||
groups:
|
||||
@@ -315,8 +319,8 @@ stages:
|
||||
parameters:
|
||||
testFormat: 2.14/linux/{0}
|
||||
targets:
|
||||
- name: Fedora 36
|
||||
test: fedora36
|
||||
- name: Alpine 3
|
||||
test: alpine3
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
|
||||
10
.github/BOTMETA.yml
vendored
10
.github/BOTMETA.yml
vendored
@@ -119,7 +119,7 @@ files:
|
||||
labels: hwc
|
||||
maintainers: $team_huawei
|
||||
$doc_fragments/nomad.py:
|
||||
maintainers: chris93111
|
||||
maintainers: chris93111 apecnascimento
|
||||
$doc_fragments/xenserver.py:
|
||||
labels: xenserver
|
||||
maintainers: bvitnik
|
||||
@@ -526,6 +526,8 @@ files:
|
||||
maintainers: russoz
|
||||
$modules/git_config.py:
|
||||
maintainers: djmattyg007 mgedmin
|
||||
$modules/git_config_info.py:
|
||||
maintainers: guenhter
|
||||
$modules/github_:
|
||||
maintainers: stpierre
|
||||
$modules/github_deploy_key.py:
|
||||
@@ -547,6 +549,8 @@ files:
|
||||
ignore: dj-wasabi
|
||||
$modules/gitlab_branch.py:
|
||||
maintainers: paytroff
|
||||
$modules/gitlab_issue.py:
|
||||
maintainers: zvaraondrej
|
||||
$modules/gitlab_merge_request.py:
|
||||
maintainers: zvaraondrej
|
||||
$modules/gitlab_project_variable.py:
|
||||
@@ -870,7 +874,7 @@ files:
|
||||
$modules/nmcli.py:
|
||||
maintainers: alcamie101
|
||||
$modules/nomad_:
|
||||
maintainers: chris93111
|
||||
maintainers: chris93111 apecnascimento
|
||||
$modules/nosh.py:
|
||||
maintainers: tacatac
|
||||
$modules/npm.py:
|
||||
@@ -1399,6 +1403,8 @@ files:
|
||||
maintainers: $team_suse
|
||||
$tests/a_module.py:
|
||||
maintainers: felixfontein
|
||||
$tests/fqdn_valid.py:
|
||||
maintainers: vbotka
|
||||
#########################
|
||||
tests/:
|
||||
labels: tests
|
||||
|
||||
@@ -6,6 +6,89 @@ Community General Release Notes
|
||||
|
||||
This changelog describes changes after version 7.0.0.
|
||||
|
||||
v8.1.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix and feature release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- bitwarden lookup plugin - when looking for items using an item ID, the item is now accessed directly with ``bw get item`` instead of searching through all items. This doubles the lookup speed (https://github.com/ansible-collections/community.general/pull/7468).
|
||||
- elastic callback plugin - close elastic client to not leak resources (https://github.com/ansible-collections/community.general/pull/7517).
|
||||
- git_config - allow multiple git configs for the same name with the new ``add_mode`` option (https://github.com/ansible-collections/community.general/pull/7260).
|
||||
- git_config - the ``after`` and ``before`` fields in the ``diff`` of the return value can be a list instead of a string in case more configs with the same key are affected (https://github.com/ansible-collections/community.general/pull/7260).
|
||||
- git_config - when a value is unset, all configs with the same key are unset (https://github.com/ansible-collections/community.general/pull/7260).
|
||||
- gitlab modules - add ``ca_path`` option (https://github.com/ansible-collections/community.general/pull/7472).
|
||||
- gitlab modules - remove duplicate ``gitlab`` package check (https://github.com/ansible-collections/community.general/pull/7486).
|
||||
- gitlab_runner - add support for new runner creation workflow (https://github.com/ansible-collections/community.general/pull/7199).
|
||||
- ipa_config - adds ``passkey`` choice to ``ipauserauthtype`` parameter's choices (https://github.com/ansible-collections/community.general/pull/7588).
|
||||
- ipa_sudorule - adds options to include denied commands or command groups (https://github.com/ansible-collections/community.general/pull/7415).
|
||||
- ipa_user - adds ``idp`` and ``passkey`` choice to ``ipauserauthtype`` parameter's choices (https://github.com/ansible-collections/community.general/pull/7589).
|
||||
- irc - add ``validate_certs`` option, and rename ``use_ssl`` to ``use_tls``, while keeping ``use_ssl`` as an alias. The default value for ``validate_certs`` is ``false`` for backwards compatibility. We recommend to every user of this module to explicitly set ``use_tls=true`` and `validate_certs=true`` whenever possible, especially when communicating to IRC servers over the internet (https://github.com/ansible-collections/community.general/pull/7550).
|
||||
- keycloak module utils - expose error message from Keycloak server for HTTP errors in some specific situations (https://github.com/ansible-collections/community.general/pull/7645).
|
||||
- keycloak_user_federation - add option for ``krbPrincipalAttribute`` (https://github.com/ansible-collections/community.general/pull/7538).
|
||||
- lvol - change ``pvs`` argument type to list of strings (https://github.com/ansible-collections/community.general/pull/7676, https://github.com/ansible-collections/community.general/issues/7504).
|
||||
- lxd connection plugin - tighten the detection logic for lxd ``Instance not found`` errors, to avoid false detection on unrelated errors such as ``/usr/bin/python3: not found`` (https://github.com/ansible-collections/community.general/pull/7521).
|
||||
- netcup_dns - adds support for record types ``OPENPGPKEY``, ``SMIMEA``, and ``SSHFP`` (https://github.com/ansible-collections/community.general/pull/7489).
|
||||
- nmcli - add support for new connection type ``loopback`` (https://github.com/ansible-collections/community.general/issues/6572).
|
||||
- nmcli - allow for ``infiniband`` slaves of ``bond`` interface types (https://github.com/ansible-collections/community.general/pull/7569).
|
||||
- nmcli - allow for the setting of ``MTU`` for ``infiniband`` and ``bond`` interface types (https://github.com/ansible-collections/community.general/pull/7499).
|
||||
- onepassword lookup plugin - support 1Password Connect with the opv2 client by setting the connect_host and connect_token parameters (https://github.com/ansible-collections/community.general/pull/7116).
|
||||
- onepassword_raw lookup plugin - support 1Password Connect with the opv2 client by setting the connect_host and connect_token parameters (https://github.com/ansible-collections/community.general/pull/7116)
|
||||
- passwordstore - adds ``timestamp`` and ``preserve`` parameters to modify the stored password format (https://github.com/ansible-collections/community.general/pull/7426).
|
||||
- proxmox - adds ``template`` value to the ``state`` parameter, allowing conversion of container to a template (https://github.com/ansible-collections/community.general/pull/7143).
|
||||
- proxmox - adds ``update`` parameter, allowing update of an already existing containers configuration (https://github.com/ansible-collections/community.general/pull/7540).
|
||||
- proxmox inventory plugin - adds an option to exclude nodes from the dynamic inventory generation. The new setting is optional, not using this option will behave as usual (https://github.com/ansible-collections/community.general/issues/6714, https://github.com/ansible-collections/community.general/pull/7461).
|
||||
- proxmox_disk - add ability to manipulate CD-ROM drive (https://github.com/ansible-collections/community.general/pull/7495).
|
||||
- proxmox_kvm - adds ``template`` value to the ``state`` parameter, allowing conversion of a VM to a template (https://github.com/ansible-collections/community.general/pull/7143).
|
||||
- proxmox_kvm - support the ``hookscript`` parameter (https://github.com/ansible-collections/community.general/issues/7600).
|
||||
- proxmox_ostype - it is now possible to specify the ``ostype`` when creating an LXC container (https://github.com/ansible-collections/community.general/pull/7462).
|
||||
- proxmox_vm_info - add ability to retrieve configuration info (https://github.com/ansible-collections/community.general/pull/7485).
|
||||
- redfish_info - adding the ``BootProgress`` property when getting ``Systems`` info (https://github.com/ansible-collections/community.general/pull/7626).
|
||||
- ssh_config - adds ``controlmaster``, ``controlpath`` and ``controlpersist`` parameters (https://github.com/ansible-collections/community.general/pull/7456).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- apt-rpm - the module did not upgrade packages if a newer version exists. Now the package will be reinstalled if the candidate is newer than the installed version (https://github.com/ansible-collections/community.general/issues/7414).
|
||||
- cloudflare_dns - fix Cloudflare lookup of SHFP records (https://github.com/ansible-collections/community.general/issues/7652).
|
||||
- interface_files - also consider ``address_family`` when changing ``option=method`` (https://github.com/ansible-collections/community.general/issues/7610, https://github.com/ansible-collections/community.general/pull/7612).
|
||||
- irc - replace ``ssl.wrap_socket`` that was removed from Python 3.12 with code for creating a proper SSL context (https://github.com/ansible-collections/community.general/pull/7542).
|
||||
- keycloak_* - fix Keycloak API client to quote ``/`` properly (https://github.com/ansible-collections/community.general/pull/7641).
|
||||
- keycloak_authz_permission - resource payload variable for scope-based permission was constructed as a string, when it needs to be a list, even for a single item (https://github.com/ansible-collections/community.general/issues/7151).
|
||||
- log_entries callback plugin - replace ``ssl.wrap_socket`` that was removed from Python 3.12 with code for creating a proper SSL context (https://github.com/ansible-collections/community.general/pull/7542).
|
||||
- lvol - test for output messages in both ``stdout`` and ``stderr`` (https://github.com/ansible-collections/community.general/pull/7601, https://github.com/ansible-collections/community.general/issues/7182).
|
||||
- onepassword lookup plugin - field and section titles are now case insensitive when using op CLI version two or later. This matches the behavior of version one (https://github.com/ansible-collections/community.general/pull/7564).
|
||||
- redhat_subscription - use the D-Bus registration on RHEL 7 only on 7.4 and
|
||||
greater; older versions of RHEL 7 do not have it
|
||||
(https://github.com/ansible-collections/community.general/issues/7622,
|
||||
https://github.com/ansible-collections/community.general/pull/7624).
|
||||
- terraform - fix multiline string handling in complex variables (https://github.com/ansible-collections/community.general/pull/7535).
|
||||
|
||||
New Plugins
|
||||
-----------
|
||||
|
||||
Lookup
|
||||
~~~~~~
|
||||
|
||||
- onepassword_doc - Fetch documents stored in 1Password
|
||||
|
||||
Test
|
||||
~~~~
|
||||
|
||||
- fqdn_valid - Validates fully-qualified domain names against RFC 1123
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- git_config_info - Read git configuration
|
||||
- gitlab_issue - Create, update, or delete GitLab issues
|
||||
- nomad_token - Manage Nomad ACL tokens
|
||||
|
||||
v8.0.2
|
||||
======
|
||||
|
||||
|
||||
@@ -823,3 +823,161 @@ releases:
|
||||
- 7506-pipx-pipargs.yml
|
||||
- 8.0.2.yml
|
||||
release_date: '2023-11-13'
|
||||
8.1.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- apt-rpm - the module did not upgrade packages if a newer version exists. Now
|
||||
the package will be reinstalled if the candidate is newer than the installed
|
||||
version (https://github.com/ansible-collections/community.general/issues/7414).
|
||||
- cloudflare_dns - fix Cloudflare lookup of SHFP records (https://github.com/ansible-collections/community.general/issues/7652).
|
||||
- interface_files - also consider ``address_family`` when changing ``option=method``
|
||||
(https://github.com/ansible-collections/community.general/issues/7610, https://github.com/ansible-collections/community.general/pull/7612).
|
||||
- irc - replace ``ssl.wrap_socket`` that was removed from Python 3.12 with code
|
||||
for creating a proper SSL context (https://github.com/ansible-collections/community.general/pull/7542).
|
||||
- keycloak_* - fix Keycloak API client to quote ``/`` properly (https://github.com/ansible-collections/community.general/pull/7641).
|
||||
- keycloak_authz_permission - resource payload variable for scope-based permission
|
||||
was constructed as a string, when it needs to be a list, even for a single
|
||||
item (https://github.com/ansible-collections/community.general/issues/7151).
|
||||
- log_entries callback plugin - replace ``ssl.wrap_socket`` that was removed
|
||||
from Python 3.12 with code for creating a proper SSL context (https://github.com/ansible-collections/community.general/pull/7542).
|
||||
- lvol - test for output messages in both ``stdout`` and ``stderr`` (https://github.com/ansible-collections/community.general/pull/7601,
|
||||
https://github.com/ansible-collections/community.general/issues/7182).
|
||||
- onepassword lookup plugin - field and section titles are now case insensitive
|
||||
when using op CLI version two or later. This matches the behavior of version
|
||||
one (https://github.com/ansible-collections/community.general/pull/7564).
|
||||
- 'redhat_subscription - use the D-Bus registration on RHEL 7 only on 7.4 and
|
||||
|
||||
greater; older versions of RHEL 7 do not have it
|
||||
|
||||
(https://github.com/ansible-collections/community.general/issues/7622,
|
||||
|
||||
https://github.com/ansible-collections/community.general/pull/7624).
|
||||
|
||||
'
|
||||
- terraform - fix multiline string handling in complex variables (https://github.com/ansible-collections/community.general/pull/7535).
|
||||
minor_changes:
|
||||
- bitwarden lookup plugin - when looking for items using an item ID, the item
|
||||
is now accessed directly with ``bw get item`` instead of searching through
|
||||
all items. This doubles the lookup speed (https://github.com/ansible-collections/community.general/pull/7468).
|
||||
- elastic callback plugin - close elastic client to not leak resources (https://github.com/ansible-collections/community.general/pull/7517).
|
||||
- git_config - allow multiple git configs for the same name with the new ``add_mode``
|
||||
option (https://github.com/ansible-collections/community.general/pull/7260).
|
||||
- git_config - the ``after`` and ``before`` fields in the ``diff`` of the return
|
||||
value can be a list instead of a string in case more configs with the same
|
||||
key are affected (https://github.com/ansible-collections/community.general/pull/7260).
|
||||
- git_config - when a value is unset, all configs with the same key are unset
|
||||
(https://github.com/ansible-collections/community.general/pull/7260).
|
||||
- gitlab modules - add ``ca_path`` option (https://github.com/ansible-collections/community.general/pull/7472).
|
||||
- gitlab modules - remove duplicate ``gitlab`` package check (https://github.com/ansible-collections/community.general/pull/7486).
|
||||
- gitlab_runner - add support for new runner creation workflow (https://github.com/ansible-collections/community.general/pull/7199).
|
||||
- ipa_config - adds ``passkey`` choice to ``ipauserauthtype`` parameter's choices
|
||||
(https://github.com/ansible-collections/community.general/pull/7588).
|
||||
- ipa_sudorule - adds options to include denied commands or command groups (https://github.com/ansible-collections/community.general/pull/7415).
|
||||
- ipa_user - adds ``idp`` and ``passkey`` choice to ``ipauserauthtype`` parameter's
|
||||
choices (https://github.com/ansible-collections/community.general/pull/7589).
|
||||
- irc - add ``validate_certs`` option, and rename ``use_ssl`` to ``use_tls``,
|
||||
while keeping ``use_ssl`` as an alias. The default value for ``validate_certs``
|
||||
is ``false`` for backwards compatibility. We recommend to every user of this
|
||||
module to explicitly set ``use_tls=true`` and `validate_certs=true`` whenever
|
||||
possible, especially when communicating to IRC servers over the internet (https://github.com/ansible-collections/community.general/pull/7550).
|
||||
- keycloak module utils - expose error message from Keycloak server for HTTP
|
||||
errors in some specific situations (https://github.com/ansible-collections/community.general/pull/7645).
|
||||
- keycloak_user_federation - add option for ``krbPrincipalAttribute`` (https://github.com/ansible-collections/community.general/pull/7538).
|
||||
- lvol - change ``pvs`` argument type to list of strings (https://github.com/ansible-collections/community.general/pull/7676,
|
||||
https://github.com/ansible-collections/community.general/issues/7504).
|
||||
- 'lxd connection plugin - tighten the detection logic for lxd ``Instance not
|
||||
found`` errors, to avoid false detection on unrelated errors such as ``/usr/bin/python3:
|
||||
not found`` (https://github.com/ansible-collections/community.general/pull/7521).'
|
||||
- netcup_dns - adds support for record types ``OPENPGPKEY``, ``SMIMEA``, and
|
||||
``SSHFP`` (https://github.com/ansible-collections/community.general/pull/7489).
|
||||
- nmcli - add support for new connection type ``loopback`` (https://github.com/ansible-collections/community.general/issues/6572).
|
||||
- nmcli - allow for ``infiniband`` slaves of ``bond`` interface types (https://github.com/ansible-collections/community.general/pull/7569).
|
||||
- nmcli - allow for the setting of ``MTU`` for ``infiniband`` and ``bond`` interface
|
||||
types (https://github.com/ansible-collections/community.general/pull/7499).
|
||||
- onepassword lookup plugin - support 1Password Connect with the opv2 client
|
||||
by setting the connect_host and connect_token parameters (https://github.com/ansible-collections/community.general/pull/7116).
|
||||
- onepassword_raw lookup plugin - support 1Password Connect with the opv2 client
|
||||
by setting the connect_host and connect_token parameters (https://github.com/ansible-collections/community.general/pull/7116)
|
||||
- passwordstore - adds ``timestamp`` and ``preserve`` parameters to modify the
|
||||
stored password format (https://github.com/ansible-collections/community.general/pull/7426).
|
||||
- proxmox - adds ``template`` value to the ``state`` parameter, allowing conversion
|
||||
of container to a template (https://github.com/ansible-collections/community.general/pull/7143).
|
||||
- proxmox - adds ``update`` parameter, allowing update of an already existing
|
||||
containers configuration (https://github.com/ansible-collections/community.general/pull/7540).
|
||||
- proxmox inventory plugin - adds an option to exclude nodes from the dynamic
|
||||
inventory generation. The new setting is optional, not using this option will
|
||||
behave as usual (https://github.com/ansible-collections/community.general/issues/6714,
|
||||
https://github.com/ansible-collections/community.general/pull/7461).
|
||||
- proxmox_disk - add ability to manipulate CD-ROM drive (https://github.com/ansible-collections/community.general/pull/7495).
|
||||
- proxmox_kvm - adds ``template`` value to the ``state`` parameter, allowing
|
||||
conversion of a VM to a template (https://github.com/ansible-collections/community.general/pull/7143).
|
||||
- proxmox_kvm - support the ``hookscript`` parameter (https://github.com/ansible-collections/community.general/issues/7600).
|
||||
- proxmox_ostype - it is now possible to specify the ``ostype`` when creating
|
||||
an LXC container (https://github.com/ansible-collections/community.general/pull/7462).
|
||||
- proxmox_vm_info - add ability to retrieve configuration info (https://github.com/ansible-collections/community.general/pull/7485).
|
||||
- redfish_info - adding the ``BootProgress`` property when getting ``Systems``
|
||||
info (https://github.com/ansible-collections/community.general/pull/7626).
|
||||
- ssh_config - adds ``controlmaster``, ``controlpath`` and ``controlpersist``
|
||||
parameters (https://github.com/ansible-collections/community.general/pull/7456).
|
||||
release_summary: Regular bugfix and feature release.
|
||||
fragments:
|
||||
- 000-redhat_subscription-dbus-on-7.4-plus.yaml
|
||||
- 5588-support-1password-connect.yml
|
||||
- 6572-nmcli-add-support-loopback-type.yml
|
||||
- 7143-proxmox-template.yml
|
||||
- 7151-fix-keycloak_authz_permission-incorrect-resource-payload.yml
|
||||
- 7199-gitlab-runner-new-creation-workflow.yml
|
||||
- 7242-multi-values-for-same-name-in-git-config.yml
|
||||
- 7426-add-timestamp-and-preserve-options-for-passwordstore.yaml
|
||||
- 7456-add-ssh-control-master.yml
|
||||
- 7461-proxmox-inventory-add-exclude-nodes.yaml
|
||||
- 7462-Add-ostype-parameter-in-LXC-container-clone-of-ProxmoxVE.yaml
|
||||
- 7472-gitlab-add-ca-path-option.yml
|
||||
- 7485-proxmox_vm_info-config.yml
|
||||
- 7486-gitlab-refactor-package-check.yml
|
||||
- 7489-netcup-dns-record-types.yml
|
||||
- 7495-proxmox_disk-manipulate-cdrom.yml
|
||||
- 7499-allow-mtu-setting-on-bond-and-infiniband-interfaces.yml
|
||||
- 7517-elastic-close-client.yaml
|
||||
- 7535-terraform-fix-multiline-string-handling-in-complex-variables.yml
|
||||
- 7538-add-krbprincipalattribute-option.yml
|
||||
- 7540-proxmox-update config.yml
|
||||
- 7542-irc-logentries-ssl.yml
|
||||
- 7550-irc-use_tls-validate_certs.yml
|
||||
- 7564-onepassword-lookup-case-insensitive.yaml
|
||||
- 7569-infiniband-slave-support.yml
|
||||
- 7577-fix-apt_rpm-module.yml
|
||||
- 7588-ipa-config-new-choice-passkey-to-ipauserauthtype.yml
|
||||
- 7589-ipa-config-new-choices-idp-and-passkey-to-ipauserauthtype.yml
|
||||
- 7600-proxmox_kvm-hookscript.yml
|
||||
- 7601-lvol-fix.yml
|
||||
- 7612-interface_file-method.yml
|
||||
- 7626-redfish-info-add-boot-progress-property.yml
|
||||
- 7641-fix-keycloak-api-client-to-quote-properly.yml
|
||||
- 7645-Keycloak-print-error-msg-from-server.yml
|
||||
- 7653-fix-cloudflare-lookup.yml
|
||||
- 7676-lvol-pvs-as-list.yml
|
||||
- 8.1.0.yml
|
||||
- add-ipa-sudorule-deny-cmd.yml
|
||||
- bitwarden-lookup-performance.yaml
|
||||
- lxd-instance-not-found-avoid-false-positives.yml
|
||||
modules:
|
||||
- description: Read git configuration
|
||||
name: git_config_info
|
||||
namespace: ''
|
||||
- description: Create, update, or delete GitLab issues
|
||||
name: gitlab_issue
|
||||
namespace: ''
|
||||
- description: Manage Nomad ACL tokens
|
||||
name: nomad_token
|
||||
namespace: ''
|
||||
plugins:
|
||||
lookup:
|
||||
- description: Fetch documents stored in 1Password
|
||||
name: onepassword_doc
|
||||
namespace: null
|
||||
test:
|
||||
- description: Validates fully-qualified domain names against RFC 1123
|
||||
name: fqdn_valid
|
||||
namespace: null
|
||||
release_date: '2023-12-04'
|
||||
|
||||
12
galaxy.yml
12
galaxy.yml
@@ -5,17 +5,17 @@
|
||||
|
||||
namespace: community
|
||||
name: general
|
||||
version: 8.0.2
|
||||
version: 8.1.0
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (https://github.com/ansible)
|
||||
description: null
|
||||
description: >-
|
||||
The community.general 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.
|
||||
license_file: COPYING
|
||||
tags: [community]
|
||||
# NOTE: No dependencies are expected to be added here
|
||||
# dependencies:
|
||||
tags:
|
||||
- community
|
||||
repository: https://github.com/ansible-collections/community.general
|
||||
documentation: https://docs.ansible.com/ansible/latest/collections/community/general/
|
||||
homepage: https://github.com/ansible-collections/community.general
|
||||
issues: https://github.com/ansible-collections/community.general/issues
|
||||
#type: flatmap
|
||||
|
||||
@@ -84,6 +84,7 @@ import time
|
||||
import uuid
|
||||
|
||||
from collections import OrderedDict
|
||||
from contextlib import closing
|
||||
from os.path import basename
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleRuntimeError
|
||||
@@ -201,24 +202,25 @@ class ElasticSource(object):
|
||||
|
||||
apm_cli = self.init_apm_client(apm_server_url, apm_service_name, apm_verify_server_cert, apm_secret_token, apm_api_key)
|
||||
if apm_cli:
|
||||
instrument() # Only call this once, as early as possible.
|
||||
if traceparent:
|
||||
parent = trace_parent_from_string(traceparent)
|
||||
apm_cli.begin_transaction("Session", trace_parent=parent, start=parent_start_time)
|
||||
else:
|
||||
apm_cli.begin_transaction("Session", start=parent_start_time)
|
||||
# Populate trace metadata attributes
|
||||
if self.ansible_version is not None:
|
||||
label(ansible_version=self.ansible_version)
|
||||
label(ansible_session=self.session, ansible_host_name=self.host, ansible_host_user=self.user)
|
||||
if self.ip_address is not None:
|
||||
label(ansible_host_ip=self.ip_address)
|
||||
with closing(apm_cli):
|
||||
instrument() # Only call this once, as early as possible.
|
||||
if traceparent:
|
||||
parent = trace_parent_from_string(traceparent)
|
||||
apm_cli.begin_transaction("Session", trace_parent=parent, start=parent_start_time)
|
||||
else:
|
||||
apm_cli.begin_transaction("Session", start=parent_start_time)
|
||||
# Populate trace metadata attributes
|
||||
if self.ansible_version is not None:
|
||||
label(ansible_version=self.ansible_version)
|
||||
label(ansible_session=self.session, ansible_host_name=self.host, ansible_host_user=self.user)
|
||||
if self.ip_address is not None:
|
||||
label(ansible_host_ip=self.ip_address)
|
||||
|
||||
for task_data in tasks:
|
||||
for host_uuid, host_data in task_data.host_data.items():
|
||||
self.create_span_data(apm_cli, task_data, host_data)
|
||||
for task_data in tasks:
|
||||
for host_uuid, host_data in task_data.host_data.items():
|
||||
self.create_span_data(apm_cli, task_data, host_data)
|
||||
|
||||
apm_cli.end_transaction(name=__name__, result=status, duration=end_time - parent_start_time)
|
||||
apm_cli.end_transaction(name=__name__, result=status, duration=end_time - parent_start_time)
|
||||
|
||||
def create_span_data(self, apm_cli, task_data, host_data):
|
||||
""" create the span with the given TaskData and HostData """
|
||||
|
||||
@@ -18,7 +18,7 @@ DOCUMENTATION = '''
|
||||
requirements:
|
||||
- whitelisting in configuration
|
||||
- certifi (Python library)
|
||||
- flatdict (Python library), if you want to use the 'flatten' option
|
||||
- flatdict (Python library), if you want to use the O(flatten) option
|
||||
options:
|
||||
api:
|
||||
description: URI to the Logentries API.
|
||||
@@ -90,9 +90,9 @@ examples: >
|
||||
api = data.logentries.com
|
||||
port = 10000
|
||||
tls_port = 20000
|
||||
use_tls = no
|
||||
use_tls = true
|
||||
token = dd21fc88-f00a-43ff-b977-e3a4233c53af
|
||||
flatten = False
|
||||
flatten = false
|
||||
'''
|
||||
|
||||
import os
|
||||
@@ -196,15 +196,11 @@ else:
|
||||
class TLSSocketAppender(PlainTextSocketAppender):
|
||||
def open_connection(self):
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock = ssl.wrap_socket(
|
||||
context = ssl.create_default_context(
|
||||
purpose=ssl.Purpose.SERVER_AUTH,
|
||||
cafile=certifi.where(), )
|
||||
sock = context.wrap_socket(
|
||||
sock=sock,
|
||||
keyfile=None,
|
||||
certfile=None,
|
||||
server_side=False,
|
||||
cert_reqs=ssl.CERT_REQUIRED,
|
||||
ssl_version=getattr(
|
||||
ssl, 'PROTOCOL_TLSv1_2', ssl.PROTOCOL_TLSv1),
|
||||
ca_certs=certifi.where(),
|
||||
do_handshake_on_connect=True,
|
||||
suppress_ragged_eofs=True, )
|
||||
sock.connect((self.LE_API, self.LE_TLS_PORT))
|
||||
|
||||
@@ -18,8 +18,6 @@ DOCUMENTATION = '''
|
||||
short_description: notify using software speech synthesizer
|
||||
description:
|
||||
- This plugin will use the C(say) or C(espeak) program to "speak" about play events.
|
||||
notes:
|
||||
- In Ansible 2.8, this callback has been renamed from C(osx_say) into M(community.general.say).
|
||||
'''
|
||||
|
||||
import platform
|
||||
|
||||
@@ -18,7 +18,6 @@ DOCUMENTATION = '''
|
||||
short_description: Sends play events to a Slack channel
|
||||
description:
|
||||
- This is an ansible callback plugin that sends status updates to a Slack channel during playbook execution.
|
||||
- Before Ansible 2.4 only environment variables were available for configuring this plugin.
|
||||
options:
|
||||
webhook_url:
|
||||
required: true
|
||||
|
||||
@@ -16,7 +16,6 @@ DOCUMENTATION = '''
|
||||
short_description: sends JSON events to syslog
|
||||
description:
|
||||
- This plugin logs ansible-playbook and ansible runs to a syslog server in JSON format.
|
||||
- Before Ansible 2.9 only environment variables were available for configuration.
|
||||
options:
|
||||
server:
|
||||
description: Syslog server that will receive the event.
|
||||
|
||||
@@ -101,6 +101,8 @@ class Connection(ConnectionBase):
|
||||
self.get_option("executable"), "-c", cmd
|
||||
])
|
||||
|
||||
self._display.vvvvv(u"EXEC {0}".format(local_cmd), host=self._host())
|
||||
|
||||
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
|
||||
in_data = to_bytes(in_data, errors='surrogate_or_strict', nonstring='passthru')
|
||||
|
||||
@@ -110,10 +112,12 @@ class Connection(ConnectionBase):
|
||||
stdout = to_text(stdout)
|
||||
stderr = to_text(stderr)
|
||||
|
||||
self._display.vvvvv(u"EXEC lxc output: {0} {1}".format(stdout, stderr), host=self._host())
|
||||
|
||||
if "is not running" in stderr:
|
||||
raise AnsibleConnectionFailure("instance not running: %s" % self._host())
|
||||
|
||||
if "not found" in stderr:
|
||||
if stderr.strip() == "Error: Instance not found" or stderr.strip() == "error: not found":
|
||||
raise AnsibleConnectionFailure("instance not found: %s" % self._host())
|
||||
|
||||
return process.returncode, stdout, stderr
|
||||
|
||||
@@ -47,7 +47,7 @@ options:
|
||||
aliases: ['assume_role']
|
||||
alicloud_assume_role_arn:
|
||||
description:
|
||||
- The Alibaba Cloud role_arn. The ARN of the role to assume. If ARN is set to an empty string,
|
||||
- The Alibaba Cloud C(role_arn). The ARN of the role to assume. If ARN is set to an empty string,
|
||||
it does not perform role switching. It supports environment variable E(ALICLOUD_ASSUME_ROLE_ARN).
|
||||
ansible will execute with provided credentials.
|
||||
aliases: ['assume_role_arn']
|
||||
@@ -61,7 +61,7 @@ options:
|
||||
type: str
|
||||
alicloud_assume_role_session_expiration:
|
||||
description:
|
||||
- The Alibaba Cloud session_expiration. The time after which the established session for assuming
|
||||
- The Alibaba Cloud C(session_expiration). The time after which the established session for assuming
|
||||
role expires. Valid value range 900-3600 seconds. Default to 3600 (in this case Alicloud use own default
|
||||
value). It supports environment variable E(ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION).
|
||||
aliases: ['assume_role_session_expiration']
|
||||
@@ -85,12 +85,12 @@ options:
|
||||
description:
|
||||
- This is the path to the shared credentials file. It can also be sourced from the E(ALICLOUD_SHARED_CREDENTIALS_FILE)
|
||||
environment variable.
|
||||
- If this is not set and a profile is specified, ~/.aliyun/config.json will be used.
|
||||
- If this is not set and a profile is specified, C(~/.aliyun/config.json) will be used.
|
||||
type: str
|
||||
author:
|
||||
- "He Guimin (@xiaozhu36)"
|
||||
requirements:
|
||||
- "python >= 3.6"
|
||||
- "Python >= 3.6"
|
||||
notes:
|
||||
- If parameters are not set within the module, the following
|
||||
environment variables can be used in decreasing order of precedence
|
||||
@@ -103,7 +103,7 @@ notes:
|
||||
E(ALICLOUD_PROFILE),
|
||||
E(ALICLOUD_ASSUME_ROLE_ARN),
|
||||
E(ALICLOUD_ASSUME_ROLE_SESSION_NAME),
|
||||
E(ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION),
|
||||
E(ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION).
|
||||
- E(ALICLOUD_REGION) or E(ALICLOUD_REGION_ID) can be typically be used to specify the
|
||||
ALICLOUD region, when required, but this can also be configured in the footmark config file
|
||||
Alicloud region, when required, but this can also be configured in the footmark config file
|
||||
'''
|
||||
|
||||
@@ -14,19 +14,19 @@ class ModuleDocFragment(object):
|
||||
options:
|
||||
api_url:
|
||||
description:
|
||||
- The resolvable endpoint for the API
|
||||
- The resolvable endpoint for the API.
|
||||
type: str
|
||||
api_username:
|
||||
description:
|
||||
- The username to use for authentication against the API
|
||||
- The username to use for authentication against the API.
|
||||
type: str
|
||||
api_password:
|
||||
description:
|
||||
- The password to use for authentication against the API
|
||||
- The password to use for authentication against the API.
|
||||
type: str
|
||||
validate_certs:
|
||||
description:
|
||||
- Whether or not to validate SSL certs when supplying a https endpoint.
|
||||
- Whether or not to validate SSL certs when supplying a HTTPS endpoint.
|
||||
type: bool
|
||||
default: true
|
||||
'''
|
||||
|
||||
@@ -20,10 +20,10 @@ options:
|
||||
region:
|
||||
description:
|
||||
- The target region.
|
||||
- Regions are defined in Apache libcloud project [libcloud/common/dimensiondata.py]
|
||||
- They are also listed in U(https://libcloud.readthedocs.io/en/latest/compute/drivers/dimensiondata.html)
|
||||
- Note that the default value "na" stands for "North America".
|
||||
- The module prepends 'dd-' to the region choice.
|
||||
- Regions are defined in Apache libcloud project [libcloud/common/dimensiondata.py].
|
||||
- They are also listed in U(https://libcloud.readthedocs.io/en/latest/compute/drivers/dimensiondata.html).
|
||||
- Note that the default value C(na) stands for "North America".
|
||||
- The module prepends C(dd-) to the region choice.
|
||||
type: str
|
||||
default: na
|
||||
mcp_user:
|
||||
|
||||
@@ -34,4 +34,4 @@ options:
|
||||
- Only applicable if O(wait=true).
|
||||
type: int
|
||||
default: 2
|
||||
'''
|
||||
'''
|
||||
|
||||
@@ -39,8 +39,7 @@ options:
|
||||
default: sysadmin
|
||||
requirements:
|
||||
- An EMC VNX Storage device.
|
||||
- Ansible 2.7.
|
||||
- storops (0.5.10 or greater). Install using 'pip install storops'.
|
||||
- storops (0.5.10 or greater). Install using C(pip install storops).
|
||||
notes:
|
||||
- The modules prefixed with emc_vnx are built to support the EMC VNX storage platform.
|
||||
- The modules prefixed with C(emc_vnx) are built to support the EMC VNX storage platform.
|
||||
'''
|
||||
|
||||
@@ -29,4 +29,9 @@ options:
|
||||
- GitLab CI job token for logging in.
|
||||
type: str
|
||||
version_added: 4.2.0
|
||||
ca_path:
|
||||
description:
|
||||
- The CA certificates bundle to use to verify GitLab server certificate.
|
||||
type: str
|
||||
version_added: 8.1.0
|
||||
'''
|
||||
|
||||
@@ -19,8 +19,8 @@ options:
|
||||
required: true
|
||||
user:
|
||||
description:
|
||||
- The user name to login with (currently only user names are
|
||||
supported, and not user IDs).
|
||||
- The user name to login with.
|
||||
- Currently only user names are supported, and not user IDs.
|
||||
type: str
|
||||
required: true
|
||||
password:
|
||||
@@ -31,14 +31,13 @@ options:
|
||||
domain:
|
||||
description:
|
||||
- The name of the Domain to scope to (Identity v3).
|
||||
(currently only domain names are supported, and not domain IDs).
|
||||
- Currently only domain names are supported, and not domain IDs.
|
||||
type: str
|
||||
required: true
|
||||
project:
|
||||
description:
|
||||
- The name of the Tenant (Identity v2) or Project (Identity v3).
|
||||
(currently only project names are supported, and not
|
||||
project IDs).
|
||||
- Currently only project names are supported, and not project IDs.
|
||||
type: str
|
||||
required: true
|
||||
region:
|
||||
@@ -47,20 +46,20 @@ options:
|
||||
type: str
|
||||
id:
|
||||
description:
|
||||
- The id of resource to be managed.
|
||||
- The ID of resource to be managed.
|
||||
type: str
|
||||
notes:
|
||||
- For authentication, you can set identity_endpoint using the
|
||||
E(ANSIBLE_HWC_IDENTITY_ENDPOINT) env variable.
|
||||
E(ANSIBLE_HWC_IDENTITY_ENDPOINT) environment variable.
|
||||
- For authentication, you can set user using the
|
||||
E(ANSIBLE_HWC_USER) env variable.
|
||||
- For authentication, you can set password using the E(ANSIBLE_HWC_PASSWORD) env
|
||||
E(ANSIBLE_HWC_USER) environment variable.
|
||||
- For authentication, you can set password using the E(ANSIBLE_HWC_PASSWORD) environment
|
||||
variable.
|
||||
- For authentication, you can set domain using the E(ANSIBLE_HWC_DOMAIN) env
|
||||
- For authentication, you can set domain using the E(ANSIBLE_HWC_DOMAIN) environment
|
||||
variable.
|
||||
- For authentication, you can set project using the E(ANSIBLE_HWC_PROJECT) env
|
||||
- For authentication, you can set project using the E(ANSIBLE_HWC_PROJECT) environment
|
||||
variable.
|
||||
- For authentication, you can set region using the E(ANSIBLE_HWC_REGION) env variable.
|
||||
- For authentication, you can set region using the E(ANSIBLE_HWC_REGION) environment variable.
|
||||
- Environment variables values will only be used if the playbook values are
|
||||
not set.
|
||||
'''
|
||||
|
||||
@@ -31,8 +31,7 @@ options:
|
||||
required: true
|
||||
notes:
|
||||
- This module requires pyxcli python library.
|
||||
Use 'pip install pyxcli' in order to get pyxcli.
|
||||
Use C(pip install pyxcli) in order to get pyxcli.
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- pyxcli
|
||||
'''
|
||||
|
||||
@@ -16,32 +16,29 @@ options:
|
||||
hostname:
|
||||
description:
|
||||
- The hostname or IP address on which InfluxDB server is listening.
|
||||
- Since Ansible 2.5, defaulted to localhost.
|
||||
type: str
|
||||
default: localhost
|
||||
username:
|
||||
description:
|
||||
- Username that will be used to authenticate against InfluxDB server.
|
||||
- Alias O(login_username) added in Ansible 2.5.
|
||||
type: str
|
||||
default: root
|
||||
aliases: [ login_username ]
|
||||
password:
|
||||
description:
|
||||
- Password that will be used to authenticate against InfluxDB server.
|
||||
- Alias O(login_password) added in Ansible 2.5.
|
||||
type: str
|
||||
default: root
|
||||
aliases: [ login_password ]
|
||||
port:
|
||||
description:
|
||||
- The port on which InfluxDB server is listening
|
||||
- The port on which InfluxDB server is listening.
|
||||
type: int
|
||||
default: 8086
|
||||
path:
|
||||
description:
|
||||
- The path on which InfluxDB server is accessible
|
||||
- Only available when using python-influxdb >= 5.1.0
|
||||
- The path on which InfluxDB server is accessible.
|
||||
- Only available when using python-influxdb >= 5.1.0.
|
||||
type: str
|
||||
default: ''
|
||||
version_added: '0.2.0'
|
||||
@@ -64,7 +61,7 @@ options:
|
||||
description:
|
||||
- Number of retries client will try before aborting.
|
||||
- V(0) indicates try until success.
|
||||
- Only available when using python-influxdb >= 4.1.0
|
||||
- Only available when using python-influxdb >= 4.1.0.
|
||||
type: int
|
||||
default: 3
|
||||
use_udp:
|
||||
|
||||
@@ -18,7 +18,6 @@ options:
|
||||
- Port of FreeIPA / IPA server.
|
||||
- If the value is not specified in the task, the value of environment variable E(IPA_PORT) will be used instead.
|
||||
- If both the environment variable E(IPA_PORT) and the value are not specified in the task, then default value is set.
|
||||
- Environment variable fallback mechanism is added in Ansible 2.5.
|
||||
type: int
|
||||
default: 443
|
||||
ipa_host:
|
||||
@@ -26,9 +25,8 @@ options:
|
||||
- IP or hostname of IPA server.
|
||||
- If the value is not specified in the task, the value of environment variable E(IPA_HOST) will be used instead.
|
||||
- If both the environment variable E(IPA_HOST) and the value are not specified in the task, then DNS will be used to try to discover the FreeIPA server.
|
||||
- The relevant entry needed in FreeIPA is the 'ipa-ca' entry.
|
||||
- The relevant entry needed in FreeIPA is the C(ipa-ca) entry.
|
||||
- If neither the DNS entry, nor the environment E(IPA_HOST), nor the value are available in the task, then the default value will be used.
|
||||
- Environment variable fallback mechanism is added in Ansible 2.5.
|
||||
type: str
|
||||
default: ipa.example.com
|
||||
ipa_user:
|
||||
@@ -36,7 +34,6 @@ options:
|
||||
- Administrative account used on IPA server.
|
||||
- If the value is not specified in the task, the value of environment variable E(IPA_USER) will be used instead.
|
||||
- If both the environment variable E(IPA_USER) and the value are not specified in the task, then default value is set.
|
||||
- Environment variable fallback mechanism is added in Ansible 2.5.
|
||||
type: str
|
||||
default: admin
|
||||
ipa_pass:
|
||||
@@ -47,14 +44,12 @@ options:
|
||||
- If the environment variable E(KRB5CCNAME) is available, the module will use this kerberos credentials cache to authenticate to the FreeIPA server.
|
||||
- If the environment variable E(KRB5_CLIENT_KTNAME) is available, and E(KRB5CCNAME) is not; the module will use this kerberos keytab to authenticate.
|
||||
- If GSSAPI is not available, the usage of O(ipa_pass) is required.
|
||||
- Environment variable fallback mechanism is added in Ansible 2.5.
|
||||
type: str
|
||||
ipa_prot:
|
||||
description:
|
||||
- Protocol used by IPA server.
|
||||
- If the value is not specified in the task, the value of environment variable E(IPA_PROT) will be used instead.
|
||||
- If both the environment variable E(IPA_PROT) and the value are not specified in the task, then default value is set.
|
||||
- Environment variable fallback mechanism is added in Ansible 2.5.
|
||||
type: str
|
||||
choices: [ http, https ]
|
||||
default: https
|
||||
|
||||
@@ -69,6 +69,7 @@ options:
|
||||
type: int
|
||||
default: 10
|
||||
version_added: 4.5.0
|
||||
|
||||
http_agent:
|
||||
description:
|
||||
- Configures the HTTP User-Agent header.
|
||||
|
||||
@@ -30,7 +30,7 @@ options:
|
||||
|
||||
auth_url:
|
||||
description:
|
||||
- lxca https full web address
|
||||
- lxca HTTPS full web address.
|
||||
type: str
|
||||
required: true
|
||||
|
||||
@@ -38,7 +38,6 @@ requirements:
|
||||
- pylxca
|
||||
|
||||
notes:
|
||||
- Additional detail about pylxca can be found at U(https://github.com/lenovo/pylxca)
|
||||
- Playbooks using these modules can be found at U(https://github.com/lenovo/ansible.lenovo-lxca)
|
||||
- Check mode is not supported.
|
||||
- Additional detail about pylxca can be found at U(https://github.com/lenovo/pylxca).
|
||||
- Playbooks using these modules can be found at U(https://github.com/lenovo/ansible.lenovo-lxca).
|
||||
'''
|
||||
|
||||
75
plugins/doc_fragments/onepassword.py
Normal file
75
plugins/doc_fragments/onepassword.py
Normal file
@@ -0,0 +1,75 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023, Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
class ModuleDocFragment(object):
|
||||
DOCUMENTATION = r'''
|
||||
requirements:
|
||||
- See U(https://support.1password.com/command-line/)
|
||||
options:
|
||||
master_password:
|
||||
description: The password used to unlock the specified vault.
|
||||
aliases: ['vault_password']
|
||||
type: str
|
||||
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: '1password.com'
|
||||
type: str
|
||||
subdomain:
|
||||
description: The 1Password subdomain to authenticate against.
|
||||
type: str
|
||||
account_id:
|
||||
description: The account ID to target.
|
||||
type: str
|
||||
username:
|
||||
description: The username used to sign in.
|
||||
type: str
|
||||
secret_key:
|
||||
description: The secret key used when performing an initial sign in.
|
||||
type: str
|
||||
service_account_token:
|
||||
description:
|
||||
- The access key for a service account.
|
||||
- Only works with 1Password CLI version 2 or later.
|
||||
type: str
|
||||
vault:
|
||||
description: Vault containing the item to retrieve (case-insensitive). If absent will search all vaults.
|
||||
type: str
|
||||
connect_host:
|
||||
description: The host for 1Password Connect. Must be used in combination with O(connect_token).
|
||||
type: str
|
||||
env:
|
||||
- name: OP_CONNECT_HOST
|
||||
version_added: 8.1.0
|
||||
connect_token:
|
||||
description: The token for 1Password Connect. Must be used in combination with O(connect_host).
|
||||
type: str
|
||||
env:
|
||||
- name: OP_CONNECT_TOKEN
|
||||
version_added: 8.1.0
|
||||
'''
|
||||
|
||||
LOOKUP = r'''
|
||||
options: {}
|
||||
notes:
|
||||
- This lookup will use an existing 1Password session if one exists. If not, and you have already
|
||||
performed an initial sign in (meaning C(~/.op/config), C(~/.config/op/config) or C(~/.config/.op/config) exists), then only the
|
||||
O(master_password) is required. You may optionally specify O(subdomain) in this scenario, otherwise the last used subdomain will be used by C(op).
|
||||
- This lookup can perform an initial login by providing O(subdomain), O(username), O(secret_key), and O(master_password).
|
||||
- Can target a specific account by providing the O(account_id).
|
||||
- Due to the B(very) sensitive nature of these credentials, it is B(highly) recommended that you only pass in the minimal credentials
|
||||
needed at any given time. Also, store these credentials in an Ansible Vault using a key that is equal to or greater in strength
|
||||
to the 1Password master password.
|
||||
- This lookup stores potentially sensitive data from 1Password as Ansible facts.
|
||||
Facts are subject to caching if enabled, which means this data could be stored in clear text
|
||||
on disk or in a database.
|
||||
- Tested with C(op) version 2.7.2.
|
||||
'''
|
||||
@@ -15,7 +15,7 @@ class ModuleDocFragment(object):
|
||||
options:
|
||||
config:
|
||||
description:
|
||||
- Path to a .json configuration file containing the OneView client configuration.
|
||||
- Path to a JSON configuration file containing the OneView client configuration.
|
||||
The configuration file is optional and when used should be present in the host running the ansible commands.
|
||||
If the file path is not provided, the configuration will be loaded from environment variables.
|
||||
For links to example configuration files or how to use the environment variables verify the notes section.
|
||||
@@ -42,7 +42,7 @@ options:
|
||||
type: str
|
||||
|
||||
requirements:
|
||||
- python >= 2.7.9
|
||||
- Python >= 2.7.9
|
||||
|
||||
notes:
|
||||
- "A sample configuration file for the config parameter can be found at:
|
||||
@@ -70,11 +70,11 @@ options:
|
||||
options:
|
||||
params:
|
||||
description:
|
||||
- List of params to delimit, filter and sort the list of resources.
|
||||
- "params allowed:
|
||||
- C(start): The first item to return, using 0-based indexing.
|
||||
- C(count): The number of resources to return.
|
||||
- C(filter): A general filter/query string to narrow the list of items returned.
|
||||
- C(sort): The sort order of the returned data set."
|
||||
- List of parameters to delimit, filter and sort the list of resources.
|
||||
- "Parameter keys allowed are:"
|
||||
- "C(start): The first item to return, using 0-based indexing."
|
||||
- "C(count): The number of resources to return."
|
||||
- "C(filter): A general filter/query string to narrow the list of items returned."
|
||||
- "C(sort): The sort order of the returned data set."
|
||||
type: dict
|
||||
'''
|
||||
|
||||
@@ -20,7 +20,7 @@ options:
|
||||
aliases: [ oauth_token ]
|
||||
api_url:
|
||||
description:
|
||||
- Online API URL
|
||||
- Online API URL.
|
||||
type: str
|
||||
default: 'https://api.online.net'
|
||||
aliases: [ base_url ]
|
||||
@@ -36,7 +36,7 @@ options:
|
||||
type: bool
|
||||
default: true
|
||||
notes:
|
||||
- Also see the API documentation on U(https://console.online.net/en/api/)
|
||||
- Also see the API documentation on U(https://console.online.net/en/api/).
|
||||
- If O(api_token) is not set within the module, the following
|
||||
environment variables can be used in decreasing order of precedence
|
||||
E(ONLINE_TOKEN), E(ONLINE_API_KEY), E(ONLINE_OAUTH_TOKEN), E(ONLINE_API_TOKEN).
|
||||
|
||||
@@ -64,7 +64,7 @@ options:
|
||||
description:
|
||||
- Configures the transport connection to use when connecting to the
|
||||
remote device. The transport argument supports connectivity to the
|
||||
device over ssh, cli or REST.
|
||||
device over SSH (V(ssh)), CLI (V(cli)), or REST (V(rest)).
|
||||
required: true
|
||||
type: str
|
||||
choices: [ cli, rest, ssh ]
|
||||
|
||||
@@ -10,22 +10,21 @@ __metaclass__ = type
|
||||
class ModuleDocFragment(object):
|
||||
DOCUMENTATION = """
|
||||
requirements:
|
||||
- "python >= 2.7"
|
||||
- Python SDK for Oracle Cloud Infrastructure U(https://oracle-cloud-infrastructure-python-sdk.readthedocs.io)
|
||||
- Python SDK for Oracle Cloud Infrastructure U(https://oracle-cloud-infrastructure-python-sdk.readthedocs.io)
|
||||
notes:
|
||||
- For OCI python sdk configuration, please refer to
|
||||
U(https://oracle-cloud-infrastructure-python-sdk.readthedocs.io/en/latest/configuration.html)
|
||||
- For OCI Python SDK configuration, please refer to
|
||||
U(https://oracle-cloud-infrastructure-python-sdk.readthedocs.io/en/latest/configuration.html).
|
||||
options:
|
||||
config_file_location:
|
||||
description:
|
||||
- Path to configuration file. If not set then the value of the E(OCI_CONFIG_FILE) environment variable,
|
||||
if any, is used. Otherwise, defaults to ~/.oci/config.
|
||||
if any, is used. Otherwise, defaults to C(~/.oci/config).
|
||||
type: str
|
||||
config_profile_name:
|
||||
description:
|
||||
- The profile to load from the config file referenced by O(config_file_location). If not set, then the
|
||||
value of the E(OCI_CONFIG_PROFILE) environment variable, if any, is used. Otherwise, defaults to the
|
||||
"DEFAULT" profile in O(config_file_location).
|
||||
C(DEFAULT) profile in O(config_file_location).
|
||||
default: "DEFAULT"
|
||||
type: str
|
||||
api_user:
|
||||
@@ -70,8 +69,8 @@ class ModuleDocFragment(object):
|
||||
description:
|
||||
- OCID of your tenancy. If not set, then the value of the OCI_TENANCY variable, if any, is
|
||||
used. This option is required if the tenancy OCID is not specified through a configuration file
|
||||
(See O(config_file_location)). To get the tenancy OCID, please refer
|
||||
U(https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm)
|
||||
(See O(config_file_location)). To get the tenancy OCID, please refer to
|
||||
U(https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/apisigningkey.htm).
|
||||
type: str
|
||||
region:
|
||||
description:
|
||||
|
||||
@@ -21,7 +21,7 @@ class ModuleDocFragment(object):
|
||||
wait_until:
|
||||
description: The lifecycle state to wait for the resource to transition into when O(wait=true). By default,
|
||||
when O(wait=true), we wait for the resource to get into ACTIVE/ATTACHED/AVAILABLE/PROVISIONED/
|
||||
RUNNING applicable lifecycle state during create operation & to get into DELETED/DETACHED/
|
||||
RUNNING applicable lifecycle state during create operation and to get into DELETED/DETACHED/
|
||||
TERMINATED lifecycle state during delete operation.
|
||||
type: str
|
||||
"""
|
||||
|
||||
@@ -32,11 +32,10 @@ options:
|
||||
- FlashBlade API token for admin privileged user.
|
||||
type: str
|
||||
notes:
|
||||
- This module requires the C(purity_fb) Python library
|
||||
- This module requires the C(purity_fb) Python library.
|
||||
- You must set E(PUREFB_URL) and E(PUREFB_API) environment variables
|
||||
if O(fb_url) and O(api_token) arguments are not passed to the module directly
|
||||
if O(fb_url) and O(api_token) arguments are not passed to the module directly.
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- purity_fb >= 1.1
|
||||
'''
|
||||
|
||||
@@ -54,10 +53,9 @@ options:
|
||||
type: str
|
||||
required: true
|
||||
notes:
|
||||
- This module requires the C(purestorage) Python library
|
||||
- This module requires the C(purestorage) Python library.
|
||||
- You must set E(PUREFA_URL) and E(PUREFA_API) environment variables
|
||||
if O(fa_url) and O(api_token) arguments are not passed to the module directly
|
||||
if O(fa_url) and O(api_token) arguments are not passed to the module directly.
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- purestorage
|
||||
'''
|
||||
|
||||
@@ -43,15 +43,14 @@ options:
|
||||
type: bool
|
||||
aliases: [ verify_ssl ]
|
||||
requirements:
|
||||
- python >= 2.6
|
||||
- pyrax
|
||||
notes:
|
||||
- The following environment variables can be used, E(RAX_USERNAME),
|
||||
E(RAX_API_KEY), E(RAX_CREDS_FILE), E(RAX_CREDENTIALS), E(RAX_REGION).
|
||||
- E(RAX_CREDENTIALS) and E(RAX_CREDS_FILE) point to a credentials file
|
||||
appropriate for pyrax. See U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating)
|
||||
- E(RAX_USERNAME) and E(RAX_API_KEY) obviate the use of a credentials file
|
||||
- E(RAX_REGION) defines a Rackspace Public Cloud region (DFW, ORD, LON, ...)
|
||||
appropriate for pyrax. See U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating).
|
||||
- E(RAX_USERNAME) and E(RAX_API_KEY) obviate the use of a credentials file.
|
||||
- E(RAX_REGION) defines a Rackspace Public Cloud region (DFW, ORD, LON, ...).
|
||||
'''
|
||||
|
||||
# Documentation fragment including attributes to enable communication
|
||||
@@ -67,7 +66,7 @@ options:
|
||||
type: str
|
||||
description:
|
||||
- The URI of the authentication service.
|
||||
- If not specified will be set to U(https://identity.api.rackspacecloud.com/v2.0/)
|
||||
- If not specified will be set to U(https://identity.api.rackspacecloud.com/v2.0/).
|
||||
credentials:
|
||||
type: path
|
||||
description:
|
||||
@@ -110,13 +109,12 @@ deprecated:
|
||||
why: This module relies on the deprecated package pyrax.
|
||||
alternative: Use the Openstack modules instead.
|
||||
requirements:
|
||||
- python >= 2.6
|
||||
- pyrax
|
||||
notes:
|
||||
- The following environment variables can be used, E(RAX_USERNAME),
|
||||
E(RAX_API_KEY), E(RAX_CREDS_FILE), E(RAX_CREDENTIALS), E(RAX_REGION).
|
||||
- E(RAX_CREDENTIALS) and E(RAX_CREDS_FILE) points to a credentials file
|
||||
appropriate for pyrax. See U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating)
|
||||
- E(RAX_USERNAME) and E(RAX_API_KEY) obviate the use of a credentials file
|
||||
- E(RAX_REGION) defines a Rackspace Public Cloud region (DFW, ORD, LON, ...)
|
||||
appropriate for pyrax. See U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating).
|
||||
- E(RAX_USERNAME) and E(RAX_API_KEY) obviate the use of a credentials file.
|
||||
- E(RAX_REGION) defines a Rackspace Public Cloud region (DFW, ORD, LON, ...).
|
||||
'''
|
||||
|
||||
@@ -42,7 +42,7 @@ options:
|
||||
type: bool
|
||||
default: true
|
||||
notes:
|
||||
- Also see the API documentation on U(https://developer.scaleway.com/)
|
||||
- Also see the API documentation on U(https://developer.scaleway.com/).
|
||||
- If O(api_token) is not set within the module, the following
|
||||
environment variables can be used in decreasing order of precedence
|
||||
E(SCW_TOKEN), E(SCW_API_KEY), E(SCW_OAUTH_TOKEN) or E(SCW_API_TOKEN).
|
||||
|
||||
@@ -14,7 +14,7 @@ options:
|
||||
headers:
|
||||
description:
|
||||
- A dictionary of additional headers to be sent to POST and PUT requests.
|
||||
- Is needed for some modules
|
||||
- Is needed for some modules.
|
||||
type: dict
|
||||
required: false
|
||||
default: {}
|
||||
@@ -30,8 +30,9 @@ options:
|
||||
default: 4444
|
||||
utm_token:
|
||||
description:
|
||||
- "The token used to identify at the REST-API. See U(https://www.sophos.com/en-us/medialibrary/\
|
||||
PDFs/documentation/UTMonAWS/Sophos-UTM-RESTful-API.pdf?la=en), Chapter 2.4.2."
|
||||
- "The token used to identify at the REST-API. See
|
||||
U(https://www.sophos.com/en-us/medialibrary/PDFs/documentation/UTMonAWS/Sophos-UTM-RESTful-API.pdf?la=en),
|
||||
Chapter 2.4.2."
|
||||
type: str
|
||||
required: true
|
||||
utm_protocol:
|
||||
@@ -48,8 +49,8 @@ options:
|
||||
state:
|
||||
description:
|
||||
- The desired state of the object.
|
||||
- V(present) will create or update an object
|
||||
- V(absent) will delete an object if it was present
|
||||
- V(present) will create or update an object.
|
||||
- V(absent) will delete an object if it was present.
|
||||
type: str
|
||||
choices: [ absent, present ]
|
||||
default: present
|
||||
|
||||
@@ -30,11 +30,13 @@ options:
|
||||
user:
|
||||
description:
|
||||
- Vexata API user with administrative privileges.
|
||||
- Uses the E(VEXATA_USER) environment variable as a fallback.
|
||||
required: false
|
||||
type: str
|
||||
password:
|
||||
description:
|
||||
- Vexata API user password.
|
||||
- Uses the E(VEXATA_PASSWORD) environment variable as a fallback.
|
||||
required: false
|
||||
type: str
|
||||
validate_certs:
|
||||
@@ -48,7 +50,6 @@ options:
|
||||
requirements:
|
||||
- Vexata VX100 storage array with VXOS >= v3.5.0 on storage array
|
||||
- vexatapi >= 0.0.1
|
||||
- python >= 2.7
|
||||
- VEXATA_USER and VEXATA_PASSWORD environment variables must be set if
|
||||
- E(VEXATA_USER) and E(VEXATA_PASSWORD) environment variables must be set if
|
||||
user and password arguments are not passed to the module directly.
|
||||
'''
|
||||
|
||||
@@ -14,7 +14,6 @@ DOCUMENTATION = '''
|
||||
- Stefan Heitmüller (@morph027) <stefan.heitmueller@gmx.com>
|
||||
short_description: Ansible dynamic inventory plugin for GitLab runners.
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- python-gitlab > 1.8.0
|
||||
extends_documentation_fragment:
|
||||
- constructed
|
||||
|
||||
@@ -72,7 +72,7 @@ url: http://localhost:5665
|
||||
user: ansible
|
||||
password: secure
|
||||
host_filter: \"linux-servers\" in host.groups
|
||||
validate_certs: false
|
||||
validate_certs: false # only do this when connecting to localhost!
|
||||
inventory_attr: name
|
||||
groups:
|
||||
# simple name matching
|
||||
|
||||
@@ -12,7 +12,6 @@ DOCUMENTATION = r'''
|
||||
- Luke Murphy (@decentral1se)
|
||||
short_description: Ansible dynamic inventory plugin for Linode.
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- linode_api4 >= 2.0.0
|
||||
description:
|
||||
- Reads inventories from the Linode API v4.
|
||||
|
||||
@@ -116,6 +116,11 @@ DOCUMENTATION = '''
|
||||
- The default of this option changed from V(true) to V(false) in community.general 6.0.0.
|
||||
type: bool
|
||||
default: false
|
||||
exclude_nodes:
|
||||
description: Exclude proxmox nodes and the nodes-group from the inventory output.
|
||||
type: bool
|
||||
default: false
|
||||
version_added: 8.1.0
|
||||
filters:
|
||||
version_added: 4.6.0
|
||||
description: A list of Jinja templates that allow filtering hosts.
|
||||
@@ -166,7 +171,6 @@ plugin: community.general.proxmox
|
||||
url: http://pve.domain.com:8006
|
||||
user: ansible@pve
|
||||
password: secure
|
||||
validate_certs: false
|
||||
want_facts: true
|
||||
keyed_groups:
|
||||
# proxmox_tags_parsed is an example of a fact only returned when 'want_facts=true'
|
||||
@@ -187,10 +191,10 @@ want_proxmox_nodes_ansible_host: true
|
||||
# Note: my_inv_var demonstrates how to add a string variable to every host used by the inventory.
|
||||
# my.proxmox.yml
|
||||
plugin: community.general.proxmox
|
||||
url: http://pve.domain.com:8006
|
||||
url: http://192.168.1.2:8006
|
||||
user: ansible@pve
|
||||
password: secure
|
||||
validate_certs: false
|
||||
validate_certs: false # only do this when you trust the network!
|
||||
want_facts: true
|
||||
want_proxmox_nodes_ansible_host: false
|
||||
compose:
|
||||
@@ -565,9 +569,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
|
||||
for group in default_groups:
|
||||
self.inventory.add_group(self._group('all_%s' % (group)))
|
||||
|
||||
nodes_group = self._group('nodes')
|
||||
self.inventory.add_group(nodes_group)
|
||||
if not self.exclude_nodes:
|
||||
self.inventory.add_group(nodes_group)
|
||||
|
||||
want_proxmox_nodes_ansible_host = self.get_option("want_proxmox_nodes_ansible_host")
|
||||
|
||||
@@ -577,22 +581,23 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
for node in self._get_nodes():
|
||||
if not node.get('node'):
|
||||
continue
|
||||
|
||||
self.inventory.add_host(node['node'])
|
||||
if node['type'] == 'node':
|
||||
if not self.exclude_nodes:
|
||||
self.inventory.add_host(node['node'])
|
||||
if node['type'] == 'node' and not self.exclude_nodes:
|
||||
self.inventory.add_child(nodes_group, node['node'])
|
||||
|
||||
if node['status'] == 'offline':
|
||||
continue
|
||||
|
||||
# get node IP address
|
||||
if want_proxmox_nodes_ansible_host:
|
||||
if want_proxmox_nodes_ansible_host and not self.exclude_nodes:
|
||||
ip = self._get_node_ip(node['node'])
|
||||
self.inventory.set_variable(node['node'], 'ansible_host', ip)
|
||||
|
||||
# Setting composite variables
|
||||
variables = self.inventory.get_host(node['node']).get_vars()
|
||||
self._set_composite_vars(self.get_option('compose'), variables, node['node'], strict=self.strict)
|
||||
if not self.exclude_nodes:
|
||||
variables = self.inventory.get_host(node['node']).get_vars()
|
||||
self._set_composite_vars(self.get_option('compose'), variables, node['node'], strict=self.strict)
|
||||
|
||||
# add LXC/Qemu groups for the node
|
||||
for ittype in ('lxc', 'qemu'):
|
||||
@@ -635,8 +640,8 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
|
||||
if self.get_option('qemu_extended_statuses') and not self.get_option('want_facts'):
|
||||
raise AnsibleError('You must set want_facts to True if you want to use qemu_extended_statuses.')
|
||||
|
||||
# read rest of options
|
||||
self.exclude_nodes = self.get_option('exclude_nodes')
|
||||
self.cache_key = self.get_cache_key(path)
|
||||
self.use_cache = cache and self.get_option('cache')
|
||||
self.host_filters = self.get_option('filters')
|
||||
|
||||
@@ -104,6 +104,8 @@ class Bitwarden(object):
|
||||
out, err = p.communicate(to_bytes(stdin))
|
||||
rc = p.wait()
|
||||
if rc != expected_rc:
|
||||
if len(args) > 2 and args[0] == 'get' and args[1] == 'item' and b'Not found.' in err:
|
||||
return 'null', ''
|
||||
raise BitwardenException(err)
|
||||
return to_text(out, errors='surrogate_or_strict'), to_text(err, errors='surrogate_or_strict')
|
||||
|
||||
@@ -112,7 +114,10 @@ class Bitwarden(object):
|
||||
"""
|
||||
|
||||
# Prepare set of params for Bitwarden CLI
|
||||
params = ['list', 'items', '--search', search_value]
|
||||
if search_field == 'id':
|
||||
params = ['get', 'item', search_value]
|
||||
else:
|
||||
params = ['list', 'items', '--search', search_value]
|
||||
|
||||
if collection_id:
|
||||
params.extend(['--collectionid', collection_id])
|
||||
@@ -121,7 +126,11 @@ class Bitwarden(object):
|
||||
|
||||
# This includes things that matched in different fields.
|
||||
initial_matches = AnsibleJSONDecoder().raw_decode(out)[0]
|
||||
|
||||
if search_field == 'id':
|
||||
if initial_matches is None:
|
||||
initial_matches = []
|
||||
else:
|
||||
initial_matches = [initial_matches]
|
||||
# Filter to only include results from the right field.
|
||||
return [item for item in initial_matches if item[search_field] == search_value]
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ EXAMPLES = '''
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ lookup('community.general.etcd', 'foo', 'bar', 'baz') }}"
|
||||
|
||||
- name: "since Ansible 2.5 you can set server options inline"
|
||||
- name: "you can set server options inline"
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ lookup('community.general.etcd', 'foo', version='v2', url='http://192.168.0.27:4001') }}"
|
||||
'''
|
||||
@@ -62,7 +62,7 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
_raw:
|
||||
description:
|
||||
- list of values associated with input keys
|
||||
- List of values associated with input keys.
|
||||
type: list
|
||||
elements: string
|
||||
'''
|
||||
|
||||
@@ -14,59 +14,28 @@ DOCUMENTATION = '''
|
||||
- Scott Buchanan (@scottsb)
|
||||
- Andrew Zenk (@azenk)
|
||||
- Sam Doran (@samdoran)
|
||||
requirements:
|
||||
- C(op) 1Password command line utility. See U(https://support.1password.com/command-line/)
|
||||
short_description: fetch field values from 1Password
|
||||
short_description: Fetch field values from 1Password
|
||||
description:
|
||||
- P(community.general.onepassword#lookup) wraps the C(op) command line utility to fetch specific field values from 1Password.
|
||||
requirements:
|
||||
- C(op) 1Password command line utility
|
||||
options:
|
||||
_terms:
|
||||
description: identifier(s) (UUID, name, or subdomain; case-insensitive) of item(s) to retrieve.
|
||||
description: Identifier(s) (case-insensitive UUID or name) of item(s) to retrieve.
|
||||
required: true
|
||||
field:
|
||||
description: field to return from each matching item (case-insensitive).
|
||||
default: 'password'
|
||||
master_password:
|
||||
description: The password used to unlock the specified vault.
|
||||
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.
|
||||
version_added: 3.2.0
|
||||
default: '1password.com'
|
||||
type: str
|
||||
subdomain:
|
||||
description: The 1Password subdomain to authenticate against.
|
||||
account_id:
|
||||
description: The account ID to target.
|
||||
type: str
|
||||
version_added: 7.5.0
|
||||
username:
|
||||
description: The username used to sign in.
|
||||
secret_key:
|
||||
description: The secret key used when performing an initial sign in.
|
||||
service_account_token:
|
||||
description:
|
||||
- The access key for a service account.
|
||||
- Only works with 1Password CLI version 2 or later.
|
||||
domain:
|
||||
version_added: 3.2.0
|
||||
field:
|
||||
description: Field to return from each matching item (case-insensitive).
|
||||
default: 'password'
|
||||
type: str
|
||||
service_account_token:
|
||||
version_added: 7.1.0
|
||||
vault:
|
||||
description: Vault containing the item to retrieve (case-insensitive). If absent will search all vaults.
|
||||
notes:
|
||||
- This lookup will use an existing 1Password session if one exists. If not, and you have already
|
||||
performed an initial sign in (meaning C(~/.op/config), C(~/.config/op/config) or C(~/.config/.op/config) exists), then only the
|
||||
C(master_password) is required. You may optionally specify O(subdomain) in this scenario, otherwise the last used subdomain will be used by C(op).
|
||||
- This lookup can perform an initial login by providing O(subdomain), O(username), O(secret_key), and O(master_password).
|
||||
- Can target a specific account by providing the O(account_id).
|
||||
- Due to the B(very) sensitive nature of these credentials, it is B(highly) recommended that you only pass in the minimal credentials
|
||||
needed at any given time. Also, store these credentials in an Ansible Vault using a key that is equal to or greater in strength
|
||||
to the 1Password master password.
|
||||
- This lookup stores potentially sensitive data from 1Password as Ansible facts.
|
||||
Facts are subject to caching if enabled, which means this data could be stored in clear text
|
||||
on disk or in a database.
|
||||
- Tested with C(op) version 2.7.2
|
||||
extends_documentation_fragment:
|
||||
- community.general.onepassword
|
||||
- community.general.onepassword.lookup
|
||||
'''
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -108,7 +77,7 @@ EXAMPLES = """
|
||||
|
||||
RETURN = """
|
||||
_raw:
|
||||
description: field data requested
|
||||
description: Field data requested.
|
||||
type: list
|
||||
elements: str
|
||||
"""
|
||||
@@ -119,7 +88,7 @@ import json
|
||||
import subprocess
|
||||
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.errors import AnsibleLookupError
|
||||
from ansible.errors import AnsibleLookupError, AnsibleOptionsError
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
from ansible.module_utils.six import with_metaclass
|
||||
@@ -127,6 +96,14 @@ from ansible.module_utils.six import with_metaclass
|
||||
from ansible_collections.community.general.plugins.module_utils.onepassword import OnePasswordConfig
|
||||
|
||||
|
||||
def _lower_if_possible(value):
|
||||
"""Return the lower case version value, otherwise return the value"""
|
||||
try:
|
||||
return value.lower()
|
||||
except AttributeError:
|
||||
return value
|
||||
|
||||
|
||||
class OnePassCLIBase(with_metaclass(abc.ABCMeta, object)):
|
||||
bin = "op"
|
||||
|
||||
@@ -139,6 +116,8 @@ class OnePassCLIBase(with_metaclass(abc.ABCMeta, object)):
|
||||
master_password=None,
|
||||
service_account_token=None,
|
||||
account_id=None,
|
||||
connect_host=None,
|
||||
connect_token=None,
|
||||
):
|
||||
self.subdomain = subdomain
|
||||
self.domain = domain
|
||||
@@ -147,6 +126,8 @@ class OnePassCLIBase(with_metaclass(abc.ABCMeta, object)):
|
||||
self.secret_key = secret_key
|
||||
self.service_account_token = service_account_token
|
||||
self.account_id = account_id
|
||||
self.connect_host = connect_host
|
||||
self.connect_token = connect_token
|
||||
|
||||
self._path = None
|
||||
self._version = None
|
||||
@@ -325,6 +306,10 @@ class OnePassCLIv1(OnePassCLIBase):
|
||||
return not bool(rc)
|
||||
|
||||
def full_signin(self):
|
||||
if self.connect_host or self.connect_token:
|
||||
raise AnsibleLookupError(
|
||||
"1Password Connect is not available with 1Password CLI version 1. Please use version 2 or later.")
|
||||
|
||||
if self.service_account_token:
|
||||
raise AnsibleLookupError(
|
||||
"1Password CLI version 1 does not support Service Accounts. Please use version 2 or later.")
|
||||
@@ -480,6 +465,7 @@ class OnePassCLIv2(OnePassCLIBase):
|
||||
}
|
||||
"""
|
||||
data = json.loads(data_json)
|
||||
field_name = _lower_if_possible(field_name)
|
||||
for field in data.get("fields", []):
|
||||
if section_title is None:
|
||||
# If the field name exists in the section, return that value
|
||||
@@ -488,17 +474,19 @@ class OnePassCLIv2(OnePassCLIBase):
|
||||
|
||||
# If the field name doesn't exist in the section, match on the value of "label"
|
||||
# then "id" and return "value"
|
||||
if field.get("label") == field_name:
|
||||
if field.get("label", "").lower() == field_name:
|
||||
return field.get("value", "")
|
||||
|
||||
if field.get("id") == field_name:
|
||||
if field.get("id", "").lower() == field_name:
|
||||
return field.get("value", "")
|
||||
|
||||
# Look at the section data and get an identifier. The value of 'id' is either a unique ID
|
||||
# or a human-readable string. If a 'label' field exists, prefer that since
|
||||
# it is the value visible in the 1Password UI when both 'id' and 'label' exist.
|
||||
section = field.get("section", {})
|
||||
current_section_title = section.get("label", section.get("id"))
|
||||
section_title = _lower_if_possible(section_title)
|
||||
|
||||
current_section_title = section.get("label", section.get("id", "")).lower()
|
||||
if section_title == current_section_title:
|
||||
# In the correct section. Check "label" then "id" for the desired field_name
|
||||
if field.get("label") == field_name:
|
||||
@@ -510,6 +498,9 @@ class OnePassCLIv2(OnePassCLIBase):
|
||||
return ""
|
||||
|
||||
def assert_logged_in(self):
|
||||
if self.connect_host and self.connect_token:
|
||||
return True
|
||||
|
||||
if self.service_account_token:
|
||||
args = ["whoami"]
|
||||
environment_update = {"OP_SERVICE_ACCOUNT_TOKEN": self.service_account_token}
|
||||
@@ -569,6 +560,15 @@ class OnePassCLIv2(OnePassCLIBase):
|
||||
if vault is not None:
|
||||
args += ["--vault={0}".format(vault)]
|
||||
|
||||
if self.connect_host and self.connect_token:
|
||||
if vault is None:
|
||||
raise AnsibleLookupError("'vault' is required with 1Password Connect")
|
||||
environment_update = {
|
||||
"OP_CONNECT_HOST": self.connect_host,
|
||||
"OP_CONNECT_TOKEN": self.connect_token,
|
||||
}
|
||||
return self._run(args, environment_update=environment_update)
|
||||
|
||||
if self.service_account_token:
|
||||
if vault is None:
|
||||
raise AnsibleLookupError("'vault' is required with 'service_account_token'")
|
||||
@@ -592,7 +592,7 @@ class OnePassCLIv2(OnePassCLIBase):
|
||||
|
||||
class OnePass(object):
|
||||
def __init__(self, subdomain=None, domain="1password.com", username=None, secret_key=None, master_password=None,
|
||||
service_account_token=None, account_id=None):
|
||||
service_account_token=None, account_id=None, connect_host=None, connect_token=None, cli_class=None):
|
||||
self.subdomain = subdomain
|
||||
self.domain = domain
|
||||
self.username = username
|
||||
@@ -600,19 +600,28 @@ class OnePass(object):
|
||||
self.master_password = master_password
|
||||
self.service_account_token = service_account_token
|
||||
self.account_id = account_id
|
||||
self.connect_host = connect_host
|
||||
self.connect_token = connect_token
|
||||
|
||||
self.logged_in = False
|
||||
self.token = None
|
||||
|
||||
self._config = OnePasswordConfig()
|
||||
self._cli = self._get_cli_class()
|
||||
self._cli = self._get_cli_class(cli_class)
|
||||
|
||||
if (self.connect_host or self.connect_token) and None in (self.connect_host, self.connect_token):
|
||||
raise AnsibleOptionsError("connect_host and connect_token are required together")
|
||||
|
||||
def _get_cli_class(self, cli_class=None):
|
||||
if cli_class is not None:
|
||||
return cli_class(self.subdomain, self.domain, self.username, self.secret_key, self.master_password, self.service_account_token)
|
||||
|
||||
def _get_cli_class(self):
|
||||
version = OnePassCLIBase.get_current_version()
|
||||
for cls in OnePassCLIBase.__subclasses__():
|
||||
if cls.supports_version == version.split(".")[0]:
|
||||
try:
|
||||
return cls(self.subdomain, self.domain, self.username, self.secret_key, self.master_password, self.service_account_token, self.account_id)
|
||||
return cls(self.subdomain, self.domain, self.username, self.secret_key, self.master_password, self.service_account_token,
|
||||
self.account_id, self.connect_host, self.connect_token)
|
||||
except TypeError as e:
|
||||
raise AnsibleLookupError(e)
|
||||
|
||||
@@ -677,8 +686,20 @@ class LookupModule(LookupBase):
|
||||
master_password = self.get_option("master_password")
|
||||
service_account_token = self.get_option("service_account_token")
|
||||
account_id = self.get_option("account_id")
|
||||
connect_host = self.get_option("connect_host")
|
||||
connect_token = self.get_option("connect_token")
|
||||
|
||||
op = OnePass(subdomain, domain, username, secret_key, master_password, service_account_token, account_id)
|
||||
op = OnePass(
|
||||
subdomain=subdomain,
|
||||
domain=domain,
|
||||
username=username,
|
||||
secret_key=secret_key,
|
||||
master_password=master_password,
|
||||
service_account_token=service_account_token,
|
||||
account_id=account_id,
|
||||
connect_host=connect_host,
|
||||
connect_token=connect_token,
|
||||
)
|
||||
op.assert_logged_in()
|
||||
|
||||
values = []
|
||||
|
||||
104
plugins/lookup/onepassword_doc.py
Normal file
104
plugins/lookup/onepassword_doc.py
Normal file
@@ -0,0 +1,104 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2023, Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = '''
|
||||
name: onepassword_doc
|
||||
author:
|
||||
- Sam Doran (@samdoran)
|
||||
requirements:
|
||||
- C(op) 1Password command line utility version 2 or later.
|
||||
short_description: Fetch documents stored in 1Password
|
||||
version_added: "8.1.0"
|
||||
description:
|
||||
- P(community.general.onepassword_doc#lookup) wraps C(op) command line utility to fetch one or more documents from 1Password.
|
||||
notes:
|
||||
- The document contents are a string exactly as stored in 1Password.
|
||||
- This plugin requires C(op) version 2 or later.
|
||||
|
||||
options:
|
||||
_terms:
|
||||
description: Identifier(s) (case-insensitive UUID or name) of item(s) to retrieve.
|
||||
required: true
|
||||
|
||||
extends_documentation_fragment:
|
||||
- community.general.onepassword
|
||||
- community.general.onepassword.lookup
|
||||
'''
|
||||
|
||||
EXAMPLES = """
|
||||
- name: Retrieve a private key from 1Password
|
||||
ansible.builtin.debug:
|
||||
var: lookup('community.general.onepassword_doc', 'Private key')
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
_raw:
|
||||
description: Requested document
|
||||
type: list
|
||||
elements: string
|
||||
"""
|
||||
|
||||
from ansible_collections.community.general.plugins.lookup.onepassword import OnePass, OnePassCLIv2
|
||||
from ansible.errors import AnsibleLookupError
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
|
||||
class OnePassCLIv2Doc(OnePassCLIv2):
|
||||
def get_raw(self, item_id, vault=None, token=None):
|
||||
args = ["document", "get", item_id]
|
||||
if vault is not None:
|
||||
args = [*args, "--vault={0}".format(vault)]
|
||||
|
||||
if self.service_account_token:
|
||||
if vault is None:
|
||||
raise AnsibleLookupError("'vault' is required with 'service_account_token'")
|
||||
|
||||
environment_update = {"OP_SERVICE_ACCOUNT_TOKEN": self.service_account_token}
|
||||
return self._run(args, environment_update=environment_update)
|
||||
|
||||
if token is not None:
|
||||
args = [*args, to_bytes("--session=") + token]
|
||||
|
||||
return self._run(args)
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
vault = self.get_option("vault")
|
||||
subdomain = self.get_option("subdomain")
|
||||
domain = self.get_option("domain", "1password.com")
|
||||
username = self.get_option("username")
|
||||
secret_key = self.get_option("secret_key")
|
||||
master_password = self.get_option("master_password")
|
||||
service_account_token = self.get_option("service_account_token")
|
||||
account_id = self.get_option("account_id")
|
||||
connect_host = self.get_option("connect_host")
|
||||
connect_token = self.get_option("connect_token")
|
||||
|
||||
op = OnePass(
|
||||
subdomain=subdomain,
|
||||
domain=domain,
|
||||
username=username,
|
||||
secret_key=secret_key,
|
||||
master_password=master_password,
|
||||
service_account_token=service_account_token,
|
||||
account_id=account_id,
|
||||
connect_host=connect_host,
|
||||
connect_token=connect_token,
|
||||
cli_class=OnePassCLIv2Doc,
|
||||
)
|
||||
op.assert_logged_in()
|
||||
|
||||
values = []
|
||||
for term in terms:
|
||||
values.append(op.get_raw(term, vault))
|
||||
|
||||
return values
|
||||
@@ -15,55 +15,23 @@ DOCUMENTATION = '''
|
||||
- Andrew Zenk (@azenk)
|
||||
- Sam Doran (@samdoran)
|
||||
requirements:
|
||||
- C(op) 1Password command line utility. See U(https://support.1password.com/command-line/)
|
||||
short_description: fetch an entire item from 1Password
|
||||
- C(op) 1Password command line utility
|
||||
short_description: Fetch an entire item from 1Password
|
||||
description:
|
||||
- P(community.general.onepassword_raw#lookup) wraps C(op) command line utility to fetch an entire item from 1Password.
|
||||
options:
|
||||
_terms:
|
||||
description: identifier(s) (UUID, name, or domain; case-insensitive) of item(s) to retrieve.
|
||||
description: Identifier(s) (case-insensitive UUID or name) of item(s) to retrieve.
|
||||
required: true
|
||||
master_password:
|
||||
description: The password used to unlock the specified vault.
|
||||
aliases: ['vault_password']
|
||||
section:
|
||||
description: Item section containing the field to retrieve (case-insensitive). If absent will return first match from any section.
|
||||
subdomain:
|
||||
description: The 1Password subdomain to authenticate against.
|
||||
domain:
|
||||
description: Domain of 1Password.
|
||||
version_added: 6.0.0
|
||||
default: '1password.com'
|
||||
type: str
|
||||
account_id:
|
||||
description: The account ID to target.
|
||||
type: str
|
||||
version_added: 7.5.0
|
||||
username:
|
||||
description: The username used to sign in.
|
||||
secret_key:
|
||||
description: The secret key used when performing an initial sign in.
|
||||
domain:
|
||||
version_added: 6.0.0
|
||||
service_account_token:
|
||||
description:
|
||||
- The access key for a service account.
|
||||
- Only works with 1Password CLI version 2 or later.
|
||||
type: string
|
||||
version_added: 7.1.0
|
||||
vault:
|
||||
description: Vault containing the item to retrieve (case-insensitive). If absent will search all vaults.
|
||||
notes:
|
||||
- This lookup will use an existing 1Password session if one exists. If not, and you have already
|
||||
performed an initial sign in (meaning C(~/.op/config exists)), then only the O(master_password) is required.
|
||||
You may optionally specify O(subdomain) in this scenario, otherwise the last used subdomain will be used by C(op).
|
||||
- This lookup can perform an initial login by providing O(subdomain), O(username), O(secret_key), and O(master_password).
|
||||
- Can target a specific account by providing the O(account_id).
|
||||
- Due to the B(very) sensitive nature of these credentials, it is B(highly) recommended that you only pass in the minimal credentials
|
||||
needed at any given time. Also, store these credentials in an Ansible Vault using a key that is equal to or greater in strength
|
||||
to the 1Password master password.
|
||||
- This lookup stores potentially sensitive data from 1Password as Ansible facts.
|
||||
Facts are subject to caching if enabled, which means this data could be stored in clear text
|
||||
on disk or in a database.
|
||||
- Tested with C(op) version 2.7.0
|
||||
extends_documentation_fragment:
|
||||
- community.general.onepassword
|
||||
- community.general.onepassword.lookup
|
||||
'''
|
||||
|
||||
EXAMPLES = """
|
||||
@@ -78,7 +46,7 @@ EXAMPLES = """
|
||||
|
||||
RETURN = """
|
||||
_raw:
|
||||
description: field data requested
|
||||
description: Entire item requested.
|
||||
type: list
|
||||
elements: dict
|
||||
"""
|
||||
@@ -102,8 +70,20 @@ class LookupModule(LookupBase):
|
||||
master_password = self.get_option("master_password")
|
||||
service_account_token = self.get_option("service_account_token")
|
||||
account_id = self.get_option("account_id")
|
||||
connect_host = self.get_option("connect_host")
|
||||
connect_token = self.get_option("connect_token")
|
||||
|
||||
op = OnePass(subdomain, domain, username, secret_key, master_password, service_account_token, account_id)
|
||||
op = OnePass(
|
||||
subdomain=subdomain,
|
||||
domain=domain,
|
||||
username=username,
|
||||
secret_key=secret_key,
|
||||
master_password=master_password,
|
||||
service_account_token=service_account_token,
|
||||
account_id=account_id,
|
||||
connect_host=connect_host,
|
||||
connect_token=connect_token,
|
||||
)
|
||||
op.assert_logged_in()
|
||||
|
||||
values = []
|
||||
|
||||
@@ -129,6 +129,16 @@ DOCUMENTATION = '''
|
||||
- pass
|
||||
- gopass
|
||||
version_added: 5.2.0
|
||||
timestamp:
|
||||
description: Add the password generation information to the end of the file.
|
||||
type: bool
|
||||
default: true
|
||||
version_added: 8.1.0
|
||||
preserve:
|
||||
description: Include the old (edited) password inside the pass file.
|
||||
type: bool
|
||||
default: true
|
||||
version_added: 8.1.0
|
||||
notes:
|
||||
- The lookup supports passing all options as lookup parameters since community.general 6.0.0.
|
||||
'''
|
||||
@@ -386,11 +396,13 @@ class LookupModule(LookupBase):
|
||||
# generate new password, insert old lines from current result and return new password
|
||||
newpass = self.get_newpass()
|
||||
datetime = time.strftime("%d/%m/%Y %H:%M:%S")
|
||||
msg = newpass + '\n'
|
||||
if self.passoutput[1:]:
|
||||
msg += '\n'.join(self.passoutput[1:]) + '\n'
|
||||
if self.paramvals['backup']:
|
||||
msg += "lookup_pass: old password was {0} (Updated on {1})\n".format(self.password, datetime)
|
||||
msg = newpass
|
||||
if self.paramvals['preserve'] or self.paramvals['timestamp']:
|
||||
msg += '\n'
|
||||
if self.paramvals['preserve'] and self.passoutput[1:]:
|
||||
msg += '\n'.join(self.passoutput[1:]) + '\n'
|
||||
if self.paramvals['timestamp'] and self.paramvals['backup']:
|
||||
msg += "lookup_pass: old password was {0} (Updated on {1})\n".format(self.password, datetime)
|
||||
try:
|
||||
check_output2([self.pass_cmd, 'insert', '-f', '-m', self.passname], input=msg, env=self.env)
|
||||
except (subprocess.CalledProcessError) as e:
|
||||
@@ -402,7 +414,9 @@ class LookupModule(LookupBase):
|
||||
# use pwgen to generate the password and insert values with pass -m
|
||||
newpass = self.get_newpass()
|
||||
datetime = time.strftime("%d/%m/%Y %H:%M:%S")
|
||||
msg = newpass + '\n' + "lookup_pass: First generated by ansible on {0}\n".format(datetime)
|
||||
msg = newpass
|
||||
if self.paramvals['timestamp']:
|
||||
msg += '\n' + "lookup_pass: First generated by ansible on {0}\n".format(datetime)
|
||||
try:
|
||||
check_output2([self.pass_cmd, 'insert', '-f', '-m', self.passname], input=msg, env=self.env)
|
||||
except (subprocess.CalledProcessError) as e:
|
||||
@@ -465,6 +479,8 @@ class LookupModule(LookupBase):
|
||||
'backup': self.get_option('backup'),
|
||||
'missing': self.get_option('missing'),
|
||||
'umask': self.get_option('umask'),
|
||||
'timestamp': self.get_option('timestamp'),
|
||||
'preserve': self.get_option('preserve'),
|
||||
}
|
||||
|
||||
def run(self, terms, variables, **kwargs):
|
||||
|
||||
@@ -34,6 +34,7 @@ except Exception:
|
||||
|
||||
def auth_argument_spec(spec=None):
|
||||
arg_spec = (dict(
|
||||
ca_path=dict(type='str'),
|
||||
api_token=dict(type='str', no_log=True),
|
||||
api_oauth_token=dict(type='str', no_log=True),
|
||||
api_job_token=dict(type='str', no_log=True),
|
||||
@@ -74,33 +75,36 @@ def ensure_gitlab_package(module):
|
||||
|
||||
|
||||
def gitlab_authentication(module):
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
gitlab_url = module.params['api_url']
|
||||
validate_certs = module.params['validate_certs']
|
||||
ca_path = module.params['ca_path']
|
||||
gitlab_user = module.params['api_username']
|
||||
gitlab_password = module.params['api_password']
|
||||
gitlab_token = module.params['api_token']
|
||||
gitlab_oauth_token = module.params['api_oauth_token']
|
||||
gitlab_job_token = module.params['api_job_token']
|
||||
|
||||
ensure_gitlab_package(module)
|
||||
verify = ca_path if validate_certs and ca_path else validate_certs
|
||||
|
||||
try:
|
||||
# python-gitlab library remove support for username/password authentication since 1.13.0
|
||||
# Changelog : https://github.com/python-gitlab/python-gitlab/releases/tag/v1.13.0
|
||||
# This condition allow to still support older version of the python-gitlab library
|
||||
if LooseVersion(gitlab.__version__) < LooseVersion("1.13.0"):
|
||||
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=validate_certs, email=gitlab_user, password=gitlab_password,
|
||||
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=verify, email=gitlab_user, password=gitlab_password,
|
||||
private_token=gitlab_token, api_version=4)
|
||||
else:
|
||||
# We can create an oauth_token using a username and password
|
||||
# https://docs.gitlab.com/ee/api/oauth2.html#authorization-code-flow
|
||||
if gitlab_user:
|
||||
data = {'grant_type': 'password', 'username': gitlab_user, 'password': gitlab_password}
|
||||
resp = requests.post(urljoin(gitlab_url, "oauth/token"), data=data, verify=validate_certs)
|
||||
resp = requests.post(urljoin(gitlab_url, "oauth/token"), data=data, verify=verify)
|
||||
resp_data = resp.json()
|
||||
gitlab_oauth_token = resp_data["access_token"]
|
||||
|
||||
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=validate_certs, private_token=gitlab_token,
|
||||
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=verify, private_token=gitlab_token,
|
||||
oauth_token=gitlab_oauth_token, job_token=gitlab_job_token, api_version=4)
|
||||
|
||||
gitlab_instance.auth()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2955,7 +2955,7 @@ class RedfishUtils(object):
|
||||
result = {}
|
||||
inventory = {}
|
||||
# Get these entries, but does not fail if not found
|
||||
properties = ['Status', 'HostName', 'PowerState', 'Model', 'Manufacturer',
|
||||
properties = ['Status', 'HostName', 'PowerState', 'BootProgress', 'Model', 'Manufacturer',
|
||||
'PartNumber', 'SystemType', 'AssetTag', 'ServiceTag',
|
||||
'SerialNumber', 'SKU', 'BiosVersion', 'MemorySummary',
|
||||
'ProcessorSummary', 'TrustedModules', 'Name', 'Id']
|
||||
|
||||
@@ -253,7 +253,7 @@ options:
|
||||
author:
|
||||
- "He Guimin (@xiaozhu36)"
|
||||
requirements:
|
||||
- "python >= 3.6"
|
||||
- "Python >= 3.6"
|
||||
- "footmark >= 1.19.0"
|
||||
extends_documentation_fragment:
|
||||
- community.general.alicloud
|
||||
|
||||
@@ -31,7 +31,6 @@ short_description: Gather information on instances of Alibaba Cloud ECS
|
||||
description:
|
||||
- This module fetches data from the Open API in Alicloud.
|
||||
The module must be called from within the ECS instance itself.
|
||||
- This module was called C(ali_instance_facts) before Ansible 2.9. The usage did not change.
|
||||
|
||||
attributes:
|
||||
check_mode:
|
||||
@@ -61,7 +60,7 @@ options:
|
||||
author:
|
||||
- "He Guimin (@xiaozhu36)"
|
||||
requirements:
|
||||
- "python >= 3.6"
|
||||
- "Python >= 3.6"
|
||||
- "footmark >= 1.13.0"
|
||||
extends_documentation_fragment:
|
||||
- community.general.alicloud
|
||||
|
||||
@@ -37,7 +37,6 @@ options:
|
||||
- The type of installation performed by C(ansible-galaxy).
|
||||
- If O(type=both), then O(requirements_file) must be passed and it may contain both roles and collections.
|
||||
- "Note however that the opposite is not true: if using a O(requirements_file), then O(type) can be any of the three choices."
|
||||
- "B(Ansible 2.9): The option V(both) will have the same effect as V(role)."
|
||||
type: str
|
||||
choices: [collection, role, both]
|
||||
required: true
|
||||
@@ -54,7 +53,6 @@ options:
|
||||
- Path to a file containing a list of requirements to be installed.
|
||||
- It works for O(type) equals to V(collection) and V(role).
|
||||
- O(name) and O(requirements_file) are mutually exclusive.
|
||||
- "B(Ansible 2.9): It can only be used to install either O(type=role) or O(type=collection), but not both at the same run."
|
||||
type: path
|
||||
dest:
|
||||
description:
|
||||
|
||||
@@ -115,6 +115,7 @@ EXAMPLES = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
import re
|
||||
import traceback
|
||||
|
||||
from ansible.module_utils.basic import (
|
||||
@@ -132,6 +133,7 @@ else:
|
||||
HAS_RPM_PYTHON = True
|
||||
RPM_PYTHON_IMPORT_ERROR = None
|
||||
|
||||
APT_CACHE = "/usr/bin/apt-cache"
|
||||
APT_PATH = "/usr/bin/apt-get"
|
||||
RPM_PATH = "/usr/bin/rpm"
|
||||
APT_GET_ZERO = "\n0 upgraded, 0 newly installed"
|
||||
@@ -165,6 +167,19 @@ def query_package(module, name):
|
||||
return False
|
||||
|
||||
|
||||
def check_package_version(module, name):
|
||||
# compare installed and candidate version
|
||||
# if newest version already installed return True
|
||||
# otherwise return False
|
||||
|
||||
rc, out, err = module.run_command([APT_CACHE, "policy", name], environ_update={"LANG": "C"})
|
||||
installed = re.split("\n |: ", out)[2]
|
||||
candidate = re.split("\n |: ", out)[4]
|
||||
if installed >= candidate:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def query_package_provides(module, name):
|
||||
# rpm -q returns 0 if the package is installed,
|
||||
# 1 if it is not installed
|
||||
@@ -179,7 +194,11 @@ def query_package_provides(module, name):
|
||||
name = local_rpm_package_name(name)
|
||||
|
||||
rc, out, err = module.run_command("%s -q --provides %s" % (RPM_PATH, name))
|
||||
return rc == 0
|
||||
if rc == 0:
|
||||
if check_package_version(module, name):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def update_package_db(module):
|
||||
|
||||
@@ -36,7 +36,6 @@ options:
|
||||
format:
|
||||
description:
|
||||
- The type of compression to use.
|
||||
- Support for xz was added in Ansible 2.5.
|
||||
type: str
|
||||
choices: [ bz2, gz, tar, xz, zip ]
|
||||
default: gz
|
||||
|
||||
@@ -21,7 +21,6 @@ notes:
|
||||
- Host should support C(atomic) command
|
||||
requirements:
|
||||
- atomic
|
||||
- "python >= 2.6"
|
||||
extends_documentation_fragment:
|
||||
- community.general.attributes
|
||||
attributes:
|
||||
|
||||
@@ -21,7 +21,6 @@ notes:
|
||||
- Host should be an atomic platform (verified by existence of '/run/ostree-booted' file).
|
||||
requirements:
|
||||
- atomic
|
||||
- python >= 2.6
|
||||
extends_documentation_fragment:
|
||||
- community.general.attributes
|
||||
attributes:
|
||||
|
||||
@@ -21,7 +21,6 @@ notes:
|
||||
- Host should support C(atomic) command.
|
||||
requirements:
|
||||
- atomic
|
||||
- python >= 2.6
|
||||
extends_documentation_fragment:
|
||||
- community.general.attributes
|
||||
attributes:
|
||||
|
||||
@@ -45,8 +45,7 @@ options:
|
||||
force:
|
||||
description:
|
||||
- If V(true), any modified files in the working
|
||||
tree will be discarded. Before Ansible 1.9 the default
|
||||
value was V(true).
|
||||
tree will be discarded.
|
||||
type: bool
|
||||
default: false
|
||||
executable:
|
||||
|
||||
@@ -13,8 +13,6 @@ DOCUMENTATION = r'''
|
||||
module: cloudflare_dns
|
||||
author:
|
||||
- Michael Gruener (@mgruener)
|
||||
requirements:
|
||||
- python >= 2.6
|
||||
short_description: Manage Cloudflare DNS records
|
||||
description:
|
||||
- "Manages dns records via the Cloudflare API, see the docs: U(https://api.cloudflare.com/)."
|
||||
@@ -99,7 +97,6 @@ options:
|
||||
description:
|
||||
- Service protocol. Required for O(type=SRV) and O(type=TLSA).
|
||||
- Common values are TCP and UDP.
|
||||
- Before Ansible 2.6 only TCP and UDP were available.
|
||||
type: str
|
||||
proxied:
|
||||
description:
|
||||
@@ -151,7 +148,6 @@ options:
|
||||
type:
|
||||
description:
|
||||
- The type of DNS record to create. Required if O(state=present).
|
||||
- O(type=DS), O(type=SSHFP), and O(type=TLSA) were added in Ansible 2.7.
|
||||
type: str
|
||||
choices: [ A, AAAA, CNAME, DS, MX, NS, SPF, SRV, SSHFP, TLSA, CAA, TXT ]
|
||||
value:
|
||||
@@ -638,7 +634,7 @@ class CloudflareAPI(object):
|
||||
content = str(params['key_tag']) + '\t' + str(params['algorithm']) + '\t' + str(params['hash_type']) + '\t' + params['value']
|
||||
elif params['type'] == 'SSHFP':
|
||||
if not (params['value'] is None or params['value'] == ''):
|
||||
content = str(params['algorithm']) + '\t' + str(params['hash_type']) + '\t' + params['value']
|
||||
content = str(params['algorithm']) + ' ' + str(params['hash_type']) + ' ' + params['value'].upper()
|
||||
elif params['type'] == 'TLSA':
|
||||
if not (params['value'] is None or params['value'] == ''):
|
||||
content = str(params['cert_usage']) + '\t' + str(params['selector']) + '\t' + str(params['hash_type']) + '\t' + params['value']
|
||||
@@ -751,7 +747,7 @@ class CloudflareAPI(object):
|
||||
if (attr is None) or (attr == ''):
|
||||
self.module.fail_json(msg="You must provide algorithm, hash_type and a value to create this record type")
|
||||
sshfp_data = {
|
||||
"fingerprint": params['value'],
|
||||
"fingerprint": params['value'].upper(),
|
||||
"type": params['hash_type'],
|
||||
"algorithm": params['algorithm'],
|
||||
}
|
||||
@@ -761,7 +757,7 @@ class CloudflareAPI(object):
|
||||
'data': sshfp_data,
|
||||
"ttl": params['ttl'],
|
||||
}
|
||||
search_value = str(params['algorithm']) + '\t' + str(params['hash_type']) + '\t' + params['value']
|
||||
search_value = str(params['algorithm']) + ' ' + str(params['hash_type']) + ' ' + params['value']
|
||||
|
||||
if params['type'] == 'TLSA':
|
||||
for attr in [params['port'], params['proto'], params['cert_usage'], params['selector'], params['hash_type'], params['value']]:
|
||||
|
||||
@@ -69,7 +69,6 @@ options:
|
||||
plugin_bin:
|
||||
description:
|
||||
- Location of the plugin binary. If this file is not found, the default plugin binaries will be used.
|
||||
- The default changed in Ansible 2.4 to None.
|
||||
type: path
|
||||
plugin_dir:
|
||||
description:
|
||||
|
||||
@@ -20,7 +20,7 @@ author:
|
||||
requirements: ['git']
|
||||
short_description: Read and write git configuration
|
||||
description:
|
||||
- The M(community.general.git_config) module changes git configuration by invoking 'git config'.
|
||||
- The M(community.general.git_config) module changes git configuration by invoking C(git config).
|
||||
This is needed if you do not want to use M(ansible.builtin.template) for the entire git
|
||||
config file (for example because you need to change just C(user.email) in
|
||||
/etc/.git/config). Solutions involving M(ansible.builtin.command) are cumbersome or
|
||||
@@ -75,6 +75,16 @@ options:
|
||||
- When specifying the name of a single setting, supply a value to
|
||||
set that setting to the given value.
|
||||
type: str
|
||||
add_mode:
|
||||
description:
|
||||
- Specify if a value should replace the existing value(s) or if the new
|
||||
value should be added alongside other values with the same name.
|
||||
- This option is only relevant when adding/replacing values. If O(state=absent) or
|
||||
values are just read out, this option is not considered.
|
||||
choices: [ "add", "replace-all" ]
|
||||
type: str
|
||||
default: "replace-all"
|
||||
version_added: 8.1.0
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -118,6 +128,15 @@ EXAMPLES = '''
|
||||
name: color.ui
|
||||
value: auto
|
||||
|
||||
- name: Add several options for the same name
|
||||
community.general.git_config:
|
||||
name: push.pushoption
|
||||
value: "{{ item }}"
|
||||
add_mode: add
|
||||
loop:
|
||||
- merge_request.create
|
||||
- merge_request.draft
|
||||
|
||||
- name: Make etckeeper not complaining when it is invoked by cron
|
||||
community.general.git_config:
|
||||
name: user.email
|
||||
@@ -178,6 +197,7 @@ def main():
|
||||
name=dict(type='str'),
|
||||
repo=dict(type='path'),
|
||||
file=dict(type='path'),
|
||||
add_mode=dict(required=False, type='str', default='replace-all', choices=['add', 'replace-all']),
|
||||
scope=dict(required=False, type='str', choices=['file', 'local', 'global', 'system']),
|
||||
state=dict(required=False, type='str', default='present', choices=['present', 'absent']),
|
||||
value=dict(required=False),
|
||||
@@ -197,94 +217,118 @@ def main():
|
||||
# Set the locale to C to ensure consistent messages.
|
||||
module.run_command_environ_update = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C', LC_CTYPE='C')
|
||||
|
||||
if params['name']:
|
||||
name = params['name']
|
||||
else:
|
||||
name = None
|
||||
name = params['name'] or ''
|
||||
unset = params['state'] == 'absent'
|
||||
new_value = params['value'] or ''
|
||||
add_mode = params['add_mode']
|
||||
|
||||
if params['scope']:
|
||||
scope = params['scope']
|
||||
elif params['list_all']:
|
||||
scope = None
|
||||
else:
|
||||
scope = 'system'
|
||||
scope = determine_scope(params)
|
||||
cwd = determine_cwd(scope, params)
|
||||
|
||||
if params['state'] == 'absent':
|
||||
unset = 'unset'
|
||||
params['value'] = None
|
||||
else:
|
||||
unset = None
|
||||
base_args = [git_path, "config", "--includes"]
|
||||
|
||||
if params['value']:
|
||||
new_value = params['value']
|
||||
else:
|
||||
new_value = None
|
||||
|
||||
args = [git_path, "config", "--includes"]
|
||||
if params['list_all']:
|
||||
args.append('-l')
|
||||
if scope == 'file':
|
||||
args.append('-f')
|
||||
args.append(params['file'])
|
||||
base_args.append('-f')
|
||||
base_args.append(params['file'])
|
||||
elif scope:
|
||||
args.append("--" + scope)
|
||||
base_args.append("--" + scope)
|
||||
|
||||
list_args = list(base_args)
|
||||
|
||||
if params['list_all']:
|
||||
list_args.append('-l')
|
||||
|
||||
if name:
|
||||
args.append(name)
|
||||
list_args.append("--get-all")
|
||||
list_args.append(name)
|
||||
|
||||
if scope == 'local':
|
||||
dir = params['repo']
|
||||
elif params['list_all'] and params['repo']:
|
||||
# Include local settings from a specific repo when listing all available settings
|
||||
dir = params['repo']
|
||||
else:
|
||||
# Run from root directory to avoid accidentally picking up any local config settings
|
||||
dir = "/"
|
||||
(rc, out, err) = module.run_command(list_args, cwd=cwd, expand_user_and_vars=False)
|
||||
|
||||
(rc, out, err) = module.run_command(args, cwd=dir, expand_user_and_vars=False)
|
||||
if params['list_all'] and scope and rc == 128 and 'unable to read config file' in err:
|
||||
# This just means nothing has been set at the given scope
|
||||
module.exit_json(changed=False, msg='', config_values={})
|
||||
elif rc >= 2:
|
||||
# If the return code is 1, it just means the option hasn't been set yet, which is fine.
|
||||
module.fail_json(rc=rc, msg=err, cmd=' '.join(args))
|
||||
module.fail_json(rc=rc, msg=err, cmd=' '.join(list_args))
|
||||
|
||||
old_values = out.rstrip().splitlines()
|
||||
|
||||
if params['list_all']:
|
||||
values = out.rstrip().splitlines()
|
||||
config_values = {}
|
||||
for value in values:
|
||||
for value in old_values:
|
||||
k, v = value.split('=', 1)
|
||||
config_values[k] = v
|
||||
module.exit_json(changed=False, msg='', config_values=config_values)
|
||||
elif not new_value and not unset:
|
||||
module.exit_json(changed=False, msg='', config_value=out.rstrip())
|
||||
module.exit_json(changed=False, msg='', config_value=old_values[0] if old_values else '')
|
||||
elif unset and not out:
|
||||
module.exit_json(changed=False, msg='no setting to unset')
|
||||
elif new_value in old_values and (len(old_values) == 1 or add_mode == "add"):
|
||||
module.exit_json(changed=False, msg="")
|
||||
|
||||
# Until this point, the git config was just read and in case no change is needed, the module has already exited.
|
||||
|
||||
set_args = list(base_args)
|
||||
if unset:
|
||||
set_args.append("--unset-all")
|
||||
set_args.append(name)
|
||||
else:
|
||||
old_value = out.rstrip()
|
||||
if old_value == new_value:
|
||||
module.exit_json(changed=False, msg="")
|
||||
set_args.append("--" + add_mode)
|
||||
set_args.append(name)
|
||||
set_args.append(new_value)
|
||||
|
||||
if not module.check_mode:
|
||||
if unset:
|
||||
args.insert(len(args) - 1, "--" + unset)
|
||||
cmd = args
|
||||
else:
|
||||
cmd = args + [new_value]
|
||||
(rc, out, err) = module.run_command(cmd, cwd=dir, ignore_invalid_cwd=False, expand_user_and_vars=False)
|
||||
(rc, out, err) = module.run_command(set_args, cwd=cwd, ignore_invalid_cwd=False, expand_user_and_vars=False)
|
||||
if err:
|
||||
module.fail_json(rc=rc, msg=err, cmd=cmd)
|
||||
module.fail_json(rc=rc, msg=err, cmd=set_args)
|
||||
|
||||
if unset:
|
||||
after_values = []
|
||||
elif add_mode == "add":
|
||||
after_values = old_values + [new_value]
|
||||
else:
|
||||
after_values = [new_value]
|
||||
|
||||
module.exit_json(
|
||||
msg='setting changed',
|
||||
diff=dict(
|
||||
before_header=' '.join(args),
|
||||
before=old_value + "\n",
|
||||
after_header=' '.join(args),
|
||||
after=(new_value or '') + "\n"
|
||||
before_header=' '.join(set_args),
|
||||
before=build_diff_value(old_values),
|
||||
after_header=' '.join(set_args),
|
||||
after=build_diff_value(after_values),
|
||||
),
|
||||
changed=True
|
||||
)
|
||||
|
||||
|
||||
def determine_scope(params):
|
||||
if params['scope']:
|
||||
return params['scope']
|
||||
elif params['list_all']:
|
||||
return ""
|
||||
else:
|
||||
return 'system'
|
||||
|
||||
|
||||
def build_diff_value(value):
|
||||
if not value:
|
||||
return "\n"
|
||||
elif len(value) == 1:
|
||||
return value[0] + "\n"
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
def determine_cwd(scope, params):
|
||||
if scope == 'local':
|
||||
return params['repo']
|
||||
elif params['list_all'] and params['repo']:
|
||||
# Include local settings from a specific repo when listing all available settings
|
||||
return params['repo']
|
||||
else:
|
||||
# Run from root directory to avoid accidentally picking up any local config settings
|
||||
return "/"
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
187
plugins/modules/git_config_info.py
Normal file
187
plugins/modules/git_config_info.py
Normal file
@@ -0,0 +1,187 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023, Guenther Grill <grill.guenther@gmail.com>
|
||||
#
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: git_config_info
|
||||
author:
|
||||
- Guenther Grill (@guenhter)
|
||||
version_added: 8.1.0
|
||||
requirements: ['git']
|
||||
short_description: Read git configuration
|
||||
description:
|
||||
- The M(community.general.git_config_info) module reads the git configuration
|
||||
by invoking C(git config).
|
||||
extends_documentation_fragment:
|
||||
- community.general.attributes
|
||||
- community.general.attributes.info_module
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- The name of the setting to read.
|
||||
- If not provided, all settings will be returned as RV(config_values).
|
||||
type: str
|
||||
path:
|
||||
description:
|
||||
- Path to a git repository or file for reading values from a specific repo.
|
||||
- If O(scope) is V(local), this must point to a repository to read from.
|
||||
- If O(scope) is V(file), this must point to specific git config file to read from.
|
||||
- Otherwise O(path) is ignored if set.
|
||||
type: path
|
||||
scope:
|
||||
description:
|
||||
- Specify which scope to read values from.
|
||||
- If set to V(global), the global git config is used. O(path) is ignored.
|
||||
- If set to V(system), the system git config is used. O(path) is ignored.
|
||||
- If set to V(local), O(path) must be set to the repo to read from.
|
||||
- If set to V(file), O(path) must be set to the config file to read from.
|
||||
choices: [ "global", "system", "local", "file" ]
|
||||
default: "system"
|
||||
type: str
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Read a system wide config
|
||||
community.general.git_config_info:
|
||||
name: core.editor
|
||||
register: result
|
||||
|
||||
- name: Show value of core.editor
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ result.config_value | default('(not set)', true) }}"
|
||||
|
||||
- name: Read a global config from ~/.gitconfig
|
||||
community.general.git_config_info:
|
||||
name: alias.remotev
|
||||
scope: global
|
||||
|
||||
- name: Read a project specific config
|
||||
community.general.git_config_info:
|
||||
name: color.ui
|
||||
scope: local
|
||||
path: /etc
|
||||
|
||||
- name: Read all global values
|
||||
community.general.git_config_info:
|
||||
scope: global
|
||||
|
||||
- name: Read all system wide values
|
||||
community.general.git_config_info:
|
||||
|
||||
- name: Read all values of a specific file
|
||||
community.general.git_config_info:
|
||||
scope: file
|
||||
path: /etc/gitconfig
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
---
|
||||
config_value:
|
||||
description: >
|
||||
When O(name) is set, a string containing the value of the setting in name. If O(name) is not set, empty.
|
||||
If a config key such as V(push.pushoption) has more then one entry, just the first one is returned here.
|
||||
returned: success if O(name) is set
|
||||
type: str
|
||||
sample: "vim"
|
||||
|
||||
config_values:
|
||||
description:
|
||||
- This is a dictionary mapping a git configuration setting to a list of its values.
|
||||
- When O(name) is not set, all configuration settings are returned here.
|
||||
- When O(name) is set, only the setting specified in O(name) is returned here.
|
||||
If that setting is not set, the key will still be present, and its value will be an empty list.
|
||||
returned: success
|
||||
type: dict
|
||||
sample:
|
||||
core.editor: ["vim"]
|
||||
color.ui: ["auto"]
|
||||
push.pushoption: ["merge_request.create", "merge_request.draft"]
|
||||
alias.remotev: ["remote -v"]
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
name=dict(type="str"),
|
||||
path=dict(type="path"),
|
||||
scope=dict(required=False, type="str", default="system", choices=["global", "system", "local", "file"]),
|
||||
),
|
||||
required_if=[
|
||||
("scope", "local", ["path"]),
|
||||
("scope", "file", ["path"]),
|
||||
],
|
||||
required_one_of=[],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
# We check error message for a pattern, so we need to make sure the messages appear in the form we're expecting.
|
||||
# Set the locale to C to ensure consistent messages.
|
||||
module.run_command_environ_update = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C', LC_CTYPE='C')
|
||||
|
||||
name = module.params["name"]
|
||||
path = module.params["path"]
|
||||
scope = module.params["scope"]
|
||||
|
||||
run_cwd = path if scope == "local" else "/"
|
||||
args = build_args(module, name, path, scope)
|
||||
|
||||
(rc, out, err) = module.run_command(args, cwd=run_cwd, expand_user_and_vars=False)
|
||||
|
||||
if rc == 128 and "unable to read config file" in err:
|
||||
# This just means nothing has been set at the given scope
|
||||
pass
|
||||
elif rc >= 2:
|
||||
# If the return code is 1, it just means the option hasn't been set yet, which is fine.
|
||||
module.fail_json(rc=rc, msg=err, cmd=" ".join(args))
|
||||
|
||||
output_lines = out.strip("\0").split("\0") if out else []
|
||||
|
||||
if name:
|
||||
first_value = output_lines[0] if output_lines else ""
|
||||
config_values = {name: output_lines}
|
||||
module.exit_json(changed=False, msg="", config_value=first_value, config_values=config_values)
|
||||
else:
|
||||
config_values = text_to_dict(output_lines)
|
||||
module.exit_json(changed=False, msg="", config_value="", config_values=config_values)
|
||||
|
||||
|
||||
def build_args(module, name, path, scope):
|
||||
git_path = module.get_bin_path("git", True)
|
||||
args = [git_path, "config", "--includes", "--null", "--" + scope]
|
||||
|
||||
if scope == "file":
|
||||
args.append(path)
|
||||
|
||||
if name:
|
||||
args.extend(["--get-all", name])
|
||||
else:
|
||||
args.append("--list")
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def text_to_dict(text_lines):
|
||||
config_values = {}
|
||||
for value in text_lines:
|
||||
k, v = value.split("\n", 1)
|
||||
if k in config_values:
|
||||
config_values[k].append(v)
|
||||
else:
|
||||
config_values[k] = [v]
|
||||
return config_values
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -94,7 +94,7 @@ EXAMPLES = '''
|
||||
repo: testrepo
|
||||
action: latest_release
|
||||
|
||||
- name: Get latest release of test repo using username and password. Ansible 2.4.
|
||||
- name: Get latest release of test repo using username and password
|
||||
community.general.github_release:
|
||||
user: testuser
|
||||
password: secret123
|
||||
|
||||
@@ -14,7 +14,6 @@ module: github_webhook_info
|
||||
short_description: Query information about GitHub webhooks
|
||||
description:
|
||||
- "Query information about GitHub webhooks"
|
||||
- This module was called C(github_webhook_facts) before Ansible 2.9. The usage did not change.
|
||||
requirements:
|
||||
- "PyGithub >= 1.3.5"
|
||||
extends_documentation_fragment:
|
||||
|
||||
@@ -16,7 +16,6 @@ description:
|
||||
author:
|
||||
- paytroff (@paytroff)
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- python-gitlab >= 2.3.0
|
||||
extends_documentation_fragment:
|
||||
- community.general.auth_basic
|
||||
@@ -84,7 +83,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, gitlab, ensure_gitlab_package
|
||||
auth_argument_spec, gitlab_authentication, gitlab
|
||||
)
|
||||
|
||||
|
||||
@@ -144,7 +143,9 @@ def main():
|
||||
],
|
||||
supports_check_mode=False
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
project = module.params['project']
|
||||
branch = module.params['branch']
|
||||
@@ -156,7 +157,6 @@ def main():
|
||||
module.fail_json(msg="community.general.gitlab_proteched_branch requires python-gitlab Python module >= 2.3.0 (installed version: [%s])."
|
||||
" Please upgrade python-gitlab to version 2.3.0 or above." % gitlab_version)
|
||||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
this_gitlab = GitlabBranch(module=module, project=project, gitlab_instance=gitlab_instance)
|
||||
|
||||
this_branch = this_gitlab.get_branch(branch)
|
||||
|
||||
@@ -20,7 +20,6 @@ author:
|
||||
- Marcus Watkins (@marwatk)
|
||||
- Guillaume Martinez (@Lunik)
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- python-gitlab python module
|
||||
extends_documentation_fragment:
|
||||
- community.general.auth_basic
|
||||
@@ -121,7 +120,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, find_project, gitlab_authentication, gitlab, ensure_gitlab_package
|
||||
auth_argument_spec, find_project, gitlab_authentication, gitlab
|
||||
)
|
||||
|
||||
|
||||
@@ -261,7 +260,9 @@ def main():
|
||||
],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
state = module.params['state']
|
||||
project_identifier = module.params['project']
|
||||
@@ -269,8 +270,6 @@ def main():
|
||||
key_keyfile = module.params['key']
|
||||
key_can_push = module.params['can_push']
|
||||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
gitlab_deploy_key = GitLabDeployKey(module, gitlab_instance)
|
||||
|
||||
project = find_project(gitlab_instance, project_identifier)
|
||||
|
||||
@@ -20,7 +20,6 @@ author:
|
||||
- Werner Dijkerman (@dj-wasabi)
|
||||
- Guillaume Martinez (@Lunik)
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- python-gitlab python module
|
||||
extends_documentation_fragment:
|
||||
- community.general.auth_basic
|
||||
@@ -108,7 +107,6 @@ EXAMPLES = '''
|
||||
community.general.gitlab_group:
|
||||
api_url: https://gitlab.example.com/
|
||||
api_token: "{{ access_token }}"
|
||||
validate_certs: false
|
||||
name: my_first_group
|
||||
state: absent
|
||||
|
||||
@@ -178,7 +176,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, find_group, gitlab_authentication, gitlab, ensure_gitlab_package
|
||||
auth_argument_spec, find_group, gitlab_authentication, gitlab
|
||||
)
|
||||
|
||||
|
||||
@@ -355,7 +353,9 @@ def main():
|
||||
],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
group_name = module.params['name']
|
||||
group_path = module.params['path']
|
||||
@@ -370,8 +370,6 @@ def main():
|
||||
avatar_path = module.params['avatar_path']
|
||||
force_delete = module.params['force_delete']
|
||||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
# Define default group_path based on group_name
|
||||
if group_path is None:
|
||||
group_path = group_name.replace(" ", "_")
|
||||
|
||||
@@ -160,7 +160,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, gitlab, ensure_gitlab_package
|
||||
auth_argument_spec, gitlab_authentication, gitlab
|
||||
)
|
||||
|
||||
|
||||
@@ -273,7 +273,9 @@ def main():
|
||||
],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gl = gitlab_authentication(module)
|
||||
|
||||
access_level_int = {
|
||||
'guest': gitlab.const.GUEST_ACCESS,
|
||||
@@ -291,9 +293,6 @@ def main():
|
||||
if purge_users:
|
||||
purge_users = [access_level_int[level] for level in purge_users]
|
||||
|
||||
# connect to gitlab server
|
||||
gl = gitlab_authentication(module)
|
||||
|
||||
group = GitLabGroup(module, gl)
|
||||
|
||||
gitlab_group_id = group.get_group_id(gitlab_group)
|
||||
|
||||
@@ -21,7 +21,6 @@ description:
|
||||
author:
|
||||
- Florent Madiot (@scodeman)
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- python-gitlab python module
|
||||
extends_documentation_fragment:
|
||||
- community.general.auth_basic
|
||||
@@ -207,7 +206,7 @@ group_variable:
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, ensure_gitlab_package, filter_returned_variables, vars_to_variables
|
||||
auth_argument_spec, gitlab_authentication, filter_returned_variables, vars_to_variables
|
||||
)
|
||||
|
||||
|
||||
@@ -413,7 +412,9 @@ def main():
|
||||
],
|
||||
supports_check_mode=True
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
purge = module.params['purge']
|
||||
var_list = module.params['vars']
|
||||
@@ -428,8 +429,6 @@ def main():
|
||||
if any(x['value'] is None for x in variables):
|
||||
module.fail_json(msg='value parameter is required in state present')
|
||||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
this_gitlab = GitlabGroupVariables(module=module, gitlab_instance=gitlab_instance)
|
||||
|
||||
changed, raw_return_value, before, after = native_python_main(this_gitlab, purge, variables, state, module)
|
||||
|
||||
@@ -21,7 +21,6 @@ author:
|
||||
- Marcus Watkins (@marwatk)
|
||||
- Guillaume Martinez (@Lunik)
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- python-gitlab python module
|
||||
extends_documentation_fragment:
|
||||
- community.general.auth_basic
|
||||
@@ -123,7 +122,6 @@ EXAMPLES = '''
|
||||
state: present
|
||||
push_events: true
|
||||
tag_push_events: true
|
||||
hook_validate_certs: false
|
||||
token: "my-super-secret-token-that-my-ci-server-will-check"
|
||||
|
||||
- name: "Delete the previous hook"
|
||||
@@ -171,7 +169,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, find_project, gitlab_authentication, ensure_gitlab_package
|
||||
auth_argument_spec, find_project, gitlab_authentication
|
||||
)
|
||||
|
||||
|
||||
@@ -325,7 +323,9 @@ def main():
|
||||
],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
state = module.params['state']
|
||||
project_identifier = module.params['project']
|
||||
@@ -342,8 +342,6 @@ def main():
|
||||
enable_ssl_verification = module.params['hook_validate_certs']
|
||||
hook_token = module.params['token']
|
||||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
gitlab_hook = GitLabHook(module, gitlab_instance)
|
||||
|
||||
project = find_project(gitlab_instance, project_identifier)
|
||||
|
||||
@@ -23,7 +23,6 @@ description:
|
||||
author:
|
||||
- Benedikt Braunger (@benibr)
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- python-gitlab python module
|
||||
extends_documentation_fragment:
|
||||
- community.general.auth_basic
|
||||
@@ -139,7 +138,7 @@ instance_variable:
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, ensure_gitlab_package, filter_returned_variables
|
||||
auth_argument_spec, gitlab_authentication, filter_returned_variables
|
||||
)
|
||||
|
||||
|
||||
@@ -326,7 +325,9 @@ def main():
|
||||
],
|
||||
supports_check_mode=True
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
purge = module.params['purge']
|
||||
state = module.params['state']
|
||||
@@ -337,8 +338,6 @@ def main():
|
||||
if any(x['value'] is None for x in variables):
|
||||
module.fail_json(msg='value parameter is required in state present')
|
||||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
this_gitlab = GitlabInstanceVariables(module=module, gitlab_instance=gitlab_instance)
|
||||
|
||||
changed, raw_return_value, before, after = native_python_main(this_gitlab, purge, variables, state, module)
|
||||
|
||||
408
plugins/modules/gitlab_issue.py
Normal file
408
plugins/modules/gitlab_issue.py
Normal file
@@ -0,0 +1,408 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023, Ondrej Zvara (ozvara1@gmail.com)
|
||||
# Based on code:
|
||||
# Copyright (c) 2021, Lennert Mertens (lennert@nubera.be)
|
||||
# Copyright (c) 2021, Werner Dijkerman (ikben@werner-dijkerman.nl)
|
||||
# Copyright (c) 2015, Werner Dijkerman (ikben@werner-dijkerman.nl)
|
||||
# Copyright (c) 2019, Guillaume Martinez (lunik@tiwabbit.fr)
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = '''
|
||||
module: gitlab_issue
|
||||
short_description: Create, update, or delete GitLab issues
|
||||
version_added: '8.1.0'
|
||||
description:
|
||||
- Creates an issue if it does not exist.
|
||||
- When an issue does exist, it will be updated if the provided parameters are different.
|
||||
- When an issue does exist and O(state=absent), the issue will be deleted.
|
||||
- When multiple issues are detected, the task fails.
|
||||
- Existing issues are matched based on O(title) and O(state_filter) filters.
|
||||
author:
|
||||
- zvaraondrej (@zvaraondrej)
|
||||
requirements:
|
||||
- python-gitlab >= 2.3.0
|
||||
extends_documentation_fragment:
|
||||
- community.general.auth_basic
|
||||
- community.general.gitlab
|
||||
- community.general.attributes
|
||||
|
||||
attributes:
|
||||
check_mode:
|
||||
support: full
|
||||
diff_mode:
|
||||
support: none
|
||||
|
||||
options:
|
||||
assignee_ids:
|
||||
description:
|
||||
- A list of assignee usernames omitting V(@) character.
|
||||
- Set to an empty array to unassign all assignees.
|
||||
type: list
|
||||
elements: str
|
||||
description:
|
||||
description:
|
||||
- A description of the issue.
|
||||
- Gets overridden by a content of file specified at O(description_path), if found.
|
||||
type: str
|
||||
description_path:
|
||||
description:
|
||||
- A path of file containing issue's description.
|
||||
- Accepts MarkDown formatted files.
|
||||
type: path
|
||||
issue_type:
|
||||
description:
|
||||
- Type of the issue.
|
||||
default: issue
|
||||
type: str
|
||||
choices: ["issue", "incident", "test_case"]
|
||||
labels:
|
||||
description:
|
||||
- A list of label names.
|
||||
- Set to an empty array to remove all labels.
|
||||
type: list
|
||||
elements: str
|
||||
milestone_search:
|
||||
description:
|
||||
- The name of the milestone.
|
||||
- Set to empty string to unassign milestone.
|
||||
type: str
|
||||
milestone_group_id:
|
||||
description:
|
||||
- The path or numeric ID of the group hosting desired milestone.
|
||||
type: str
|
||||
project:
|
||||
description:
|
||||
- The path or name of the project.
|
||||
required: true
|
||||
type: str
|
||||
state:
|
||||
description:
|
||||
- Create or delete issue.
|
||||
default: present
|
||||
type: str
|
||||
choices: ["present", "absent"]
|
||||
state_filter:
|
||||
description:
|
||||
- Filter specifying state of issues while searching.
|
||||
type: str
|
||||
choices: ["opened", "closed"]
|
||||
default: opened
|
||||
title:
|
||||
description:
|
||||
- A title for the issue. The title is used as a unique identifier to ensure idempotency.
|
||||
type: str
|
||||
required: true
|
||||
'''
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Create Issue
|
||||
community.general.gitlab_issue:
|
||||
api_url: https://gitlab.com
|
||||
api_token: secret_access_token
|
||||
project: "group1/project1"
|
||||
title: "Ansible demo Issue"
|
||||
description: "Demo Issue description"
|
||||
labels:
|
||||
- Ansible
|
||||
- Demo
|
||||
assignee_ids:
|
||||
- testassignee
|
||||
state_filter: "opened"
|
||||
state: present
|
||||
|
||||
- name: Delete Issue
|
||||
community.general.gitlab_issue:
|
||||
api_url: https://gitlab.com
|
||||
api_token: secret_access_token
|
||||
project: "group1/project1"
|
||||
title: "Ansible demo Issue"
|
||||
state_filter: "opened"
|
||||
state: absent
|
||||
'''
|
||||
|
||||
RETURN = r'''
|
||||
msg:
|
||||
description: Success or failure message.
|
||||
returned: always
|
||||
type: str
|
||||
sample: "Success"
|
||||
|
||||
issue:
|
||||
description: API object.
|
||||
returned: success
|
||||
type: dict
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, gitlab, find_project, find_group
|
||||
)
|
||||
|
||||
|
||||
class GitlabIssue(object):
|
||||
|
||||
def __init__(self, module, project, gitlab_instance):
|
||||
self._gitlab = gitlab_instance
|
||||
self._module = module
|
||||
self.project = project
|
||||
|
||||
'''
|
||||
@param milestone_id Title of the milestone
|
||||
'''
|
||||
def get_milestone(self, milestone_id, group):
|
||||
milestones = []
|
||||
try:
|
||||
milestones = group.milestones.list(search=milestone_id)
|
||||
except gitlab.exceptions.GitlabGetError as e:
|
||||
self._module.fail_json(msg="Failed to list the Milestones: %s" % to_native(e))
|
||||
|
||||
if len(milestones) > 1:
|
||||
self._module.fail_json(msg="Multiple Milestones matched search criteria.")
|
||||
if len(milestones) < 1:
|
||||
self._module.fail_json(msg="No Milestones matched search criteria.")
|
||||
if len(milestones) == 1:
|
||||
try:
|
||||
return group.milestones.get(id=milestones[0].id)
|
||||
except gitlab.exceptions.GitlabGetError as e:
|
||||
self._module.fail_json(msg="Failed to get the Milestones: %s" % to_native(e))
|
||||
|
||||
'''
|
||||
@param title Title of the Issue
|
||||
@param state_filter Issue's state to filter on
|
||||
'''
|
||||
def get_issue(self, title, state_filter):
|
||||
issues = []
|
||||
try:
|
||||
issues = self.project.issues.list(title=title, state=state_filter)
|
||||
except gitlab.exceptions.GitlabGetError as e:
|
||||
self._module.fail_json(msg="Failed to list the Issues: %s" % to_native(e))
|
||||
|
||||
if len(issues) > 1:
|
||||
self._module.fail_json(msg="Multiple Issues matched search criteria.")
|
||||
if len(issues) == 1:
|
||||
try:
|
||||
return self.project.issues.get(id=issues[0].iid)
|
||||
except gitlab.exceptions.GitlabGetError as e:
|
||||
self._module.fail_json(msg="Failed to get the Issue: %s" % to_native(e))
|
||||
|
||||
'''
|
||||
@param username Name of the user
|
||||
'''
|
||||
def get_user(self, username):
|
||||
users = []
|
||||
try:
|
||||
users = [user for user in self.project.users.list(username=username, all=True) if user.username == username]
|
||||
except gitlab.exceptions.GitlabGetError as e:
|
||||
self._module.fail_json(msg="Failed to list the users: %s" % to_native(e))
|
||||
|
||||
if len(users) > 1:
|
||||
self._module.fail_json(msg="Multiple Users matched search criteria.")
|
||||
elif len(users) < 1:
|
||||
self._module.fail_json(msg="No User matched search criteria.")
|
||||
else:
|
||||
return users[0]
|
||||
|
||||
'''
|
||||
@param users List of usernames
|
||||
'''
|
||||
def get_user_ids(self, users):
|
||||
return [self.get_user(user).id for user in users]
|
||||
|
||||
'''
|
||||
@param options Options of the Issue
|
||||
'''
|
||||
def create_issue(self, options):
|
||||
if self._module.check_mode:
|
||||
self._module.exit_json(changed=True, msg="Successfully created Issue '%s'." % options["title"])
|
||||
|
||||
try:
|
||||
return self.project.issues.create(options)
|
||||
except gitlab.exceptions.GitlabCreateError as e:
|
||||
self._module.fail_json(msg="Failed to create Issue: %s " % to_native(e))
|
||||
|
||||
'''
|
||||
@param issue Issue object to delete
|
||||
'''
|
||||
def delete_issue(self, issue):
|
||||
if self._module.check_mode:
|
||||
self._module.exit_json(changed=True, msg="Successfully deleted Issue '%s'." % issue["title"])
|
||||
|
||||
try:
|
||||
return issue.delete()
|
||||
except gitlab.exceptions.GitlabDeleteError as e:
|
||||
self._module.fail_json(msg="Failed to delete Issue: '%s'." % to_native(e))
|
||||
|
||||
'''
|
||||
@param issue Issue object to update
|
||||
@param options Options of the Issue
|
||||
'''
|
||||
def update_issue(self, issue, options):
|
||||
if self._module.check_mode:
|
||||
self._module.exit_json(changed=True, msg="Successfully updated Issue '%s'." % issue["title"])
|
||||
|
||||
try:
|
||||
return self.project.issues.update(issue.iid, options)
|
||||
except gitlab.exceptions.GitlabUpdateError as e:
|
||||
self._module.fail_json(msg="Failed to update Issue %s." % to_native(e))
|
||||
|
||||
'''
|
||||
@param issue Issue object to evaluate
|
||||
@param options New options to update Issue with
|
||||
'''
|
||||
def issue_has_changed(self, issue, options):
|
||||
for key, value in options.items():
|
||||
if value is not None:
|
||||
|
||||
if key == 'milestone_id':
|
||||
old_milestone = getattr(issue, 'milestone')['id'] if getattr(issue, 'milestone') else ""
|
||||
if options[key] != old_milestone:
|
||||
return True
|
||||
elif key == 'assignee_ids':
|
||||
if options[key] != sorted([user["id"] for user in getattr(issue, 'assignees')]):
|
||||
return True
|
||||
|
||||
elif key == 'labels':
|
||||
if options[key] != sorted(getattr(issue, key)):
|
||||
return True
|
||||
|
||||
elif getattr(issue, key) != value:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = basic_auth_argument_spec()
|
||||
argument_spec.update(auth_argument_spec())
|
||||
argument_spec.update(
|
||||
assignee_ids=dict(type='list', elements='str', required=False),
|
||||
description=dict(type='str', required=False),
|
||||
description_path=dict(type='path', required=False),
|
||||
issue_type=dict(type='str', default='issue', choices=["issue", "incident", "test_case"], required=False),
|
||||
labels=dict(type='list', elements='str', required=False),
|
||||
milestone_search=dict(type='str', required=False),
|
||||
milestone_group_id=dict(type='str', required=False),
|
||||
project=dict(type='str', required=True),
|
||||
state=dict(type='str', default="present", choices=["absent", "present"]),
|
||||
state_filter=dict(type='str', default="opened", choices=["opened", "closed"]),
|
||||
title=dict(type='str', required=True),
|
||||
)
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=argument_spec,
|
||||
mutually_exclusive=[
|
||||
['api_username', 'api_token'],
|
||||
['api_username', 'api_oauth_token'],
|
||||
['api_username', 'api_job_token'],
|
||||
['api_token', 'api_oauth_token'],
|
||||
['api_token', 'api_job_token'],
|
||||
['description', 'description_path'],
|
||||
],
|
||||
required_together=[
|
||||
['api_username', 'api_password'],
|
||||
['milestone_search', 'milestone_group_id'],
|
||||
],
|
||||
required_one_of=[
|
||||
['api_username', 'api_token', 'api_oauth_token', 'api_job_token']
|
||||
],
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
assignee_ids = module.params['assignee_ids']
|
||||
description = module.params['description']
|
||||
description_path = module.params['description_path']
|
||||
issue_type = module.params['issue_type']
|
||||
labels = module.params['labels']
|
||||
milestone_id = module.params['milestone_search']
|
||||
milestone_group_id = module.params['milestone_group_id']
|
||||
project = module.params['project']
|
||||
state = module.params['state']
|
||||
state_filter = module.params['state_filter']
|
||||
title = module.params['title']
|
||||
|
||||
gitlab_version = gitlab.__version__
|
||||
if LooseVersion(gitlab_version) < LooseVersion('2.3.0'):
|
||||
module.fail_json(msg="community.general.gitlab_issue requires python-gitlab Python module >= 2.3.0 (installed version: [%s])."
|
||||
" Please upgrade python-gitlab to version 2.3.0 or above." % gitlab_version)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
this_project = find_project(gitlab_instance, project)
|
||||
if this_project is None:
|
||||
module.fail_json(msg="Failed to get the project: %s" % project)
|
||||
|
||||
this_gitlab = GitlabIssue(module=module, project=this_project, gitlab_instance=gitlab_instance)
|
||||
|
||||
if milestone_id and milestone_group_id:
|
||||
this_group = find_group(gitlab_instance, milestone_group_id)
|
||||
if this_group is None:
|
||||
module.fail_json(msg="Failed to get the group: %s" % milestone_group_id)
|
||||
|
||||
milestone_id = this_gitlab.get_milestone(milestone_id, this_group).id
|
||||
|
||||
this_issue = this_gitlab.get_issue(title, state_filter)
|
||||
|
||||
if state == "present":
|
||||
if description_path:
|
||||
try:
|
||||
with open(description_path, 'rb') as f:
|
||||
description = to_text(f.read(), errors='surrogate_or_strict')
|
||||
except IOError as e:
|
||||
module.fail_json(msg='Cannot open {0}: {1}'.format(description_path, e))
|
||||
|
||||
# sorting necessary in order to properly detect changes, as we don't want to get false positive
|
||||
# results due to differences in ids ordering;
|
||||
assignee_ids = sorted(this_gitlab.get_user_ids(assignee_ids)) if assignee_ids else assignee_ids
|
||||
labels = sorted(labels) if labels else labels
|
||||
|
||||
options = {
|
||||
"title": title,
|
||||
"description": description,
|
||||
"labels": labels,
|
||||
"issue_type": issue_type,
|
||||
"milestone_id": milestone_id,
|
||||
"assignee_ids": assignee_ids,
|
||||
}
|
||||
|
||||
if not this_issue:
|
||||
issue = this_gitlab.create_issue(options)
|
||||
module.exit_json(
|
||||
changed=True, msg="Created Issue '{t}'.".format(t=title),
|
||||
issue=issue.asdict()
|
||||
)
|
||||
else:
|
||||
if this_gitlab.issue_has_changed(this_issue, options):
|
||||
issue = this_gitlab.update_issue(this_issue, options)
|
||||
module.exit_json(
|
||||
changed=True, msg="Updated Issue '{t}'.".format(t=title),
|
||||
issue=issue
|
||||
)
|
||||
else:
|
||||
module.exit_json(
|
||||
changed=False, msg="Issue '{t}' already exists".format(t=title),
|
||||
issue=this_issue.asdict()
|
||||
)
|
||||
elif state == "absent":
|
||||
if not this_issue:
|
||||
module.exit_json(changed=False, msg="Issue '{t}' does not exist or has already been deleted.".format(t=title))
|
||||
else:
|
||||
issue = this_gitlab.delete_issue(this_issue)
|
||||
module.exit_json(
|
||||
changed=True, msg="Issue '{t}' deleted.".format(t=title),
|
||||
issue=issue
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -26,7 +26,6 @@ description:
|
||||
author:
|
||||
- zvaraondrej (@zvaraondrej)
|
||||
requirements:
|
||||
- Python >= 2.7
|
||||
- python-gitlab >= 2.3.0
|
||||
extends_documentation_fragment:
|
||||
- community.general.auth_basic
|
||||
@@ -152,7 +151,7 @@ from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, gitlab, ensure_gitlab_package, find_project
|
||||
auth_argument_spec, gitlab_authentication, gitlab, find_project
|
||||
)
|
||||
|
||||
|
||||
@@ -321,7 +320,9 @@ def main():
|
||||
],
|
||||
supports_check_mode=True
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
project = module.params['project']
|
||||
source_branch = module.params['source_branch']
|
||||
@@ -341,8 +342,6 @@ def main():
|
||||
module.fail_json(msg="community.general.gitlab_merge_request requires python-gitlab Python module >= 2.3.0 (installed version: [%s])."
|
||||
" Please upgrade python-gitlab to version 2.3.0 or above." % gitlab_version)
|
||||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
this_project = find_project(gitlab_instance, project)
|
||||
if this_project is None:
|
||||
module.fail_json(msg="Failed to get the project: %s" % project)
|
||||
|
||||
@@ -21,7 +21,6 @@ author:
|
||||
- Werner Dijkerman (@dj-wasabi)
|
||||
- Guillaume Martinez (@Lunik)
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- python-gitlab python module
|
||||
extends_documentation_fragment:
|
||||
- community.general.auth_basic
|
||||
@@ -274,7 +273,6 @@ EXAMPLES = r'''
|
||||
community.general.gitlab_project:
|
||||
api_url: https://gitlab.example.com/
|
||||
api_token: "{{ access_token }}"
|
||||
validate_certs: false
|
||||
name: my_first_project
|
||||
state: absent
|
||||
delegate_to: localhost
|
||||
@@ -340,7 +338,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, find_group, find_project, gitlab_authentication, gitlab, ensure_gitlab_package
|
||||
auth_argument_spec, find_group, find_project, gitlab_authentication, gitlab
|
||||
)
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
@@ -558,7 +556,9 @@ def main():
|
||||
],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
group_identifier = module.params['group']
|
||||
project_name = module.params['name']
|
||||
@@ -596,8 +596,6 @@ def main():
|
||||
security_and_compliance_access_level = module.params['security_and_compliance_access_level']
|
||||
topics = module.params['topics']
|
||||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
# Set project_path to project_name if it is empty.
|
||||
if project_path is None:
|
||||
project_path = project_name.replace(" ", "_")
|
||||
|
||||
@@ -97,7 +97,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, find_project, ensure_gitlab_package
|
||||
auth_argument_spec, gitlab_authentication, find_project
|
||||
)
|
||||
|
||||
|
||||
@@ -159,13 +159,12 @@ state_strategy = {
|
||||
|
||||
|
||||
def core(module):
|
||||
ensure_gitlab_package(module)
|
||||
# check prerequisites and connect to gitlab server
|
||||
gl = gitlab_authentication(module)
|
||||
|
||||
gitlab_project = module.params['project']
|
||||
state = module.params['state']
|
||||
|
||||
gl = gitlab_authentication(module)
|
||||
|
||||
project = find_project(gl, gitlab_project)
|
||||
# project doesn't exist
|
||||
if not project:
|
||||
|
||||
@@ -106,7 +106,6 @@ EXAMPLES = r'''
|
||||
community.general.gitlab_project_members:
|
||||
api_url: 'https://gitlab.example.com'
|
||||
api_token: 'Your-Private-Token'
|
||||
validate_certs: false
|
||||
project: projectname
|
||||
gitlab_user: username
|
||||
state: absent
|
||||
@@ -163,7 +162,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, gitlab, ensure_gitlab_package
|
||||
auth_argument_spec, gitlab_authentication, gitlab
|
||||
)
|
||||
|
||||
|
||||
@@ -279,7 +278,9 @@ def main():
|
||||
],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gl = gitlab_authentication(module)
|
||||
|
||||
access_level_int = {
|
||||
'guest': gitlab.const.GUEST_ACCESS,
|
||||
@@ -296,9 +297,6 @@ def main():
|
||||
if purge_users:
|
||||
purge_users = [access_level_int[level] for level in purge_users]
|
||||
|
||||
# connect to gitlab server
|
||||
gl = gitlab_authentication(module)
|
||||
|
||||
project = GitLabProjectMembers(module, gl)
|
||||
|
||||
gitlab_project_id = project.get_project(gitlab_project)
|
||||
|
||||
@@ -18,7 +18,6 @@ description:
|
||||
author:
|
||||
- "Markus Bergholz (@markuman)"
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- python-gitlab python module
|
||||
extends_documentation_fragment:
|
||||
- community.general.auth_basic
|
||||
@@ -221,13 +220,12 @@ project_variable:
|
||||
sample: ['ACCESS_KEY_ID', 'SECRET_ACCESS_KEY']
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.api import basic_auth_argument_spec
|
||||
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, ensure_gitlab_package, filter_returned_variables, vars_to_variables,
|
||||
HAS_GITLAB_PACKAGE, GITLAB_IMP_ERR
|
||||
auth_argument_spec, gitlab_authentication, filter_returned_variables, vars_to_variables
|
||||
)
|
||||
|
||||
|
||||
@@ -436,10 +434,9 @@ def main():
|
||||
],
|
||||
supports_check_mode=True
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
if not HAS_GITLAB_PACKAGE:
|
||||
module.fail_json(msg=missing_required_lib("python-gitlab"), exception=GITLAB_IMP_ERR)
|
||||
# check prerequisites and connect to gitlab server
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
purge = module.params['purge']
|
||||
var_list = module.params['vars']
|
||||
@@ -454,8 +451,6 @@ def main():
|
||||
if any(x['value'] is None for x in variables):
|
||||
module.fail_json(msg='value parameter is required for all variables in state present')
|
||||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
this_gitlab = GitlabProjectVariables(module=module, gitlab_instance=gitlab_instance)
|
||||
|
||||
change, raw_return_value, before, after = native_python_main(this_gitlab, purge, variables, state, module)
|
||||
|
||||
@@ -16,7 +16,6 @@ description:
|
||||
author:
|
||||
- "Werner Dijkerman (@dj-wasabi)"
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- python-gitlab >= 2.3.0
|
||||
extends_documentation_fragment:
|
||||
- community.general.auth_basic
|
||||
@@ -83,7 +82,7 @@ from ansible.module_utils.api import basic_auth_argument_spec
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, gitlab, ensure_gitlab_package
|
||||
auth_argument_spec, gitlab_authentication, gitlab
|
||||
)
|
||||
|
||||
|
||||
@@ -164,7 +163,9 @@ def main():
|
||||
],
|
||||
supports_check_mode=True
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
project = module.params['project']
|
||||
name = module.params['name']
|
||||
@@ -177,7 +178,6 @@ def main():
|
||||
module.fail_json(msg="community.general.gitlab_proteched_branch requires python-gitlab Python module >= 2.3.0 (installed version: [%s])."
|
||||
" Please upgrade python-gitlab to version 2.3.0 or above." % gitlab_version)
|
||||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
this_gitlab = GitlabProtectedBranch(module=module, project=project, gitlab_instance=gitlab_instance)
|
||||
|
||||
p_branch = this_gitlab.protected_branch_exist(name=name)
|
||||
|
||||
@@ -30,7 +30,6 @@ author:
|
||||
- Samy Coenen (@SamyCoenen)
|
||||
- Guillaume Martinez (@Lunik)
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- python-gitlab >= 1.5.0
|
||||
extends_documentation_fragment:
|
||||
- community.general.auth_basic
|
||||
@@ -48,6 +47,7 @@ options:
|
||||
description:
|
||||
- ID or full path of the group in the form group/subgroup.
|
||||
- Mutually exclusive with O(owned) and O(project).
|
||||
- Must be group's numeric ID if O(registration_token) is not set and O(state=present).
|
||||
type: str
|
||||
version_added: '6.5.0'
|
||||
project:
|
||||
@@ -55,6 +55,7 @@ options:
|
||||
- ID or full path of the project in the form of group/name.
|
||||
- Mutually exclusive with O(owned) since community.general 4.5.0.
|
||||
- Mutually exclusive with O(group).
|
||||
- Must be project's numeric ID if O(registration_token) is not set and O(state=present).
|
||||
type: str
|
||||
version_added: '3.7.0'
|
||||
description:
|
||||
@@ -73,8 +74,11 @@ options:
|
||||
type: str
|
||||
registration_token:
|
||||
description:
|
||||
- The registration token is used to register new runners.
|
||||
- Required if O(state=present).
|
||||
- The registration token is used to register new runners before GitLab 16.0.
|
||||
- Required if O(state=present) for GitLab < 16.0.
|
||||
- If set, the runner will be created using the old runner creation workflow.
|
||||
- If not set, the runner will be created using the new runner creation workflow, introduced in GitLab 16.0.
|
||||
- If not set, requires python-gitlab >= 4.0.0.
|
||||
type: str
|
||||
owned:
|
||||
description:
|
||||
@@ -87,9 +91,18 @@ options:
|
||||
active:
|
||||
description:
|
||||
- Define if the runners is immediately active after creation.
|
||||
- Mutually exclusive with O(paused).
|
||||
required: false
|
||||
default: true
|
||||
type: bool
|
||||
paused:
|
||||
description:
|
||||
- Define if the runners is active or paused after creation.
|
||||
- Mutually exclusive with O(active).
|
||||
required: false
|
||||
default: false
|
||||
type: bool
|
||||
version_added: 8.1.0
|
||||
locked:
|
||||
description:
|
||||
- Determines if the runner is locked or not.
|
||||
@@ -206,10 +219,13 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, gitlab_authentication, gitlab, ensure_gitlab_package
|
||||
auth_argument_spec, gitlab_authentication, gitlab
|
||||
)
|
||||
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
|
||||
class GitLabRunner(object):
|
||||
def __init__(self, module, gitlab_instance, group=None, project=None):
|
||||
self._module = module
|
||||
@@ -232,18 +248,32 @@ class GitLabRunner(object):
|
||||
changed = False
|
||||
|
||||
arguments = {
|
||||
'active': options['active'],
|
||||
'locked': options['locked'],
|
||||
'run_untagged': options['run_untagged'],
|
||||
'maximum_timeout': options['maximum_timeout'],
|
||||
'tag_list': options['tag_list'],
|
||||
}
|
||||
|
||||
if options.get('paused') is not None:
|
||||
arguments['paused'] = options['paused']
|
||||
else:
|
||||
arguments['active'] = options['active']
|
||||
|
||||
if options.get('access_level') is not None:
|
||||
arguments['access_level'] = options['access_level']
|
||||
# Because we have already call userExists in main()
|
||||
if self.runner_object is None:
|
||||
arguments['description'] = description
|
||||
arguments['token'] = options['registration_token']
|
||||
if options.get('registration_token') is not None:
|
||||
arguments['token'] = options['registration_token']
|
||||
elif options.get('group') is not None:
|
||||
arguments['runner_type'] = 'group_type'
|
||||
arguments['group_id'] = options['group']
|
||||
elif options.get('project') is not None:
|
||||
arguments['runner_type'] = 'project_type'
|
||||
arguments['project_id'] = options['project']
|
||||
else:
|
||||
arguments['runner_type'] = 'instance_type'
|
||||
|
||||
access_level_on_creation = self._module.params['access_level_on_creation']
|
||||
if not access_level_on_creation:
|
||||
@@ -253,19 +283,17 @@ class GitLabRunner(object):
|
||||
changed = True
|
||||
else:
|
||||
changed, runner = self.update_runner(self.runner_object, arguments)
|
||||
if changed:
|
||||
if self._module.check_mode:
|
||||
self._module.exit_json(changed=True, msg="Successfully updated the runner %s" % description)
|
||||
|
||||
try:
|
||||
runner.save()
|
||||
except Exception as e:
|
||||
self._module.fail_json(msg="Failed to update runner: %s " % to_native(e))
|
||||
|
||||
self.runner_object = runner
|
||||
if changed:
|
||||
if self._module.check_mode:
|
||||
self._module.exit_json(changed=True, msg="Successfully created or updated the runner %s" % description)
|
||||
|
||||
try:
|
||||
runner.save()
|
||||
except Exception as e:
|
||||
self._module.fail_json(msg="Failed to update runner: %s " % to_native(e))
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return changed
|
||||
|
||||
'''
|
||||
@param arguments Attributes of the runner
|
||||
@@ -275,7 +303,12 @@ class GitLabRunner(object):
|
||||
return True
|
||||
|
||||
try:
|
||||
runner = self._gitlab.runners.create(arguments)
|
||||
if arguments.get('token') is not None:
|
||||
runner = self._gitlab.runners.create(arguments)
|
||||
elif LooseVersion(gitlab.__version__) < LooseVersion('4.0.0'):
|
||||
self._module.fail_json(msg="New runner creation workflow requires python-gitlab 4.0.0 or higher")
|
||||
else:
|
||||
runner = self._gitlab.user.runners.create(arguments)
|
||||
except (gitlab.exceptions.GitlabCreateError) as e:
|
||||
self._module.fail_json(msg="Failed to create runner: %s " % to_native(e))
|
||||
|
||||
@@ -348,6 +381,7 @@ def main():
|
||||
argument_spec.update(dict(
|
||||
description=dict(type='str', required=True, aliases=["name"]),
|
||||
active=dict(type='bool', default=True),
|
||||
paused=dict(type='bool', default=False),
|
||||
owned=dict(type='bool', default=False),
|
||||
tag_list=dict(type='list', elements='str', default=[]),
|
||||
run_untagged=dict(type='bool', default=True),
|
||||
@@ -372,6 +406,7 @@ def main():
|
||||
['project', 'owned'],
|
||||
['group', 'owned'],
|
||||
['project', 'group'],
|
||||
['active', 'paused'],
|
||||
],
|
||||
required_together=[
|
||||
['api_username', 'api_password'],
|
||||
@@ -379,12 +414,11 @@ def main():
|
||||
required_one_of=[
|
||||
['api_username', 'api_token', 'api_oauth_token', 'api_job_token'],
|
||||
],
|
||||
required_if=[
|
||||
('state', 'present', ['registration_token']),
|
||||
],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
state = module.params['state']
|
||||
runner_description = module.params['description']
|
||||
@@ -398,7 +432,6 @@ def main():
|
||||
project = module.params['project']
|
||||
group = module.params['group']
|
||||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
gitlab_project = None
|
||||
gitlab_group = None
|
||||
|
||||
@@ -432,6 +465,8 @@ def main():
|
||||
"access_level": access_level,
|
||||
"maximum_timeout": maximum_timeout,
|
||||
"registration_token": registration_token,
|
||||
"group": group,
|
||||
"project": project,
|
||||
}):
|
||||
module.exit_json(changed=True, runner=gitlab_runner.runner_object._attrs,
|
||||
msg="Successfully created or updated the runner %s" % runner_description)
|
||||
|
||||
@@ -27,7 +27,6 @@ author:
|
||||
- Lennert Mertens (@LennertMertens)
|
||||
- Stef Graces (@stgrace)
|
||||
requirements:
|
||||
- python >= 2.7
|
||||
- python-gitlab python module
|
||||
- administrator rights on the GitLab server
|
||||
extends_documentation_fragment:
|
||||
@@ -151,7 +150,6 @@ EXAMPLES = '''
|
||||
community.general.gitlab_user:
|
||||
api_url: https://gitlab.example.com/
|
||||
api_token: "{{ access_token }}"
|
||||
validate_certs: false
|
||||
username: myusername
|
||||
state: absent
|
||||
|
||||
@@ -191,7 +189,6 @@ EXAMPLES = '''
|
||||
community.general.gitlab_user:
|
||||
api_url: https://gitlab.example.com/
|
||||
api_token: "{{ access_token }}"
|
||||
validate_certs: false
|
||||
username: myusername
|
||||
state: blocked
|
||||
|
||||
@@ -199,7 +196,6 @@ EXAMPLES = '''
|
||||
community.general.gitlab_user:
|
||||
api_url: https://gitlab.example.com/
|
||||
api_token: "{{ access_token }}"
|
||||
validate_certs: false
|
||||
username: myusername
|
||||
state: unblocked
|
||||
'''
|
||||
@@ -234,7 +230,7 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.gitlab import (
|
||||
auth_argument_spec, find_group, gitlab_authentication, gitlab, ensure_gitlab_package
|
||||
auth_argument_spec, find_group, gitlab_authentication, gitlab
|
||||
)
|
||||
|
||||
|
||||
@@ -616,7 +612,9 @@ def main():
|
||||
('state', 'present', ['name', 'email']),
|
||||
)
|
||||
)
|
||||
ensure_gitlab_package(module)
|
||||
|
||||
# check prerequisites and connect to gitlab server
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
user_name = module.params['name']
|
||||
state = module.params['state']
|
||||
@@ -635,8 +633,6 @@ def main():
|
||||
user_identities = module.params['identities']
|
||||
overwrite_identities = module.params['overwrite_identities']
|
||||
|
||||
gitlab_instance = gitlab_authentication(module)
|
||||
|
||||
gitlab_user = GitLabUser(module, gitlab_instance)
|
||||
user_exists = gitlab_user.exists_user(user_username)
|
||||
if user_exists:
|
||||
|
||||
@@ -43,8 +43,7 @@ options:
|
||||
type: str
|
||||
force:
|
||||
description:
|
||||
- Discards uncommitted changes. Runs C(hg update -C). Prior to
|
||||
Ansible 1.9, the default was V(true).
|
||||
- Discards uncommitted changes. Runs C(hg update -C).
|
||||
type: bool
|
||||
default: false
|
||||
purge:
|
||||
|
||||
@@ -19,8 +19,6 @@ description:
|
||||
These information includes hardware and network related information useful
|
||||
for provisioning (e.g. macaddress, uuid).
|
||||
- This module requires the C(hpilo) python module.
|
||||
- This module was called C(hpilo_facts) before Ansible 2.9, returning C(ansible_facts).
|
||||
Note that the M(community.general.hpilo_info) module no longer returns C(ansible_facts)!
|
||||
extends_documentation_fragment:
|
||||
- community.general.attributes
|
||||
- community.general.attributes.info_module
|
||||
|
||||
@@ -16,8 +16,6 @@ description:
|
||||
- Builds Redfish URIs locally and sends them to remote iDRAC controllers to
|
||||
get information back.
|
||||
- For use with Dell EMC iDRAC operations that require Redfish OEM extensions.
|
||||
- This module was called C(idrac_redfish_facts) before Ansible 2.9, returning C(ansible_facts).
|
||||
Note that the M(community.general.idrac_redfish_info) module no longer returns C(ansible_facts)!
|
||||
extends_documentation_fragment:
|
||||
- community.general.attributes
|
||||
- community.general.attributes.info_module
|
||||
|
||||
@@ -100,7 +100,7 @@ EXAMPLES = r'''
|
||||
hostname: '{{ imc_hostname }}'
|
||||
username: '{{ imc_username }}'
|
||||
password: '{{ imc_password }}'
|
||||
validate_certs: false
|
||||
validate_certs: false # only do this when you trust the network!
|
||||
content: |
|
||||
<configConfMo><inConfig>
|
||||
<computeRackUnit dn="sys/rack-unit-1" adminPower="down"/>
|
||||
@@ -112,7 +112,7 @@ EXAMPLES = r'''
|
||||
hostname: '{{ imc_hostname }}'
|
||||
username: '{{ imc_username }}'
|
||||
password: '{{ imc_password }}'
|
||||
validate_certs: false
|
||||
validate_certs: false # only do this when you trust the network!
|
||||
timeout: 120
|
||||
content: |
|
||||
<!-- Configure Serial-on-LAN -->
|
||||
@@ -137,7 +137,7 @@ EXAMPLES = r'''
|
||||
hostname: '{{ imc_hostname }}'
|
||||
username: '{{ imc_username }}'
|
||||
password: '{{ imc_password }}'
|
||||
validate_certs: false
|
||||
validate_certs: false # only do this when you trust the network!
|
||||
content: |
|
||||
<!-- Configure PXE boot -->
|
||||
<configConfMo><inConfig>
|
||||
@@ -155,7 +155,7 @@ EXAMPLES = r'''
|
||||
hostname: '{{ imc_host }}'
|
||||
username: '{{ imc_username }}'
|
||||
password: '{{ imc_password }}'
|
||||
validate_certs: false
|
||||
validate_certs: false # only do this when you trust the network!
|
||||
content: |
|
||||
<configConfMo><inConfig>
|
||||
<lsbootStorage dn="sys/rack-unit-1/boot-policy/storage-read-write" access="read-write" order="1" type="storage"/>
|
||||
@@ -167,7 +167,7 @@ EXAMPLES = r'''
|
||||
hostname: '{{ imc_host }}'
|
||||
username: '{{ imc_username }}'
|
||||
password: '{{ imc_password }}'
|
||||
validate_certs: false
|
||||
validate_certs: false # only do this when you trust the network!
|
||||
content: |
|
||||
<configConfMo><inConfig>
|
||||
<computeRackUnit dn="sys/rack-unit-1" usrLbl="Customer Lab - POD{{ pod_id }} - {{ inventory_hostname_short }}"/>
|
||||
@@ -179,7 +179,7 @@ EXAMPLES = r'''
|
||||
hostname: '{{ imc_host }}'
|
||||
username: '{{ imc_username }}'
|
||||
password: '{{ imc_password }}'
|
||||
validate_certs: false
|
||||
validate_certs: false # only do this when you trust the network!
|
||||
timeout: 120
|
||||
content: |
|
||||
<configConfMo><inConfig>
|
||||
|
||||
@@ -62,9 +62,6 @@ options:
|
||||
description:
|
||||
- Image UUID. Can either be a full UUID or V(*) for all images.
|
||||
type: str
|
||||
|
||||
requirements:
|
||||
- python >= 2.6
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
|
||||
@@ -17,7 +17,6 @@ description:
|
||||
- Manage InfluxDB databases.
|
||||
author: "Kamil Szczygiel (@kamsz)"
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "influxdb >= 0.9"
|
||||
- requests
|
||||
attributes:
|
||||
|
||||
@@ -16,7 +16,6 @@ description:
|
||||
- Query data points from InfluxDB.
|
||||
author: "René Moser (@resmo)"
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "influxdb >= 0.9"
|
||||
attributes:
|
||||
check_mode:
|
||||
|
||||
@@ -17,7 +17,6 @@ description:
|
||||
- Manage InfluxDB retention policies.
|
||||
author: "Kamil Szczygiel (@kamsz)"
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "influxdb >= 0.9"
|
||||
- requests
|
||||
attributes:
|
||||
@@ -115,7 +114,6 @@ EXAMPLES = r'''
|
||||
duration: INF
|
||||
replication: 1
|
||||
ssl: false
|
||||
validate_certs: false
|
||||
shard_group_duration: 1w
|
||||
state: present
|
||||
|
||||
@@ -127,7 +125,6 @@ EXAMPLES = r'''
|
||||
duration: 5d1h30m
|
||||
replication: 1
|
||||
ssl: false
|
||||
validate_certs: false
|
||||
shard_group_duration: 1d10h30m
|
||||
state: present
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ description:
|
||||
- Manage InfluxDB users.
|
||||
author: "Vitaliy Zhhuta (@zhhuta)"
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "influxdb >= 0.9"
|
||||
attributes:
|
||||
check_mode:
|
||||
|
||||
@@ -16,7 +16,6 @@ description:
|
||||
- Write data points into InfluxDB.
|
||||
author: "René Moser (@resmo)"
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "influxdb >= 0.9"
|
||||
attributes:
|
||||
check_mode:
|
||||
|
||||
@@ -23,8 +23,7 @@ description:
|
||||
- Manage (add, remove, change) individual settings in an INI-style file without having
|
||||
to manage the file as a whole with, say, M(ansible.builtin.template) or M(ansible.builtin.assemble).
|
||||
- Adds missing sections if they don't exist.
|
||||
- Before Ansible 2.0, comments are discarded when the source file is read, and therefore will not show up in the destination file.
|
||||
- Since Ansible 2.3, this module adds missing ending newlines to files to keep in line with the POSIX standard, even when
|
||||
- This module adds missing ending newlines to files to keep in line with the POSIX standard, even when
|
||||
no other modifications need to be applied.
|
||||
attributes:
|
||||
check_mode:
|
||||
@@ -35,7 +34,6 @@ options:
|
||||
path:
|
||||
description:
|
||||
- Path to the INI-style file; this file is created if required.
|
||||
- Before Ansible 2.3 this option was only usable as O(dest).
|
||||
type: path
|
||||
required: true
|
||||
aliases: [ dest ]
|
||||
@@ -43,8 +41,8 @@ options:
|
||||
description:
|
||||
- Section name in INI file. This is added if O(state=present) automatically when
|
||||
a single value is being set.
|
||||
- If left empty, being omitted, or being set to V(null), the O(option) will be placed before the first O(section).
|
||||
- Using V(null) is also required if the config format does not support sections.
|
||||
- If being omitted, the O(option) will be placed before the first O(section).
|
||||
- Omitting O(section) is also required if the config format does not support sections.
|
||||
type: str
|
||||
option:
|
||||
description:
|
||||
@@ -133,7 +131,6 @@ options:
|
||||
version_added: 7.1.0
|
||||
notes:
|
||||
- While it is possible to add an O(option) without specifying a O(value), this makes no sense.
|
||||
- As of Ansible 2.3, the O(dest) option has been changed to O(path) as default, but O(dest) still works as well.
|
||||
- As of community.general 3.2.0, UTF-8 BOM markers are discarded when reading files.
|
||||
author:
|
||||
- Jan-Piet Mens (@jpmens)
|
||||
@@ -141,7 +138,6 @@ author:
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
# Before Ansible 2.3, option 'dest' was used instead of 'path'
|
||||
- name: Ensure "fav=lemonade is in section "[drinks]" in specified file
|
||||
community.general.ini_file:
|
||||
path: /etc/conf
|
||||
@@ -179,6 +175,13 @@ EXAMPLES = r'''
|
||||
- pepsi
|
||||
mode: '0600'
|
||||
state: present
|
||||
|
||||
- name: Add "beverage=lemon juice" outside a section in specified file
|
||||
community.general.ini_file:
|
||||
path: /etc/conf
|
||||
option: beverage
|
||||
value: lemon juice
|
||||
state: present
|
||||
'''
|
||||
|
||||
import io
|
||||
|
||||
@@ -12,14 +12,14 @@ __metaclass__ = type
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: interfaces_file
|
||||
short_description: Tweak settings in /etc/network/interfaces files
|
||||
short_description: Tweak settings in C(/etc/network/interfaces) files
|
||||
extends_documentation_fragment:
|
||||
- ansible.builtin.files
|
||||
- community.general.attributes
|
||||
description:
|
||||
- Manage (add, remove, change) individual interface options in an interfaces-style file without having
|
||||
to manage the file as a whole with, say, M(ansible.builtin.template) or M(ansible.builtin.assemble). Interface has to be presented in a file.
|
||||
- Read information about interfaces from interfaces-styled files
|
||||
- Read information about interfaces from interfaces-styled files.
|
||||
attributes:
|
||||
check_mode:
|
||||
support: full
|
||||
@@ -29,27 +29,27 @@ options:
|
||||
dest:
|
||||
type: path
|
||||
description:
|
||||
- Path to the interfaces file
|
||||
- Path to the interfaces file.
|
||||
default: /etc/network/interfaces
|
||||
iface:
|
||||
type: str
|
||||
description:
|
||||
- Name of the interface, required for value changes or option remove
|
||||
- Name of the interface, required for value changes or option remove.
|
||||
address_family:
|
||||
type: str
|
||||
description:
|
||||
- Address family of the interface, useful if same interface name is used for both inet and inet6
|
||||
- Address family of the interface, useful if same interface name is used for both V(inet) and V(inet6).
|
||||
option:
|
||||
type: str
|
||||
description:
|
||||
- Name of the option, required for value changes or option remove
|
||||
- Name of the option, required for value changes or option remove.
|
||||
value:
|
||||
type: str
|
||||
description:
|
||||
- If O(option) is not presented for the O(iface) and O(state) is V(present) option will be added.
|
||||
If O(option) already exists and is not V(pre-up), V(up), V(post-up) or V(down), it's value will be updated.
|
||||
V(pre-up), V(up), V(post-up) and V(down) options cannot be updated, only adding new options, removing existing
|
||||
ones or cleaning the whole option set are supported
|
||||
ones or cleaning the whole option set are supported.
|
||||
backup:
|
||||
description:
|
||||
- Create a backup file including the timestamp information so you can get
|
||||
@@ -64,72 +64,76 @@ options:
|
||||
choices: [ "present", "absent" ]
|
||||
|
||||
notes:
|
||||
- If option is defined multiple times last one will be updated but all will be deleted in case of an absent state
|
||||
- If option is defined multiple times last one will be updated but all will be deleted in case of an absent state.
|
||||
requirements: []
|
||||
author: "Roman Belyakovsky (@hryamzik)"
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
dest:
|
||||
description: destination file/path
|
||||
description: Destination file/path.
|
||||
returned: success
|
||||
type: str
|
||||
sample: "/etc/network/interfaces"
|
||||
ifaces:
|
||||
description: interfaces dictionary
|
||||
description: Interfaces dictionary.
|
||||
returned: success
|
||||
type: complex
|
||||
type: dict
|
||||
contains:
|
||||
ifaces:
|
||||
description: interface dictionary
|
||||
description: Interface dictionary.
|
||||
returned: success
|
||||
type: dict
|
||||
contains:
|
||||
eth0:
|
||||
description: Name of the interface
|
||||
description: Name of the interface.
|
||||
returned: success
|
||||
type: dict
|
||||
contains:
|
||||
address_family:
|
||||
description: interface address family
|
||||
description: Interface address family.
|
||||
returned: success
|
||||
type: str
|
||||
sample: "inet"
|
||||
method:
|
||||
description: interface method
|
||||
description: Interface method.
|
||||
returned: success
|
||||
type: str
|
||||
sample: "manual"
|
||||
mtu:
|
||||
description: other options, all values returned as strings
|
||||
description: Other options, all values returned as strings.
|
||||
returned: success
|
||||
type: str
|
||||
sample: "1500"
|
||||
pre-up:
|
||||
description: list of C(pre-up) scripts
|
||||
description: List of C(pre-up) scripts.
|
||||
returned: success
|
||||
type: list
|
||||
elements: str
|
||||
sample:
|
||||
- "route add -net 10.10.10.0/24 gw 10.10.10.1 dev eth1"
|
||||
- "route add -net 10.10.11.0/24 gw 10.10.11.1 dev eth2"
|
||||
up:
|
||||
description: list of C(up) scripts
|
||||
description: List of C(up) scripts.
|
||||
returned: success
|
||||
type: list
|
||||
elements: str
|
||||
sample:
|
||||
- "route add -net 10.10.10.0/24 gw 10.10.10.1 dev eth1"
|
||||
- "route add -net 10.10.11.0/24 gw 10.10.11.1 dev eth2"
|
||||
post-up:
|
||||
description: list of C(post-up) scripts
|
||||
description: List of C(post-up) scripts.
|
||||
returned: success
|
||||
type: list
|
||||
elements: str
|
||||
sample:
|
||||
- "route add -net 10.10.10.0/24 gw 10.10.10.1 dev eth1"
|
||||
- "route add -net 10.10.11.0/24 gw 10.10.11.1 dev eth2"
|
||||
down:
|
||||
description: list of C(down) scripts
|
||||
description: List of C(down) scripts.
|
||||
returned: success
|
||||
type: list
|
||||
elements: str
|
||||
sample:
|
||||
- "route del -net 10.10.10.0/24 gw 10.10.10.1 dev eth1"
|
||||
- "route del -net 10.10.11.0/24 gw 10.10.11.1 dev eth2"
|
||||
@@ -336,6 +340,8 @@ def addOptionAfterLine(option, value, iface, lines, last_line_dict, iface_option
|
||||
changed = False
|
||||
for ln in lines:
|
||||
if ln.get('line_type', '') == 'iface' and ln.get('iface', '') == iface and value != ln.get('params', {}).get('method', ''):
|
||||
if address_family is not None and ln.get('address_family') != address_family:
|
||||
continue
|
||||
changed = True
|
||||
ln['line'] = re.sub(ln.get('params', {}).get('method', '') + '$', value, ln.get('line'))
|
||||
ln['params']['method'] = value
|
||||
|
||||
@@ -94,8 +94,9 @@ options:
|
||||
description:
|
||||
- The authentication type to use by default.
|
||||
- The choice V(idp) has been added in community.general 7.3.0.
|
||||
- The choice V(passkey) has been added in community.general 8.1.0.
|
||||
aliases: ["userauthtype"]
|
||||
choices: ["password", "radius", "otp", "pkinit", "hardened", "idp", "disabled"]
|
||||
choices: ["password", "radius", "otp", "pkinit", "hardened", "idp", "passkey", "disabled"]
|
||||
type: list
|
||||
elements: str
|
||||
version_added: '2.5.0'
|
||||
@@ -360,7 +361,7 @@ def main():
|
||||
ipauserauthtype=dict(type='list', elements='str',
|
||||
aliases=['userauthtype'],
|
||||
choices=["password", "radius", "otp", "pkinit",
|
||||
"hardened", "idp", "disabled"]),
|
||||
"hardened", "idp", "passkey", "disabled"]),
|
||||
ipausersearchfields=dict(type='list', elements='str',
|
||||
aliases=['usersearchfields']),
|
||||
ipauserobjectclasses=dict(type='list', elements='str',
|
||||
|
||||
@@ -118,7 +118,6 @@ EXAMPLES = r'''
|
||||
ipa_host: ipa.example.com
|
||||
ipa_user: admin
|
||||
ipa_pass: topsecret
|
||||
validate_certs: false
|
||||
random_password: true
|
||||
|
||||
- name: Ensure host is disabled
|
||||
|
||||
@@ -47,6 +47,22 @@ options:
|
||||
type: list
|
||||
elements: str
|
||||
version_added: 2.0.0
|
||||
deny_cmd:
|
||||
description:
|
||||
- List of denied commands assigned to the rule.
|
||||
- If an empty list is passed all commands will be removed from the rule.
|
||||
- If option is omitted commands will not be checked or changed.
|
||||
type: list
|
||||
elements: str
|
||||
version_added: 8.1.0
|
||||
deny_cmdgroup:
|
||||
description:
|
||||
- List of denied command groups assigned to the rule.
|
||||
- If an empty list is passed all command groups will be removed from the rule.
|
||||
- If option is omitted command groups will not be checked or changed.
|
||||
type: list
|
||||
elements: str
|
||||
version_added: 8.1.0
|
||||
description:
|
||||
description:
|
||||
- Description of the sudo rule.
|
||||
@@ -246,6 +262,12 @@ class SudoRuleIPAClient(IPAClient):
|
||||
def sudorule_add_allow_command_group(self, name, item):
|
||||
return self._post_json(method='sudorule_add_allow_command', name=name, item={'sudocmdgroup': item})
|
||||
|
||||
def sudorule_add_deny_command(self, name, item):
|
||||
return self._post_json(method='sudorule_add_deny_command', name=name, item={'sudocmd': item})
|
||||
|
||||
def sudorule_add_deny_command_group(self, name, item):
|
||||
return self._post_json(method='sudorule_add_deny_command', name=name, item={'sudocmdgroup': item})
|
||||
|
||||
def sudorule_remove_allow_command(self, name, item):
|
||||
return self._post_json(method='sudorule_remove_allow_command', name=name, item=item)
|
||||
|
||||
@@ -303,6 +325,8 @@ def ensure(module, client):
|
||||
cmd = module.params['cmd']
|
||||
cmdgroup = module.params['cmdgroup']
|
||||
cmdcategory = module.params['cmdcategory']
|
||||
deny_cmd = module.params['deny_cmd']
|
||||
deny_cmdgroup = module.params['deny_cmdgroup']
|
||||
host = module.params['host']
|
||||
hostcategory = module.params['hostcategory']
|
||||
hostgroup = module.params['hostgroup']
|
||||
@@ -359,6 +383,16 @@ def ensure(module, client):
|
||||
if not module.check_mode:
|
||||
client.sudorule_add_allow_command_group(name=name, item=cmdgroup)
|
||||
|
||||
if deny_cmd is not None:
|
||||
changed = category_changed(module, client, 'cmdcategory', ipa_sudorule) or changed
|
||||
if not module.check_mode:
|
||||
client.sudorule_add_deny_command(name=name, item=deny_cmd)
|
||||
|
||||
if deny_cmdgroup is not None:
|
||||
changed = category_changed(module, client, 'cmdcategory', ipa_sudorule) or changed
|
||||
if not module.check_mode:
|
||||
client.sudorule_add_deny_command_group(name=name, item=deny_cmdgroup)
|
||||
|
||||
if runasusercategory is not None:
|
||||
changed = category_changed(module, client, 'iparunasusercategory', ipa_sudorule) or changed
|
||||
|
||||
@@ -433,6 +467,8 @@ def main():
|
||||
cmdgroup=dict(type='list', elements='str'),
|
||||
cmdcategory=dict(type='str', choices=['all']),
|
||||
cn=dict(type='str', required=True, aliases=['name']),
|
||||
deny_cmd=dict(type='list', elements='str'),
|
||||
deny_cmdgroup=dict(type='list', elements='str'),
|
||||
description=dict(type='str'),
|
||||
host=dict(type='list', elements='str'),
|
||||
hostcategory=dict(type='str', choices=['all']),
|
||||
@@ -447,7 +483,9 @@ def main():
|
||||
runasextusers=dict(type='list', elements='str'))
|
||||
module = AnsibleModule(argument_spec=argument_spec,
|
||||
mutually_exclusive=[['cmdcategory', 'cmd'],
|
||||
['cmdcategory', 'deny_cmd'],
|
||||
['cmdcategory', 'cmdgroup'],
|
||||
['cmdcategory', 'deny_cmdgroup'],
|
||||
['hostcategory', 'host'],
|
||||
['hostcategory', 'hostgroup'],
|
||||
['usercategory', 'user'],
|
||||
|
||||
@@ -103,7 +103,8 @@ options:
|
||||
userauthtype:
|
||||
description:
|
||||
- The authentication type to use for the user.
|
||||
choices: ["password", "radius", "otp", "pkinit", "hardened"]
|
||||
- The choice V(idp) and V(passkey) has been added in community.general 8.1.0.
|
||||
choices: ["password", "radius", "otp", "pkinit", "hardened", "idp", "passkey"]
|
||||
type: list
|
||||
elements: str
|
||||
version_added: '1.2.0'
|
||||
@@ -378,7 +379,7 @@ def main():
|
||||
title=dict(type='str'),
|
||||
homedirectory=dict(type='str'),
|
||||
userauthtype=dict(type='list', elements='str',
|
||||
choices=['password', 'radius', 'otp', 'pkinit', 'hardened']))
|
||||
choices=['password', 'radius', 'otp', 'pkinit', 'hardened', 'idp', 'passkey']))
|
||||
|
||||
module = AnsibleModule(argument_spec=argument_spec,
|
||||
supports_check_mode=True)
|
||||
|
||||
@@ -93,7 +93,6 @@ EXAMPLES = r'''
|
||||
ipa_host: ipa.example.com
|
||||
ipa_user: admin
|
||||
ipa_pass: topsecret
|
||||
validate_certs: false
|
||||
|
||||
- name: Ensure vault is present for Admin user
|
||||
community.general.ipa_vault:
|
||||
|
||||
@@ -93,7 +93,6 @@ options:
|
||||
type: bool
|
||||
default: false
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- pyghmi
|
||||
author: "Bulat Gaifullin (@bgaifullin) <gaifullinbf@gmail.com>"
|
||||
'''
|
||||
|
||||
@@ -90,7 +90,6 @@ options:
|
||||
type: str
|
||||
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- pyghmi
|
||||
author: "Bulat Gaifullin (@bgaifullin) <gaifullinbf@gmail.com>"
|
||||
'''
|
||||
|
||||
@@ -50,8 +50,7 @@ options:
|
||||
color:
|
||||
type: str
|
||||
description:
|
||||
- Text color for the message. ("none" is a valid option in 1.6 or later, in 1.6 and prior, the default color is black, not "none").
|
||||
Added 11 more colors in version 2.0.
|
||||
- Text color for the message.
|
||||
default: "none"
|
||||
choices: [ "none", "white", "black", "blue", "green", "red", "brown", "purple", "orange", "yellow", "light_green", "teal", "light_cyan",
|
||||
"light_blue", "pink", "gray", "light_gray"]
|
||||
@@ -79,11 +78,17 @@ options:
|
||||
- Timeout to use while waiting for successful registration and join
|
||||
messages, this is to prevent an endless loop
|
||||
default: 30
|
||||
use_ssl:
|
||||
use_tls:
|
||||
description:
|
||||
- Designates whether TLS/SSL should be used when connecting to the IRC server
|
||||
- O(use_tls) is available since community.general 8.1.0, before the option
|
||||
was exlusively called O(use_ssl). The latter is now an alias of O(use_tls).
|
||||
- B(Note:) for security reasons, you should always set O(use_tls=true) and
|
||||
O(validate_certs=true) whenever possible.
|
||||
type: bool
|
||||
default: false
|
||||
aliases:
|
||||
- use_ssl
|
||||
part:
|
||||
description:
|
||||
- Designates whether user should part from channel after sending message or not.
|
||||
@@ -96,6 +101,16 @@ options:
|
||||
- Text style for the message. Note italic does not work on some clients
|
||||
choices: [ "bold", "underline", "reverse", "italic", "none" ]
|
||||
default: none
|
||||
validate_certs:
|
||||
description:
|
||||
- If set to V(false), the SSL certificates will not be validated.
|
||||
- This should always be set to V(true). Using V(false) is unsafe and should only be done
|
||||
if the network between between Ansible and the IRC server is known to be safe.
|
||||
- B(Note:) for security reasons, you should always set O(use_tls=true) and
|
||||
O(validate_certs=true) whenever possible.
|
||||
default: false
|
||||
type: bool
|
||||
version_added: 8.1.0
|
||||
|
||||
# informational: requirements for nodes
|
||||
requirements: [ socket ]
|
||||
@@ -108,6 +123,8 @@ EXAMPLES = '''
|
||||
- name: Send a message to an IRC channel from nick ansible
|
||||
community.general.irc:
|
||||
server: irc.example.net
|
||||
use_tls: true
|
||||
validate_certs: true
|
||||
channel: #t1
|
||||
msg: Hello world
|
||||
|
||||
@@ -116,6 +133,8 @@ EXAMPLES = '''
|
||||
module: irc
|
||||
port: 6669
|
||||
server: irc.example.net
|
||||
use_tls: true
|
||||
validate_certs: true
|
||||
channel: #t1
|
||||
msg: 'All finished at {{ ansible_date_time.iso8601 }}'
|
||||
color: red
|
||||
@@ -126,6 +145,8 @@ EXAMPLES = '''
|
||||
module: irc
|
||||
port: 6669
|
||||
server: irc.example.net
|
||||
use_tls: true
|
||||
validate_certs: true
|
||||
channel: #t1
|
||||
nick_to:
|
||||
- nick1
|
||||
@@ -150,7 +171,8 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
|
||||
def send_msg(msg, server='localhost', port='6667', channel=None, nick_to=None, key=None, topic=None,
|
||||
nick="ansible", color='none', passwd=False, timeout=30, use_ssl=False, part=True, style=None):
|
||||
nick="ansible", color='none', passwd=False, timeout=30, use_tls=False, validate_certs=True,
|
||||
part=True, style=None):
|
||||
'''send message to IRC'''
|
||||
nick_to = [] if nick_to is None else nick_to
|
||||
|
||||
@@ -194,8 +216,20 @@ def send_msg(msg, server='localhost', port='6667', channel=None, nick_to=None, k
|
||||
message = styletext + colortext + msg
|
||||
|
||||
irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
if use_ssl:
|
||||
irc = ssl.wrap_socket(irc)
|
||||
if use_tls:
|
||||
if validate_certs:
|
||||
try:
|
||||
context = ssl.create_default_context()
|
||||
except AttributeError:
|
||||
raise Exception('Need at least Python 2.7.9 for SSL certificate validation')
|
||||
else:
|
||||
if getattr(ssl, 'PROTOCOL_TLS', None) is not None:
|
||||
# Supported since Python 2.7.13
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
|
||||
else:
|
||||
context = ssl.SSLContext()
|
||||
context.verify_mode = ssl.CERT_NONE
|
||||
irc = context.wrap_socket(irc)
|
||||
irc.connect((server, int(port)))
|
||||
|
||||
if passwd:
|
||||
@@ -275,7 +309,8 @@ def main():
|
||||
passwd=dict(no_log=True),
|
||||
timeout=dict(type='int', default=30),
|
||||
part=dict(type='bool', default=True),
|
||||
use_ssl=dict(type='bool', default=False)
|
||||
use_tls=dict(type='bool', default=False, aliases=['use_ssl']),
|
||||
validate_certs=dict(type='bool', default=False),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
required_one_of=[['channel', 'nick_to']]
|
||||
@@ -294,12 +329,13 @@ def main():
|
||||
key = module.params["key"]
|
||||
passwd = module.params["passwd"]
|
||||
timeout = module.params["timeout"]
|
||||
use_ssl = module.params["use_ssl"]
|
||||
use_tls = module.params["use_tls"]
|
||||
part = module.params["part"]
|
||||
style = module.params["style"]
|
||||
validate_certs = module.params["validate_certs"]
|
||||
|
||||
try:
|
||||
send_msg(msg, server, port, channel, nick_to, key, topic, nick, color, passwd, timeout, use_ssl, part, style)
|
||||
send_msg(msg, server, port, channel, nick_to, key, topic, nick, color, passwd, timeout, use_tls, validate_certs, part, style)
|
||||
except Exception as e:
|
||||
module.fail_json(msg="unable to send to IRC: %s" % to_native(e), exception=traceback.format_exc())
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ author:
|
||||
- Diane Wang (@Tomorrow9) <dianew@vmware.com>
|
||||
requirements:
|
||||
- "pycdlib"
|
||||
- "python >= 2.7"
|
||||
version_added: '0.2.0'
|
||||
|
||||
extends_documentation_fragment:
|
||||
|
||||
@@ -20,7 +20,6 @@ author:
|
||||
- Yuhua Zou (@ZouYuhua) <zouy@vmware.com>
|
||||
requirements:
|
||||
- "pycdlib"
|
||||
- "python >= 2.7"
|
||||
version_added: '5.8.0'
|
||||
|
||||
extends_documentation_fragment:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user