43 Commits

Author SHA1 Message Date
centosinfra-prod-github-app[bot]
fe77b17251 Merge pull request #712 from Akasurde/ignore_nuke
remove old ansible-core release

SUMMARY
Signed-off-by: Abhijeet Kasurde Akasurde@redhat.com
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
.azure-pipelines/azure-pipelines.yml

Reviewed-by: Hideki Saito <saito@fgrep.org>
2026-05-07 00:58:05 +00:00
Abhijeet Kasurde
28a09cd805 remove old ansible-core release
Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
2026-05-06 15:33:18 -04:00
Abhijeet Kasurde
853a333142 remove old ignore.txt
Signed-off-by: Abhijeet Kasurde <Akasurde@redhat.com>
2026-05-06 15:31:04 -04:00
centosinfra-prod-github-app[bot]
2022c1bd86 Merge pull request #690 from barpavel/fix-686-module-utils-deprecation
Fix all deprecated module_utils imports before ansible-core 2.24 removal

SUMMARY
Fixes all deprecated ansible.module_utils imports across the entire collection that will be removed in ansible-core 2.24.
This PR comprehensively addresses deprecation warnings reported in #686 by updating import statements in 20 files to use the new recommended import paths, and removes 8 unused test utility files that contained deprecated imports.
Deprecated imports replaced:



Deprecated import
Replacement




ansible.module_utils._text
ansible.module_utils.common.text.converters


ansible.module_utils.common._collections_compat
collections.abc


ansible.module_utils.six.moves.shlex_quote
shlex.quote


ansible.module_utils.six.moves.reduce
functools.reduce


ansible.module_utils.six.moves.urllib.parse.urlparse
urllib.parse.urlparse


ansible.module_utils.six.string_types
basestring/str (Python 2/3 compatible)


ansible.module_utils.six.text_type
str


ansible.module_utils.six.PY3
Removed (simplified Python 2/3 conditionals)


ansible.module_utils.six.with_metaclass
Native metaclass= syntax


ansible.module_utils.six.iteritems
dict.items()



Files fixed (20 files, 1 commit per file for easier review):

plugins/action/patch.py
plugins/action/synchronize.py
plugins/callback/cgroup_perf_recap.py
plugins/callback/json.py
plugins/callback/jsonl.py
plugins/callback/profile_roles.py
plugins/callback/profile_tasks.py
plugins/modules/acl.py
plugins/modules/authorized_key.py
plugins/modules/firewalld_info.py
plugins/modules/mount.py
plugins/modules/patch.py
plugins/modules/rhel_rpm_ostree.py
plugins/modules/rpm_ostree_upgrade.py
plugins/modules/seboolean.py
plugins/modules/synchronize.py
plugins/modules/sysctl.py
plugins/shell/csh.py
plugins/shell/fish.py
tests/unit/modules/system/test_mount.py

Files deleted (8 unused test utility files):
These files are dead code - none of them are imported or used anywhere in the test suite or the collection. Removing them also addresses Python 2.7 compatibility concerns raised in code review, as several contained deprecated imports that would be incorrect to fix for Python 2.

tests/unit/compat/builtins.py
tests/unit/mock/loader.py
tests/unit/mock/path.py
tests/unit/mock/procenv.py
tests/unit/mock/vault_helper.py
tests/unit/mock/yaml_helper.py
tests/unit/modules/conftest.py
tests/unit/modules/utils.py

Completeness verified with:
git grep -n -P '_compat|utils._text|utils.six' -- '*.py' | grep -v yml

This command returns no results, confirming all deprecated imports have been replaced.
Notes on Python 2.7 compatibility:
For modules that may run on Python 2.7 managed hosts (e.g., authorized_key.py, synchronize.py, sysctl.py), Python 2/3 compatible fallbacks were used instead of direct Python 3 replacements:

authorized_key.py: try/except ImportError for urllib.parse.urlparse (falls back to urlparse on Python 2)
synchronize.py: try/except ImportError for shlex.quote (falls back to pipes.quote on Python 2)
sysctl.py: uses sys.version_info to set string_types to str on Python 3 (basestring on Python 2)

Also removes corresponding pylint:ansible-bad-import-from entries from tests/sanity/ignore-2.21.txt and tests/sanity/ignore-2.22.txt where applicable.
Fixes #686
ISSUE TYPE

Bugfix Pull Request

ADDITIONAL INFORMATION
Approach:
Each file is fixed in a separate commit for easier code review. The changelog fragment is added in a final commit. Corresponding pylint:ansible-bad-import-from ignore entries in tests/sanity/ignore-2.21.txt and tests/sanity/ignore-2.22.txt are removed in the same commit as the file fix (or the file removal commit).
CI results:
All 59 checks passing (Azure Pipelines sanity, units, lint, Docker, Remote across ansible-core 2.17 through devel, and Zuul ansible/check).

Reviewed-by: Felix Fontein <felix@fontein.de>
Reviewed-by: Pavel Bar
Reviewed-by: Abhijeet Kasurde
2026-05-06 19:19:51 +00:00
Pavel Bar
42d76de1cf Add changelog fragment for deprecated imports fix
Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 19:06:51 +03:00
Pavel Bar
fb2bc7b4b5 Remove unused test utility files
These files are dead code - none of them are imported or used anywhere
in the test suite or the collection:
- tests/unit/compat/builtins.py
- tests/unit/mock/loader.py
- tests/unit/mock/path.py
- tests/unit/mock/procenv.py
- tests/unit/mock/vault_helper.py
- tests/unit/mock/yaml_helper.py
- tests/unit/modules/conftest.py
- tests/unit/modules/utils.py

Removing these files also addresses Python 2.7 compatibility concerns
raised in code review, as several contained deprecated imports that
would be incorrect to fix for Python 2.

Also removes corresponding pylint:ansible-bad-import-from entries from
tests/sanity/ignore-2.21.txt.

Related to #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 19:06:51 +03:00
Pavel Bar
9603ef890f Fix deprecated imports in tests/unit/modules/system/test_mount.py
Replace deprecated module_utils import:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:15 +03:00
Pavel Bar
513d50192d Fix deprecated imports in plugins/shell/fish.py
Replace deprecated module_utils imports:
- ansible.module_utils.six.text_type -> str
- ansible.module_utils.six.moves.shlex_quote -> shlex.quote

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:15 +03:00
Pavel Bar
5cbe684b48 Fix deprecated imports in plugins/shell/csh.py
Replace deprecated module_utils imports:
- ansible.module_utils.six.text_type -> str
- ansible.module_utils.six.moves.shlex_quote -> shlex.quote

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:15 +03:00
Pavel Bar
17dd3b2e01 Fix deprecated imports in plugins/modules/sysctl.py
Replace deprecated module_utils imports:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters
- ansible.module_utils.six.string_types -> basestring/str (Python 2/3 compatible)

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
35bcea6ec9 Fix deprecated imports in plugins/modules/seboolean.py
Replace deprecated module_utils import:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
065af18c26 Fix deprecated imports in plugins/modules/rpm_ostree_upgrade.py
Replace deprecated module_utils import:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
a2fa110036 Fix deprecated imports in plugins/modules/rhel_rpm_ostree.py
Replace deprecated module_utils import:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
935a644f3c Fix deprecated imports in plugins/modules/patch.py
Replace deprecated module_utils import:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
37e46324f5 Fix deprecated imports in plugins/modules/firewalld_info.py
Replace deprecated module_utils import:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
1aa2f974e9 Fix deprecated imports in plugins/modules/authorized_key.py
Replace deprecated module_utils imports:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters
- ansible.module_utils.six.moves.urllib.parse -> urllib.parse

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
7c9c261faf Fix deprecated imports in plugins/modules/acl.py
Replace deprecated module_utils import:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
bfe81d4388 Fix deprecated imports in plugins/callback/profile_tasks.py
Replace deprecated module_utils import:
- ansible.module_utils.six.moves.reduce -> functools.reduce

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
ba58f22d2e Fix deprecated imports in plugins/callback/profile_roles.py
Replace deprecated module_utils import:
- ansible.module_utils.six.moves.reduce -> functools.reduce

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
23a8948110 Fix deprecated imports in plugins/callback/jsonl.py
Replace deprecated module_utils import:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
4f43537804 Fix deprecated imports in plugins/callback/json.py
Replace deprecated module_utils import:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
e5f6e0be0c Fix deprecated imports in plugins/callback/cgroup_perf_recap.py
Replace deprecated module_utils imports:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters
- ansible.module_utils.six.with_metaclass -> Python 3 metaclass syntax

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
25f4419e19 Fix deprecated imports in plugins/action/patch.py
Replace deprecated module_utils import:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
f31b7a380b Fix deprecated imports in plugins/modules/mount.py
Replace deprecated module_utils imports:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters
- ansible.module_utils.six.iteritems -> dict.items()

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
1f0844bf98 Fix deprecated imports in plugins/modules/synchronize.py
Replace deprecated module_utils imports:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters
- ansible.module_utils.six.moves.shlex_quote -> shlex.quote

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
Pavel Bar
6462116447 Fix deprecated imports in plugins/action/synchronize.py
Replace deprecated module_utils imports:
- ansible.module_utils._text -> ansible.module_utils.common.text.converters
- ansible.module_utils.common._collections_compat -> collections.abc
- ansible.module_utils.six.string_types -> str
- ansible.module_utils.six.moves.shlex_quote -> shlex.quote

