mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-30 10:26:52 +00:00
Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5fd87a1811 | ||
|
|
e463f94ce9 | ||
|
|
4205a94f0c | ||
|
|
bcfcdd1052 | ||
|
|
2638413475 | ||
|
|
9ea55a81b3 | ||
|
|
32c1e39df1 | ||
|
|
7bb23e9649 | ||
|
|
eeedd97eec | ||
|
|
4e1ba6af46 | ||
|
|
aa1ae85b55 | ||
|
|
4d2873afd2 | ||
|
|
43c1d9f66c | ||
|
|
201f49acd9 | ||
|
|
6f0d46d0a2 | ||
|
|
92529d5605 | ||
|
|
f635ed6c2e | ||
|
|
0e0fce54ab | ||
|
|
caae74abd8 | ||
|
|
c01a16c1bc | ||
|
|
15c832b8d5 | ||
|
|
b104c580e1 | ||
|
|
a4e1beefe3 | ||
|
|
b0898e5c51 | ||
|
|
eca1d0191f | ||
|
|
08036e7f65 | ||
|
|
3c6c9ba425 | ||
|
|
3eeb0009cb | ||
|
|
c92215d339 | ||
|
|
1a4ae5e9aa | ||
|
|
9ecfa370ff | ||
|
|
f3828ebdd7 | ||
|
|
7b71ffa1c4 | ||
|
|
d7494bb9e4 | ||
|
|
443a1c3ed7 | ||
|
|
177e327c24 | ||
|
|
6ff4b479ab | ||
|
|
feb8d421dc | ||
|
|
d633f6c4c8 | ||
|
|
3405b24fa6 | ||
|
|
540c92fa62 | ||
|
|
8cf2358fb1 | ||
|
|
2d92ab91eb | ||
|
|
d03abae7a1 | ||
|
|
d7efa7eb13 | ||
|
|
a9a9e723e5 | ||
|
|
3d87fbf6f9 | ||
|
|
9e6960639f | ||
|
|
7074a52721 | ||
|
|
d18afe6746 | ||
|
|
ee03af599c | ||
|
|
42c643ddda | ||
|
|
a7d89fc1ee | ||
|
|
d4477615a9 | ||
|
|
c84738324e | ||
|
|
0c3ae48f85 |
@@ -53,7 +53,7 @@ variables:
|
||||
resources:
|
||||
containers:
|
||||
- container: default
|
||||
image: quay.io/ansible/azure-pipelines-test-container:3.0.0
|
||||
image: quay.io/ansible/azure-pipelines-test-container:4.0.1
|
||||
|
||||
pool: Standard
|
||||
|
||||
@@ -171,10 +171,10 @@ stages:
|
||||
parameters:
|
||||
testFormat: devel/{0}
|
||||
targets:
|
||||
- name: Alpine 3.17
|
||||
test: alpine/3.17
|
||||
# - name: Fedora 37
|
||||
# test: fedora/37
|
||||
- name: Alpine 3.18
|
||||
test: alpine/3.18
|
||||
# - name: Fedora 38
|
||||
# test: fedora/38
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu/22.04
|
||||
groups:
|
||||
@@ -189,12 +189,12 @@ stages:
|
||||
targets:
|
||||
- name: macOS 13.2
|
||||
test: macos/13.2
|
||||
- name: RHEL 9.1
|
||||
test: rhel/9.1
|
||||
- name: RHEL 9.2
|
||||
test: rhel/9.2
|
||||
- name: RHEL 8.8
|
||||
test: rhel/8.8
|
||||
- name: FreeBSD 13.2
|
||||
test: freebsd/13.2
|
||||
- name: FreeBSD 12.4
|
||||
test: freebsd/12.4
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
@@ -207,10 +207,16 @@ stages:
|
||||
parameters:
|
||||
testFormat: 2.15/{0}
|
||||
targets:
|
||||
- name: RHEL 9.1
|
||||
test: rhel/9.1
|
||||
- name: RHEL 8.7
|
||||
test: rhel/8.7
|
||||
- name: RHEL 7.9
|
||||
test: rhel/7.9
|
||||
- name: FreeBSD 13.1
|
||||
test: freebsd/13.1
|
||||
- name: FreeBSD 12.4
|
||||
test: freebsd/12.4
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
@@ -259,8 +265,8 @@ stages:
|
||||
parameters:
|
||||
testFormat: devel/linux/{0}
|
||||
targets:
|
||||
- name: Fedora 37
|
||||
test: fedora37
|
||||
- name: Fedora 38
|
||||
test: fedora38
|
||||
- name: openSUSE 15
|
||||
test: opensuse15
|
||||
- name: Ubuntu 20.04
|
||||
@@ -281,6 +287,8 @@ stages:
|
||||
parameters:
|
||||
testFormat: 2.15/linux/{0}
|
||||
targets:
|
||||
- name: Fedora 37
|
||||
test: fedora37
|
||||
- name: CentOS 7
|
||||
test: centos7
|
||||
groups:
|
||||
|
||||
7
.github/BOTMETA.yml
vendored
7
.github/BOTMETA.yml
vendored
@@ -527,6 +527,7 @@ files:
|
||||
keywords: gitlab source_control
|
||||
maintainers: $team_gitlab
|
||||
notify: jlozadad
|
||||
ignore: dj-wasabi
|
||||
$modules/gitlab_branch.py:
|
||||
maintainers: paytroff
|
||||
$modules/gitlab_project_variable.py:
|
||||
@@ -669,9 +670,9 @@ files:
|
||||
$modules/jenkins_script.py:
|
||||
maintainers: hogarthj
|
||||
$modules/jira.py:
|
||||
ignore: DWSR
|
||||
ignore: DWSR tarka
|
||||
labels: jira
|
||||
maintainers: Slezhuk tarka pertoft
|
||||
maintainers: Slezhuk pertoft
|
||||
$modules/kdeconfig.py:
|
||||
maintainers: smeso
|
||||
$modules/kernel_blacklist.py:
|
||||
@@ -1393,7 +1394,7 @@ macros:
|
||||
team_cyberark_conjur: jvanderhoof ryanprior
|
||||
team_e_spirit: MatrixCrawler getjack
|
||||
team_flatpak: JayKayy oolongbrothers
|
||||
team_gitlab: Lunik Shaps dj-wasabi marwatk waheedi zanssa scodeman metanovii sh0shin nejch lgatellier suukit
|
||||
team_gitlab: Lunik Shaps marwatk waheedi zanssa scodeman metanovii sh0shin nejch lgatellier suukit
|
||||
team_hpux: bcoca davx8342
|
||||
team_huawei: QijunPan TommyLike edisonxiang freesky-edward hwDCN niuzhenguo xuxiaowei0512 yanzhangi zengchen1024 zhongjun2
|
||||
team_ipa: Akasurde Nosmoht fxfitz justchris1
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.0.1
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: mixed-line-ending
|
||||
args: [--fix=lf]
|
||||
- id: fix-encoding-pragma
|
||||
- id: check-ast
|
||||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||
rev: v1.9.0
|
||||
hooks:
|
||||
- id: rst-backticks
|
||||
types: [file]
|
||||
files: changelogs/fragments/.*\.(yml|yaml)$
|
||||
@@ -6,6 +6,68 @@ Community General Release Notes
|
||||
|
||||
This changelog describes changes after version 5.0.0.
|
||||
|
||||
v6.6.4
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- redfish_utils - use ``Controllers`` key in redfish data to obtain Storage controllers properties (https://github.com/ansible-collections/community.general/pull/7081).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- bitwarden lookup plugin - the plugin made assumptions about the structure of a Bitwarden JSON object which may have been broken by an update in the Bitwarden API. Remove assumptions, and allow queries for general fields such as ``notes`` (https://github.com/ansible-collections/community.general/pull/7061).
|
||||
- cmd_runner module utils - when a parameter in ``argument_spec`` has no type, meaning it is implicitly a ``str``, ``CmdRunner`` would fail trying to find the ``type`` key in that dictionary (https://github.com/ansible-collections/community.general/pull/6968).
|
||||
- ejabberd_user - module was failing to detect whether user was already created and/or password was changed (https://github.com/ansible-collections/community.general/pull/7033).
|
||||
- ejabberd_user - provide meaningful error message when the ``ejabberdctl`` command is not found (https://github.com/ansible-collections/community.general/pull/7028, https://github.com/ansible-collections/community.general/issues/6949).
|
||||
- oci_utils module utils - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
|
||||
- proxmox module utils - fix proxmoxer library version check (https://github.com/ansible-collections/community.general/issues/6974, https://github.com/ansible-collections/community.general/issues/6975, https://github.com/ansible-collections/community.general/pull/6980).
|
||||
- proxmox_kvm - when ``name`` option is provided without ``vmid`` and VM with that name already exists then no new VM will be created (https://github.com/ansible-collections/community.general/issues/6911, https://github.com/ansible-collections/community.general/pull/6981).
|
||||
- proxmox_user_info - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
|
||||
- rundeck - fix ``TypeError`` on 404 API response (https://github.com/ansible-collections/community.general/pull/6983).
|
||||
|
||||
v6.6.3
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- cobbler inventory plugin - convert Ansible unicode strings to native Python unicode strings before passing user/password to XMLRPC client (https://github.com/ansible-collections/community.general/pull/6923).
|
||||
- redfish_info - fix for ``GetVolumeInventory``, Controller name was getting populated incorrectly and duplicates were seen in the volumes retrieved (https://github.com/ansible-collections/community.general/pull/6719).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- datadog_downtime - presence of ``rrule`` param lead to the Datadog API returning Bad Request due to a missing recurrence type (https://github.com/ansible-collections/community.general/pull/6811).
|
||||
- icinga2_host - fix a key error when updating an existing host (https://github.com/ansible-collections/community.general/pull/6748).
|
||||
- ipa_dnszone - fix 'idnsallowsyncptr' key error for reverse zone (https://github.com/ansible-collections/community.general/pull/6906, https://github.com/ansible-collections/community.general/issues/6905).
|
||||
- locale_gen - now works for locales without the underscore character such as ``C.UTF-8`` (https://github.com/ansible-collections/community.general/pull/6774, https://github.com/ansible-collections/community.general/issues/5142, https://github.com/ansible-collections/community.general/issues/4305).
|
||||
- machinectl become plugin - mark plugin as ``require_tty`` to automatically disable pipelining, with which this plugin is not compatible (https://github.com/ansible-collections/community.general/issues/6932, https://github.com/ansible-collections/community.general/pull/6935).
|
||||
- nmcli - fix support for empty list (in compare and scrape) (https://github.com/ansible-collections/community.general/pull/6769).
|
||||
- openbsd_pkg - the pkg_info(1) behavior has changed in OpenBSD >7.3. The error message ``Can't find`` should not lead to an error case (https://github.com/ansible-collections/community.general/pull/6785).
|
||||
- pacman - module recognizes the output of ``yay`` running as ``root`` (https://github.com/ansible-collections/community.general/pull/6713).
|
||||
- proxmox - fix error when a configuration had no ``template`` field (https://github.com/ansible-collections/community.general/pull/6838, https://github.com/ansible-collections/community.general/issues/5372).
|
||||
- proxmox module utils - add logic to detect whether an old Promoxer complains about the ``token_name`` and ``token_value`` parameters and provide a better error message when that happens (https://github.com/ansible-collections/community.general/pull/6839, https://github.com/ansible-collections/community.general/issues/5371).
|
||||
- proxmox_disk - fix unable to create ``cdrom`` media due to ``size`` always being appended (https://github.com/ansible-collections/community.general/pull/6770).
|
||||
- proxmox_kvm - ``absent`` state with ``force`` specified failed to stop the VM due to the ``timeout`` value not being passed to ``stop_vm`` (https://github.com/ansible-collections/community.general/pull/6827).
|
||||
- redfish_info - fix ``ListUsers`` to not show empty account slots (https://github.com/ansible-collections/community.general/issues/6771, https://github.com/ansible-collections/community.general/pull/6772).
|
||||
- refish_utils module utils - changing variable names to avoid issues occuring when fetching Volumes data (https://github.com/ansible-collections/community.general/pull/6883).
|
||||
- rhsm_repository - when using the ``purge`` option, the ``repositories``
|
||||
dictionary element in the returned JSON is now properly updated according
|
||||
to the pruning operation
|
||||
(https://github.com/ansible-collections/community.general/pull/6676).
|
||||
|
||||
v6.6.2
|
||||
======
|
||||
|
||||
|
||||
@@ -121,19 +121,3 @@ Creating new modules and plugins requires a bit more work than other Pull Reques
|
||||
listed as `maintainers` will be pinged for new issues and PRs that modify the module/plugin or its tests.
|
||||
|
||||
When you add a new plugin/module, we expect that you perform maintainer duty for at least some time after contributing it.
|
||||
|
||||
## pre-commit
|
||||
|
||||
To help ensure high-quality contributions this repository includes a [pre-commit](https://pre-commit.com) configuration which
|
||||
corrects and tests against common issues that would otherwise cause CI to fail. To begin using these pre-commit hooks see
|
||||
the [Installation](#installation) section below.
|
||||
|
||||
This is optional and not required to contribute to this repository.
|
||||
|
||||
### Installation
|
||||
|
||||
Follow the [instructions](https://pre-commit.com/#install) provided with pre-commit and run `pre-commit install` under the repository base. If for any reason you would like to disable the pre-commit hooks run `pre-commit uninstall`.
|
||||
|
||||
This is optional to run it locally.
|
||||
|
||||
You can trigger it locally with `pre-commit run --all-files` or even to run only for a given file `pre-commit run --files YOUR_FILE`.
|
||||
|
||||
@@ -24,7 +24,7 @@ If you encounter abusive behavior violating the [Ansible Code of Conduct](https:
|
||||
|
||||
## Tested with Ansible
|
||||
|
||||
Tested with the current ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, ansible-core 2.14 releases and the current development version of ansible-core. Ansible-core versions before 2.11.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases.
|
||||
Tested with the current ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, ansible-core 2.14, ansible-core 2.15 releases and the current development version of ansible-core. Ansible-core versions before 2.11.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases.
|
||||
|
||||
Parts of this collection will not work with ansible-core 2.11 on Python 3.12+.
|
||||
|
||||
|
||||
@@ -1424,3 +1424,109 @@ releases:
|
||||
- 6712-gitlab_group-filtered-for-none-values.yml
|
||||
- ini_file-use-inactive-options-when-possible.yml
|
||||
release_date: '2023-06-19'
|
||||
6.6.3:
|
||||
changes:
|
||||
bugfixes:
|
||||
- datadog_downtime - presence of ``rrule`` param lead to the Datadog API returning
|
||||
Bad Request due to a missing recurrence type (https://github.com/ansible-collections/community.general/pull/6811).
|
||||
- icinga2_host - fix a key error when updating an existing host (https://github.com/ansible-collections/community.general/pull/6748).
|
||||
- ipa_dnszone - fix 'idnsallowsyncptr' key error for reverse zone (https://github.com/ansible-collections/community.general/pull/6906,
|
||||
https://github.com/ansible-collections/community.general/issues/6905).
|
||||
- locale_gen - now works for locales without the underscore character such as
|
||||
``C.UTF-8`` (https://github.com/ansible-collections/community.general/pull/6774,
|
||||
https://github.com/ansible-collections/community.general/issues/5142, https://github.com/ansible-collections/community.general/issues/4305).
|
||||
- machinectl become plugin - mark plugin as ``require_tty`` to automatically
|
||||
disable pipelining, with which this plugin is not compatible (https://github.com/ansible-collections/community.general/issues/6932,
|
||||
https://github.com/ansible-collections/community.general/pull/6935).
|
||||
- nmcli - fix support for empty list (in compare and scrape) (https://github.com/ansible-collections/community.general/pull/6769).
|
||||
- openbsd_pkg - the pkg_info(1) behavior has changed in OpenBSD >7.3. The error
|
||||
message ``Can't find`` should not lead to an error case (https://github.com/ansible-collections/community.general/pull/6785).
|
||||
- pacman - module recognizes the output of ``yay`` running as ``root`` (https://github.com/ansible-collections/community.general/pull/6713).
|
||||
- proxmox - fix error when a configuration had no ``template`` field (https://github.com/ansible-collections/community.general/pull/6838,
|
||||
https://github.com/ansible-collections/community.general/issues/5372).
|
||||
- proxmox module utils - add logic to detect whether an old Promoxer complains
|
||||
about the ``token_name`` and ``token_value`` parameters and provide a better
|
||||
error message when that happens (https://github.com/ansible-collections/community.general/pull/6839,
|
||||
https://github.com/ansible-collections/community.general/issues/5371).
|
||||
- proxmox_disk - fix unable to create ``cdrom`` media due to ``size`` always
|
||||
being appended (https://github.com/ansible-collections/community.general/pull/6770).
|
||||
- proxmox_kvm - ``absent`` state with ``force`` specified failed to stop the
|
||||
VM due to the ``timeout`` value not being passed to ``stop_vm`` (https://github.com/ansible-collections/community.general/pull/6827).
|
||||
- redfish_info - fix ``ListUsers`` to not show empty account slots (https://github.com/ansible-collections/community.general/issues/6771,
|
||||
https://github.com/ansible-collections/community.general/pull/6772).
|
||||
- refish_utils module utils - changing variable names to avoid issues occuring
|
||||
when fetching Volumes data (https://github.com/ansible-collections/community.general/pull/6883).
|
||||
- 'rhsm_repository - when using the ``purge`` option, the ``repositories``
|
||||
|
||||
dictionary element in the returned JSON is now properly updated according
|
||||
|
||||
to the pruning operation
|
||||
|
||||
(https://github.com/ansible-collections/community.general/pull/6676).
|
||||
|
||||
'
|
||||
minor_changes:
|
||||
- cobbler inventory plugin - convert Ansible unicode strings to native Python
|
||||
unicode strings before passing user/password to XMLRPC client (https://github.com/ansible-collections/community.general/pull/6923).
|
||||
- redfish_info - fix for ``GetVolumeInventory``, Controller name was getting
|
||||
populated incorrectly and duplicates were seen in the volumes retrieved (https://github.com/ansible-collections/community.general/pull/6719).
|
||||
release_summary: Regular bugfix release.
|
||||
fragments:
|
||||
- 6.6.3.yml
|
||||
- 6676-rhsm_repository-fix-returned-repositories-with-purge.yml
|
||||
- 6713-yay-become.yml
|
||||
- 6719-redfish-utils-fix-for-get-volume-inventory.yml
|
||||
- 6748-icinga2_host-datafix.yml
|
||||
- 6769-nmcli-fix-empty-list.yml
|
||||
- 6770-proxmox_disk_create_cdrom.yml
|
||||
- 6771-redfish-filter-empty-account-slots.yml
|
||||
- 6774-locale-gen-fix.yml
|
||||
- 6785-openbsd_pkg_pkg_info_handling.yml
|
||||
- 6811-datadog-downtime-rrule-type.yaml
|
||||
- 6827-proxmox_kvm-force-delete-bug-fix.yaml
|
||||
- 6838-proxmox-dict-template.yml
|
||||
- 6839-promoxer-tokens.yml
|
||||
- 6883-redfish-utils-changing-variable-names-in-get-volume-inventory.yml
|
||||
- 6905-ipa_dnszone-key-error-fix.yml
|
||||
- 6923-cobbler-inventory_unicode.yml
|
||||
- 6935-machinectl-become.yml
|
||||
release_date: '2023-07-16'
|
||||
6.6.4:
|
||||
changes:
|
||||
bugfixes:
|
||||
- bitwarden lookup plugin - the plugin made assumptions about the structure
|
||||
of a Bitwarden JSON object which may have been broken by an update in the
|
||||
Bitwarden API. Remove assumptions, and allow queries for general fields such
|
||||
as ``notes`` (https://github.com/ansible-collections/community.general/pull/7061).
|
||||
- cmd_runner module utils - when a parameter in ``argument_spec`` has no type,
|
||||
meaning it is implicitly a ``str``, ``CmdRunner`` would fail trying to find
|
||||
the ``type`` key in that dictionary (https://github.com/ansible-collections/community.general/pull/6968).
|
||||
- ejabberd_user - module was failing to detect whether user was already created
|
||||
and/or password was changed (https://github.com/ansible-collections/community.general/pull/7033).
|
||||
- ejabberd_user - provide meaningful error message when the ``ejabberdctl``
|
||||
command is not found (https://github.com/ansible-collections/community.general/pull/7028,
|
||||
https://github.com/ansible-collections/community.general/issues/6949).
|
||||
- oci_utils module utils - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
|
||||
- proxmox module utils - fix proxmoxer library version check (https://github.com/ansible-collections/community.general/issues/6974,
|
||||
https://github.com/ansible-collections/community.general/issues/6975, https://github.com/ansible-collections/community.general/pull/6980).
|
||||
- proxmox_kvm - when ``name`` option is provided without ``vmid`` and VM with
|
||||
that name already exists then no new VM will be created (https://github.com/ansible-collections/community.general/issues/6911,
|
||||
https://github.com/ansible-collections/community.general/pull/6981).
|
||||
- proxmox_user_info - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
|
||||
- rundeck - fix ``TypeError`` on 404 API response (https://github.com/ansible-collections/community.general/pull/6983).
|
||||
minor_changes:
|
||||
- redfish_utils - use ``Controllers`` key in redfish data to obtain Storage
|
||||
controllers properties (https://github.com/ansible-collections/community.general/pull/7081).
|
||||
release_summary: Regular bugfix release.
|
||||
fragments:
|
||||
- 6.6.4.yml
|
||||
- 6949-ejabberdctl-error.yml
|
||||
- 6968-cmdrunner-implicit-type.yml
|
||||
- 6980-proxmox-fix-token-auth.yml
|
||||
- 6981-proxmox-fix-vm-creation-when-only-name-provided.yml
|
||||
- 6983-rundeck-fix-typerrror-on-404-api-response.yml
|
||||
- 7033-ejabberd-user-bugs.yml
|
||||
- 7061-fix-bitwarden-get_field.yml
|
||||
- 7081-redfish-utils-fix-for-storagecontrollers-deprecated-key.yaml
|
||||
- 7085-sanity.yml
|
||||
release_date: '2023-08-13'
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace: community
|
||||
name: general
|
||||
version: 6.6.2
|
||||
version: 6.6.4
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (https://github.com/ansible)
|
||||
|
||||
@@ -102,6 +102,7 @@ class BecomeModule(BecomeBase):
|
||||
prompt = 'Password: '
|
||||
fail = ('==== AUTHENTICATION FAILED ====',)
|
||||
success = ('==== AUTHENTICATION COMPLETE ====',)
|
||||
require_tty = True # see https://github.com/ansible-collections/community.general/issues/6932
|
||||
|
||||
@staticmethod
|
||||
def remove_ansi_codes(line):
|
||||
|
||||
@@ -48,6 +48,27 @@ DOCUMENTATION = '''
|
||||
default: chroot
|
||||
'''
|
||||
|
||||
EXAMPLES = r"""
|
||||
# Plugin requires root privileges for chroot, -E preserves your env (and location of ~/.ansible):
|
||||
# sudo -E ansible-playbook ...
|
||||
#
|
||||
# Static inventory file
|
||||
# [chroots]
|
||||
# /path/to/debootstrap
|
||||
# /path/to/feboostrap
|
||||
# /path/to/lxc-image
|
||||
# /path/to/chroot
|
||||
|
||||
# playbook
|
||||
---
|
||||
- hosts: chroots
|
||||
connection: community.general.chroot
|
||||
tasks:
|
||||
- debug:
|
||||
msg: "This is coming from chroot environment"
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
|
||||
@@ -29,11 +29,13 @@ options:
|
||||
api_token_id:
|
||||
description:
|
||||
- Specify the token ID.
|
||||
- Requires C(proxmoxer>=1.1.0) to work.
|
||||
type: str
|
||||
version_added: 1.3.0
|
||||
api_token_secret:
|
||||
description:
|
||||
- Specify the token secret.
|
||||
- Requires C(proxmoxer>=1.1.0) to work.
|
||||
type: str
|
||||
version_added: 1.3.0
|
||||
validate_certs:
|
||||
|
||||
@@ -87,6 +87,7 @@ from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils.six import iteritems
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, to_safe_group_name
|
||||
from ansible.module_utils.six import text_type
|
||||
|
||||
# xmlrpc
|
||||
try:
|
||||
@@ -128,7 +129,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||
self.connection = xmlrpc_client.Server(self.cobbler_url, allow_none=True)
|
||||
self.token = None
|
||||
if self.get_option('user') is not None:
|
||||
self.token = self.connection.login(self.get_option('user'), self.get_option('password'))
|
||||
self.token = self.connection.login(text_type(self.get_option('user')), text_type(self.get_option('password')))
|
||||
return self.connection
|
||||
|
||||
def _init_cache(self):
|
||||
|
||||
@@ -132,20 +132,29 @@ class Bitwarden(object):
|
||||
If field is None, return the whole record for each match.
|
||||
"""
|
||||
matches = self._get_matches(search_value, search_field, collection_id)
|
||||
|
||||
if field in ['autofillOnPageLoad', 'password', 'passwordRevisionDate', 'totp', 'uris', 'username']:
|
||||
return [match['login'][field] for match in matches]
|
||||
elif not field:
|
||||
if not field:
|
||||
return matches
|
||||
else:
|
||||
custom_field_matches = []
|
||||
for match in matches:
|
||||
field_matches = []
|
||||
for match in matches:
|
||||
# if there are no custom fields, then `match` has no key 'fields'
|
||||
if 'fields' in match:
|
||||
custom_field_found = False
|
||||
for custom_field in match['fields']:
|
||||
if custom_field['name'] == field:
|
||||
custom_field_matches.append(custom_field['value'])
|
||||
if matches and not custom_field_matches:
|
||||
raise AnsibleError("Custom field {field} does not exist in {search_value}".format(field=field, search_value=search_value))
|
||||
return custom_field_matches
|
||||
if field == custom_field['name']:
|
||||
field_matches.append(custom_field['value'])
|
||||
custom_field_found = True
|
||||
break
|
||||
if custom_field_found:
|
||||
continue
|
||||
if 'login' in match and field in match['login']:
|
||||
field_matches.append(match['login'][field])
|
||||
continue
|
||||
if field in match:
|
||||
field_matches.append(match[field])
|
||||
continue
|
||||
if matches and not field_matches:
|
||||
raise AnsibleError("field {field} does not exist in {search_value}".format(field=field, search_value=search_value))
|
||||
return field_matches
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
|
||||
@@ -74,18 +74,18 @@ EXAMPLES = """
|
||||
|
||||
- name: Retrieve password for HAL when not signed in to 1Password
|
||||
ansible.builtin.debug:
|
||||
var: lookup('community.general.onepassword'
|
||||
'HAL 9000'
|
||||
subdomain='Discovery'
|
||||
var: lookup('community.general.onepassword',
|
||||
'HAL 9000',
|
||||
subdomain='Discovery',
|
||||
master_password=vault_master_password)
|
||||
|
||||
- name: Retrieve password for HAL when never signed in to 1Password
|
||||
ansible.builtin.debug:
|
||||
var: lookup('community.general.onepassword'
|
||||
'HAL 9000'
|
||||
subdomain='Discovery'
|
||||
master_password=vault_master_password
|
||||
username='tweety@acme.com'
|
||||
var: lookup('community.general.onepassword',
|
||||
'HAL 9000',
|
||||
subdomain='Discovery',
|
||||
master_password=vault_master_password,
|
||||
username='tweety@acme.com',
|
||||
secret_key=vault_secret_key)
|
||||
"""
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ DOCUMENTATION = r"""
|
||||
version_added: '3.2.0'
|
||||
description:
|
||||
- Generates random string based upon the given constraints.
|
||||
- Uses L(random.SystemRandom,https://docs.python.org/3/library/random.html#random.SystemRandom),
|
||||
so should be strong enough for cryptographic purposes.
|
||||
options:
|
||||
length:
|
||||
description: The length of the string.
|
||||
|
||||
@@ -203,7 +203,7 @@ class CmdRunner(object):
|
||||
|
||||
for mod_param_name, spec in iteritems(module.argument_spec):
|
||||
if mod_param_name not in self.arg_formats:
|
||||
self.arg_formats[mod_param_name] = _Format.as_default_type(spec['type'], mod_param_name)
|
||||
self.arg_formats[mod_param_name] = _Format.as_default_type(spec.get('type', 'str'), mod_param_name)
|
||||
|
||||
def __call__(self, args_order=None, output_process=None, ignore_value_none=True, check_mode_skip=False, check_mode_return=None, **kwargs):
|
||||
if output_process is None:
|
||||
|
||||
@@ -570,7 +570,7 @@ def are_lists_equal(s, t):
|
||||
s = to_dict(s)
|
||||
t = to_dict(t)
|
||||
|
||||
if type(s[0]) == dict:
|
||||
if isinstance(s[0], dict):
|
||||
# Handle list of dicts. Dictionary returned by the API may have additional keys. For example, a get call on
|
||||
# service gateway has an attribute `services` which is a list of `ServiceIdResponseDetails`. This has a key
|
||||
# `service_name` which is not provided in the list of `services` by a user while making an update call; only
|
||||
@@ -604,9 +604,9 @@ def get_attr_to_update(get_fn, kwargs_get, module, update_attributes):
|
||||
user_provided_attr_value = module.params.get(attr, None)
|
||||
|
||||
unequal_list_attr = (
|
||||
type(resources_attr_value) == list or type(user_provided_attr_value) == list
|
||||
isinstance(resources_attr_value, list) or isinstance(user_provided_attr_value, list)
|
||||
) and not are_lists_equal(user_provided_attr_value, resources_attr_value)
|
||||
unequal_attr = type(resources_attr_value) != list and to_dict(
|
||||
unequal_attr = not isinstance(resources_attr_value, list) and to_dict(
|
||||
resources_attr_value
|
||||
) != to_dict(user_provided_attr_value)
|
||||
if unequal_list_attr or unequal_attr:
|
||||
@@ -936,9 +936,9 @@ def tuplize(d):
|
||||
list_of_tuples = []
|
||||
key_list = sorted(list(d.keys()))
|
||||
for key in key_list:
|
||||
if type(d[key]) == list:
|
||||
if isinstance(d[key], list):
|
||||
# Convert a value which is itself a list of dict to a list of tuples.
|
||||
if d[key] and type(d[key][0]) == dict:
|
||||
if d[key] and isinstance(d[key][0], dict):
|
||||
sub_tuples = []
|
||||
for sub_dict in d[key]:
|
||||
sub_tuples.append(tuplize(sub_dict))
|
||||
@@ -948,7 +948,7 @@ def tuplize(d):
|
||||
list_of_tuples.append((sub_tuples is None, key, sub_tuples))
|
||||
else:
|
||||
list_of_tuples.append((d[key] is None, key, d[key]))
|
||||
elif type(d[key]) == dict:
|
||||
elif isinstance(d[key], dict):
|
||||
tupled_value = tuplize(d[key])
|
||||
list_of_tuples.append((tupled_value is None, key, tupled_value))
|
||||
else:
|
||||
@@ -969,13 +969,13 @@ def sort_dictionary(d):
|
||||
"""
|
||||
sorted_d = {}
|
||||
for key in d:
|
||||
if type(d[key]) == list:
|
||||
if d[key] and type(d[key][0]) == dict:
|
||||
if isinstance(d[key], list):
|
||||
if d[key] and isinstance(d[key][0], dict):
|
||||
sorted_value = sort_list_of_dictionary(d[key])
|
||||
sorted_d[key] = sorted_value
|
||||
else:
|
||||
sorted_d[key] = sorted(d[key])
|
||||
elif type(d[key]) == dict:
|
||||
elif isinstance(d[key], dict):
|
||||
sorted_d[key] = sort_dictionary(d[key])
|
||||
else:
|
||||
sorted_d[key] = d[key]
|
||||
@@ -1044,7 +1044,7 @@ def check_if_user_value_matches_resources_attr(
|
||||
|
||||
if (
|
||||
user_provided_value_for_attr
|
||||
and type(user_provided_value_for_attr[0]) == dict
|
||||
and isinstance(user_provided_value_for_attr[0], dict)
|
||||
):
|
||||
# Process a list of dict
|
||||
sorted_user_provided_value_for_attr = sort_list_of_dictionary(
|
||||
@@ -1547,7 +1547,7 @@ def delete_and_wait(
|
||||
except ServiceError as ex:
|
||||
# DNS API throws a 400 InvalidParameter when a zone id is provided for zone_name_or_id and if the zone
|
||||
# resource is not available, instead of the expected 404. So working around this for now.
|
||||
if type(client) == oci.dns.DnsClient:
|
||||
if isinstance(client, oci.dns.DnsClient):
|
||||
if ex.status == 400 and ex.code == "InvalidParameter":
|
||||
_debug(
|
||||
"Resource {0} with {1} already deleted. So returning changed=False".format(
|
||||
|
||||
@@ -18,6 +18,7 @@ import traceback
|
||||
PROXMOXER_IMP_ERR = None
|
||||
try:
|
||||
from proxmoxer import ProxmoxAPI
|
||||
from proxmoxer import __version__ as proxmoxer_version
|
||||
HAS_PROXMOXER = True
|
||||
except ImportError:
|
||||
HAS_PROXMOXER = False
|
||||
@@ -79,6 +80,7 @@ class ProxmoxAnsible(object):
|
||||
module.fail_json(msg=missing_required_lib('proxmoxer'), exception=PROXMOXER_IMP_ERR)
|
||||
|
||||
self.module = module
|
||||
self.proxmoxer_version = proxmoxer_version
|
||||
self.proxmox_api = self._connect()
|
||||
# Test token validity
|
||||
try:
|
||||
@@ -98,6 +100,8 @@ class ProxmoxAnsible(object):
|
||||
if api_password:
|
||||
auth_args['password'] = api_password
|
||||
else:
|
||||
if self.proxmoxer_version < LooseVersion('1.1.0'):
|
||||
self.module.fail_json('Using "token_name" and "token_value" require proxmoxer>=1.1.0')
|
||||
auth_args['token_name'] = api_token_id
|
||||
auth_args['token_value'] = api_token_secret
|
||||
|
||||
|
||||
@@ -652,7 +652,8 @@ class RedfishUtils(object):
|
||||
properties = ['CacheSummary', 'FirmwareVersion', 'Identifiers',
|
||||
'Location', 'Manufacturer', 'Model', 'Name', 'Id',
|
||||
'PartNumber', 'SerialNumber', 'SpeedGbps', 'Status']
|
||||
key = "StorageControllers"
|
||||
key = "Controllers"
|
||||
deprecated_key = "StorageControllers"
|
||||
|
||||
# Find Storage service
|
||||
response = self.get_request(self.root_uri + systems_uri)
|
||||
@@ -680,7 +681,30 @@ class RedfishUtils(object):
|
||||
data = response['data']
|
||||
|
||||
if key in data:
|
||||
controller_list = data[key]
|
||||
controllers_uri = data[key][u'@odata.id']
|
||||
|
||||
response = self.get_request(self.root_uri + controllers_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
result['ret'] = True
|
||||
data = response['data']
|
||||
|
||||
if data[u'Members']:
|
||||
for controller_member in data[u'Members']:
|
||||
controller_member_uri = controller_member[u'@odata.id']
|
||||
response = self.get_request(self.root_uri + controller_member_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
result['ret'] = True
|
||||
data = response['data']
|
||||
|
||||
controller_result = {}
|
||||
for property in properties:
|
||||
if property in data:
|
||||
controller_result[property] = data[property]
|
||||
controller_results.append(controller_result)
|
||||
elif deprecated_key in data:
|
||||
controller_list = data[deprecated_key]
|
||||
for controller in controller_list:
|
||||
controller_result = {}
|
||||
for property in properties:
|
||||
@@ -735,7 +759,25 @@ class RedfishUtils(object):
|
||||
return response
|
||||
data = response['data']
|
||||
controller_name = 'Controller 1'
|
||||
if 'StorageControllers' in data:
|
||||
if 'Controllers' in data:
|
||||
controllers_uri = data['Controllers'][u'@odata.id']
|
||||
|
||||
response = self.get_request(self.root_uri + controllers_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
result['ret'] = True
|
||||
cdata = response['data']
|
||||
|
||||
if cdata[u'Members']:
|
||||
controller_member_uri = cdata[u'Members'][0][u'@odata.id']
|
||||
|
||||
response = self.get_request(self.root_uri + controller_member_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
result['ret'] = True
|
||||
cdata = response['data']
|
||||
controller_name = cdata['Name']
|
||||
elif 'StorageControllers' in data:
|
||||
sc = data['StorageControllers']
|
||||
if sc:
|
||||
if 'Name' in sc[0]:
|
||||
@@ -832,14 +874,32 @@ class RedfishUtils(object):
|
||||
if data.get('Members'):
|
||||
for controller in data[u'Members']:
|
||||
controller_list.append(controller[u'@odata.id'])
|
||||
for c in controller_list:
|
||||
for idx, c in enumerate(controller_list):
|
||||
uri = self.root_uri + c
|
||||
response = self.get_request(uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
data = response['data']
|
||||
controller_name = 'Controller 1'
|
||||
if 'StorageControllers' in data:
|
||||
controller_name = 'Controller %s' % str(idx)
|
||||
if 'Controllers' in data:
|
||||
response = self.get_request(self.root_uri + data['Controllers'][u'@odata.id'])
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
c_data = response['data']
|
||||
|
||||
if c_data.get('Members') and c_data['Members']:
|
||||
response = self.get_request(self.root_uri + c_data['Members'][0][u'@odata.id'])
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
member_data = response['data']
|
||||
|
||||
if member_data:
|
||||
if 'Name' in member_data:
|
||||
controller_name = member_data['Name']
|
||||
else:
|
||||
controller_id = member_data.get('Id', '1')
|
||||
controller_name = 'Controller %s' % controller_id
|
||||
elif 'StorageControllers' in data:
|
||||
sc = data['StorageControllers']
|
||||
if sc:
|
||||
if 'Name' in sc[0]:
|
||||
@@ -848,6 +908,7 @@ class RedfishUtils(object):
|
||||
sc_id = sc[0].get('Id', '1')
|
||||
controller_name = 'Controller %s' % sc_id
|
||||
volume_results = []
|
||||
volume_list = []
|
||||
if 'Volumes' in data:
|
||||
# Get a list of all volumes and build respective URIs
|
||||
volumes_uri = data[u'Volumes'][u'@odata.id']
|
||||
@@ -1079,6 +1140,12 @@ class RedfishUtils(object):
|
||||
if property in data:
|
||||
user[property] = data[property]
|
||||
|
||||
# Filter out empty account slots
|
||||
# An empty account slot can be detected if the username is an empty
|
||||
# string and if the account is disabled
|
||||
if user.get('UserName', '') == '' and not user.get('Enabled', False):
|
||||
continue
|
||||
|
||||
users_results.append(user)
|
||||
result["entries"] = users_results
|
||||
return result
|
||||
|
||||
@@ -72,7 +72,9 @@ def api_request(module, endpoint, data=None, method="GET"):
|
||||
if info["status"] == 403:
|
||||
module.fail_json(msg="Token authorization failed",
|
||||
execution_info=json.loads(info["body"]))
|
||||
if info["status"] == 409:
|
||||
elif info["status"] == 404:
|
||||
return None, info
|
||||
elif info["status"] == 409:
|
||||
module.fail_json(msg="Job executions limit reached",
|
||||
execution_info=json.loads(info["body"]))
|
||||
elif info["status"] >= 500:
|
||||
|
||||
@@ -248,7 +248,8 @@ def build_downtime(module):
|
||||
downtime.timezone = module.params["timezone"]
|
||||
if module.params["rrule"]:
|
||||
downtime.recurrence = DowntimeRecurrence(
|
||||
rrule=module.params["rrule"]
|
||||
rrule=module.params["rrule"],
|
||||
type="rrule",
|
||||
)
|
||||
return downtime
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ class EjabberdUser(object):
|
||||
changed. It will return True if the user does not match the supplied
|
||||
credentials and False if it does not
|
||||
"""
|
||||
return self.run_command('check_password', [self.user, self.host, self.pwd])
|
||||
return bool(self.run_command('check_password', [self.user, self.host, self.pwd])[0])
|
||||
|
||||
@property
|
||||
def exists(self):
|
||||
@@ -110,7 +110,7 @@ class EjabberdUser(object):
|
||||
host specified. If the user exists True is returned, otherwise False
|
||||
is returned
|
||||
"""
|
||||
return self.run_command('check_account', [self.user, self.host])
|
||||
return not bool(self.run_command('check_account', [self.user, self.host])[0])
|
||||
|
||||
def log(self, entry):
|
||||
""" This method will log information to the local syslog facility """
|
||||
@@ -122,7 +122,7 @@ class EjabberdUser(object):
|
||||
""" This method will run the any command specified and return the
|
||||
returns using the Ansible common module
|
||||
"""
|
||||
cmd = [self.module.get_bin_path('ejabberdctl'), cmd] + options
|
||||
cmd = [self.module.get_bin_path('ejabberdctl', required=True), cmd] + options
|
||||
self.log('command: %s' % " ".join(cmd))
|
||||
return self.module.run_command(cmd)
|
||||
|
||||
|
||||
@@ -82,8 +82,14 @@ EXAMPLES = '''
|
||||
name: Access Key for Some Machine
|
||||
token: '{{ github_access_token }}'
|
||||
pubkey: '{{ ssh_pub_key.stdout }}'
|
||||
'''
|
||||
|
||||
# Alternatively, a single task can be used reading a key from a file on the controller
|
||||
- name: Authorize key with GitHub
|
||||
community.general.github_key:
|
||||
name: Access Key for Some Machine
|
||||
token: '{{ github_access_token }}'
|
||||
pubkey: "{{ lookup('ansible.builtin.file', '/home/foo/.ssh/id_rsa.pub') }}"
|
||||
'''
|
||||
|
||||
import json
|
||||
import re
|
||||
|
||||
@@ -306,7 +306,7 @@ def main():
|
||||
module.exit_json(changed=False, name=name, data=data)
|
||||
|
||||
# Template attribute is not allowed in modification
|
||||
del data['attrs']['templates']
|
||||
del data['templates']
|
||||
|
||||
ret = icinga.modify(name, data)
|
||||
|
||||
|
||||
@@ -152,7 +152,8 @@ def ensure(module, client):
|
||||
changed = True
|
||||
if not module.check_mode:
|
||||
client.dnszone_add(zone_name=zone_name, details={'idnsallowdynupdate': dynamicupdate, 'idnsallowsyncptr': allowsyncptr})
|
||||
elif ipa_dnszone['idnsallowdynupdate'][0] != str(dynamicupdate).upper() or ipa_dnszone['idnsallowsyncptr'][0] != str(allowsyncptr).upper():
|
||||
elif ipa_dnszone['idnsallowdynupdate'][0] != str(dynamicupdate).upper() or \
|
||||
ipa_dnszone.get('idnsallowsyncptr') and ipa_dnszone['idnsallowsyncptr'][0] != str(allowsyncptr).upper():
|
||||
changed = True
|
||||
if not module.check_mode:
|
||||
client.dnszone_mod(zone_name=zone_name, details={'idnsallowdynupdate': dynamicupdate, 'idnsallowsyncptr': allowsyncptr})
|
||||
|
||||
@@ -27,7 +27,7 @@ options:
|
||||
group:
|
||||
type: str
|
||||
description:
|
||||
- Name of the Jenkins group on the OS.
|
||||
- GID or name of the Jenkins group on the OS.
|
||||
default: jenkins
|
||||
jenkins_home:
|
||||
type: path
|
||||
@@ -47,7 +47,7 @@ options:
|
||||
owner:
|
||||
type: str
|
||||
description:
|
||||
- Name of the Jenkins user on the OS.
|
||||
- UID or name of the Jenkins user on the OS.
|
||||
default: jenkins
|
||||
state:
|
||||
type: str
|
||||
@@ -195,6 +195,29 @@ EXAMPLES = '''
|
||||
url_password: p4ssw0rd
|
||||
url: http://localhost:8888
|
||||
|
||||
#
|
||||
# Example of how to authenticate with serverless deployment
|
||||
#
|
||||
- name: Update plugins on ECS Fargate Jenkins instance
|
||||
community.general.jenkins_plugin:
|
||||
# plugin name and version
|
||||
name: ws-cleanup
|
||||
version: '0.45'
|
||||
# Jenkins home path mounted on ec2-helper VM (example)
|
||||
jenkins_home: "/mnt/{{ jenkins_instance }}"
|
||||
# matching the UID/GID to one in official Jenkins image
|
||||
owner: 1000
|
||||
group: 1000
|
||||
# Jenkins instance URL and admin credentials
|
||||
url: "https://{{ jenkins_instance }}.com/"
|
||||
url_username: admin
|
||||
url_password: p4ssw0rd
|
||||
# make module work from EC2 which has local access
|
||||
# to EFS mount as well as Jenkins URL
|
||||
delegate_to: ec2-helper
|
||||
vars:
|
||||
jenkins_instance: foobar
|
||||
|
||||
#
|
||||
# Example of a Play which handles Jenkins restarts during the state changes
|
||||
#
|
||||
|
||||
@@ -35,6 +35,8 @@ options:
|
||||
- Whether the locale shall be present.
|
||||
choices: [ absent, present ]
|
||||
default: present
|
||||
notes:
|
||||
- This module does not support RHEL-based systems.
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
@@ -74,11 +76,10 @@ def is_available(name, ubuntuMode):
|
||||
checking either :
|
||||
* if the locale is present in /etc/locales.gen
|
||||
* or if the locale is present in /usr/share/i18n/SUPPORTED"""
|
||||
__regexp = r'^#?\s*(?P<locale>\S+[\._\S]*) (?P<charset>\S+)\s*$'
|
||||
if ubuntuMode:
|
||||
__regexp = r'^(?P<locale>\S+_\S+) (?P<charset>\S+)\s*$'
|
||||
__locales_available = '/usr/share/i18n/SUPPORTED'
|
||||
else:
|
||||
__regexp = r'^#{0,1}\s*(?P<locale>\S+_\S+) (?P<charset>\S+)\s*$'
|
||||
__locales_available = '/etc/locale.gen'
|
||||
|
||||
re_compiled = re.compile(__regexp)
|
||||
@@ -88,7 +89,8 @@ def is_available(name, ubuntuMode):
|
||||
if result and result.group('locale') == name:
|
||||
return True
|
||||
fd.close()
|
||||
return False
|
||||
# locale may be installed but not listed in the file, for example C.UTF-8 in some systems
|
||||
return is_present(name)
|
||||
|
||||
|
||||
def is_present(name):
|
||||
@@ -106,20 +108,6 @@ def fix_case(name):
|
||||
return name
|
||||
|
||||
|
||||
def replace_line(existing_line, new_line):
|
||||
"""Replaces lines in /etc/locale.gen"""
|
||||
try:
|
||||
f = open("/etc/locale.gen", "r")
|
||||
lines = [line.replace(existing_line, new_line) for line in f]
|
||||
finally:
|
||||
f.close()
|
||||
try:
|
||||
f = open("/etc/locale.gen", "w")
|
||||
f.write("".join(lines))
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
|
||||
def set_locale(name, enabled=True):
|
||||
""" Sets the state of the locale. Defaults to enabled. """
|
||||
search_string = r'#{0,1}\s*%s (?P<charset>.+)' % name
|
||||
@@ -209,7 +197,7 @@ def main():
|
||||
# We found the common way to manage locales.
|
||||
ubuntuMode = False
|
||||
else:
|
||||
module.fail_json(msg="/etc/locale.gen and /var/lib/locales/supported.d/local are missing. Is the package \"locales\" installed?")
|
||||
module.fail_json(msg="/etc/locale.gen and /var/lib/locales/supported.d/local are missing. Is the package 'locales' installed?")
|
||||
else:
|
||||
# Ubuntu created its own system to manage locales.
|
||||
ubuntuMode = True
|
||||
|
||||
@@ -2104,7 +2104,10 @@ class Nmcli(object):
|
||||
if key and len(pair) > 1:
|
||||
raw_value = pair[1].lstrip()
|
||||
if raw_value == '--':
|
||||
conn_info[key] = None
|
||||
if key_type == list:
|
||||
conn_info[key] = []
|
||||
else:
|
||||
conn_info[key] = None
|
||||
elif key == 'bond.options':
|
||||
# Aliases such as 'miimon', 'downdelay' are equivalent to the +bond.options 'option=value' syntax.
|
||||
opts = raw_value.split(',')
|
||||
@@ -2191,7 +2194,7 @@ class Nmcli(object):
|
||||
# We can't just do `if not value` because then if there's a value
|
||||
# of 0 specified as an integer it'll be interpreted as empty when
|
||||
# it actually isn't.
|
||||
if value != 0 and not value:
|
||||
if value not in (0, []) and not value:
|
||||
continue
|
||||
|
||||
if key in conn_info:
|
||||
|
||||
@@ -169,7 +169,11 @@ def get_package_state(names, pkg_spec, module):
|
||||
rc, stdout, stderr = execute_command(command, module)
|
||||
|
||||
if stderr:
|
||||
module.fail_json(msg="failed in get_package_state(): " + stderr)
|
||||
match = re.search(r"^Can't find inst:%s$" % re.escape(name), stderr)
|
||||
if match:
|
||||
pkg_spec[name]['installed_state'] = False
|
||||
else:
|
||||
module.fail_json(msg="failed in get_package_state(): " + stderr)
|
||||
|
||||
if stdout:
|
||||
# If the requested package name is just a stem, like "python", we may
|
||||
|
||||
@@ -133,6 +133,9 @@ notes:
|
||||
it is much more efficient to pass the list directly to the I(name) option.
|
||||
- To use an AUR helper (I(executable) option), a few extra setup steps might be required beforehand.
|
||||
For example, a dedicated build user with permissions to install packages could be necessary.
|
||||
- >
|
||||
In the tests, while using C(yay) as the I(executable) option, the module failed to install AUR packages
|
||||
with the error: C(error: target not found: <pkg>).
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
@@ -263,6 +266,7 @@ EXAMPLES = """
|
||||
reason_for: all
|
||||
"""
|
||||
|
||||
import re
|
||||
import shlex
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from collections import defaultdict, namedtuple
|
||||
@@ -418,7 +422,7 @@ class Pacman(object):
|
||||
for p in name_ver:
|
||||
# With Pacman v6.0.1 - libalpm v13.0.1, --upgrade outputs "loading packages..." on stdout. strip that.
|
||||
# When installing from URLs, pacman can also output a 'nothing to do' message. strip that too.
|
||||
if "loading packages" in p or "there is nothing to do" in p:
|
||||
if "loading packages" in p or "there is nothing to do" in p or 'Avoid running' in p:
|
||||
continue
|
||||
name, version = p.split()
|
||||
if name in self.inventory["installed_pkgs"]:
|
||||
@@ -706,11 +710,12 @@ class Pacman(object):
|
||||
installed_pkgs = {}
|
||||
dummy, stdout, dummy = self.m.run_command([self.pacman_path, "--query"], check_rc=True)
|
||||
# Format of a line: "pacman 6.0.1-2"
|
||||
query_re = re.compile(r'^\s*(?P<pkg>\S+)\s+(?P<ver>\S+)\s*$')
|
||||
for l in stdout.splitlines():
|
||||
l = l.strip()
|
||||
if not l:
|
||||
query_match = query_re.match(l)
|
||||
if not query_match:
|
||||
continue
|
||||
pkg, ver = l.split()
|
||||
pkg, ver = query_match.groups()
|
||||
installed_pkgs[pkg] = ver
|
||||
|
||||
installed_groups = defaultdict(set)
|
||||
@@ -721,11 +726,12 @@ class Pacman(object):
|
||||
# base-devel file
|
||||
# base-devel findutils
|
||||
# ...
|
||||
query_groups_re = re.compile(r'^\s*(?P<group>\S+)\s+(?P<pkg>\S+)\s*$')
|
||||
for l in stdout.splitlines():
|
||||
l = l.strip()
|
||||
if not l:
|
||||
query_groups_match = query_groups_re.match(l)
|
||||
if not query_groups_match:
|
||||
continue
|
||||
group, pkgname = l.split()
|
||||
group, pkgname = query_groups_match.groups()
|
||||
installed_groups[group].add(pkgname)
|
||||
|
||||
available_pkgs = {}
|
||||
@@ -747,11 +753,12 @@ class Pacman(object):
|
||||
# vim-plugins vim-airline-themes
|
||||
# vim-plugins vim-ale
|
||||
# ...
|
||||
sync_groups_re = re.compile(r'^\s*(?P<group>\S+)\s+(?P<pkg>\S+)\s*$')
|
||||
for l in stdout.splitlines():
|
||||
l = l.strip()
|
||||
if not l:
|
||||
sync_groups_match = sync_groups_re.match(l)
|
||||
if not sync_groups_match:
|
||||
continue
|
||||
group, pkg = l.split()
|
||||
group, pkg = sync_groups_match.groups()
|
||||
available_groups[group].add(pkg)
|
||||
|
||||
upgradable_pkgs = {}
|
||||
@@ -759,9 +766,14 @@ class Pacman(object):
|
||||
[self.pacman_path, "--query", "--upgrades"], check_rc=False
|
||||
)
|
||||
|
||||
stdout = stdout.splitlines()
|
||||
if stdout and "Avoid running" in stdout[0]:
|
||||
stdout = stdout[1:]
|
||||
stdout = "\n".join(stdout)
|
||||
|
||||
# non-zero exit with nothing in stdout -> nothing to upgrade, all good
|
||||
# stderr can have warnings, so not checked here
|
||||
if rc == 1 and stdout == "":
|
||||
if rc == 1 and not stdout:
|
||||
pass # nothing to upgrade
|
||||
elif rc == 0:
|
||||
# Format of lines:
|
||||
@@ -771,7 +783,7 @@ class Pacman(object):
|
||||
l = l.strip()
|
||||
if not l:
|
||||
continue
|
||||
if "[ignored]" in l:
|
||||
if "[ignored]" in l or "Avoid running" in l:
|
||||
continue
|
||||
s = l.split()
|
||||
if len(s) != 4:
|
||||
|
||||
@@ -427,7 +427,7 @@ class ProxmoxLxcAnsible(ProxmoxAnsible):
|
||||
"""Check if the specified container is a template."""
|
||||
proxmox_node = self.proxmox_api.nodes(node)
|
||||
config = getattr(proxmox_node, VZ_TYPE)(vmid).config.get()
|
||||
return config['template']
|
||||
return config.get('template', False)
|
||||
|
||||
def create_instance(self, vmid, node, disk, storage, cpus, memory, swap, timeout, clone, **kwargs):
|
||||
|
||||
|
||||
@@ -505,7 +505,9 @@ class ProxmoxDiskAnsible(ProxmoxAnsible):
|
||||
timeout_str = "Reached timeout while importing VM disk. Last line in task before timeout: %s"
|
||||
ok_str = "Disk %s imported into VM %s"
|
||||
else:
|
||||
config_str = "%s:%s" % (self.module.params["storage"], self.module.params["size"])
|
||||
config_str = self.module.params["storage"]
|
||||
if self.module.params.get("media") != "cdrom":
|
||||
config_str += ":%s" % (self.module.params["size"])
|
||||
ok_str = "Disk %s created in VM %s"
|
||||
timeout_str = "Reached timeout while creating VM disk. Last line in task before timeout: %s"
|
||||
|
||||
|
||||
@@ -281,8 +281,9 @@ options:
|
||||
type: int
|
||||
name:
|
||||
description:
|
||||
- Specifies the VM name. Only used on the configuration web interface.
|
||||
- Required only for C(state=present).
|
||||
- Specifies the VM name. Name could be non-unique across the cluster.
|
||||
- Required only for I(state=present).
|
||||
- With I(state=present) if I(vmid) not provided and VM with name exists in the cluster then no changes will be made.
|
||||
type: str
|
||||
nameservers:
|
||||
description:
|
||||
@@ -763,6 +764,15 @@ EXAMPLES = '''
|
||||
node: sabrewulf
|
||||
state: absent
|
||||
|
||||
- name: Get VM current state
|
||||
community.general.proxmox_kvm:
|
||||
api_user: root@pam
|
||||
api_password: secret
|
||||
api_host: helldorado
|
||||
name: spynal
|
||||
node: sabrewulf
|
||||
state: current
|
||||
|
||||
- name: Update VM configuration
|
||||
community.general.proxmox_kvm:
|
||||
api_user: root@pam
|
||||
@@ -1201,10 +1211,14 @@ def main():
|
||||
# the cloned vm name or retrieve the next free VM id from ProxmoxAPI.
|
||||
if not vmid:
|
||||
if state == 'present' and not update and not clone and not delete and not revert:
|
||||
try:
|
||||
vmid = proxmox.get_nextvmid()
|
||||
except Exception:
|
||||
module.fail_json(msg="Can't get the next vmid for VM {0} automatically. Ensure your cluster state is good".format(name))
|
||||
existing_vmid = proxmox.get_vmid(name, ignore_missing=True)
|
||||
if existing_vmid:
|
||||
vmid = existing_vmid
|
||||
else:
|
||||
try:
|
||||
vmid = proxmox.get_nextvmid()
|
||||
except Exception:
|
||||
module.fail_json(msg="Can't get the next vmid for VM {0} automatically. Ensure your cluster state is good".format(name))
|
||||
else:
|
||||
clone_target = clone or name
|
||||
vmid = proxmox.get_vmid(clone_target, ignore_missing=True)
|
||||
@@ -1404,7 +1418,7 @@ def main():
|
||||
status['status'] = vm['status']
|
||||
if vm['status'] == 'running':
|
||||
if module.params['force']:
|
||||
proxmox.stop_vm(vm, True)
|
||||
proxmox.stop_vm(vm, True, timeout=module.params['timeout'])
|
||||
else:
|
||||
module.exit_json(changed=False, vmid=vmid, msg="VM %s is running. Stop it before deletion or use force=true." % vmid)
|
||||
taskid = proxmox_node.qemu.delete(vmid)
|
||||
|
||||
@@ -193,14 +193,14 @@ class ProxmoxUser:
|
||||
self.user[k] = v
|
||||
elif k in ['groups', 'tokens'] and (v == '' or v is None):
|
||||
self.user[k] = []
|
||||
elif k == 'groups' and type(v) == str:
|
||||
elif k == 'groups' and isinstance(v, str):
|
||||
self.user['groups'] = v.split(',')
|
||||
elif k == 'tokens' and type(v) == list:
|
||||
elif k == 'tokens' and isinstance(v, list):
|
||||
for token in v:
|
||||
if 'privsep' in token:
|
||||
token['privsep'] = proxmox_to_ansible_bool(token['privsep'])
|
||||
self.user['tokens'] = v
|
||||
elif k == 'tokens' and type(v) == dict:
|
||||
elif k == 'tokens' and isinstance(v, dict):
|
||||
self.user['tokens'] = list()
|
||||
for tokenid, tokenvalues in v.items():
|
||||
t = tokenvalues
|
||||
|
||||
@@ -222,6 +222,9 @@ def repository_modify(module, state, name, purge=False):
|
||||
diff_after.join("Repository '{repoid}' is disabled for this system\n".format(repoid=repoid))
|
||||
results.append("Repository '{repoid}' is disabled for this system".format(repoid=repoid))
|
||||
rhsm_arguments.extend(['--disable', repoid])
|
||||
for updated_repo in updated_repo_list:
|
||||
if updated_repo['id'] in difference:
|
||||
updated_repo['enabled'] = False
|
||||
|
||||
diff = {'before': diff_before,
|
||||
'after': diff_after,
|
||||
|
||||
@@ -26,6 +26,7 @@ def main():
|
||||
arg_values=dict(type="dict", default={}),
|
||||
check_mode_skip=dict(type="bool", default=False),
|
||||
aa=dict(type="raw"),
|
||||
tt=dict(),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
@@ -121,3 +121,20 @@ cmd_echo_tests:
|
||||
- test_result.rc == None
|
||||
- test_result.out == None
|
||||
- test_result.err == None
|
||||
|
||||
- name: set aa and tt value
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --tt-arg potatoes\n"
|
||||
- test_result.err == ""
|
||||
|
||||
@@ -11,5 +11,9 @@ skip/rhel8.2
|
||||
skip/rhel8.3
|
||||
skip/rhel8.4
|
||||
skip/rhel8.5
|
||||
skip/rhel8.6
|
||||
skip/rhel8.7
|
||||
skip/rhel8.8
|
||||
skip/rhel9.0
|
||||
skip/rhel9.1
|
||||
skip/rhel9.2
|
||||
|
||||
11
tests/integration/targets/ejabberd_user/aliases
Normal file
11
tests/integration/targets/ejabberd_user/aliases
Normal file
@@ -0,0 +1,11 @@
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
azp/posix/3
|
||||
skip/osx
|
||||
skip/macos
|
||||
skip/freebsd
|
||||
skip/alpine
|
||||
skip/rhel
|
||||
destructive
|
||||
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
---
|
||||
- name: Remove ejabberd
|
||||
ansible.builtin.package:
|
||||
name: ejabberd
|
||||
state: absent
|
||||
7
tests/integration/targets/ejabberd_user/meta/main.yml
Normal file
7
tests/integration/targets/ejabberd_user/meta/main.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
dependencies:
|
||||
- setup_pkg_mgr
|
||||
106
tests/integration/targets/ejabberd_user/tasks/main.yml
Normal file
106
tests/integration/targets/ejabberd_user/tasks/main.yml
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Bail out if not supported
|
||||
ansible.builtin.meta: end_play
|
||||
when: ansible_distribution in ('Alpine', 'openSUSE Leap', 'CentOS', 'Fedora')
|
||||
|
||||
|
||||
- name: Remove ejabberd
|
||||
ansible.builtin.package:
|
||||
name: ejabberd
|
||||
state: absent
|
||||
|
||||
- name: Create user without ejabberdctl installed
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
password: pa$$w0rd
|
||||
state: present
|
||||
register: user_no_ejabberdctl
|
||||
ignore_errors: true
|
||||
|
||||
- name: Install ejabberd
|
||||
ansible.builtin.package:
|
||||
name: ejabberd
|
||||
state: present
|
||||
notify: Remove ejabberd
|
||||
|
||||
- ansible.builtin.service:
|
||||
name: ejabberd
|
||||
state: started
|
||||
|
||||
- name: Create user alice (check)
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
password: pa$$w0rd
|
||||
state: present
|
||||
check_mode: true
|
||||
register: user_alice_check
|
||||
|
||||
- name: Create user alice
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
password: pa$$w0rd
|
||||
state: present
|
||||
register: user_alice
|
||||
|
||||
- name: Create user alice (idempotency)
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
password: pa$$w0rd
|
||||
state: present
|
||||
register: user_alice_idempot
|
||||
|
||||
- name: Create user alice (change password)
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
password: different_pa$$w0rd
|
||||
state: present
|
||||
register: user_alice_chgpw
|
||||
|
||||
- name: Remove user alice (check)
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
state: absent
|
||||
register: remove_alice_check
|
||||
check_mode: true
|
||||
|
||||
- name: Remove user alice
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
state: absent
|
||||
register: remove_alice
|
||||
|
||||
- name: Remove user alice (idempotency)
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
state: absent
|
||||
register: remove_alice_idempot
|
||||
|
||||
- name: Assertions
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- user_no_ejabberdctl is failed
|
||||
- "'Failed to find required executable' in user_no_ejabberdctl.msg"
|
||||
- user_alice_check is changed
|
||||
- user_alice is changed
|
||||
- user_alice_idempot is not changed
|
||||
- user_alice_chgpw is changed
|
||||
- remove_alice_check is changed
|
||||
- remove_alice is changed
|
||||
- remove_alice_idempot is not changed
|
||||
@@ -9,3 +9,4 @@ skip/osx
|
||||
skip/macos
|
||||
skip/rhel9.0 # See https://www.reddit.com/r/Fedora/comments/si7nzk/homectl/
|
||||
skip/rhel9.1 # See https://www.reddit.com/r/Fedora/comments/si7nzk/homectl/
|
||||
skip/rhel9.2 # See https://www.reddit.com/r/Fedora/comments/si7nzk/homectl/
|
||||
|
||||
7
tests/integration/targets/htpasswd/aliases
Normal file
7
tests/integration/targets/htpasswd/aliases
Normal file
@@ -0,0 +1,7 @@
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
azp/posix/2
|
||||
destructive
|
||||
needs/root
|
||||
9
tests/integration/targets/htpasswd/handlers/main.yml
Normal file
9
tests/integration/targets/htpasswd/handlers/main.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: remove passlib
|
||||
ansible.builtin.pip:
|
||||
name: passlib
|
||||
state: absent
|
||||
7
tests/integration/targets/htpasswd/meta/main.yml
Normal file
7
tests/integration/targets/htpasswd/meta/main.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
dependencies:
|
||||
- setup_remote_tmp_dir
|
||||
83
tests/integration/targets/htpasswd/tasks/main.yml
Normal file
83
tests/integration/targets/htpasswd/tasks/main.yml
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: install passlib
|
||||
ansible.builtin.pip:
|
||||
name: passlib
|
||||
notify: remove passlib
|
||||
|
||||
- name: add bob (check mode)
|
||||
community.general.htpasswd:
|
||||
path: "{{ htpasswd_path }}"
|
||||
name: bob
|
||||
password: c00lbob
|
||||
check_mode: true
|
||||
register: add_bob_check
|
||||
|
||||
- name: add bob
|
||||
community.general.htpasswd:
|
||||
path: "{{ htpasswd_path }}"
|
||||
name: bob
|
||||
password: c00lbob
|
||||
register: add_bob
|
||||
|
||||
- name: add bob (idempotency)
|
||||
community.general.htpasswd:
|
||||
path: "{{ htpasswd_path }}"
|
||||
name: bob
|
||||
password: c00lbob
|
||||
register: add_bob_idempot
|
||||
|
||||
- name: add bob new password
|
||||
community.general.htpasswd:
|
||||
path: "{{ htpasswd_path }}"
|
||||
name: bob
|
||||
password: SUPERsecret
|
||||
register: add_bob_newpw
|
||||
|
||||
- name: add bob new password (idempotency)
|
||||
community.general.htpasswd:
|
||||
path: "{{ htpasswd_path }}"
|
||||
name: bob
|
||||
password: SUPERsecret
|
||||
register: add_bob_newpw_idempot
|
||||
|
||||
- name: test add bob assertions
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- add_bob_check is changed
|
||||
- add_bob is changed
|
||||
- add_bob_idempot is not changed
|
||||
- add_bob_newpw is changed
|
||||
- add_bob_newpw_idempot is not changed
|
||||
|
||||
- name: remove bob (check mode)
|
||||
community.general.htpasswd:
|
||||
path: "{{ htpasswd_path }}"
|
||||
name: bob
|
||||
state: absent
|
||||
check_mode: true
|
||||
register: del_bob_check
|
||||
|
||||
- name: remove bob
|
||||
community.general.htpasswd:
|
||||
path: "{{ htpasswd_path }}"
|
||||
name: bob
|
||||
state: absent
|
||||
register: del_bob
|
||||
|
||||
- name: remove bob (idempotency)
|
||||
community.general.htpasswd:
|
||||
path: "{{ htpasswd_path }}"
|
||||
name: bob
|
||||
state: absent
|
||||
register: del_bob_idempot
|
||||
|
||||
- name: test remove bob assertions
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- del_bob_check is changed
|
||||
- del_bob is changed
|
||||
- del_bob_idempot is not changed
|
||||
6
tests/integration/targets/htpasswd/vars/main.yml
Normal file
6
tests/integration/targets/htpasswd/vars/main.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
htpasswd_path: "{{ remote_tmp_dir }}/dot_htpasswd"
|
||||
@@ -3,3 +3,4 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
azp/posix/2
|
||||
skip/python2.6
|
||||
|
||||
@@ -9,5 +9,6 @@ skip/aix
|
||||
skip/osx # FIXME
|
||||
skip/rhel9.0 # FIXME
|
||||
skip/rhel9.1 # FIXME
|
||||
skip/rhel9.2 # FIXME
|
||||
skip/freebsd12.4 # FIXME
|
||||
skip/freebsd13.2 # FIXME
|
||||
|
||||
@@ -9,3 +9,4 @@ skip/osx
|
||||
skip/macos
|
||||
skip/freebsd
|
||||
needs/root
|
||||
skip/rhel # FIXME: keytool seems to be broken on newer RHELs
|
||||
|
||||
@@ -9,3 +9,4 @@ skip/osx
|
||||
skip/macos
|
||||
skip/freebsd
|
||||
needs/root
|
||||
skip/rhel # FIXME: keytool seems to be broken on newer RHELs
|
||||
|
||||
@@ -6,3 +6,5 @@ azp/posix/3
|
||||
destructive
|
||||
needs/root
|
||||
skip/aix
|
||||
skip/freebsd
|
||||
skip/macos
|
||||
|
||||
102
tests/integration/targets/locale_gen/tasks/basic.yml
Normal file
102
tests/integration/targets/locale_gen/tasks/basic.yml
Normal file
@@ -0,0 +1,102 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Is the locale we're going to test against installed? {{ locale_basic.localegen }}
|
||||
command: locale -a
|
||||
register: initial_state
|
||||
ignore_errors: true
|
||||
|
||||
- name: Make sure the locale is not installed {{ locale_basic.localegen }}
|
||||
locale_gen:
|
||||
name: "{{ locale_basic.localegen }}"
|
||||
state: absent
|
||||
|
||||
- name: Is the locale present? {{ locale_basic.localegen }}
|
||||
command: locale -a
|
||||
register: cleaned
|
||||
ignore_errors: true
|
||||
|
||||
- name: Make sure the locale is not present {{ locale_basic.localegen }}
|
||||
assert:
|
||||
that:
|
||||
- locale_basic.skip_removal or locale_basic.locales | intersect(cleaned.stdout_lines) == []
|
||||
|
||||
- name: Install the locale {{ locale_basic.localegen }}
|
||||
locale_gen:
|
||||
name: "{{ locale_basic.localegen }}"
|
||||
state: present
|
||||
register: output_present
|
||||
|
||||
- name: Is the locale present? {{ locale_basic.localegen }}
|
||||
command: locale -a
|
||||
register: post_check_output_present
|
||||
ignore_errors: true
|
||||
|
||||
- name: Make sure the locale is present and we say we installed it {{ locale_basic.localegen }}
|
||||
assert:
|
||||
that:
|
||||
- locale_basic.locales | intersect(post_check_output_present.stdout_lines) != []
|
||||
- locale_basic.skip_removal or output_present is changed
|
||||
|
||||
- name: Install the locale a second time {{ locale_basic.localegen }}
|
||||
locale_gen:
|
||||
name: "{{ locale_basic.localegen }}"
|
||||
state: present
|
||||
register: output_present_idempotent
|
||||
|
||||
- name: Is the locale present? {{ locale_basic.localegen }}
|
||||
command: locale -a
|
||||
register: post_check_output_present_idempotent
|
||||
ignore_errors: true
|
||||
|
||||
- name: Make sure the locale is present and we reported no change {{ locale_basic.localegen }}
|
||||
assert:
|
||||
that:
|
||||
- locale_basic.locales | intersect(post_check_output_present_idempotent.stdout_lines) != []
|
||||
- output_present_idempotent is not changed
|
||||
|
||||
- name: Removals
|
||||
when: locale_basic.skip_removal is false
|
||||
block:
|
||||
- name: Remove the locale {{ locale_basic.localegen }}
|
||||
locale_gen:
|
||||
name: "{{ locale_basic.localegen }}"
|
||||
state: absent
|
||||
register: output_absent
|
||||
|
||||
- name: Is the locale present? {{ locale_basic.localegen }}
|
||||
command: locale -a
|
||||
register: post_check_output_absent
|
||||
ignore_errors: true
|
||||
|
||||
- name: Make sure the locale is absent and we reported a change {{ locale_basic.localegen }}
|
||||
assert:
|
||||
that:
|
||||
- locale_basic.locales | intersect(post_check_output_absent.stdout_lines) == []
|
||||
- output_absent is changed
|
||||
|
||||
- name: Remove the locale a second time {{ locale_basic.localegen }}
|
||||
locale_gen:
|
||||
name: "{{ locale_basic.localegen }}"
|
||||
state: absent
|
||||
register: output_absent_idempotent
|
||||
|
||||
- name: Is the locale present? {{ locale_basic.localegen }}
|
||||
command: locale -a
|
||||
register: post_check_output_absent_idempotent
|
||||
ignore_errors: true
|
||||
|
||||
- name: Make sure the locale is absent and we reported no change {{ locale_basic.localegen }}
|
||||
assert:
|
||||
that:
|
||||
- locale_basic.locales | intersect(post_check_output_absent_idempotent.stdout_lines) == []
|
||||
- output_absent_idempotent is not changed
|
||||
|
||||
# Cleanup
|
||||
- name: Reinstall the locale we tested against if it was initially installed {{ locale_basic.localegen }}
|
||||
locale_gen:
|
||||
name: "{{ locale_basic.localegen }}"
|
||||
state: present
|
||||
when: locale_basic.locales | intersect(initial_state.stdout_lines) != []
|
||||
@@ -1,99 +0,0 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Is the locale we're going to test against installed?
|
||||
shell: locale -a | grep pt_BR
|
||||
register: initial_state
|
||||
ignore_errors: true
|
||||
|
||||
- name: Make sure the locale is not installed
|
||||
locale_gen:
|
||||
name: pt_BR
|
||||
state: absent
|
||||
|
||||
- name: Is the locale present?
|
||||
shell: locale -a | grep pt_BR
|
||||
register: cleaned
|
||||
ignore_errors: true
|
||||
|
||||
- name: Make sure the locale is not present
|
||||
assert:
|
||||
that:
|
||||
- "cleaned.rc == 1"
|
||||
|
||||
- name: Install the locale
|
||||
locale_gen:
|
||||
name: pt_BR
|
||||
state: present
|
||||
register: output
|
||||
|
||||
- name: Is the locale present?
|
||||
shell: locale -a | grep pt_BR
|
||||
register: post_check_output
|
||||
ignore_errors: true
|
||||
|
||||
- name: Make sure the locale is present and we say we installed it
|
||||
assert:
|
||||
that:
|
||||
- "post_check_output.rc == 0"
|
||||
- "output.changed"
|
||||
|
||||
- name: Install the locale a second time
|
||||
locale_gen:
|
||||
name: pt_BR
|
||||
state: present
|
||||
register: output
|
||||
|
||||
- name: Is the locale present?
|
||||
shell: locale -a | grep pt_BR
|
||||
register: post_check_output
|
||||
ignore_errors: true
|
||||
|
||||
- name: Make sure the locale is present and we reported no change
|
||||
assert:
|
||||
that:
|
||||
- "post_check_output.rc == 0"
|
||||
- "not output.changed"
|
||||
|
||||
- name: Remove the locale
|
||||
locale_gen:
|
||||
name: pt_BR
|
||||
state: absent
|
||||
register: output
|
||||
|
||||
- name: Is the locale present?
|
||||
shell: locale -a | grep pt_BR
|
||||
register: post_check_output
|
||||
ignore_errors: true
|
||||
|
||||
- name: Make sure the locale is absent and we reported a change
|
||||
assert:
|
||||
that:
|
||||
- "post_check_output.rc == 1"
|
||||
- "output.changed"
|
||||
|
||||
- name: Remove the locale a second time
|
||||
locale_gen:
|
||||
name: pt_BR
|
||||
state: absent
|
||||
register: output
|
||||
|
||||
- name: Is the locale present?
|
||||
shell: locale -a | grep pt_BR
|
||||
register: post_check_output
|
||||
ignore_errors: true
|
||||
|
||||
- name: Make sure the locale is absent and we reported no change
|
||||
assert:
|
||||
that:
|
||||
- "post_check_output.rc == 1"
|
||||
- "not output.changed"
|
||||
|
||||
# Cleanup
|
||||
- name: Reinstall the locale we tested against if it was initially installed
|
||||
locale_gen:
|
||||
name: pt_BR
|
||||
state: present
|
||||
when: initial_state.rc == 0
|
||||
@@ -8,5 +8,11 @@
|
||||
# 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
|
||||
|
||||
- include_tasks: 'locale_gen.yml'
|
||||
when: ansible_distribution in ('Ubuntu', 'Debian')
|
||||
- name: Bail out if not supported
|
||||
ansible.builtin.meta: end_play
|
||||
when: ansible_distribution not in ('Ubuntu', 'Debian')
|
||||
|
||||
- include_tasks: basic.yml
|
||||
loop: "{{ locale_list_basic }}"
|
||||
loop_control:
|
||||
loop_var: locale_basic
|
||||
|
||||
17
tests/integration/targets/locale_gen/vars/main.yml
Normal file
17
tests/integration/targets/locale_gen/vars/main.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# locale_basic: pt_BR
|
||||
|
||||
locale_list_basic:
|
||||
- localegen: pt_BR
|
||||
locales: [pt_BR]
|
||||
skip_removal: false
|
||||
- localegen: C.UTF-8
|
||||
locales: [C.utf8, C.UTF-8]
|
||||
skip_removal: true
|
||||
- localegen: eo
|
||||
locales: [eo]
|
||||
skip_removal: false
|
||||
@@ -9,4 +9,5 @@ skip/macos
|
||||
skip/rhel8.0
|
||||
skip/rhel9.0
|
||||
skip/rhel9.1
|
||||
skip/rhel9.2
|
||||
skip/freebsd
|
||||
|
||||
23
tests/integration/targets/pacman/handlers/main.yml
Normal file
23
tests/integration/targets/pacman/handlers/main.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Remove user yaybuilder
|
||||
ansible.builtin.user:
|
||||
name: yaybuilder
|
||||
state: absent
|
||||
|
||||
- name: Remove yay
|
||||
ansible.builtin.package:
|
||||
name: yay
|
||||
state: absent
|
||||
|
||||
- name: Remove packages for yay-become
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- base-devel
|
||||
- yay
|
||||
- git
|
||||
- nmap
|
||||
state: absent
|
||||
@@ -17,3 +17,4 @@
|
||||
- include_tasks: 'update_cache.yml'
|
||||
- include_tasks: 'locally_installed_package.yml'
|
||||
- include_tasks: 'reason.yml'
|
||||
- include_tasks: 'yay-become.yml'
|
||||
|
||||
66
tests/integration/targets/pacman/tasks/yay-become.yml
Normal file
66
tests/integration/targets/pacman/tasks/yay-become.yml
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# This is more convoluted that one might expect, because:
|
||||
# - yay is not available or installation in ArchLinux (as it is in Manjaro - issue 6184 reports using it)
|
||||
# - to install yay in ArchLinux requires building the package
|
||||
# - makepkg cannot be run as root, but the user running it must have sudo to install the resulting package
|
||||
|
||||
- name: create user
|
||||
ansible.builtin.user:
|
||||
name: yaybuilder
|
||||
state: present
|
||||
notify: Remove user yaybuilder
|
||||
|
||||
- name: grant sudo powers to builder
|
||||
community.general.sudoers:
|
||||
name: yaybuilder
|
||||
user: yaybuilder
|
||||
commands: ALL
|
||||
nopassword: true
|
||||
|
||||
- name: Install base packages
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- base-devel
|
||||
- git
|
||||
- go
|
||||
state: present
|
||||
notify: Remove packages for yay-become
|
||||
|
||||
- name: Hack permssions for the remote_tmp_dir
|
||||
ansible.builtin.file:
|
||||
path: "{{ remote_tmp_dir }}"
|
||||
mode: '0777'
|
||||
|
||||
- name: Create temp directory for builder
|
||||
ansible.builtin.file:
|
||||
path: "{{ remote_tmp_dir }}/builder"
|
||||
owner: yaybuilder
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: clone yay git repo
|
||||
become: true
|
||||
become_user: yaybuilder
|
||||
ansible.builtin.git:
|
||||
repo: https://aur.archlinux.org/yay.git
|
||||
dest: "{{ remote_tmp_dir }}/builder/yay"
|
||||
depth: 1
|
||||
|
||||
- name: make package
|
||||
become: true
|
||||
become_user: yaybuilder
|
||||
ansible.builtin.command:
|
||||
chdir: "{{ remote_tmp_dir }}/builder/yay"
|
||||
cmd: makepkg -si --noconfirm
|
||||
notify: Remove yay
|
||||
|
||||
- name: Install nmap
|
||||
community.general.pacman:
|
||||
name: nmap
|
||||
state: present
|
||||
executable: yay
|
||||
extra_args: --builddir /var/cache/yay
|
||||
@@ -6,3 +6,4 @@ azp/posix/2
|
||||
destructive
|
||||
skip/python2
|
||||
skip/python3.5
|
||||
disabled # TODO
|
||||
|
||||
@@ -6,3 +6,4 @@ azp/posix/3
|
||||
destructive
|
||||
skip/python2
|
||||
skip/python3.5
|
||||
disabled # TODO
|
||||
|
||||
@@ -3,17 +3,29 @@
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Remove python requests
|
||||
ansible.builtin.pip:
|
||||
name:
|
||||
- requests
|
||||
state: absent
|
||||
|
||||
- name: Stop docker service
|
||||
become: true
|
||||
ansible.builtin.service:
|
||||
name: docker
|
||||
state: stopped
|
||||
|
||||
- name: Remove Docker packages
|
||||
package:
|
||||
ansible.builtin.package:
|
||||
name: "{{ docker_packages }}"
|
||||
state: absent
|
||||
|
||||
- name: "D-Fedora : Remove repository"
|
||||
file:
|
||||
ansible.builtin.file:
|
||||
path: /etc/yum.repos.d/docker-ce.repo
|
||||
state: absent
|
||||
|
||||
- name: "D-Fedora : Remove dnf-plugins-core"
|
||||
package:
|
||||
ansible.builtin.package:
|
||||
name: dnf-plugins-core
|
||||
state: absent
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
ansible.builtin.service:
|
||||
name: docker
|
||||
state: started
|
||||
notify: Stop docker service
|
||||
|
||||
- name: Cheat on the docker socket permissions
|
||||
become: true
|
||||
@@ -53,3 +54,4 @@
|
||||
name:
|
||||
- requests
|
||||
state: present
|
||||
notify: Remove python requests
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# Do nothing
|
||||
1
tests/integration/targets/setup_snap/tasks/D-RedHat-9.1.yml
Symbolic link
1
tests/integration/targets/setup_snap/tasks/D-RedHat-9.1.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
nothing.yml
|
||||
1
tests/integration/targets/setup_snap/tasks/D-RedHat-9.2.yml
Symbolic link
1
tests/integration/targets/setup_snap/tasks/D-RedHat-9.2.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
nothing.yml
|
||||
@@ -11,6 +11,7 @@ skip/freebsd
|
||||
skip/rhel8.0 # FIXME
|
||||
skip/rhel9.0 # FIXME
|
||||
skip/rhel9.1 # FIXME
|
||||
skip/rhel9.2 # FIXME
|
||||
skip/docker
|
||||
needs/root
|
||||
needs/target/setup_epel
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
.azure-pipelines/scripts/publish-codecov.py replace-urlopen
|
||||
plugins/modules/consul.py validate-modules:doc-missing-type
|
||||
plugins/modules/consul.py validate-modules:undocumented-parameter
|
||||
plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice
|
||||
plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0
|
||||
plugins/modules/homectl.py import-3.11 # Uses deprecated stdlib library 'crypt'
|
||||
plugins/modules/homectl.py import-3.12 # Uses deprecated stdlib library 'crypt'
|
||||
plugins/modules/iptables_state.py validate-modules:undocumented-parameter # params _back and _timeout used by action plugin
|
||||
plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen
|
||||
plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice # state=list - removed in 8.0.0
|
||||
@@ -20,4 +20,5 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice
|
||||
plugins/modules/rax.py use-argspec-type-path # module deprecated - removed in 9.0.0
|
||||
plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice
|
||||
plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt'
|
||||
plugins/modules/udm_user.py import-3.12 # Uses deprecated stdlib library 'crypt'
|
||||
plugins/modules/xfconf.py validate-modules:return-syntax-error
|
||||
|
||||
@@ -17,7 +17,7 @@ class DictDataLoader(DataLoader):
|
||||
|
||||
def __init__(self, file_mapping=None):
|
||||
file_mapping = {} if file_mapping is None else file_mapping
|
||||
assert type(file_mapping) == dict
|
||||
assert isinstance(file_mapping, dict)
|
||||
|
||||
super(DictDataLoader, self).__init__()
|
||||
|
||||
|
||||
@@ -262,6 +262,25 @@ ipv4.routes: { ip = 192.168.200.0/24, nh = 192.168.1.
|
||||
ipv4.route-metric: 10
|
||||
"""
|
||||
|
||||
TESTCASE_ETHERNET_MOD_IPV4_INT_WITH_ROUTE_AND_METRIC_CLEAR = [
|
||||
{
|
||||
'type': 'ethernet',
|
||||
'conn_name': 'non_existent_nw_device',
|
||||
'routes4': [],
|
||||
'state': 'present',
|
||||
'_ansible_check_mode': False,
|
||||
'_ansible_diff': True,
|
||||
},
|
||||
{
|
||||
'type': 'ethernet',
|
||||
'conn_name': 'non_existent_nw_device',
|
||||
'routes4_extended': [],
|
||||
'state': 'present',
|
||||
'_ansible_check_mode': False,
|
||||
'_ansible_diff': True,
|
||||
},
|
||||
]
|
||||
|
||||
TESTCASE_ETHERNET_MOD_IPV6_INT_WITH_ROUTE_AND_METRIC = [
|
||||
{
|
||||
'type': 'ethernet',
|
||||
@@ -1671,6 +1690,17 @@ def mocked_ethernet_connection_with_ipv4_static_address_static_route_metric_modi
|
||||
))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mocked_ethernet_connection_with_ipv4_static_address_static_route_metric_clear(mocker):
|
||||
mocker_set(mocker,
|
||||
connection_exists=True,
|
||||
execute_return=None,
|
||||
execute_side_effect=(
|
||||
(0, TESTCASE_ETHERNET_MOD_IPV4_INT_WITH_ROUTE_AND_METRIC_SHOW_OUTPUT, ""),
|
||||
(0, "", ""),
|
||||
))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mocked_ethernet_connection_with_ipv6_static_address_static_route_metric_modify(mocker):
|
||||
mocker_set(mocker,
|
||||
@@ -2991,6 +3021,38 @@ def test_ethernet_connection_static_ipv4_address_static_route_with_metric_modify
|
||||
assert not results.get('failed')
|
||||
|
||||
|
||||
@pytest.mark.parametrize('patch_ansible_module', TESTCASE_ETHERNET_MOD_IPV4_INT_WITH_ROUTE_AND_METRIC_CLEAR, indirect=['patch_ansible_module'])
|
||||
def test_ethernet_connection_static_ipv4_address_static_route_with_metric_clear(
|
||||
mocked_ethernet_connection_with_ipv4_static_address_static_route_metric_clear, capfd):
|
||||
"""
|
||||
Test : Modify ethernet connection with static IPv4 address and static route
|
||||
"""
|
||||
with pytest.raises(SystemExit):
|
||||
nmcli.main()
|
||||
|
||||
arg_list = nmcli.Nmcli.execute_command.call_args_list
|
||||
add_args, add_kw = arg_list[1]
|
||||
|
||||
assert add_args[0][0] == '/usr/bin/nmcli'
|
||||
assert add_args[0][1] == 'con'
|
||||
assert add_args[0][2] == 'modify'
|
||||
assert add_args[0][3] == 'non_existent_nw_device'
|
||||
|
||||
add_args_text = list(map(to_text, add_args[0]))
|
||||
|
||||
for param in ['ipv4.routes', '']:
|
||||
assert param in add_args_text
|
||||
|
||||
out, err = capfd.readouterr()
|
||||
results = json.loads(out)
|
||||
|
||||
assert 'ipv4.routes' in results['diff']['before']
|
||||
assert 'ipv4.routes' in results['diff']['after']
|
||||
|
||||
assert results.get('changed') is True
|
||||
assert not results.get('failed')
|
||||
|
||||
|
||||
@pytest.mark.parametrize('patch_ansible_module', TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_ROUTE, indirect=['patch_ansible_module'])
|
||||
def test_ethernet_connection_static_ipv6_address_static_route_create(mocked_ethernet_connection_with_ipv6_static_address_static_route_create, capfd):
|
||||
"""
|
||||
|
||||
@@ -8,6 +8,13 @@ __metaclass__ = type
|
||||
|
||||
import json
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
proxmoxer = pytest.importorskip('proxmoxer')
|
||||
mandatory_py_version = pytest.mark.skipif(
|
||||
sys.version_info < (2, 7),
|
||||
reason='The proxmoxer dependency requires python2.7 or higher'
|
||||
)
|
||||
|
||||
from ansible_collections.community.general.tests.unit.compat.mock import MagicMock, patch
|
||||
from ansible_collections.community.general.plugins.modules import proxmox_snap
|
||||
|
||||
@@ -12,6 +12,13 @@ __metaclass__ = type
|
||||
|
||||
import pytest
|
||||
import json
|
||||
import sys
|
||||
|
||||
proxmoxer = pytest.importorskip('proxmoxer')
|
||||
mandatory_py_version = pytest.mark.skipif(
|
||||
sys.version_info < (2, 7),
|
||||
reason='The proxmoxer dependency requires python2.7 or higher'
|
||||
)
|
||||
|
||||
from ansible_collections.community.general.plugins.modules import proxmox_tasks_info
|
||||
import ansible_collections.community.general.plugins.module_utils.proxmox as proxmox_utils
|
||||
|
||||
712
tests/unit/plugins/modules/test_rhsm_repository.py
Normal file
712
tests/unit/plugins/modules/test_rhsm_repository.py
Normal file
@@ -0,0 +1,712 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Author: Pino Toscano (ptoscano@redhat.com)
|
||||
# Largely adapted from test_rhsm_repository by
|
||||
# Jiri Hnidek (jhnidek@redhat.com)
|
||||
#
|
||||
# Copyright (c) Pino Toscano (ptoscano@redhat.com)
|
||||
# Copyright (c) Jiri Hnidek (jhnidek@redhat.com)
|
||||
#
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
import copy
|
||||
import fnmatch
|
||||
import json
|
||||
|
||||
from ansible.module_utils import basic
|
||||
from ansible_collections.community.general.plugins.modules import rhsm_repository
|
||||
|
||||
import pytest
|
||||
|
||||
TESTED_MODULE = rhsm_repository.__name__
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def patch_rhsm_repository(mocker):
|
||||
"""
|
||||
Function used for mocking some parts of rhsm_repository module
|
||||
"""
|
||||
mocker.patch('ansible_collections.community.general.plugins.modules.rhsm_repository.AnsibleModule.get_bin_path',
|
||||
return_value='/testbin/subscription-manager')
|
||||
mocker.patch('ansible_collections.community.general.plugins.modules.rhsm_repository.os.getuid',
|
||||
return_value=0)
|
||||
|
||||
|
||||
class Repos(object):
|
||||
"""
|
||||
Helper class to represent a list of repositories
|
||||
|
||||
Each repository is an object with few properties.
|
||||
"""
|
||||
|
||||
_SUBMAN_OUT_HEADER = """+----------------------------------------------------------+
|
||||
Available Repositories in /etc/yum.repos.d/redhat.repo
|
||||
+----------------------------------------------------------+
|
||||
"""
|
||||
_SUBMAN_OUT_ENTRY = """Repo ID: %s
|
||||
Repo Name: %s
|
||||
Repo URL: %s
|
||||
Enabled: %s
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, repos):
|
||||
self.repos = repos
|
||||
|
||||
def to_subman_list_output(self):
|
||||
"""
|
||||
Return a string mimicking the output of `subscription-manager repos --list`
|
||||
"""
|
||||
out = self._SUBMAN_OUT_HEADER
|
||||
for repo in self.repos:
|
||||
out += self._SUBMAN_OUT_ENTRY % (
|
||||
repo["id"],
|
||||
repo["name"],
|
||||
repo["url"],
|
||||
"1" if repo["enabled"] else "0",
|
||||
)
|
||||
|
||||
return out
|
||||
|
||||
def copy(self):
|
||||
"""
|
||||
Clone the object; used to do changes (enable(), disable()) without
|
||||
affecting the original object.
|
||||
"""
|
||||
return copy.deepcopy(self)
|
||||
|
||||
def _set_status(self, repo_id, status):
|
||||
for repo in self.repos:
|
||||
if fnmatch.fnmatch(repo['id'], repo_id):
|
||||
repo['enabled'] = status
|
||||
|
||||
def enable(self, repo_ids):
|
||||
"""
|
||||
Enable the specified IDs.
|
||||
|
||||
'repo_ids' can be either a string or a list of strings representing
|
||||
an ID (wilcard included).
|
||||
|
||||
Returns the same object, so calls to this can be chained.
|
||||
"""
|
||||
if not isinstance(repo_ids, list):
|
||||
repo_ids = [repo_ids]
|
||||
for repo_id in repo_ids:
|
||||
self._set_status(repo_id, True)
|
||||
return self
|
||||
|
||||
def disable(self, repo_ids):
|
||||
"""
|
||||
Disable the specified IDs.
|
||||
|
||||
'repo_ids' can be either a string or a list of strings representing
|
||||
an ID (wilcard included).
|
||||
|
||||
Returns the same object, so calls to this can be chained.
|
||||
"""
|
||||
if not isinstance(repo_ids, list):
|
||||
repo_ids = [repo_ids]
|
||||
for repo_id in repo_ids:
|
||||
self._set_status(repo_id, False)
|
||||
return self
|
||||
|
||||
def _filter_by_status(self, filter, status):
|
||||
return [
|
||||
repo['id']
|
||||
for repo in self.repos
|
||||
if repo['enabled'] == status and fnmatch.fnmatch(repo['id'], filter)
|
||||
]
|
||||
|
||||
def ids_enabled(self, filter='*'):
|
||||
"""
|
||||
Get a list with the enabled repositories.
|
||||
|
||||
'filter' is a wildcard expression.
|
||||
"""
|
||||
return self._filter_by_status(filter, True)
|
||||
|
||||
def ids_disabled(self, filter='*'):
|
||||
"""
|
||||
Get a list with the disabled repositories.
|
||||
|
||||
'filter' is a wildcard expression.
|
||||
"""
|
||||
return self._filter_by_status(filter, False)
|
||||
|
||||
def to_list(self):
|
||||
"""
|
||||
Get the list of repositories.
|
||||
"""
|
||||
return self.repos
|
||||
|
||||
|
||||
# List with test repositories, directly from the Candlepin test data.
|
||||
REPOS_LIST = [
|
||||
{
|
||||
"id": "never-enabled-content-801",
|
||||
"name": "never-enabled-content-801",
|
||||
"url": "https://candlepin.local/foo/path/never_enabled/801-100",
|
||||
"enabled": False,
|
||||
},
|
||||
{
|
||||
"id": "never-enabled-content-100000000000060",
|
||||
"name": "never-enabled-content-100000000000060",
|
||||
"url": "https://candlepin.local/foo/path/never_enabled/100000000000060-100",
|
||||
"enabled": False,
|
||||
},
|
||||
{
|
||||
"id": "awesomeos-x86_64-1000000000000023",
|
||||
"name": "awesomeos-x86_64-1000000000000023",
|
||||
"url": "https://candlepin.local/path/to/awesomeos/x86_64/1000000000000023-11124",
|
||||
"enabled": False,
|
||||
},
|
||||
{
|
||||
"id": "awesomeos-ppc64-100000000000011",
|
||||
"name": "awesomeos-ppc64-100000000000011",
|
||||
"url": "https://candlepin.local/path/to/awesomeos/ppc64/100000000000011-11126",
|
||||
"enabled": False,
|
||||
},
|
||||
{
|
||||
"id": "awesomeos-99000",
|
||||
"name": "awesomeos-99000",
|
||||
"url": "https://candlepin.local/path/to/generic/awesomeos/99000-11113",
|
||||
"enabled": True,
|
||||
},
|
||||
{
|
||||
"id": "content-label-27060",
|
||||
"name": "content-27060",
|
||||
"url": "https://candlepin.local/foo/path/common/27060-1111",
|
||||
"enabled": True,
|
||||
},
|
||||
{
|
||||
"id": "content-label-no-gpg-32060",
|
||||
"name": "content-nogpg-32060",
|
||||
"url": "https://candlepin.local/foo/path/no_gpg/32060-234",
|
||||
"enabled": False,
|
||||
},
|
||||
{
|
||||
"id": "awesomeos-1000000000000023",
|
||||
"name": "awesomeos-1000000000000023",
|
||||
"url": "https://candlepin.local/path/to/generic/awesomeos/1000000000000023-11113",
|
||||
"enabled": False,
|
||||
},
|
||||
{
|
||||
"id": "awesomeos-x86-100000000000020",
|
||||
"name": "awesomeos-x86-100000000000020",
|
||||
"url": "https://candlepin.local/path/to/awesomeos/x86/100000000000020-11120",
|
||||
"enabled": False,
|
||||
},
|
||||
{
|
||||
"id": "awesomeos-x86_64-99000",
|
||||
"name": "awesomeos-x86_64-99000",
|
||||
"url": "https://candlepin.local/path/to/awesomeos/x86_64/99000-11124",
|
||||
"enabled": True,
|
||||
},
|
||||
{
|
||||
"id": "awesomeos-s390x-99000",
|
||||
"name": "awesomeos-s390x-99000",
|
||||
"url": "https://candlepin.local/path/to/awesomeos/s390x/99000-11121",
|
||||
"enabled": False,
|
||||
},
|
||||
{
|
||||
"id": "awesomeos-modifier-37080",
|
||||
"name": "awesomeos-modifier-37080",
|
||||
"url": "https://candlepin.local/example.com/awesomeos-modifier/37080-1112",
|
||||
"enabled": False,
|
||||
},
|
||||
{
|
||||
"id": "awesomeos-i686-99000",
|
||||
"name": "awesomeos-i686-99000",
|
||||
"url": "https://candlepin.local/path/to/awesomeos/i686/99000-11123",
|
||||
"enabled": False,
|
||||
},
|
||||
{
|
||||
"id": "fake-content-38072",
|
||||
"name": "fake-content-38072",
|
||||
"url": "https://candlepin.local/path/to/fake-content/38072-3902",
|
||||
"enabled": True,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# A static object with the list of repositories, used as reference to query
|
||||
# the repositories, and create (by copy()) new Repos objects.
|
||||
REPOS = Repos(REPOS_LIST)
|
||||
|
||||
# The mock string for the output of `subscription-manager repos --list`.
|
||||
REPOS_LIST_OUTPUT = REPOS.to_subman_list_output()
|
||||
|
||||
# MUST match what's in run_subscription_manager() in the module.
|
||||
SUBMAN_KWARGS = {
|
||||
'environ_update': dict(LANG='C', LC_ALL='C', LC_MESSAGES='C'),
|
||||
}
|
||||
|
||||
|
||||
TEST_CASES = [
|
||||
# enable a disabled repository
|
||||
[
|
||||
{
|
||||
'name': 'awesomeos-1000000000000023',
|
||||
},
|
||||
{
|
||||
'id': 'test_enable_single',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
(
|
||||
(
|
||||
'/testbin/subscription-manager repos'
|
||||
' --enable awesomeos-1000000000000023'
|
||||
),
|
||||
SUBMAN_KWARGS,
|
||||
(0, '', '')
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'repositories': REPOS.copy().enable('awesomeos-1000000000000023'),
|
||||
}
|
||||
],
|
||||
# enable an already enabled repository
|
||||
[
|
||||
{
|
||||
'name': 'fake-content-38072',
|
||||
},
|
||||
{
|
||||
'id': 'test_enable_already_enabled',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
],
|
||||
'changed': False,
|
||||
'repositories': REPOS.copy(),
|
||||
}
|
||||
],
|
||||
# enable two disabled repositories
|
||||
[
|
||||
{
|
||||
'name': ['awesomeos-1000000000000023', 'content-label-no-gpg-32060'],
|
||||
},
|
||||
{
|
||||
'id': 'test_enable_multiple',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
(
|
||||
(
|
||||
'/testbin/subscription-manager repos'
|
||||
' --enable awesomeos-1000000000000023'
|
||||
' --enable content-label-no-gpg-32060'
|
||||
),
|
||||
SUBMAN_KWARGS,
|
||||
(0, '', '')
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'repositories': REPOS.copy().enable('awesomeos-1000000000000023').enable('content-label-no-gpg-32060'),
|
||||
}
|
||||
],
|
||||
# enable two repositories, one disabled and one already enabled
|
||||
[
|
||||
{
|
||||
'name': ['awesomeos-1000000000000023', 'fake-content-38072'],
|
||||
},
|
||||
{
|
||||
'id': 'test_enable_multiple_mixed',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
(
|
||||
(
|
||||
'/testbin/subscription-manager repos'
|
||||
' --enable awesomeos-1000000000000023'
|
||||
' --enable fake-content-38072'
|
||||
),
|
||||
SUBMAN_KWARGS,
|
||||
(0, '', '')
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'repositories': REPOS.copy().enable('awesomeos-1000000000000023'),
|
||||
}
|
||||
],
|
||||
# purge everything but never-enabled-content-801 (disabled)
|
||||
[
|
||||
{
|
||||
'name': 'never-enabled-content-801',
|
||||
'purge': True,
|
||||
},
|
||||
{
|
||||
'id': 'test_purge_everything_but_one_disabled',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
(
|
||||
(
|
||||
'/testbin/subscription-manager repos'
|
||||
' --enable never-enabled-content-801'
|
||||
) + ''.join([' --disable ' + i for i in REPOS.ids_enabled() if i != 'never-enabled-content-801']),
|
||||
SUBMAN_KWARGS,
|
||||
(0, '', '')
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'repositories': REPOS.copy().disable('*').enable('never-enabled-content-801'),
|
||||
}
|
||||
],
|
||||
# purge everything but awesomeos-99000 (already enabled)
|
||||
[
|
||||
{
|
||||
'name': 'awesomeos-99000',
|
||||
'purge': True,
|
||||
},
|
||||
{
|
||||
'id': 'test_purge_everything_but_one_enabled',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
(
|
||||
(
|
||||
'/testbin/subscription-manager repos'
|
||||
' --enable awesomeos-99000'
|
||||
' --disable content-label-27060'
|
||||
' --disable awesomeos-x86_64-99000'
|
||||
' --disable fake-content-38072'
|
||||
),
|
||||
SUBMAN_KWARGS,
|
||||
(0, '', '')
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'repositories': REPOS.copy().disable('*').enable('awesomeos-99000'),
|
||||
}
|
||||
],
|
||||
# enable everything, then purge everything but content-label-27060
|
||||
[
|
||||
{
|
||||
'name': 'content-label-27060',
|
||||
'purge': True,
|
||||
},
|
||||
{
|
||||
'id': 'test_enable_everything_purge_everything_but_one_enabled',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS.copy().enable('*').to_subman_list_output(), '')
|
||||
),
|
||||
(
|
||||
(
|
||||
'/testbin/subscription-manager repos'
|
||||
' --enable content-label-27060'
|
||||
' --disable never-enabled-content-801'
|
||||
' --disable never-enabled-content-100000000000060'
|
||||
' --disable awesomeos-x86_64-1000000000000023'
|
||||
' --disable awesomeos-ppc64-100000000000011'
|
||||
' --disable awesomeos-99000'
|
||||
' --disable content-label-no-gpg-32060'
|
||||
' --disable awesomeos-1000000000000023'
|
||||
' --disable awesomeos-x86-100000000000020'
|
||||
' --disable awesomeos-x86_64-99000'
|
||||
' --disable awesomeos-s390x-99000'
|
||||
' --disable awesomeos-modifier-37080'
|
||||
' --disable awesomeos-i686-99000'
|
||||
' --disable fake-content-38072'
|
||||
),
|
||||
SUBMAN_KWARGS,
|
||||
(0, '', '')
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'repositories': REPOS.copy().disable('*').enable('content-label-27060'),
|
||||
}
|
||||
],
|
||||
# enable all awesomeos-*
|
||||
[
|
||||
{
|
||||
'name': 'awesomeos-*',
|
||||
},
|
||||
{
|
||||
'id': 'test_enable_all_awesomeos_star',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
(
|
||||
(
|
||||
'/testbin/subscription-manager repos'
|
||||
' --enable awesomeos-x86_64-1000000000000023'
|
||||
' --enable awesomeos-ppc64-100000000000011'
|
||||
' --enable awesomeos-99000'
|
||||
' --enable awesomeos-1000000000000023'
|
||||
' --enable awesomeos-x86-100000000000020'
|
||||
' --enable awesomeos-x86_64-99000'
|
||||
' --enable awesomeos-s390x-99000'
|
||||
' --enable awesomeos-modifier-37080'
|
||||
' --enable awesomeos-i686-99000'
|
||||
),
|
||||
SUBMAN_KWARGS,
|
||||
(0, '', '')
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'repositories': REPOS.copy().enable('awesomeos-*'),
|
||||
}
|
||||
],
|
||||
# purge everything but awesomeos-*
|
||||
[
|
||||
{
|
||||
'name': REPOS.ids_enabled('awesomeos-*'),
|
||||
'purge': True,
|
||||
},
|
||||
{
|
||||
'id': 'test_purge_everything_but_awesomeos_list',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
(
|
||||
(
|
||||
'/testbin/subscription-manager repos'
|
||||
' --enable awesomeos-99000'
|
||||
' --enable awesomeos-x86_64-99000'
|
||||
' --disable content-label-27060'
|
||||
' --disable fake-content-38072'
|
||||
),
|
||||
SUBMAN_KWARGS,
|
||||
(0, '', '')
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'repositories': REPOS.copy().disable('*').enable(REPOS.ids_enabled('awesomeos-*')),
|
||||
}
|
||||
],
|
||||
# enable a repository that does not exist
|
||||
[
|
||||
{
|
||||
'name': 'repo-that-does-not-exist',
|
||||
},
|
||||
{
|
||||
'id': 'test_enable_nonexisting',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
],
|
||||
'failed': True,
|
||||
'msg': 'repo-that-does-not-exist is not a valid repository ID',
|
||||
}
|
||||
],
|
||||
# disable an enabled repository
|
||||
[
|
||||
{
|
||||
'name': 'awesomeos-99000',
|
||||
'state': 'disabled',
|
||||
},
|
||||
{
|
||||
'id': 'test_disable_single',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
(
|
||||
(
|
||||
'/testbin/subscription-manager repos'
|
||||
' --disable awesomeos-99000'
|
||||
),
|
||||
SUBMAN_KWARGS,
|
||||
(0, '', '')
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'repositories': REPOS.copy().disable('awesomeos-99000'),
|
||||
}
|
||||
],
|
||||
# disable an enabled repository (using state=absent)
|
||||
[
|
||||
{
|
||||
'name': 'awesomeos-99000',
|
||||
'state': 'absent',
|
||||
},
|
||||
{
|
||||
'id': 'test_disable_single_using_absent',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
(
|
||||
(
|
||||
'/testbin/subscription-manager repos'
|
||||
' --disable awesomeos-99000'
|
||||
),
|
||||
SUBMAN_KWARGS,
|
||||
(0, '', '')
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'repositories': REPOS.copy().disable('awesomeos-99000'),
|
||||
}
|
||||
],
|
||||
# disable an already disabled repository
|
||||
[
|
||||
{
|
||||
'name': 'never-enabled-content-801',
|
||||
'state': 'disabled',
|
||||
},
|
||||
{
|
||||
'id': 'test_disable_already_disabled',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
],
|
||||
'changed': False,
|
||||
'repositories': REPOS.copy(),
|
||||
}
|
||||
],
|
||||
# disable an already disabled repository, and purge
|
||||
[
|
||||
{
|
||||
'name': 'never-enabled-content-801',
|
||||
'state': 'disabled',
|
||||
'purge': True,
|
||||
},
|
||||
{
|
||||
'id': 'test_disable_already_disabled_and_purge',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
(
|
||||
(
|
||||
'/testbin/subscription-manager repos'
|
||||
' --disable never-enabled-content-801'
|
||||
) + ''.join([' --disable ' + i for i in REPOS.ids_enabled()]),
|
||||
SUBMAN_KWARGS,
|
||||
(0, '', '')
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'repositories': REPOS.copy().disable('*'),
|
||||
}
|
||||
],
|
||||
# disable an enabled repository, and purge
|
||||
[
|
||||
{
|
||||
'name': 'awesomeos-99000',
|
||||
'state': 'disabled',
|
||||
'purge': True,
|
||||
},
|
||||
{
|
||||
'id': 'test_disable_single_and_purge',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
(
|
||||
(
|
||||
'/testbin/subscription-manager repos'
|
||||
) + ''.join([' --disable ' + i for i in REPOS.ids_enabled()]),
|
||||
SUBMAN_KWARGS,
|
||||
(0, '', '')
|
||||
),
|
||||
],
|
||||
'changed': True,
|
||||
'repositories': REPOS.copy().disable('*'),
|
||||
}
|
||||
],
|
||||
# disable a repository that does not exist
|
||||
[
|
||||
{
|
||||
'name': 'repo-that-does-not-exist',
|
||||
'state': 'disabled',
|
||||
},
|
||||
{
|
||||
'id': 'test_disable_nonexisting',
|
||||
'run_command.calls': [
|
||||
(
|
||||
'/testbin/subscription-manager repos --list',
|
||||
SUBMAN_KWARGS,
|
||||
(0, REPOS_LIST_OUTPUT, '')
|
||||
),
|
||||
],
|
||||
'failed': True,
|
||||
'msg': 'repo-that-does-not-exist is not a valid repository ID',
|
||||
}
|
||||
],
|
||||
]
|
||||
|
||||
|
||||
TEST_CASES_IDS = [item[1]['id'] for item in TEST_CASES]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('patch_ansible_module, testcase', TEST_CASES, ids=TEST_CASES_IDS, indirect=['patch_ansible_module'])
|
||||
@pytest.mark.usefixtures('patch_ansible_module')
|
||||
def test_rhsm_repository(mocker, capfd, patch_rhsm_repository, testcase):
|
||||
"""
|
||||
Run unit tests for test cases listen in TEST_CASES
|
||||
"""
|
||||
|
||||
# Mock function used for running commands first
|
||||
call_results = [item[2] for item in testcase['run_command.calls']]
|
||||
mock_run_command = mocker.patch.object(
|
||||
basic.AnsibleModule,
|
||||
'run_command',
|
||||
side_effect=call_results)
|
||||
|
||||
# Try to run test case
|
||||
with pytest.raises(SystemExit):
|
||||
rhsm_repository.main()
|
||||
|
||||
out, err = capfd.readouterr()
|
||||
results = json.loads(out)
|
||||
|
||||
if 'failed' in testcase:
|
||||
assert results['failed'] == testcase['failed']
|
||||
assert results['msg'] == testcase['msg']
|
||||
else:
|
||||
assert 'changed' in results
|
||||
assert results['changed'] == testcase['changed']
|
||||
assert results['repositories'] == testcase['repositories'].to_list()
|
||||
|
||||
assert basic.AnsibleModule.run_command.call_count == len(testcase['run_command.calls'])
|
||||
# FIXME ideally we need also to compare the actual calls with the expected
|
||||
# ones; the problem is that the module uses a dict to collect the repositories
|
||||
# to enable and disable, so the order of the --enable/--disable parameters to
|
||||
# `subscription-manager repos` is not stable
|
||||
@@ -43,4 +43,8 @@ dataclasses ; python_version == '3.6'
|
||||
elastic-apm ; python_version >= '3.6'
|
||||
|
||||
# requirements for scaleway modules
|
||||
passlib[argon2]
|
||||
passlib[argon2]
|
||||
|
||||
# requirements for the proxmox modules
|
||||
proxmoxer < 2.0.0 ; python_version >= '2.7' and python_version <= '3.6'
|
||||
proxmoxer ; python_version > '3.6'
|
||||
|
||||
@@ -19,7 +19,7 @@ wheel < 0.30.0 ; python_version < '2.7' # wheel 0.30.0 and later require python
|
||||
yamllint != 1.8.0, < 1.14.0 ; python_version < '2.7' # yamllint 1.8.0 and 1.14.0+ require python 2.7+
|
||||
pycrypto >= 2.6 # Need features found in 2.6 and greater
|
||||
ncclient >= 0.5.2 # Need features added in 0.5.2 and greater
|
||||
idna < 2.6, >= 2.5 # linode requires idna < 2.9, >= 2.5, requests requires idna < 2.6, but cryptography will cause the latest version to be installed instead
|
||||
# idna < 2.6, >= 2.5 # linode requires idna < 2.9, >= 2.5, requests requires idna < 2.6, but cryptography will cause the latest version to be installed instead
|
||||
paramiko < 2.4.0 ; python_version < '2.7' # paramiko 2.4.0 drops support for python 2.6
|
||||
python-nomad < 2.0.0 ; python_version <= '3.7' # python-nomad 2.0.0 needs Python 3.7+
|
||||
pytest < 3.3.0 ; python_version < '2.7' # pytest 3.3.0 drops support for python 2.6
|
||||
|
||||
Reference in New Issue
Block a user