Fixes #686

Co-authored-by: Cursor AI
Signed-off-by: Pavel Bar <pbar@redhat.com>
2026-05-06 18:58:14 +03:00
centosinfra-prod-github-app[bot]
28b6db7845 Merge pull request #711 from saito-hideki/pr/ci_2026050500
[CI] Update Azure Pipelines distros and fix shebang

SUMMARY
Update Azure Pipelines distros and fix shebang:

Add devel targets for Docker and Remote stages
Split existing targets into 2.21 stages
Fix shebang in timing.py to pass sanity test

ISSUE TYPE

CI

COMPONENT NAME

ansible.posix

ADDITIONAL INFORMATION
None

Reviewed-by: Andrew Klychkov <aklychko@redhat.com>
2026-05-05 12:57:42 +00:00
Hideki Saito
7709fbe168 [CI] Update Azure Pipelines distros and fix shebang
- Add devel targets for Docker and Remote stages
- Split existing targets into 2.21 stages
- Fix shebang in timing.py to pass sanity test
- Remove unnecessary shebang ignores from sanity ignore files

Signed-off-by: Hideki Saito <saito@fgrep.org>
2026-05-05 17:04:12 +09:00
Andrew Klychkov
692b906b82 chore: remove .github/BOTMETA.yml (#706) 2026-02-25 09:38:38 +01:00
Andrew Klychkov
aece4a9632 ci: add certification.yml GitHub workflow (#705) 2026-02-25 09:38:02 +01:00
softwarefactory-project-zuul[bot]
2cd1a6e4ab Merge pull request #704 from Andersson007/update_ci0
ci: .azure-pipelines/azure-pipelines.yml update distros

SUMMARY
ci: .azure-pipelines/azure-pipelines.yml update distros
As were reported in https://forum.ansible.com/t/ansible-test-images-and-vms-update-devel-2-20-2-19-2-18/45080
ISSUE TYPE


CI

Reviewed-by: Hideki Saito <saito@fgrep.org>
2026-02-25 08:19:39 +00:00
Andrew Klychkov
8af0b227cc ci: .azure-pipelines/azure-pipelines.yml update distros 2026-02-25 08:47:31 +01:00
softwarefactory-project-zuul[bot]
5f44339fa5 Merge pull request #693 from saito-hideki/pr/ci_2025120500
[CI] Update AZP CI matrix and sanity tests

SUMMARY

Update AZP CI matrix. Bump the remote target version for 2.16 and 2.17
Add ignore file for Ansible Core 2.21 for the current devel version sanity test

ISSUE TYPE

CI tests Pull Request

COMPONENT NAME

ansible.posix

ADDITIONAL INFORMATION
None
2025-12-09 05:56:49 +00:00
Hideki Saito
7d5aef07e2 Update AZP CI matrix and sanity test
* Update AZP CI matrix
* Add ignore file for Ansible Core 2.21
* Remove ignore lines for ansible-bad-import-from in 2.20 sanity tests

Signed-off-by: Hideki Saito <saito@fgrep.org>
2025-12-09 05:23:05 +00:00
softwarefactory-project-zuul[bot]
b39ee97ccc Merge pull request #677 from shenxianpeng/patch-1
docs: fix broken badge and restore coverage badge

SUMMARY
Replaced the outdated Shippable badge and active Codecov coverage badge, like other repos in ansible-collections org
ISSUE TYPE


Docs Pull Request

COMPONENT NAME

ADDITIONAL INFORMATION

Reviewed-by: Hideki Saito <saito@fgrep.org>
2025-11-28 07:14:56 +00:00
softwarefactory-project-zuul[bot]
72a6eb9729 Merge pull request #639 from Klaas-/Klaas-fix_authorized_key
Fixes #462 notice permission denied on authorized_key module

SUMMARY
As of right now the authorized_key module does not notice on an "absent" if a authorized_keys file is simply not readable to the executing user. I am trying to fix that
ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME
authorized_key
ADDITIONAL INFORMATION


Execute as a user that does not have access to the root users authorized keys file

- name: Delete key from root user
  ansible.posix.authorized_key:
    state: absent
    user: root
    key: ssh-rsa xxxxxxxx

- name: Delete key from root user
  become: true
  ansible.posix.authorized_key:
    state: absent
    user: root
    key: ssh-rsa xxxxxxxx

The one without become will succeed before my change and will fail with a permission denied error after my change. The 2nd task will actually remove a key from root user if become privileges are available for the executing user

Reviewed-by: Brian Coca
Reviewed-by: Klaas Demter
Reviewed-by: Felix Fontein <felix@fontein.de>
Reviewed-by: Hideki Saito <saito@fgrep.org>
2025-11-28 03:25:21 +00:00
Klaas Demter
9651a19805 change result.failed==True to result is failed in check_permissions.yml
Co-authored-by: Felix Fontein <felix@fontein.de>
2025-10-22 08:29:46 +02:00
Klaas Demter
413ab782a8 Fixes #462 notice permission denied on authorized_key module 2025-10-21 10:00:12 +02:00
softwarefactory-project-zuul[bot]
9343c6f56f Merge pull request #682 from saito-hideki/pr/ci_update_20250929
Ignore pylint errors caused by compatibility checks for six

SUMMARY
Ignore pylint errors caused by compatibility checks for six:

pylint:ansible-bad-import-from

Ansible Core 2.16 supports Python2 environment,  and six is required to maintain compatibility with Python 2.
We plan to continue supporting Ansible Core 2.16 at this time.
Additionally, removing the standalone ansible-lint test because it is already included in ansible-test sanity.
ISSUE TYPE

CI tests Request

COMPONENT NAME

ansible.posix

ADDITIONAL INFORMATION
None

Reviewed-by: Andrew Klychkov <aklychko@redhat.com>
Reviewed-by: Felix Fontein <felix@fontein.de>
Reviewed-by: Hideki Saito <saito@fgrep.org>
2025-10-02 05:55:28 +00:00
saito-hideki
9dc73a686a Ignore pylint errors caused by compatibility checks for six
* This is a temporary measure until we stop covering Python2
* Skipped sanity[cannot-ignore] to keep backward compatibility with Python2
* Consolidate all ansible-lint option locations into .ansible-lint
* Fixed some typos

Signed-off-by: saito-hideki <saito@fgrep.org>
2025-10-02 14:02:56 +09:00
softwarefactory-project-zuul[bot]
6da1331018 Merge pull request #670 from felixfontein/deprecations
Use module.warn() instead of returning warnings

SUMMARY
Returning warnings as warnings has been deprecated.
Ref: #635.
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
firewalld_info
mount

Reviewed-by: Hideki Saito <saito@fgrep.org>
2025-08-16 01:03:30 +00:00
Xianpeng Shen
cda2e0657f docs: fix broken badge and restore coverage badge 2025-08-14 14:33:30 +03:00
Felix Fontein
ab8dfefd90 Use module.warn() instead of returning warnings. 2025-08-06 06:49:32 +02:00
53 changed files with 327 additions and 1130 deletions

View File

@@ -4,7 +4,12 @@
# SPDX-FileCopyrightText: 2024, Ansible Project
skip_list:
- meta-runtime[unsupported-version] # Tis rule doesn't make any sense
- meta-runtime[unsupported-version] # This rule doesn't make any sense
- fqcn[deep] # This rule produces false positives for files in tests/unit/plugins/action/fixtures/
- sanity[cannot-ignore] # This rule is skipped to keep backward compatibility with Python 2
exclude_paths:
- changelogs/
- .github/
- tests/
- meta/

View File

@@ -43,7 +43,7 @@ pool: Standard
stages:
- stage: Sanity_devel
displayName: Ansible devel sanity
displayName: Ansible devel Sanity & Units & Lint
dependsOn: []
jobs:
- template: templates/matrix.yml
@@ -57,8 +57,41 @@ stages:
test: units
- name: Lint
test: lint
- stage: Sanity_2_21
displayName: Ansible 2.21 Sanity & Units & Lint
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: "{0}"
testFormat: 2.21/{0}
targets:
- name: Sanity
test: sanity
- name: Units
test: units
- name: Lint
test: lint
- stage: Sanity_2_20
displayName: Ansible 2.20 Sanity & Units & Lint
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: "{0}"
testFormat: 2.20/{0}
targets:
- name: Sanity
test: sanity
- name: Units
test: units
- name: Lint
test: lint
- stage: Sanity_2_19
displayName: Ansible 2.19 sanitay & Units & Lint
displayName: Ansible 2.19 Sanity & Units & Lint
dependsOn: []
jobs:
- template: templates/matrix.yml
@@ -72,8 +105,9 @@ stages:
test: units
- name: Lint
test: lint
- stage: Sanity_2_18
displayName: Ansible 2.18 sanity & Units & Lint
displayName: Ansible 2.18 Sanity & Units & Lint
dependsOn: []
jobs:
- template: templates/matrix.yml
@@ -87,34 +121,7 @@ stages:
test: units
- name: Lint
test: lint
- stage: Sanity_2_17
displayName: Ansible 2.17 sanity & Units & Lint
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: "{0}"
testFormat: 2.17/{0}
targets:
- name: Sanity
test: sanity
- name: Units
test: units
- name: Lint
test: lint
- stage: Sanity_2_16
displayName: Ansible 2.16 sanity & Units & Lint
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: "{0}"
testFormat: 2.16/{0}
targets:
- name: Sanity
test: sanity
- name: Units
test: units
## Docker
- stage: Docker_devel
displayName: Docker devel
@@ -123,6 +130,36 @@ stages:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux/{0}/1
targets:
- name: Fedora 44
test: fedora44
- name: Ubuntu 22.04
test: ubuntu2204
- name: Ubuntu 24.04
test: ubuntu2404
- stage: Docker_2_21
displayName: Docker 2.21
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux/{0}/1
targets:
- name: Fedora 44
test: fedora44
- name: Ubuntu 22.04
test: ubuntu2204
- name: Ubuntu 24.04
test: ubuntu2404
- stage: Docker_2_20
displayName: Docker 2.20
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.20/linux/{0}/1
targets:
- name: Fedora 42
test: fedora42
@@ -130,6 +167,7 @@ stages:
test: ubuntu2204
- name: Ubuntu 24.04
test: ubuntu2404
- stage: Docker_2_19
displayName: Docker 2.19
dependsOn: []
@@ -144,6 +182,7 @@ stages:
test: ubuntu2204
- name: Ubuntu 24.04
test: ubuntu2404
- stage: Docker_2_18
displayName: Docker 2.18
dependsOn: []
@@ -158,32 +197,6 @@ stages:
test: ubuntu2204
- name: Ubuntu 24.04
test: ubuntu2404
- stage: Docker_2_17
displayName: Docker 2.17
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.17/linux/{0}/1
targets:
- name: Fedora 39
test: fedora39
- name: Ubuntu 22.04
test: ubuntu2204
- stage: Docker_2_16
displayName: Docker 2.16
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.16/linux/{0}/1
targets:
- name: CentOS 7
test: centos7
- name: Fedora 38
test: fedora38
- name: Ubuntu 22.04
test: ubuntu2204
## Remote
- stage: Remote_devel
@@ -194,14 +207,49 @@ stages:
parameters:
testFormat: devel/{0}/1
targets:
- name: RHEL 10.0
test: rhel/10.0
- name: RHEL 9.6
test: rhel/9.6
- name: RHEL 10.1
test: rhel/10.1
- name: RHEL 9.7
test: rhel/9.7
- name: FreeBSD 14.4
test: freebsd/14.4
- name: FreeBSD 15.0
test: freebsd/15.0
- stage: Remote_2_21
displayName: Remote 2.21
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/{0}/1
targets:
- name: RHEL 10.1
test: rhel/10.1
- name: RHEL 9.7
test: rhel/9.7
- name: FreeBSD 14.4
test: freebsd/14.4
- name: FreeBSD 15.0
test: freebsd/15.0
- stage: Remote_2_20
displayName: Remote 2.20
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.20/{0}/1
targets:
- name: RHEL 10.1
test: rhel/10.1
- name: RHEL 9.7
test: rhel/9.7
- name: FreeBSD 14.3
test: freebsd/14.3
- name: FreeBSD 13.5
test: freebsd/13.5
- stage: Remote_2_19
displayName: Remote 2.19
dependsOn: []
@@ -210,14 +258,15 @@ stages:
parameters:
testFormat: 2.19/{0}/1
targets:
- name: RHEL 10.0
test: rhel/10.0
- name: RHEL 9.5
test: rhel/9.5
- name: RHEL 10.1
test: rhel/10.1
- name: RHEL 9.7
test: rhel/9.7
- name: FreeBSD 14.2
test: freebsd/14.2
- name: FreeBSD 13.5
test: freebsd/13.5
- stage: Remote_2_18
displayName: Remote 2.18
dependsOn: []
@@ -226,52 +275,30 @@ stages:
parameters:
testFormat: 2.18/{0}/1
targets:
- name: RHEL 9.4
test: rhel/9.4
- name: RHEL 10.1
test: rhel/10.1
- name: RHEL 9.7
test: rhel/9.7
- name: FreeBSD 13.5
test: freebsd/13.5
- stage: Remote_2_17
displayName: Remote 2.17
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.17/{0}/1
targets:
- name: RHEL 9.3
test: rhel/9.3
- name: FreeBSD 13.5
test: freebsd/13.5
- stage: Remote_2_16
displayName: Remote 2.16
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.16/{0}/1
targets:
- name: RHEL 8.8
test: rhel/8.8
- name: RHEL 9.2
test: rhel/9.2
## Finally
- stage: Summary
condition: succeededOrFailed()
dependsOn:
- Sanity_2_16
- Remote_2_16
- Docker_2_16
- Sanity_2_17
- Remote_2_17
- Docker_2_17
- Sanity_2_18
- Remote_2_18
- Docker_2_18
- Sanity_2_19
- Remote_2_19
- Docker_2_19
- Sanity_2_20
- Remote_2_20
- Docker_2_20
- Sanity_2_21
- Remote_2_21
- Docker_2_21
- Sanity_devel
- Remote_devel
- Docker_devel

52
.github/BOTMETA.yml vendored
View File

@@ -1,52 +0,0 @@
---
automerge: false
files:
$module_utils/mount.py:
labels: mount
$modules/acl.py:
authors: astorije bcoca
labels: acl
ignore: astorije
$modules/at.py:
authors: risaacson
labels: at
$modules/authorized_key.py:
authors: ansible
labels: authorized_key
$modules/mount.py:
authors: ansible skvidal
maintainers: jtyr
labels: mount
ignore: skvidal
$modules/patch.py:
authors: jirutka luisperlaz
$modules/seboolean.py:
authors: sfromm
labels: seboolean
$modules/selinux.py:
authors: goozbach
maintainers: samdoran
labels: selinux
$modules/synchronize.py:
authors: tima
labels: synchronize
$modules/sysctl.py:
authors: davixx
maintainers: Akasurde
labels: sysctl
$plugins/:
labels: profile
$plugins/debug.py:
labels: debug
$plugins/patch.py:
labels: patch
$plugins/synchronize.py:
labels: synchronize
$plugins/timer.py:
macros:
actions: plugins/action
callbacks: plugins/callback
module_utils: plugins/module_utils
modules: plugins/modules
plugins: plugins/plugins
shells: plugins/shell

35
.github/workflows/certification.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
---
# This workflow calls the latest version of the
# reusable workflow.
# You can copy this file into your respository if
# you want to check against pinned versions of
# Automation Hub tests.
name: Run collection certification checks
on:
pull_request:
branches: [main]
workflow_dispatch:
schedule:
- cron: '0 6 * * *'
concurrency:
group: cert-ver-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
# Files that are not related to the core functionality
# of your collection can cause Ansible Lint to fail.
# If this happens, add an .ansible-lint file that includes
# those files and directories to the root of your
# repository; for example:
# https://github.com/ansible-collections/partner-certification-checker/blob/main/.ansible-lint
# https://github.com/ansible-collections/partner-certification-checker/blob/main/.ansible-lint
# If there are sanity test failures that cannot be fixed and are allowed to ignore
# https://docs.ansible.com/projects/lint/rules/sanity/, create a sanity ignore file
# https://docs.ansible.com/projects/ansible/devel/dev_guide/testing/sanity/ignores.html#ignore-file-location
# for each affected version of ansible-core (for example, `tests/sanity/ignore-2.18.txt`) and add corresponding entries.
jobs:
call:
uses: ansible-collections/partner-certification-checker/.github/workflows/certification-reusable.yml@v0.1

View File

@@ -2,7 +2,7 @@
<!-- Add CI and code coverage badges here. Samples included below. -->
[![Build Status](
https://dev.azure.com/ansible/ansible.posix/_apis/build/status/CI?branchName=main)](https://dev.azure.com/ansible/ansible.posix/_build?definitionId=26)
[![Run Status](https://api.shippable.com/projects/5e669aaf8b17a60007e4d18d/badge?branch=main)]() <!--[![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/ansible.posix)](https://codecov.io/gh/ansible-collections/ansible.posix)-->
[![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/ansible.posix)](https://codecov.io/gh/ansible-collections/ansible.posix)
## Communication

View File

@@ -0,0 +1,3 @@
---
bugfixes:
- ansible.posix.authorized_key - fixes error on permission denied in authorized_key module (https://github.com/ansible-collections/ansible.posix/issues/462).

View File

@@ -0,0 +1,3 @@
bugfixes:
- "firewalld_info - stop returning warnings as return values; this has been deprecated by ansible-core (https://github.com/ansible-collections/ansible.posix/pull/670)."
- "mount - stop returning warnings as return values; this has been deprecated by ansible-core (https://github.com/ansible-collections/ansible.posix/pull/670)."

View File

@@ -0,0 +1,4 @@
trivial:
- Updatng AZP CI matrix to ignore ansible-bad-import-from on six(https://github.com/ansible-collections/ansible.posix/pull/682).
- Skipped sanity[cannot-ignore] to keep backward compatibility with Python2.
- Consolidate all ansible-lint option locations into .ansible-lint file.

View File

@@ -0,0 +1,19 @@
---
minor_changes:
- acl - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
- authorized_key - fix deprecated ``ansible.module_utils._text`` and ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).
- cgroup_perf_recap callback - fix deprecated ``ansible.module_utils._text`` and ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).
- csh shell plugin - fix deprecated ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).
- firewalld_info - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
- fish shell plugin - fix deprecated ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).
- json callback - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
- jsonl callback - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
- mount - fix deprecated ``ansible.module_utils._text`` and ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).
- patch - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
- profile_roles callback - fix deprecated ``ansible.module_utils.six`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
- profile_tasks callback - fix deprecated ``ansible.module_utils.six`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
- rhel_rpm_ostree - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
- rpm_ostree_upgrade - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
- seboolean - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
- synchronize - fix deprecated ``ansible.module_utils._text``, ``ansible.module_utils.common._collections_compat``, and ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).
- sysctl - fix deprecated ``ansible.module_utils._text`` and ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).

View File

@@ -0,0 +1,5 @@
---
trivial:
- AZP - Update AZP matrix to follow ansible-test changes.
- Add ignore file for Ansible Core 2.21.
- Remove ignore lines for ansible-bad-import-from in 2.20 sanity tests.

View File

@@ -21,7 +21,7 @@ __metaclass__ = type
import os
from ansible.errors import AnsibleError, AnsibleAction, _AnsibleActionDone, AnsibleActionFail
from ansible.module_utils._text import to_native
from ansible.module_utils.common.text.converters import to_native
from ansible.module_utils.parsing.convert_bool import boolean
from ansible.plugins.action import ActionBase

View File

@@ -18,12 +18,11 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os.path
from collections.abc import MutableSequence
from shlex import quote as shlex_quote
from ansible import constants as C
from ansible.module_utils.six import string_types
from ansible.module_utils.six.moves import shlex_quote
from ansible.module_utils._text import to_text
from ansible.module_utils.common._collections_compat import MutableSequence
from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.parsing.convert_bool import boolean
from ansible.plugins.action import ActionBase
from ansible.plugins.loader import connection_loader
@@ -417,7 +416,7 @@ class ActionModule(ActionBase):
# Replicate what we do in the module argumentspec handling for lists
if not isinstance(_tmp_args.get('rsync_opts'), MutableSequence):
tmp_rsync_opts = _tmp_args.get('rsync_opts', [])
if isinstance(tmp_rsync_opts, string_types):
if isinstance(tmp_rsync_opts, str):
tmp_rsync_opts = tmp_rsync_opts.split(',')
elif isinstance(tmp_rsync_opts, (int, float)):
tmp_rsync_opts = [to_text(tmp_rsync_opts)]

View File

@@ -141,8 +141,7 @@ from abc import ABCMeta, abstractmethod
from functools import partial
from ansible.module_utils._text import to_bytes, to_text
from ansible.module_utils.six import with_metaclass
from ansible.module_utils.common.text.converters import to_bytes, to_text
from ansible.parsing.ajson import AnsibleJSONEncoder
from ansible.plugins.callback import CallbackBase
@@ -158,7 +157,7 @@ def dict_fromkeys(keys, default=None):
return d
class BaseProf(with_metaclass(ABCMeta, threading.Thread)):
class BaseProf(threading.Thread, metaclass=ABCMeta):
def __init__(self, path, obj=None, writer=None):
threading.Thread.__init__(self) # pylint: disable=non-parent-init-called
self.obj = obj

View File

@@ -48,7 +48,7 @@ import json
from functools import partial
from ansible.inventory.host import Host
from ansible.module_utils._text import to_text
from ansible.module_utils.common.text.converters import to_text
from ansible.parsing.ajson import AnsibleJSONEncoder
from ansible.plugins.callback import CallbackBase

View File

@@ -50,7 +50,7 @@ import copy
from functools import partial
from ansible.inventory.host import Host
from ansible.module_utils._text import to_text
from ansible.module_utils.common.text.converters import to_text
from ansible.parsing.ajson import AnsibleJSONEncoder
from ansible.plugins.callback import CallbackBase

View File

@@ -33,7 +33,7 @@ import collections
import time
from ansible.plugins.callback import CallbackBase
from ansible.module_utils.six.moves import reduce
from functools import reduce
# define start time
t0 = tn = time.time()

View File

@@ -86,7 +86,7 @@ import collections
from datetime import datetime
from ansible.module_utils.six.moves import reduce
from functools import reduce
from ansible.plugins.callback import CallbackBase

View File

@@ -147,7 +147,7 @@ import os
import platform
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native
from ansible.module_utils.common.text.converters import to_native
def split_entry(entry):

View File

@@ -225,12 +225,21 @@ import os.path
import tempfile
import re
import shlex
import errno
import traceback
from operator import itemgetter
from ansible.module_utils._text import to_native
# TODO(Python2): urllib.parse is available in Python 3. This module may run on
# target hosts with Python 2.7 (e.g., older RHEL systems in CI integration tests).
# Remove the try/except fallback to urlparse when Python 2 support is dropped.
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.text.converters import to_native
from ansible.module_utils.urls import fetch_url
from ansible.module_utils.six.moves.urllib.parse import urlparse
class keydict(dict):
@@ -475,16 +484,18 @@ def parsekey(module, raw_key, rank=None):
return (key, key_type, options, comment, rank)
def readfile(filename):
if not os.path.isfile(filename):
return ''
f = open(filename)
def readfile(module, filename):
try:
return f.read()
finally:
f.close()
with open(filename, 'r') as f:
return f.read()
except IOError as e:
if e.errno == errno.EACCES:
module.fail_json(msg="Permission denied on file or path for authorized keys file: %s" % filename,
exception=traceback.format_exc())
elif e.errno == errno.ENOENT:
return ''
else:
raise
def parsekeys(module, lines):
@@ -597,7 +608,7 @@ def enforce_state(module, params):
# check current state -- just get the filename, don't create file
do_write = False
params["keyfile"] = keyfile(module, user, do_write, path, manage_dir)
existing_content = readfile(params["keyfile"])
existing_content = readfile(module, params["keyfile"])
existing_keys = parsekeys(module, existing_content)
# Add a place holder for keys that should exist in the state=present and

View File

@@ -210,7 +210,7 @@ firewalld_info:
'''
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils._text import to_native
from ansible.module_utils.common.text.converters import to_native
from ansible_collections.ansible.posix.plugins.module_utils._respawn import respawn_module, HAS_RESPAWN_UTIL
from ansible_collections.ansible.posix.plugins.module_utils.version import StrictVersion
@@ -319,7 +319,6 @@ def main():
active_zones=module.params['active_zones'],
collected_zones=list(),
undefined_zones=list(),
warnings=list(),
)
# Exit with failure message if requirements modules are not installed.

View File

@@ -225,8 +225,7 @@ import platform
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.ansible.posix.plugins.module_utils.mount import ismount
from ansible.module_utils.six import iteritems
from ansible.module_utils._text import to_bytes, to_native
from ansible.module_utils.common.text.converters import to_bytes, to_native
from ansible.module_utils.parsing.convert_bool import boolean
@@ -279,7 +278,7 @@ def _set_mount_save_old(module, args):
old_lines = []
exists = False
changed = False
escaped_args = dict([(k, _escape_fstab(v)) for k, v in iteritems(args) if k != 'warnings'])
escaped_args = dict([(k, _escape_fstab(v)) for k, v in args.items()])
new_line = '%(src)s %(name)s %(fstype)s %(opts)s %(dump)s %(passno)s\n'
if platform.system() == 'SunOS':
@@ -804,7 +803,6 @@ def main():
passno='-',
fstab=module.params['fstab'],
boot='yes' if module.params['boot'] else 'no',
warnings=[]
)
if args['fstab'] is None:
args['fstab'] = '/etc/vfstab'
@@ -816,7 +814,6 @@ def main():
passno='0',
fstab=module.params['fstab'],
boot='yes',
warnings=[]
)
if args['fstab'] is None:
args['fstab'] = '/etc/fstab'
@@ -834,8 +831,7 @@ def main():
linux_mounts = get_linux_mounts(module)
if linux_mounts is None:
args['warnings'].append('Cannot open file /proc/self/mountinfo.'
' Bind mounts might be misinterpreted.')
module.warn('Cannot open file /proc/self/mountinfo. Bind mounts might be misinterpreted.')
# Override defaults with user specified params
for key in ('src', 'fstype', 'passno', 'opts', 'dump', 'fstab'):
@@ -847,7 +843,7 @@ def main():
# specified in 'opts', mount module will ignore 'boot'.
opts = args['opts'].split(',')
if module.params['boot'] and 'noauto' in opts:
args['warnings'].append("Ignore the 'boot' due to 'opts' contains 'noauto'.")
module.warn("Ignore the 'boot' due to 'opts' contains 'noauto'.")
elif not module.params['boot']:
args['boot'] = 'no'
opts.append('noauto')

View File

@@ -106,7 +106,7 @@ import os
import platform
from traceback import format_exc
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native
from ansible.module_utils.common.text.converters import to_native
class PatchError(Exception):

View File

@@ -73,7 +73,7 @@ import os
import traceback
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_text
from ansible.module_utils.common.text.converters import to_text
def locally_installed(module, pkgname):

View File

@@ -71,7 +71,7 @@ import os
import traceback
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native, to_text
from ansible.module_utils.common.text.converters import to_native, to_text
def rpm_ostree_transaction(module):

View File

@@ -73,7 +73,7 @@ except ImportError:
HAVE_SEMANAGE = False
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils._text import to_text
from ansible.module_utils.common.text.converters import to_text
from ansible_collections.ansible.posix.plugins.module_utils._respawn import respawn_module, HAS_RESPAWN_UTIL

View File

@@ -367,9 +367,16 @@ EXAMPLES = r'''
import os
import errno
# TODO(Python2): shlex.quote was added in Python 3.3. This module may run on
# target hosts with Python 2.7 (e.g., older RHEL systems in CI integration tests).
# Remove the try/except fallback to pipes.quote when Python 2 support is dropped.
try:
from shlex import quote as shlex_quote
except ImportError:
from pipes import quote as shlex_quote
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_bytes, to_native
from ansible.module_utils.six.moves import shlex_quote
from ansible.module_utils.common.text.converters import to_bytes, to_native
client_addr = None

View File

@@ -56,16 +56,6 @@ options:
- Verify token value with the sysctl command and set with C(-w) if necessary.
type: bool
default: false
system_wide:
description:
- If V(true), uses C(sysctl --system) behavior to reload all sysctl configuration files.
- This will reload configuration from C(/etc/sysctl.d/*.conf), C(/run/sysctl.d/*.conf),
C(/usr/local/lib/sysctl.d/*.conf), C(/usr/lib/sysctl.d/*.conf), C(/lib/sysctl.d/*.conf),
and C(/etc/sysctl.conf) in that order.
- If V(false), only reloads the specific sysctl file defined by O(sysctl_file).
- Only applies when O(reload) is V(true).
type: bool
default: false
author:
- David CHANIAL (@davixx)
'''
@@ -110,14 +100,6 @@ EXAMPLES = r'''
sysctl_set: true
state: present
reload: true
# Set vm.swappiness and reload all system sysctl configuration files (equivalent to sysctl --system)
- ansible.posix.sysctl:
name: vm.swappiness
value: '10'
state: present
reload: true
system_wide: true
'''
# ==============================================================
@@ -125,13 +107,20 @@ EXAMPLES = r'''
import os
import platform
import re
import sys
import tempfile
import glob
# TODO(Python2): On Python 2, string_types is basestring (str + unicode).
# This module may run on target hosts with Python 2.7.
# Remove the Python 2 branch when Python 2 support is dropped.
if sys.version_info >= (3, 0):
string_types = str
else:
string_types = basestring # pylint: disable=undefined-variable
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six import string_types
from ansible.module_utils.common.text.converters import to_native
from ansible.module_utils.parsing.convert_bool import BOOLEANS_FALSE, BOOLEANS_TRUE
from ansible.module_utils._text import to_native
class SysctlModule(object):
@@ -140,30 +129,17 @@ class SysctlModule(object):
# success or failure.
LANG_ENV = {'LANG': 'C', 'LC_ALL': 'C', 'LC_MESSAGES': 'C'}
# We define a variable to keep all the directories to be read, equivalent to
# (/sbin/sysctl --system) option
SYSCTL_DIRS = [
'/etc/sysctl.d/*.conf',
'/run/sysctl.d/*.conf',
'/usr/local/lib/sysctl.d/*.conf',
'/usr/lib/sysctl.d/*.conf',
'/lib/sysctl.d/*.conf',
'/etc/sysctl.conf'
]
def __init__(self, module):
self.module = module
self.args = self.module.params
self.sysctl_cmd = self.module.get_bin_path('sysctl', required=True)
self.sysctl_file = self.args['sysctl_file']
self.system_wide = self.args['system_wide']
self.proc_value = None # current token value in proc fs
self.file_value = None # current token value in file
self.file_lines = [] # all lines in the file
self.file_values = {} # dict of token values
self.system_wide_file_value = None # current token value from system-wide files
self.changed = False # will change occur
self.set_proc = False # does sysctl need to set value
@@ -193,36 +169,19 @@ class SysctlModule(object):
if thisname not in self.file_values:
self.file_values[thisname] = None
# if system_wide is enabled, also check system-wide configuration
if self.system_wide:
system_wide_values = self.read_system_wide_sysctl_files()
# If the value exists in system-wide config, use that for comparison
if thisname in system_wide_values:
self.system_wide_file_value = system_wide_values[thisname]
else:
self.system_wide_file_value = None
else:
self.system_wide_file_value = None
# update file contents with desired token/value
self.fix_lines()
# what do we need to do now?
# Determine the effective current value (system-wide takes precedence if enabled)
if self.system_wide and self.system_wide_file_value is not None:
current_file_value = self.system_wide_file_value
else:
current_file_value = self.file_values[thisname]
if current_file_value is None and self.args['state'] == "present":
if self.file_values[thisname] is None and self.args['state'] == "present":
self.changed = True
self.write_file = True
elif current_file_value is None and self.args['state'] == "absent":
elif self.file_values[thisname] is None and self.args['state'] == "absent":
self.changed = False
elif current_file_value and self.args['state'] == "absent":
elif self.file_values[thisname] and self.args['state'] == "absent":
self.changed = True
self.write_file = True
elif current_file_value != self.args['value']:
elif self.file_values[thisname] != self.args['value']:
self.changed = True
self.write_file = True
# with reload=yes we should check if the current system values are
@@ -355,22 +314,15 @@ class SysctlModule(object):
# https://github.com/ansible/ansible/issues/58158
return
else:
if self.system_wide:
for sysctl_file in self.SYSCTL_DIRS:
for conf_file in glob.glob(sysctl_file):
rc, out, err = self.module.run_command([self.sysctl_cmd, '-p', conf_file], environ_update=self.LANG_ENV)
if rc != 0 or self._stderr_failed(err):
self.module.fail_json(msg="Failed to reload sysctl: %s" % to_native(out) + to_native(err))
else:
# system supports reloading via the -p flag to sysctl, so we'll use that
sysctl_args = [self.sysctl_cmd, '-p', self.sysctl_file]
if self.args['ignoreerrors']:
sysctl_args.insert(1, '-e')
# system supports reloading via the -p flag to sysctl, so we'll use that
sysctl_args = [self.sysctl_cmd, '-p', self.sysctl_file]
if self.args['ignoreerrors']:
sysctl_args.insert(1, '-e')
rc, out, err = self.module.run_command(sysctl_args, environ_update=self.LANG_ENV)
rc, out, err = self.module.run_command(sysctl_args, environ_update=self.LANG_ENV)
if rc != 0 or self._stderr_failed(err):
self.module.fail_json(msg="Failed to reload sysctl: %s" % to_native(out) + to_native(err))
if rc != 0 or self._stderr_failed(err):
self.module.fail_json(msg="Failed to reload sysctl: %s" % to_native(out) + to_native(err))
# ==============================================================
# SYSCTL FILE MANAGEMENT
@@ -400,35 +352,6 @@ class SysctlModule(object):
v = v.strip()
self.file_values[k] = v.strip()
# Get the token value from all system-wide sysctl files
def read_system_wide_sysctl_files(self):
"""Read all system-wide sysctl configuration files when system_wide=True"""
system_values = {}
for sysctl_pattern in self.SYSCTL_DIRS:
for conf_file in glob.glob(sysctl_pattern):
if os.path.isfile(conf_file):
try:
with open(conf_file, "r") as read_file:
lines = read_file.readlines()
for line in lines:
line = line.strip()
# don't split empty lines or comments or line without equal sign
if not line or line.startswith(("#", ";")) or "=" not in line:
continue
k, v = line.split('=', 1)
k = k.strip()
v = v.strip()
# Later files override earlier ones (mimicking sysctl --system behavior)
system_values[k] = v.strip()
except IOError:
# Skip files that can't be read
continue
return system_values
# Fix the value in the sysctl file content
def fix_lines(self):
checked = []
@@ -486,8 +409,7 @@ def main():
reload=dict(default=True, type='bool'),
sysctl_set=dict(default=False, type='bool'),
ignoreerrors=dict(default=False, type='bool'),
sysctl_file=dict(default='/etc/sysctl.conf', type='path'),
system_wide=dict(default=False, type='bool'), # system_wide parameter
sysctl_file=dict(default='/etc/sysctl.conf', type='path')
),
supports_check_mode=True,
required_if=[('state', 'present', ['value'])],

View File

@@ -13,8 +13,7 @@ DOCUMENTATION = '''
- shell_common
'''
from ansible.module_utils.six import text_type
from ansible.module_utils.six.moves import shlex_quote
from shlex import quote as shlex_quote
from ansible.plugins.shell import ShellBase
@@ -43,5 +42,5 @@ class ShellModule(ShellBase):
ret = []
# All the -u options must be first, so we process them first
ret += ['-u %s' % k for k, v in kwargs.items() if v is None]
ret += ['%s=%s' % (k, shlex_quote(text_type(v))) for k, v in kwargs.items() if v is not None]
ret += ['%s=%s' % (k, shlex_quote(str(v))) for k, v in kwargs.items() if v is not None]
return 'env %s' % ' '.join(ret)

View File

@@ -13,8 +13,7 @@ DOCUMENTATION = '''
- shell_common
'''
from ansible.module_utils.six import text_type
from ansible.module_utils.six.moves import shlex_quote
from shlex import quote as shlex_quote
from ansible.plugins.shell.sh import ShellModule as ShModule
@@ -42,7 +41,7 @@ class ShellModule(ShModule):
if v is None:
ret.append('set -e %s;' % k)
else:
ret.append('set -lx %s %s;' % (k, shlex_quote(text_type(v))))
ret.append('set -lx %s %s;' % (k, shlex_quote(str(v))))
return ' '.join(ret)
def build_module_command(self, env_string, shebang, cmd, arg_path=None):

View File

@@ -0,0 +1,41 @@
---
# -------------------------------------------------------------
# check permissions
- name: Create a file that is not accessible
ansible.builtin.file:
state: touch
path: "{{ output_dir | expanduser }}/file_permissions"
owner: root
mode: '0000'
- name: Create unprivileged user
ansible.builtin.user:
name: nopriv
create_home: true
- name: Try to delete a key from an unreadable file
become: true
become_user: nopriv
ansible.posix.authorized_key:
user: root
key: "{{ dss_key_basic }}"
state: absent
path: "{{ output_dir | expanduser }}/file_permissions"
register: result
ignore_errors: true
- name: Assert that the key deletion has failed
ansible.builtin.assert:
that:
- result is failed
- name: Remove the file
ansible.builtin.file:
state: absent
path: "{{ output_dir | expanduser }}/file_permissions"
- name: Remove the user
ansible.builtin.user:
name: nopriv
state: absent

View File

@@ -34,3 +34,6 @@
- name: Test for specifying key as a path
ansible.builtin.import_tasks: check_path.yml
- name: Test for permission denied files
ansible.builtin.import_tasks: check_permissions.yml

View File

@@ -229,91 +229,6 @@
ansible.builtin.assert:
that:
- sysctl_test4 is failed
##
## sysctl --system
##
- name: Set vm.swappiness to 10 with --system option
ansible.posix.sysctl:
name: vm.swappiness
value: 10
state: present
reload: false
sysctl_set: true
system_wide: true
register: sysctl_system_test1
- name: Check with sysctl command
ansible.builtin.command: sysctl vm.swappiness
changed_when: false
register: sysctl_check_system1
- name: Debug sysctl_system_test1 sysctl_check_system1
ansible.builtin.debug:
var: item
verbosity: 1
with_items:
- "{{ sysctl_system_test1 }}"
- "{{ sysctl_check_system1 }}"
- name: Validate results for --system option
ansible.builtin.assert:
that:
- sysctl_system_test1 is changed
- sysctl_check_system1.stdout_lines == ["vm.swappiness = 10"]
# Test system_wide with reload=true
- name: Set vm.dirty_ratio to 20 with system_wide and reload=true
ansible.posix.sysctl:
name: vm.dirty_ratio
value: 20
state: present
reload: true
system_wide: true
register: sysctl_system_reload_test
- name: Check vm.dirty_ratio value
ansible.builtin.command: sysctl -n vm.dirty_ratio
changed_when: false
register: sysctl_check_dirty_ratio
- name: Validate system_wide with reload
ansible.builtin.assert:
that:
- sysctl_system_reload_test is changed
- sysctl_check_dirty_ratio.stdout == "20"
# Test system_wide=false behavior (default)
- name: Create custom sysctl file for testing
ansible.builtin.copy:
content: |
# Custom sysctl test file
vm.dirty_background_ratio=5
dest: "{{ output_dir_test }}/custom_sysctl.conf"
mode: "0644"
- name: Set vm.dirty_background_ratio with system_wide=false
ansible.posix.sysctl:
name: vm.dirty_background_ratio
value: 10
state: present
reload: true
system_wide: false
sysctl_file: "{{ output_dir_test }}/custom_sysctl.conf"
register: sysctl_system_false_test
- name: Check custom sysctl file content
ansible.builtin.command: cat {{ output_dir_test }}/custom_sysctl.conf
changed_when: false
register: custom_sysctl_content
- name: Validate system_wide=false behavior
ansible.builtin.assert:
that:
- sysctl_system_false_test is changed
- "'vm.dirty_background_ratio=10' in custom_sysctl_content.stdout"
- name: Test on RHEL VMs
when:
@@ -451,36 +366,3 @@
that:
- stat_result.stat.islnk is defined and stat_result.stat.islnk
- stat_result.stat.lnk_source == '/tmp/ansible_sysctl_test.conf'
# Test sysctl: --system
- name: Set vm.swappiness to 10 with --system option
ansible.posix.sysctl:
name: vm.swappiness
value: 10
state: present
reload: false
sysctl_set: true
system_wide: true
register: sysctl_system_test1
- name: Check with sysctl command
ansible.builtin.command: sysctl vm.swappiness
changed_when: false
register: sysctl_check_system1
- name: Debug sysctl_system_test1 sysctl_check_system1
ansible.builtin.debug:
var: item
verbosity: 1
with_items:
- "{{ sysctl_system_test1 }}"
- "{{ sysctl_check_system1 }}"
- name: Validate results for --system option
ansible.builtin.assert:
that:
- sysctl_system_test1 is changed
- sysctl_check_system1.stdout_lines == ["vm.swappiness = 10"]
- name: Include system_wide specific tests
ansible.builtin.include_tasks: system_wide_tests.yml

View File

@@ -1,203 +0,0 @@
---
# Additional tests specifically for system_wide parameter functionality
- name: Test system_wide parameter basic functionality
block:
# Test system_wide with a simple sysctl parameter
- name: Set vm.swappiness with system_wide=true (first time)
ansible.posix.sysctl:
name: vm.swappiness
value: 35
state: present
reload: false
system_wide: true
register: sysctl_system_wide_first_test
- name: Debug first test result
ansible.builtin.debug:
var: sysctl_system_wide_first_test
- name: Set vm.swappiness with system_wide=true (second time - should not change)
ansible.posix.sysctl:
name: vm.swappiness
value: 35
state: present
reload: false
system_wide: true
register: sysctl_system_wide_second_test
- name: Debug second test result
ansible.builtin.debug:
var: sysctl_system_wide_second_test
- name: Validate system_wide basic functionality
ansible.builtin.assert:
that:
- sysctl_system_wide_first_test is changed
- sysctl_system_wide_second_test is not changed
# Test system_wide with reload=true
- name: Set vm.dirty_expire_centisecs with system_wide=true and reload
ansible.posix.sysctl:
name: vm.dirty_expire_centisecs
value: 3000
state: present
reload: true
system_wide: true
register: sysctl_system_wide_reload_test
- name: Check vm.dirty_expire_centisecs value
ansible.builtin.command: sysctl -n vm.dirty_expire_centisecs
changed_when: false
register: sysctl_check_dirty_expire
- name: Validate system_wide with reload=true
ansible.builtin.assert:
that:
- sysctl_system_wide_reload_test is changed
- sysctl_check_dirty_expire.stdout == "3000"
# Test system_wide=false behavior (default)
- name: Create custom sysctl file for testing system_wide=false
ansible.builtin.copy:
content: |
# Custom sysctl test file
vm.dirty_background_ratio=5
dest: "{{ output_dir_test }}/custom_sysctl.conf"
mode: "0644"
- name: Set vm.dirty_background_ratio with system_wide=false
ansible.posix.sysctl:
name: vm.dirty_background_ratio
value: 10
state: present
reload: true
system_wide: false
sysctl_file: "{{ output_dir_test }}/custom_sysctl.conf"
register: sysctl_system_false_test
- name: Check custom sysctl file content
ansible.builtin.command: cat {{ output_dir_test }}/custom_sysctl.conf
changed_when: false
register: custom_sysctl_content
- name: Validate system_wide=false behavior
ansible.builtin.assert:
that:
- sysctl_system_false_test is changed
- "'vm.dirty_background_ratio=10' in custom_sysctl_content.stdout"
# Test system_wide with check mode
- name: Test system_wide in check mode
ansible.posix.sysctl:
name: vm.swappiness
value: 25
state: present
reload: true
system_wide: true
check_mode: true
register: sysctl_system_wide_check_mode
- name: Validate check mode works with system_wide
ansible.builtin.assert:
that:
- sysctl_system_wide_check_mode is changed
# Test system_wide with missing directories (should not fail)
- name: Test system_wide with potentially missing directories
ansible.posix.sysctl:
name: vm.overcommit_memory
value: 1
state: present
reload: true
system_wide: true
ignoreerrors: true
register: sysctl_system_wide_missing_dirs
- name: Validate system_wide handles missing directories
ansible.builtin.assert:
that:
- sysctl_system_wide_missing_dirs is not failed
- name: Test system_wide with multiple configuration files (RHEL/CentOS only)
when:
- ansible_facts.os_family == 'RedHat'
- ansible_facts.virtualization_type != 'docker'
block:
# Test that system_wide processes multiple configuration files
- name: Create test sysctl.d file
ansible.builtin.copy:
content: |
# Test system-wide sysctl reload
vm.dirty_writeback_centisecs=500
dest: /etc/sysctl.d/99-ansible-test.conf
mode: "0644"
backup: true
register: test_sysctl_file
- name: Apply setting with system_wide to test multiple file processing
ansible.posix.sysctl:
name: vm.overcommit_memory
value: 1
state: present
reload: true
system_wide: true
register: sysctl_multifile_test
- name: Verify both settings are applied
ansible.builtin.shell: |
sysctl -n vm.dirty_writeback_centisecs
sysctl -n vm.overcommit_memory
changed_when: false
register: sysctl_multifile_check
- name: Validate multiple file processing
ansible.builtin.assert:
that:
- sysctl_multifile_test is changed
- "'500' in sysctl_multifile_check.stdout"
- "'1' in sysctl_multifile_check.stdout"
- name: Cleanup test sysctl.d file
ansible.builtin.file:
path: /etc/sysctl.d/99-ansible-test.conf
state: absent
- name: Test system_wide parameter combinations
block:
# Test system_wide with sysctl_set
- name: Test system_wide with sysctl_set=true
ansible.posix.sysctl:
name: vm.swappiness
value: 15
state: present
reload: true
system_wide: true
sysctl_set: true
register: sysctl_system_wide_set_test
- name: Check vm.swappiness value after system_wide + sysctl_set
ansible.builtin.command: sysctl -n vm.swappiness
changed_when: false
register: sysctl_check_swappiness_set
- name: Validate system_wide with sysctl_set
ansible.builtin.assert:
that:
- sysctl_system_wide_set_test is changed
- sysctl_check_swappiness_set.stdout == "15"
# Test system_wide with reload=false (should not trigger system reload)
- name: Test system_wide with reload=false
ansible.posix.sysctl:
name: vm.dirty_ratio
value: 25
state: present
reload: false
system_wide: true
register: sysctl_system_wide_no_reload
- name: Validate system_wide with reload=false
ansible.builtin.assert:
that:
- sysctl_system_wide_no_reload is changed

View File

@@ -1,2 +0,0 @@
tests/utils/shippable/check_matrix.py replace-urlopen
tests/utils/shippable/timing.py shebang

View File

@@ -1,2 +0,0 @@
tests/utils/shippable/check_matrix.py replace-urlopen
tests/utils/shippable/timing.py shebang

View File

@@ -1 +0,0 @@
tests/utils/shippable/timing.py shebang

View File

@@ -1 +0,0 @@
tests/utils/shippable/timing.py shebang

View File

@@ -1 +0,0 @@
tests/utils/shippable/timing.py shebang

View File

@@ -1 +0,0 @@
tests/utils/shippable/timing.py shebang

View File

@@ -1 +0,0 @@
tests/utils/shippable/timing.py shebang

View File

View File

View File

@@ -1,34 +0,0 @@
# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
#
# Compat for python2.7
#
# One unittest needs to import builtins via __import__() so we need to have
# the string that represents it
try:
import __builtin__
except ImportError:
BUILTINS = 'builtins'
else:
BUILTINS = '__builtin__'
__all__ = ['__builtin__']

View File

@@ -1,116 +0,0 @@
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
from ansible.errors import AnsibleParserError
from ansible.parsing.dataloader import DataLoader
from ansible.module_utils._text import to_bytes, to_text
class DictDataLoader(DataLoader):
def __init__(self, file_mapping=None):
file_mapping = {} if file_mapping is None else file_mapping
assert isinstance(file_mapping, dict)
super(DictDataLoader, self).__init__()
self._file_mapping = file_mapping
self._build_known_directories()
self._vault_secrets = None
def load_from_file(self, path, cache=True, unsafe=False):
path = to_text(path)
if path in self._file_mapping:
return self.load(self._file_mapping[path], path)
return None
# TODO: the real _get_file_contents returns a bytestring, so we actually convert the
# unicode/text it's created with to utf-8
def _get_file_contents(self, file_name):
path = to_text(file_name)
if path in self._file_mapping:
return (to_bytes(self._file_mapping[path]), False)
else:
raise AnsibleParserError("file not found: %s" % path)
def path_exists(self, path):
path = to_text(path)
return path in self._file_mapping or path in self._known_directories
def is_file(self, path):
path = to_text(path)
return path in self._file_mapping
def is_directory(self, path):
path = to_text(path)
return path in self._known_directories
def list_directory(self, path):
ret = []
path = to_text(path)
for x in (list(self._file_mapping.keys()) + self._known_directories):
if x.startswith(path):
if os.path.dirname(x) == path:
ret.append(os.path.basename(x))
return ret
def is_executable(self, path):
# FIXME: figure out a way to make paths return true for this
return False
def _add_known_directory(self, directory):
if directory not in self._known_directories:
self._known_directories.append(directory)
def _build_known_directories(self):
self._known_directories = []
for path in self._file_mapping:
dirname = os.path.dirname(path)
while dirname not in ('/', ''):
self._add_known_directory(dirname)
dirname = os.path.dirname(dirname)
def push(self, path, content):
rebuild_dirs = False
if path not in self._file_mapping:
rebuild_dirs = True
self._file_mapping[path] = content
if rebuild_dirs:
self._build_known_directories()
def pop(self, path):
if path in self._file_mapping:
del self._file_mapping[path]
self._build_known_directories()
def clear(self):
self._file_mapping = dict()
self._known_directories = []
def get_basedir(self):
return os.getcwd()
def set_vault_secrets(self, vault_secrets):
self._vault_secrets = vault_secrets

View File

@@ -1,9 +0,0 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from ansible_collections.ansible.posix.tests.unit.compat.mock import MagicMock
from ansible.utils.path import unfrackpath
mock_unfrackpath_noop = MagicMock(spec_set=unfrackpath, side_effect=lambda x, *args, **kwargs: x)

View File

@@ -1,90 +0,0 @@
# (c) 2016, Matt Davis <mdavis@ansible.com>
# (c) 2016, Toshio Kuratomi <tkuratomi@ansible.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import sys
import json
from contextlib import contextmanager
from io import BytesIO, StringIO
from ansible_collections.ansible.posix.tests.unit.compat import unittest
from ansible.module_utils.six import PY3
from ansible.module_utils._text import to_bytes
@contextmanager
def swap_stdin_and_argv(stdin_data='', argv_data=tuple()):
"""
context manager that temporarily masks the test runner's values for stdin and argv
"""
real_stdin = sys.stdin
real_argv = sys.argv
if PY3:
fake_stream = StringIO(stdin_data)
fake_stream.buffer = BytesIO(to_bytes(stdin_data))
else:
fake_stream = BytesIO(to_bytes(stdin_data))
try:
sys.stdin = fake_stream
sys.argv = argv_data
yield
finally:
sys.stdin = real_stdin
sys.argv = real_argv
@contextmanager
def swap_stdout():
"""
context manager that temporarily replaces stdout for tests that need to verify output
"""
old_stdout = sys.stdout
if PY3:
fake_stream = StringIO()
else:
fake_stream = BytesIO()
try:
sys.stdout = fake_stream
yield fake_stream
finally:
sys.stdout = old_stdout
class ModuleTestCase(unittest.TestCase):
def setUp(self, module_args=None):
if module_args is None:
module_args = {'_ansible_remote_tmp': '/tmp', '_ansible_keep_remote_files': False}
args = json.dumps(dict(ANSIBLE_MODULE_ARGS=module_args))
# unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually
self.stdin_swap = swap_stdin_and_argv(stdin_data=args)
self.stdin_swap.__enter__()
def tearDown(self):
# unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually
self.stdin_swap.__exit__(None, None, None)

View File

@@ -1,39 +0,0 @@
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.module_utils._text import to_bytes
from ansible.parsing.vault import VaultSecret
class TextVaultSecret(VaultSecret):
'''A secret piece of text. ie, a password. Tracks text encoding.
The text encoding of the text may not be the default text encoding so
we keep track of the encoding so we encode it to the same bytes.'''
def __init__(self, text, encoding=None, errors=None, _bytes=None):
super(TextVaultSecret, self).__init__()
self.text = text
self.encoding = encoding or 'utf-8'
self._bytes = _bytes
self.errors = errors or 'strict'
@property
def bytes(self):
'''The text encoded with encoding, unless we specifically set _bytes.'''
return self._bytes or to_bytes(self.text, encoding=self.encoding, errors=self.errors)

View File

@@ -1,125 +0,0 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import io
import yaml
from ansible.module_utils.six import PY3
from ansible.parsing.yaml.loader import AnsibleLoader
from ansible.parsing.yaml.dumper import AnsibleDumper
class YamlTestUtils(object):
"""Mixin class to combine with a unittest.TestCase subclass."""
def _loader(self, stream):
"""Vault related tests will want to override this.
Vault cases should setup a AnsibleLoader that has the vault password."""
return AnsibleLoader(stream)
def _dump_stream(self, obj, stream, dumper=None):
"""Dump to a py2-unicode or py3-string stream."""
if PY3:
return yaml.dump(obj, stream, Dumper=dumper)
else:
return yaml.dump(obj, stream, Dumper=dumper, encoding=None)
def _dump_string(self, obj, dumper=None):
"""Dump to a py2-unicode or py3-string"""
if PY3:
return yaml.dump(obj, Dumper=dumper)
else:
return yaml.dump(obj, Dumper=dumper, encoding=None)
def _dump_load_cycle(self, obj):
# Each pass though a dump or load revs the 'generation'
# obj to yaml string
string_from_object_dump = self._dump_string(obj, dumper=AnsibleDumper)
# wrap a stream/file like StringIO around that yaml
stream_from_object_dump = io.StringIO(string_from_object_dump)
loader = self._loader(stream_from_object_dump)
# load the yaml stream to create a new instance of the object (gen 2)
obj_2 = loader.get_data()
# dump the gen 2 objects directory to strings
string_from_object_dump_2 = self._dump_string(obj_2,
dumper=AnsibleDumper)
# The gen 1 and gen 2 yaml strings
self.assertEqual(string_from_object_dump, string_from_object_dump_2)
# the gen 1 (orig) and gen 2 py object
self.assertEqual(obj, obj_2)
# again! gen 3... load strings into py objects
stream_3 = io.StringIO(string_from_object_dump_2)
loader_3 = self._loader(stream_3)
obj_3 = loader_3.get_data()
string_from_object_dump_3 = self._dump_string(obj_3, dumper=AnsibleDumper)
self.assertEqual(obj, obj_3)
# should be transitive, but...
self.assertEqual(obj_2, obj_3)
self.assertEqual(string_from_object_dump, string_from_object_dump_3)
def _old_dump_load_cycle(self, obj):
'''Dump the passed in object to yaml, load it back up, dump again, compare.'''
stream = io.StringIO()
yaml_string = self._dump_string(obj, dumper=AnsibleDumper)
self._dump_stream(obj, stream, dumper=AnsibleDumper)
yaml_string_from_stream = stream.getvalue()
# reset stream
stream.seek(0)
loader = self._loader(stream)
# loader = AnsibleLoader(stream, vault_password=self.vault_password)
obj_from_stream = loader.get_data()
stream_from_string = io.StringIO(yaml_string)
loader2 = self._loader(stream_from_string)
# loader2 = AnsibleLoader(stream_from_string, vault_password=self.vault_password)
obj_from_string = loader2.get_data()
stream_obj_from_stream = io.StringIO()
stream_obj_from_string = io.StringIO()
if PY3:
yaml.dump(obj_from_stream, stream_obj_from_stream, Dumper=AnsibleDumper)
yaml.dump(obj_from_stream, stream_obj_from_string, Dumper=AnsibleDumper)
else:
yaml.dump(obj_from_stream, stream_obj_from_stream, Dumper=AnsibleDumper, encoding=None)
yaml.dump(obj_from_stream, stream_obj_from_string, Dumper=AnsibleDumper, encoding=None)
yaml_string_stream_obj_from_stream = stream_obj_from_stream.getvalue()
yaml_string_stream_obj_from_string = stream_obj_from_string.getvalue()
stream_obj_from_stream.seek(0)
stream_obj_from_string.seek(0)
if PY3:
yaml_string_obj_from_stream = yaml.dump(obj_from_stream, Dumper=AnsibleDumper)
yaml_string_obj_from_string = yaml.dump(obj_from_string, Dumper=AnsibleDumper)
else:
yaml_string_obj_from_stream = yaml.dump(obj_from_stream, Dumper=AnsibleDumper, encoding=None)
yaml_string_obj_from_string = yaml.dump(obj_from_string, Dumper=AnsibleDumper, encoding=None)
assert yaml_string == yaml_string_obj_from_stream
assert yaml_string == yaml_string_obj_from_stream == yaml_string_obj_from_string
assert (yaml_string == yaml_string_obj_from_stream == yaml_string_obj_from_string == yaml_string_stream_obj_from_stream ==
yaml_string_stream_obj_from_string)
assert obj == obj_from_stream
assert obj == obj_from_string
assert obj == yaml_string_obj_from_stream
assert obj == yaml_string_obj_from_string
assert obj == obj_from_stream == obj_from_string == yaml_string_obj_from_stream == yaml_string_obj_from_string
return {'obj': obj,
'yaml_string': yaml_string,
'yaml_string_from_stream': yaml_string_from_stream,
'obj_from_stream': obj_from_stream,
'obj_from_string': obj_from_string,
'yaml_string_obj_from_string': yaml_string_obj_from_string}

View File

@@ -1,32 +0,0 @@
# Copyright (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import json
import pytest
from ansible.module_utils.six import string_types
from ansible.module_utils._text import to_bytes
from ansible.module_utils.common._collections_compat import MutableMapping
@pytest.fixture
def patch_ansible_module(request, mocker):
if isinstance(request.param, string_types):
args = request.param
elif isinstance(request.param, MutableMapping):
if 'ANSIBLE_MODULE_ARGS' not in request.param:
request.param = {'ANSIBLE_MODULE_ARGS': request.param}
if '_ansible_remote_tmp' not in request.param['ANSIBLE_MODULE_ARGS']:
request.param['ANSIBLE_MODULE_ARGS']['_ansible_remote_tmp'] = '/tmp'
if '_ansible_keep_remote_files' not in request.param['ANSIBLE_MODULE_ARGS']:
request.param['ANSIBLE_MODULE_ARGS']['_ansible_keep_remote_files'] = False
args = json.dumps(request.param)
else:
raise Exception('Malformed data to the patch_ansible_module pytest fixture')
mocker.patch('ansible.module_utils.basic._ANSIBLE_ARGS', to_bytes(args))

View File

@@ -7,7 +7,7 @@ import tempfile
from ansible_collections.ansible.posix.tests.unit.compat import unittest
from ansible_collections.ansible.posix.tests.unit.compat.mock import MagicMock
from ansible.module_utils._text import to_bytes
from ansible.module_utils.common.text.converters import to_bytes
from ansible_collections.ansible.posix.plugins.modules.mount import (
get_linux_mounts,

View File

@@ -1,51 +0,0 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import json
from ansible_collections.ansible.posix.tests.unit.compat import unittest
from ansible_collections.ansible.posix.tests.unit.compat.mock import patch
from ansible.module_utils import basic
from ansible.module_utils._text import to_bytes
def set_module_args(args):
if '_ansible_remote_tmp' not in args:
args['_ansible_remote_tmp'] = '/tmp'
if '_ansible_keep_remote_files' not in args:
args['_ansible_keep_remote_files'] = False
args = json.dumps({'ANSIBLE_MODULE_ARGS': args})
basic._ANSIBLE_ARGS = to_bytes(args)
class AnsibleExitJson(Exception):
pass
class AnsibleFailJson(Exception):
pass
def exit_json(*args, **kwargs):
if 'changed' not in kwargs:
kwargs['changed'] = False
raise AnsibleExitJson(kwargs)
def fail_json(*args, **kwargs):
kwargs['failed'] = True
raise AnsibleFailJson(kwargs)
class ModuleTestCase(unittest.TestCase):
def setUp(self):
self.mock_module = patch.multiple(basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json)
self.mock_module.start()
self.mock_sleep = patch('time.sleep')
self.mock_sleep.start()
set_module_args({})
self.addCleanup(self.mock_module.stop)
self.addCleanup(self.mock_sleep.stop)

View File

@@ -9,6 +9,5 @@ command -v ansible
pip install --upgrade --user pip
pip install --upgrade --user ansible-lint
PATH="${PATH/\~/${HOME}}" ansible-lint \
--exclude changelogs/ \
--profile=production
# To specify additional options, you can specify them into .ansible-lint file.
PATH="${PATH/\~/${HOME}}" ansible-lint

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type